diff options
author | Zach Reizner <zachr@google.com> | 2015-06-26 18:25:38 -0700 |
---|---|---|
committer | Zach Reizner <zachr@google.com> | 2015-07-08 14:11:59 -0700 |
commit | 6cbe883275ec58139ea13fef69628f233822808e (patch) | |
tree | e3b83ac4346c7f4d1bf1a54b415464c0dcaf3377 /glworker.h | |
parent | be98c8cb94511d374238e4a02c92b545b6e5fde2 (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.h | 137 |
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 |