#ifndef ANDROID_GL_WORKER_H_
#define ANDROID_GL_WORKER_H_
-#include <pthread.h>
-
-#include <memory>
#include <vector>
#define EGL_EGLEXT_PROTOTYPES
#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) {
- }
+#include <ui/GraphicBuffer.h>
- void operator()(EGLImageKHR p) const {
- if (p != EGL_NO_IMAGE_KHR) {
- eglDestroyImageKHR(egl_display_, p);
- }
- }
-};
-typedef std::unique_ptr<EGLImageKHR, EGLImageDeleter> AutoEGLImageKHR;
+#include "autogl.h"
-struct AutoEGLImageAndGLTexture {
- AutoEGLImageKHR image;
- AutoGLTexture texture;
+namespace android {
- AutoEGLImageAndGLTexture(EGLDisplay egl_display)
- : image(EGL_NO_IMAGE_KHR, EGLImageDeleter(egl_display)) {
- }
-};
+struct DrmHwcLayer;
+struct DrmCompositionRegion;
-class GLWorker {
+class GLWorkerCompositor {
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();
+ GLWorkerCompositor();
+ ~GLWorkerCompositor();
- int Composite(hwc_layer_1 *layers, size_t num_layers,
- sp<GraphicBuffer> framebuffer);
-
- private:
- EGLDisplay egl_display_;
- EGLContext egl_ctx_;
+ int Init();
+ int Composite(DrmHwcLayer *layers, DrmCompositionRegion *regions,
+ size_t num_regions, const sp<GraphicBuffer> &framebuffer);
+ void Finish();
- std::vector<AutoGLProgram> blend_programs_;
- AutoGLBuffer vertex_buffer_;
+ private:
+ struct CachedFramebuffer {
+ // If the strong_framebuffer is non-NULL, we are holding a strong reference
+ // until we are sure rendering is done. The weak reference will be equal in
+ // that case.
+ sp<GraphicBuffer> strong_framebuffer;
+ wp<GraphicBuffer> weak_framebuffer;
+ AutoEGLDisplayImage egl_fb_image;
+ AutoGLTexture gl_fb_tex;
+ AutoGLFramebuffer gl_fb;
+
+ CachedFramebuffer(const sp<GraphicBuffer> &gb, AutoEGLDisplayImage &&image,
+ AutoGLTexture &&tex, AutoGLFramebuffer &&fb);
+
+ bool Promote();
};
- GLWorker();
- ~GLWorker();
+ CachedFramebuffer *FindCachedFramebuffer(
+ const sp<GraphicBuffer> &framebuffer);
+ CachedFramebuffer *PrepareAndCacheFramebuffer(
+ const sp<GraphicBuffer> &framebuffer);
- int Init();
+ GLint PrepareAndCacheProgram(unsigned texture_count);
- int DoWork(Work *work);
+ EGLDisplay egl_display_;
+ EGLContext egl_ctx_;
- 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);
+ std::vector<AutoGLProgram> blend_programs_;
+ AutoGLBuffer vertex_buffer_;
+
+ std::vector<CachedFramebuffer> cached_framebuffers_;
};
}