drm_hwcomposer: enhance stability using various wrapper classes
This commit contains a lot of churn because it changes code to use automatic
resource lifetimes as much as possible. As more things get changed, this is
essential to maintaining stability.
In addition, this change changes how layers are passed through the compositor
API. Before each layer was passed down one at a time. Now they are passed in
all at once. This is simpler for the implementation because it makes errors
more atomic and makes decisions easier for the compositors.
Change-Id: Ic3e6b5d0089fb1631ea256adcce9910ed8f38366
diff --git a/autogl.h b/autogl.h
new file mode 100644
index 0000000..5d25e44
--- /dev/null
+++ b/autogl.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AUTO_GL_H_
+#define ANDROID_AUTO_GL_H_
+
+#include <memory>
+#define EGL_EGLEXT_PROTOTYPES
+#define GL_GLEXT_PROTOTYPES
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+// TODO(zachr): use hwc_drm_bo to turn buffer handles into textures
+#ifndef EGL_NATIVE_HANDLE_ANDROID_NVX
+#define EGL_NATIVE_HANDLE_ANDROID_NVX 0x322A
+#endif
+
+namespace android {
+
+#define AUTO_GL_TYPE(name, type, zero, deleter) \
+ struct name##Deleter { \
+ typedef type pointer; \
+ \
+ void operator()(pointer p) const { \
+ if (p != zero) { \
+ deleter; \
+ } \
+ } \
+ }; \
+ typedef std::unique_ptr<type, name##Deleter> name;
+
+AUTO_GL_TYPE(AutoGLFramebuffer, GLuint, 0, glDeleteFramebuffers(1, &p))
+AUTO_GL_TYPE(AutoGLBuffer, GLuint, 0, glDeleteBuffers(1, &p))
+AUTO_GL_TYPE(AutoGLTexture, GLuint, 0, glDeleteTextures(1, &p))
+AUTO_GL_TYPE(AutoGLShader, GLint, 0, glDeleteShader(p))
+AUTO_GL_TYPE(AutoGLProgram, GLint, 0, glDeleteProgram(p))
+
+struct AutoEGLDisplayImage {
+ AutoEGLDisplayImage() : display_(EGL_NO_DISPLAY), image_(EGL_NO_IMAGE_KHR) {
+ }
+
+ AutoEGLDisplayImage(EGLDisplay display, EGLImageKHR image)
+ : display_(display), image_(image) {
+ }
+
+ AutoEGLDisplayImage(const AutoEGLDisplayImage& rhs) = delete;
+ AutoEGLDisplayImage(AutoEGLDisplayImage&& rhs) {
+ clear();
+ std::swap(display_, rhs.display_);
+ std::swap(image_, rhs.image_);
+ }
+
+ ~AutoEGLDisplayImage() {
+ clear();
+ }
+
+ AutoEGLDisplayImage& operator=(const AutoEGLDisplayImage& rhs) = delete;
+ AutoEGLDisplayImage& operator=(AutoEGLDisplayImage&& rhs) {
+ clear();
+ std::swap(display_, rhs.display_);
+ std::swap(image_, rhs.image_);
+ return *this;
+ }
+
+ void reset(EGLDisplay display, EGLImageKHR image) {
+ clear();
+ display_ = display;
+ image_ = image;
+ }
+
+ void clear() {
+ if (image_ != EGL_NO_IMAGE_KHR) {
+ eglDestroyImageKHR(display_, image_);
+ display_ = EGL_NO_DISPLAY;
+ image_ = EGL_NO_IMAGE_KHR;
+ }
+ }
+
+ EGLImageKHR image() const {
+ return image_;
+ }
+
+ private:
+ EGLDisplay display_;
+ EGLImageKHR image_;
+};
+
+struct AutoEGLImageAndGLTexture {
+ AutoEGLDisplayImage image;
+ AutoGLTexture texture;
+};
+}
+
+#endif