summaryrefslogtreecommitdiff
path: root/glworker.h
diff options
context:
space:
mode:
authorZach Reizner <zachr@google.com>2015-06-26 18:25:38 -0700
committerZach Reizner <zachr@google.com>2015-07-08 14:11:59 -0700
commit6cbe883275ec58139ea13fef69628f233822808e (patch)
treee3b83ac4346c7f4d1bf1a54b415464c0dcaf3377 /glworker.h
parentbe98c8cb94511d374238e4a02c92b545b6e5fde2 (diff)
drm_hwcomposer: Add glworker
The glworker allows signalling the fence synchronously once the GL work is done. It also helps performance by putting all GL in a separate thread, which avoids (costly on some GPUs) makecurrent. Change-Id: Ia4ee137df5c9a4b1afcf6180407371d6ba7f699a
Diffstat (limited to 'glworker.h')
-rw-r--r--glworker.h137
1 files changed, 137 insertions, 0 deletions
diff --git a/glworker.h b/glworker.h
new file mode 100644
index 0000000..4ac0e7d
--- /dev/null
+++ b/glworker.h
@@ -0,0 +1,137 @@
+/*
+ * 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_GL_WORKER_H_
+#define ANDROID_GL_WORKER_H_
+
+#include <pthread.h>
+
+#include <memory>
+#include <vector>
+
+#define EGL_EGLEXT_PROTOTYPES
+#define GL_GLEXT_PROTOTYPES
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+struct hwc_layer_1;
+
+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 EGLImageDeleter {
+ typedef EGLImageKHR pointer;
+
+ EGLDisplay egl_display_;
+
+ EGLImageDeleter(EGLDisplay egl_display) : egl_display_(egl_display) {
+ }
+
+ void operator()(EGLImageKHR p) const {
+ if (p != EGL_NO_IMAGE_KHR) {
+ eglDestroyImageKHR(egl_display_, p);
+ }
+ }
+};
+typedef std::unique_ptr<EGLImageKHR, EGLImageDeleter> AutoEGLImageKHR;
+
+struct AutoEGLImageAndGLTexture {
+ AutoEGLImageKHR image;
+ AutoGLTexture texture;
+
+ AutoEGLImageAndGLTexture(EGLDisplay egl_display)
+ : image(EGL_NO_IMAGE_KHR, EGLImageDeleter(egl_display)) {
+ }
+};
+
+class GLWorker {
+ public:
+ struct Work {
+ hwc_layer_1 *layers;
+ size_t num_layers;
+ int timeline_fd;
+ sp<GraphicBuffer> framebuffer;
+
+ Work() = default;
+ Work(const Work &rhs) = delete;
+ };
+
+ class Compositor {
+ public:
+ Compositor();
+ ~Compositor();
+
+ int Init();
+
+ int Composite(hwc_layer_1 *layers, size_t num_layers,
+ sp<GraphicBuffer> framebuffer);
+
+ private:
+ EGLDisplay egl_display_;
+ EGLContext egl_ctx_;
+
+ std::vector<AutoGLProgram> blend_programs_;
+ AutoGLBuffer vertex_buffer_;
+ };
+
+ GLWorker();
+ ~GLWorker();
+
+ int Init();
+
+ int DoWork(Work *work);
+
+ private:
+ bool initialized_;
+ pthread_t thread_;
+ pthread_mutex_t lock_;
+ pthread_cond_t work_ready_cond_;
+ pthread_cond_t work_done_cond_;
+ Work *worker_work_;
+ bool work_ready_;
+ bool worker_exit_;
+ int worker_ret_;
+
+ void WorkerRoutine();
+ int DoComposition(Compositor &compositor, Work *work);
+
+ int SignalWorker(Work *work, bool worker_exit);
+
+ static void *StartRoutine(void *arg);
+};
+}
+
+#endif