diff --git a/Android.mk b/Android.mk
index 5eef35f..e20615e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -49,6 +49,7 @@
 	drmplane.cpp \
 	drmproperty.cpp \
 	gl_compositor.cpp \
+	glworker.cpp \
 	hwcomposer.cpp \
 	seperate_rects.cpp \
 	vsyncworker.cpp \
diff --git a/gl_compositor.cpp b/gl_compositor.cpp
index 38f1e03..0605c04 100644
--- a/gl_compositor.cpp
+++ b/gl_compositor.cpp
@@ -17,50 +17,23 @@
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 #define LOG_TAG "GLCompositor"
 
-#include <sstream>
-#include <string>
 #include <vector>
 
 #include <cutils/log.h>
 
-#define EGL_EGLEXT_PROTOTYPES
-#define GL_GLEXT_PROTOTYPES
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-#include <hardware/hardware.h>
-#include <hardware/hwcomposer.h>
-
 #include <ui/GraphicBuffer.h>
-#include <ui/PixelFormat.h>
 #include <utils/Trace.h>
 
-#include <cutils/properties.h>
 #include <sync/sync.h>
 #include <sw_sync.h>
 
 #include "drm_hwcomposer.h"
 
 #include "gl_compositor.h"
-#include "seperate_rects.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
-
-#define MAX_OVERLAPPING_LAYERS 64
+#include "glworker.h"
 
 namespace android {
 
-struct GLCompositor::texture_from_handle {
-  EGLImageKHR image;
-  GLuint texture;
-};
-
 static const char *get_gl_error(void);
 static const char *get_egl_error(void);
 static bool has_extension(const char *extension, const char *extensions);
@@ -89,58 +62,31 @@
 
 struct GLTarget {
   sp<GraphicBuffer> fb;
-  EGLImageKHR egl_fb_image;
-  GLuint gl_fb;
-  GLuint gl_fb_tex;
   bool forgotten;
   unsigned composition_count;
 
-  GLTarget()
-      : egl_fb_image(EGL_NO_IMAGE_KHR),
-        gl_fb(0),
-        gl_fb_tex(0),
-        forgotten(true),
-        composition_count(0) {
+  GLTarget() : forgotten(true), composition_count(0) {
   }
 
   void Reset() {
     fb.clear();
-    egl_fb_image = EGL_NO_IMAGE_KHR;
-    gl_fb = 0;
-    gl_fb_tex = 0;
     forgotten = true;
     composition_count = 0;
   }
 
   bool is_some() const {
-    return egl_fb_image != EGL_NO_IMAGE_KHR;
+    return fb != NULL;
   }
 };
 
 struct GLCompositor::priv_data {
-  EGLDisplay egl_display;
-  EGLContext egl_ctx;
-
-  EGLDisplay saved_egl_display;
-  EGLContext saved_egl_ctx;
-  EGLSurface saved_egl_read;
-  EGLSurface saved_egl_draw;
-
   int current_target;
   std::vector<GLTarget> targets;
   std::vector<GLComposition *> compositions;
 
-  std::vector<GLint> blend_programs;
-  GLuint vertex_buffer;
+  GLWorker worker;
 
-  priv_data()
-      : egl_display(EGL_NO_DISPLAY),
-        egl_ctx(EGL_NO_CONTEXT),
-        saved_egl_display(EGL_NO_DISPLAY),
-        saved_egl_ctx(EGL_NO_CONTEXT),
-        saved_egl_read(EGL_NO_SURFACE),
-        saved_egl_draw(EGL_NO_SURFACE),
-        current_target(-1) {
+  priv_data() : current_target(-1) {
   }
 };
 
@@ -152,10 +98,18 @@
   };
 
   GLComposition(GLCompositor *owner, Importer *imp)
-      : compositor(owner), importer(imp), target_handle(-1) {
+      : compositor(owner), importer(imp), target_handle(-1), timeline_fd(-1) {
+    int ret = sw_sync_timeline_create();
+    if (ret < 0) {
+      ALOGE("Failed to create sw sync timeline %d", ret);
+    }
+    timeline_fd = ret;
   }
 
   virtual ~GLComposition() {
+    if (timeline_fd >= 0)
+      close(timeline_fd);
+
     if (compositor == NULL) {
       return;
     }
@@ -186,10 +140,10 @@
       return 1;
     }
 
-    layer_data.push_back(LayerData());
-    LayerData &layer_datum = layer_data.back();
-    layer_datum.layer = *layer;
-    layer_datum.bo = *bo;
+    layer->releaseFenceFd = sw_sync_fence_create(
+        timeline_fd, "GLComposition release fence", layers.size() + 1);
+
+    layers.push_back(*layer);
 
     return importer->ReleaseBuffer(bo);
   }
@@ -202,114 +156,15 @@
   GLCompositor *compositor;
   Importer *importer;
   int target_handle;
-  std::vector<LayerData> layer_data;
+  int timeline_fd;
+  std::vector<hwc_layer_1> layers;
 };
 
-struct RenderingCommand {
-  struct TextureSource {
-    unsigned texture_index;
-    float crop_bounds[4];
-    float alpha;
-  };
-
-  float bounds[4];
-  unsigned texture_count;
-  TextureSource textures[MAX_OVERLAPPING_LAYERS];
-
-  RenderingCommand() : texture_count(0) {
-  }
-};
-
-static void ConstructCommands(const GLComposition &composition,
-                              std::vector<RenderingCommand> *commands) {
-  std::vector<seperate_rects::Rect<float> > in_rects;
-  std::vector<seperate_rects::RectSet<uint64_t, float> > out_rects;
-  int i;
-
-  for (unsigned rect_index = 0; rect_index < composition.layer_data.size();
-       rect_index++) {
-    const struct hwc_layer_1 &layer = composition.layer_data[rect_index].layer;
-    seperate_rects::Rect<float> rect;
-    in_rects.push_back(seperate_rects::Rect<float>(
-        layer.displayFrame.left, layer.displayFrame.top,
-        layer.displayFrame.right, layer.displayFrame.bottom));
-  }
-
-  seperate_frects_64(in_rects, &out_rects);
-
-  for (unsigned rect_index = 0; rect_index < out_rects.size(); rect_index++) {
-    const seperate_rects::RectSet<uint64_t, float> &out_rect =
-        out_rects[rect_index];
-    commands->push_back(RenderingCommand());
-    RenderingCommand &cmd = commands->back();
-
-    memcpy(cmd.bounds, out_rect.rect.bounds, sizeof(cmd.bounds));
-
-    uint64_t tex_set = out_rect.id_set.getBits();
-    for (unsigned i = composition.layer_data.size() - 1; tex_set != 0x0; i--) {
-      if (tex_set & (0x1 << i)) {
-        tex_set &= ~(0x1 << i);
-
-        const struct hwc_layer_1 &layer = composition.layer_data[i].layer;
-
-        seperate_rects::Rect<float> display_rect(
-            layer.displayFrame.left, layer.displayFrame.top,
-            layer.displayFrame.right, layer.displayFrame.bottom);
-        float display_size[2] = {
-            display_rect.bounds[2] - display_rect.bounds[0],
-            display_rect.bounds[3] - display_rect.bounds[1]};
-
-        seperate_rects::Rect<float> crop_rect(
-            layer.sourceCropf.left, layer.sourceCropf.top,
-            layer.sourceCropf.right, layer.sourceCropf.bottom);
-        float crop_size[2] = {crop_rect.bounds[2] - crop_rect.bounds[0],
-                              crop_rect.bounds[3] - crop_rect.bounds[1]};
-
-        RenderingCommand::TextureSource &src = cmd.textures[cmd.texture_count];
-        cmd.texture_count++;
-        src.texture_index = i;
-
-        for (int b = 0; b < 4; b++) {
-          float bound_percent = (cmd.bounds[b] - display_rect.bounds[b % 2]) /
-                                display_size[b % 2];
-          src.crop_bounds[b] =
-              crop_rect.bounds[b % 2] + bound_percent * crop_size[b % 2];
-        }
-
-        if (layer.blending == HWC_BLENDING_NONE) {
-          src.alpha = 1.0f;
-          // This layer is opaque. There is no point in using layers below this
-          // one.
-          break;
-        }
-
-        src.alpha = layer.planeAlpha / 255.0f;
-      }
-    }
-  }
-}
-
 GLCompositor::GLCompositor() {
   priv_ = new priv_data;
 }
 
 GLCompositor::~GLCompositor() {
-  if (BeginContext()) {
-    goto destroy_ctx;
-  }
-
-  glBindFramebuffer(GL_FRAMEBUFFER, 0);
-  glBindTexture(GL_TEXTURE_2D, 0);
-
-  for (std::vector<GLTarget>::iterator it = priv_->targets.end();
-       it != priv_->targets.begin(); it = priv_->targets.end()) {
-    --it;
-    glDeleteFramebuffers(1, &it->gl_fb);
-    glDeleteTextures(1, &it->gl_fb_tex);
-    eglDestroyImageKHR(priv_->egl_display, it->egl_fb_image);
-    priv_->targets.erase(it);
-  }
-
   for (std::vector<GLComposition *>::iterator it = priv_->compositions.end();
        it != priv_->compositions.begin(); it = priv_->compositions.end()) {
     --it;
@@ -320,111 +175,11 @@
     priv_->compositions.erase(it);
   }
 
-destroy_ctx:
-  eglMakeCurrent(priv_->egl_display,
-                 EGL_NO_SURFACE /* No default draw surface */,
-                 EGL_NO_SURFACE /* No default draw read */, EGL_NO_CONTEXT);
-  eglDestroyContext(priv_->egl_display, priv_->egl_ctx);
-
-  EndContext();
   delete priv_;
 }
 
 int GLCompositor::Init() {
-  int ret = 0;
-  const char *egl_extensions;
-  const char *gl_extensions;
-  EGLint num_configs;
-  EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE};
-  EGLConfig egl_config;
-
-  // clang-format off
-  const GLfloat verts[] = {
-    0.0f,  0.0f,    0.0f, 0.0f,
-    0.0f,  1.0f,    0.0f, 1.0f,
-    1.0f,  0.0f,    1.0f, 0.0f,
-    1.0f,  1.0f,    1.0f, 1.0f
-  };
-  // clang-format on
-
-  const EGLint config_attribs[] = {EGL_RENDERABLE_TYPE,
-                                   EGL_OPENGL_ES2_BIT,
-                                   EGL_RED_SIZE,
-                                   8,
-                                   EGL_GREEN_SIZE,
-                                   8,
-                                   EGL_BLUE_SIZE,
-                                   8,
-                                   EGL_NONE};
-
-  const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
-
-  priv_->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-  if (priv_->egl_display == EGL_NO_DISPLAY) {
-    ALOGE("Failed to get egl display");
-    ret = 1;
-    goto out;
-  }
-
-  if (!eglInitialize(priv_->egl_display, NULL, NULL)) {
-    ALOGE("Failed to initialize egl: %s", get_egl_error());
-    ret = 1;
-    goto out;
-  }
-
-  egl_extensions = eglQueryString(priv_->egl_display, EGL_EXTENSIONS);
-
-  // These extensions are all technically required but not always reported due
-  // to meta EGL filtering them out.
-  if (!has_extension("EGL_KHR_image_base", egl_extensions))
-    ALOGW("EGL_KHR_image_base extension not supported");
-
-  if (!has_extension("EGL_ANDROID_image_native_buffer", egl_extensions))
-    ALOGW("EGL_ANDROID_image_native_buffer extension not supported");
-
-  if (!has_extension("EGL_ANDROID_native_fence_sync", egl_extensions))
-    ALOGW("EGL_ANDROID_native_fence_sync extension not supported");
-
-  if (!eglChooseConfig(priv_->egl_display, config_attribs, &egl_config, 1,
-                       &num_configs)) {
-    ALOGE("eglChooseConfig() failed with error: %s", get_egl_error());
-    goto out;
-  }
-
-  priv_->egl_ctx =
-      eglCreateContext(priv_->egl_display, egl_config,
-                       EGL_NO_CONTEXT /* No shared context */, context_attribs);
-
-  if (priv_->egl_ctx == EGL_NO_CONTEXT) {
-    ALOGE("Failed to create OpenGL ES Context: %s", get_egl_error());
-    ret = 1;
-    goto out;
-  }
-
-  ret = BeginContext();
-  if (ret)
-    goto out;
-
-  gl_extensions = (const char *)glGetString(GL_EXTENSIONS);
-
-  if (!has_extension("GL_OES_EGL_image", gl_extensions))
-    ALOGW("GL_OES_EGL_image extension not supported");
-
-  glGenBuffers(1, &priv_->vertex_buffer);
-  glBindBuffer(GL_ARRAY_BUFFER, priv_->vertex_buffer);
-  glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
-  glBindBuffer(GL_ARRAY_BUFFER, 0);
-
-  if (GenerateShaders()) {
-    ret = 1;
-    goto end_ctx;
-  }
-
-end_ctx:
-  EndContext();
-
-out:
-  return ret;
+  return priv_->worker.Init();
 }
 
 Targeting *GLCompositor::targeting() {
@@ -434,63 +189,13 @@
 int GLCompositor::CreateTarget(sp<GraphicBuffer> &buffer) {
   int ret;
 
-  ret = BeginContext();
-  if (ret)
-    return -1;
-
   int target_handle = AllocResource(priv_->targets);
   GLTarget *target = &priv_->targets[target_handle];
 
   target->fb = buffer;
-
-  target->egl_fb_image = eglCreateImageKHR(
-      priv_->egl_display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
-      (EGLClientBuffer)target->fb->getNativeBuffer(), NULL /* no attribs */);
-
-  if (target->egl_fb_image == EGL_NO_IMAGE_KHR) {
-    ALOGE("Failed to make image from target buffer: %s", get_egl_error());
-    ret = -1;
-    goto fail_create_image;
-  }
-
-  glGenTextures(1, &target->gl_fb_tex);
-  glBindTexture(GL_TEXTURE_2D, target->gl_fb_tex);
-  glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
-                               (GLeglImageOES)target->egl_fb_image);
-  glBindTexture(GL_TEXTURE_2D, 0);
-
-  glGenFramebuffers(1, &target->gl_fb);
-  glBindFramebuffer(GL_FRAMEBUFFER, target->gl_fb);
-  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-                         target->gl_fb_tex, 0);
-
-  if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
-    ALOGE("Failed framebuffer check for created target buffer");
-    ret = 1;
-    goto fail_framebuffer_status;
-  }
-
   target->forgotten = false;
 
-  ret = target_handle;
-  goto out;
-
-fail_framebuffer_status:
-  glBindFramebuffer(GL_FRAMEBUFFER, 0);
-  glDeleteFramebuffers(1, &target->gl_fb);
-  glDeleteTextures(1, &target->gl_fb_tex);
-  eglDestroyImageKHR(priv_->egl_display, target->egl_fb_image);
-  target->gl_fb = 0;
-  target->gl_fb_tex = 0;
-  target->egl_fb_image = EGL_NO_IMAGE_KHR;
-
-fail_create_image:
-  target->fb.clear();
-  FreeResource(priv_->targets, target_handle);
-
-out:
-  EndContext();
-  return ret;
+  return target_handle;
 }
 
 void GLCompositor::SetTarget(int target_handle) {
@@ -525,13 +230,6 @@
 void GLCompositor::CheckAndDestroyTarget(int target_handle) {
   GLTarget *target = &priv_->targets[target_handle];
   if (target->composition_count == 0 && target->forgotten) {
-    if (BeginContext() == 0) {
-      glDeleteFramebuffers(1, &target->gl_fb);
-      glDeleteTextures(1, &target->gl_fb_tex);
-      eglDestroyImageKHR(priv_->egl_display, target->egl_fb_image);
-      EndContext();
-    }
-
     FreeResource(priv_->targets, target_handle);
   }
 }
@@ -557,7 +255,9 @@
 
 int GLCompositor::QueueComposition(Composition *composition) {
   if (composition) {
-    int ret = DoComposition(*(GLComposition *)composition);
+    GLComposition *gl_composition = (GLComposition *)composition;
+    int ret = DoComposition(gl_composition);
+    gl_composition->timeline_fd = -1;
     delete composition;
     return ret;
   }
@@ -571,454 +271,25 @@
   return 0;
 }
 
-int GLCompositor::BeginContext() {
-  priv_->saved_egl_display = eglGetCurrentDisplay();
-  priv_->saved_egl_ctx = eglGetCurrentContext();
-
-  if (priv_->saved_egl_display != priv_->egl_display ||
-      priv_->saved_egl_ctx != priv_->egl_ctx) {
-    priv_->saved_egl_read = eglGetCurrentSurface(EGL_READ);
-    priv_->saved_egl_draw = eglGetCurrentSurface(EGL_DRAW);
-  } else {
-    return 0;
-  }
-
-  if (!eglMakeCurrent(priv_->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
-                      priv_->egl_ctx)) {
-    ALOGE("Failed to make the OpenGL ES Context current: %s", get_egl_error());
-    return 1;
-  }
-  return 0;
-}
-
-int GLCompositor::EndContext() {
-  if (priv_->saved_egl_display != eglGetCurrentDisplay() ||
-      priv_->saved_egl_ctx != eglGetCurrentContext()) {
-    if (!eglMakeCurrent(priv_->saved_egl_display, priv_->saved_egl_read,
-                        priv_->saved_egl_draw, priv_->saved_egl_ctx)) {
-      ALOGE("Failed to make the old OpenGL ES Context current: %s",
-            get_egl_error());
-      return 1;
-    }
-  }
-
-  return 0;
-}
-
-GLint CompileAndCheckShader(GLenum type, unsigned source_count,
-                            const GLchar **sources, std::string *shader_log) {
-  GLint status;
-  GLint shader = glCreateShader(type);
-  if (!shader) {
-    *shader_log = "glCreateShader failed";
-    return 0;
-  }
-  glShaderSource(shader, source_count, sources, NULL);
-  glCompileShader(shader);
-  glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
-  if (!status) {
-    if (shader_log) {
-      GLint log_length;
-      glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
-      shader_log->resize(log_length);
-      glGetShaderInfoLog(shader, log_length, NULL, &(*shader_log)[0]);
-    }
-    glDeleteShader(shader);
-    return 0;
-  }
-
-  return shader;
-}
-
-int GLCompositor::GenerateShaders() {
-  // Limits: GL_MAX_VARYING_COMPONENTS, GL_MAX_TEXTURE_IMAGE_UNITS,
-  // GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
-  // clang-format off
-  const GLchar *shader_preamble = "#version 300 es\n#define LAYER_COUNT ";
-
-  const GLchar *vertex_shader_source =
-"\n"
-"precision mediump int;                                                     \n"
-"uniform vec4 uViewport;                                                    \n"
-"uniform sampler2D uLayerTextures[LAYER_COUNT];                             \n"
-"uniform vec4 uLayerCrop[LAYER_COUNT];                                      \n"
-"in vec2 vPosition;                                                         \n"
-"in vec2 vTexCoords;                                                        \n"
-"out vec2 fTexCoords[LAYER_COUNT];                                          \n"
-"void main() {                                                              \n"
-"  for (int i = 0; i < LAYER_COUNT; i++) {                                  \n"
-"    fTexCoords[i] = (uLayerCrop[i].xy + vTexCoords * uLayerCrop[i].zw) /   \n"
-"                     vec2(textureSize(uLayerTextures[i], 0));              \n"
-"  }                                                                        \n"
-"  vec2 scaledPosition = uViewport.xy + vPosition * uViewport.zw;           \n"
-"  gl_Position = vec4(scaledPosition * vec2(2.0) - vec2(1.0), 0.0, 1.0);    \n"
-"}                                                                          \n";
-
-  const GLchar *fragment_shader_source =
-"\n"
-"precision mediump float;                                                   \n"
-"uniform sampler2D uLayerTextures[LAYER_COUNT];                             \n"
-"uniform float uLayerAlpha[LAYER_COUNT];                                    \n"
-"in vec2 fTexCoords[LAYER_COUNT];                                           \n"
-"out vec4 oFragColor;                                                       \n"
-"void main() {                                                              \n"
-"  vec3 color = vec3(0.0, 0.0, 0.0);                                        \n"
-"  float alphaCover = 1.0;                                                  \n"
-"  for (int i = 0; i < LAYER_COUNT; i++) {                                  \n"
-"    vec4 texSample = texture(uLayerTextures[i], fTexCoords[i]);            \n"
-"    float a = texSample.a * uLayerAlpha[i];                                \n"
-"    color += a * alphaCover * texSample.rgb;                               \n"
-"    alphaCover *= 1.0 - a;                                                 \n"
-"    if (alphaCover <= 0.5/255.0)                                           \n"
-"      break;                                                               \n"
-"  }                                                                        \n"
-"  oFragColor = vec4(color, 1.0 - alphaCover);                              \n"
-"}                                                                          \n";
-  // clang-format on
-
-  int i, ret = 1;
-  GLint max_texture_images, vertex_shader, fragment_shader, program, status;
-  std::string shader_log;
-
-  glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_images);
-
-  for (i = 1; i <= max_texture_images; i++) {
-    std::ostringstream layer_count_formatter;
-    layer_count_formatter << i;
-    std::string layer_count(layer_count_formatter.str());
-    const GLchar *shader_sources[3] = {shader_preamble, layer_count.c_str(),
-                                       NULL};
-
-    shader_sources[2] = vertex_shader_source;
-    vertex_shader = CompileAndCheckShader(GL_VERTEX_SHADER, 3, shader_sources,
-                                          ret ? &shader_log : NULL);
-    if (!vertex_shader) {
-      if (ret) {
-        ALOGE("Failed to make vertex shader:\n%s", shader_log.c_str());
-      }
-      break;
-    }
-
-    shader_sources[2] = fragment_shader_source;
-    fragment_shader = CompileAndCheckShader(
-        GL_FRAGMENT_SHADER, 3, shader_sources, ret ? &shader_log : NULL);
-    if (!fragment_shader) {
-      if (ret) {
-        ALOGE("Failed to make fragment shader:\n%s", shader_log.c_str());
-      }
-      goto delete_vs;
-    }
-
-    program = glCreateProgram();
-    if (!program) {
-      if (ret)
-        ALOGE("Failed to create program %s", get_gl_error());
-      goto delete_fs;
-    }
-
-    glAttachShader(program, vertex_shader);
-    glAttachShader(program, fragment_shader);
-    glBindAttribLocation(program, 0, "vPosition");
-    glBindAttribLocation(program, 1, "vTexCoords");
-    glLinkProgram(program);
-    glDetachShader(program, vertex_shader);
-    glDeleteShader(vertex_shader);
-    glDetachShader(program, fragment_shader);
-    glDeleteShader(fragment_shader);
-
-    glGetProgramiv(program, GL_LINK_STATUS, &status);
-    if (!status) {
-      if (ret) {
-        GLint log_length;
-        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
-        std::string program_log(log_length, ' ');
-        glGetProgramInfoLog(program, log_length, NULL, &program_log[0]);
-        ALOGE("Failed to link program: \n%s", program_log.c_str());
-      }
-      glDeleteProgram(program);
-      break;
-    }
-
-    ret = 0;
-    priv_->blend_programs.push_back(program);
-
-    continue;
-
-  delete_fs:
-    glDeleteShader(fragment_shader);
-
-  delete_vs:
-    glDeleteShader(vertex_shader);
-
-    if (ret)
-      break;
-  }
-
-  return ret;
-}
-
-int GLCompositor::DoComposition(const GLComposition &composition) {
+int GLCompositor::DoComposition(GLComposition *composition) {
   ATRACE_CALL();
   int ret = 0;
-  size_t i;
-  std::vector<struct texture_from_handle> layer_textures;
-  std::vector<RenderingCommand> commands;
 
-  if (composition.layer_data.size() == 0) {
-    return -EALREADY;
+  GLTarget *target = &priv_->targets[composition->target_handle];
+  GLWorker::Work work;
+  work.layers = composition->layers.data();
+  work.num_layers = composition->layers.size();
+  work.timeline_fd = composition->timeline_fd;
+  work.framebuffer = target->fb;
+
+  ret = priv_->worker.DoWork(&work);
+
+  if (work.timeline_fd >= 0) {
+    sw_sync_timeline_inc(work.timeline_fd, work.num_layers + 1);
+    close(work.timeline_fd);
   }
 
-  if (BeginContext()) {
-    return -EINVAL;
-  }
-
-  GLTarget *target = &priv_->targets[composition.target_handle];
-  GLint frame_width = target->fb->getWidth();
-  GLint frame_height = target->fb->getHeight();
-  EGLSyncKHR finished_sync;
-
-  for (i = 0; i < composition.layer_data.size(); i++) {
-    const struct hwc_layer_1 *layer = &composition.layer_data[i].layer;
-
-    if (ret) {
-      if (layer->acquireFenceFd >= 0)
-        close(layer->acquireFenceFd);
-      continue;
-    }
-
-    layer_textures.push_back(texture_from_handle());
-    ret = CreateTextureFromHandle(layer->handle, &layer_textures.back());
-    if (!ret) {
-      ret = DoFenceWait(layer->acquireFenceFd);
-    }
-    if (ret) {
-      layer_textures.pop_back();
-      ret = -EINVAL;
-    }
-  }
-
-  if (ret) {
-    goto destroy_textures;
-  }
-
-  ConstructCommands(composition, &commands);
-
-  glBindFramebuffer(GL_FRAMEBUFFER, target->gl_fb);
-
-  glViewport(0, 0, frame_width, frame_height);
-
-  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-  glClear(GL_COLOR_BUFFER_BIT);
-
-  glBindBuffer(GL_ARRAY_BUFFER, priv_->vertex_buffer);
-  glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, NULL);
-  glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4,
-                        (void *)(sizeof(float) * 2));
-  glEnableVertexAttribArray(0);
-  glEnableVertexAttribArray(1);
-
-  for (std::vector<RenderingCommand>::iterator it = commands.begin();
-       it != commands.end(); ++it) {
-    const RenderingCommand &cmd = *it;
-
-    if (cmd.texture_count <= 0) {
-      continue;
-    }
-
-    // TODO(zachr): handle the case of too many overlapping textures for one
-    // area by falling back to rendering as many layers as possible using
-    // multiple blending passes.
-    if (cmd.texture_count > priv_->blend_programs.size()) {
-      ALOGE("Too many layers to render in one area");
-      continue;
-    }
-
-    GLint program = priv_->blend_programs[cmd.texture_count - 1];
-    glUseProgram(program);
-    GLint gl_viewport_loc = glGetUniformLocation(program, "uViewport");
-    GLint gl_tex_loc = glGetUniformLocation(program, "uLayerTextures");
-    GLint gl_crop_loc = glGetUniformLocation(program, "uLayerCrop");
-    GLint gl_alpha_loc = glGetUniformLocation(program, "uLayerAlpha");
-    glUniform4f(gl_viewport_loc, cmd.bounds[0] / (float)frame_width,
-                cmd.bounds[1] / (float)frame_height,
-                (cmd.bounds[2] - cmd.bounds[0]) / (float)frame_width,
-                (cmd.bounds[3] - cmd.bounds[1]) / (float)frame_height);
-
-    for (unsigned src_index = 0; src_index < cmd.texture_count; src_index++) {
-      const RenderingCommand::TextureSource &src = cmd.textures[src_index];
-      glUniform1f(gl_alpha_loc + src_index, src.alpha);
-      glUniform4f(gl_crop_loc + src_index, src.crop_bounds[0],
-                  src.crop_bounds[1], src.crop_bounds[2] - src.crop_bounds[0],
-                  src.crop_bounds[3] - src.crop_bounds[1]);
-
-      glUniform1i(gl_tex_loc + src_index, src_index);
-      glActiveTexture(GL_TEXTURE0 + src_index);
-      glBindTexture(GL_TEXTURE_2D, layer_textures[src.texture_index].texture);
-    }
-
-    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
-    for (unsigned src_index = 0; src_index < cmd.texture_count; src_index++) {
-      glActiveTexture(GL_TEXTURE0 + src_index);
-      glBindTexture(GL_TEXTURE_2D, 0);
-    }
-  }
-
-  glActiveTexture(GL_TEXTURE0);
-  glDisableVertexAttribArray(0);
-  glDisableVertexAttribArray(1);
-  glBindBuffer(GL_ARRAY_BUFFER, 0);
-  glUseProgram(0);
-
-  glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
-  finished_sync =
-      eglCreateSyncKHR(priv_->egl_display, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
-  if (finished_sync != EGL_NO_SYNC_KHR) {
-    glFlush();  // Creates the syncpoint
-    ret = eglDupNativeFenceFDANDROID(priv_->egl_display, finished_sync);
-    eglDestroySyncKHR(priv_->egl_display, finished_sync);
-    if (ret != EGL_NO_NATIVE_FENCE_FD_ANDROID) {
-      goto destroy_textures;
-    }
-  }
-
-  // Used as a fallback if the native sync fence fails.
-  ret = -EALREADY;
-  glFinish();
-
-destroy_textures:
-  for (i = 0; i < layer_textures.size(); i++)
-    DestroyTextureFromHandle(layer_textures[i]);
-
-  EndContext();
-
   return ret;
 }
 
-int GLCompositor::DoFenceWait(int acquireFenceFd) {
-  int ret = 0;
-
-  EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, acquireFenceFd,
-                      EGL_NONE};
-  EGLSyncKHR egl_sync = eglCreateSyncKHR(
-      priv_->egl_display, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
-  if (egl_sync == EGL_NO_SYNC_KHR) {
-    ALOGE("Failed to make EGLSyncKHR from acquireFenceFd: %s", get_egl_error());
-    close(acquireFenceFd);
-    return 1;
-  }
-
-  EGLint success = eglWaitSyncKHR(priv_->egl_display, egl_sync, 0);
-  if (success == EGL_FALSE) {
-    ALOGE("Failed to wait for acquire: %s", get_egl_error());
-    ret = 1;
-  }
-  eglDestroySyncKHR(priv_->egl_display, egl_sync);
-
-  return ret;
-}
-
-int GLCompositor::CreateTextureFromHandle(buffer_handle_t handle,
-                                          struct texture_from_handle *tex) {
-  EGLImageKHR image = eglCreateImageKHR(
-      priv_->egl_display, EGL_NO_CONTEXT, EGL_NATIVE_HANDLE_ANDROID_NVX,
-      (EGLClientBuffer)handle, NULL /* no attribs */);
-
-  if (image == EGL_NO_IMAGE_KHR) {
-    ALOGE("Failed to make image %s %p", get_egl_error(), handle);
-    return 1;
-  }
-
-  glGenTextures(1, &tex->texture);
-  glBindTexture(GL_TEXTURE_2D, tex->texture);
-  glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
-  tex->image = image;
-
-  return 0;
-}
-
-void GLCompositor::DestroyTextureFromHandle(
-    const struct texture_from_handle &tex) {
-  glDeleteTextures(1, &tex.texture);
-  eglDestroyImageKHR(priv_->egl_display, tex.image);
-}
-
-static const char *get_gl_error(void) {
-  switch (glGetError()) {
-    case GL_NO_ERROR:
-      return "GL_NO_ERROR";
-    case GL_INVALID_ENUM:
-      return "GL_INVALID_ENUM";
-    case GL_INVALID_VALUE:
-      return "GL_INVALID_VALUE";
-    case GL_INVALID_OPERATION:
-      return "GL_INVALID_OPERATION";
-    case GL_INVALID_FRAMEBUFFER_OPERATION:
-      return "GL_INVALID_FRAMEBUFFER_OPERATION";
-    case GL_OUT_OF_MEMORY:
-      return "GL_OUT_OF_MEMORY";
-    default:
-      return "Unknown error";
-  }
-}
-
-static const char *get_egl_error(void) {
-  switch (eglGetError()) {
-    case EGL_SUCCESS:
-      return "EGL_SUCCESS";
-    case EGL_NOT_INITIALIZED:
-      return "EGL_NOT_INITIALIZED";
-    case EGL_BAD_ACCESS:
-      return "EGL_BAD_ACCESS";
-    case EGL_BAD_ALLOC:
-      return "EGL_BAD_ALLOC";
-    case EGL_BAD_ATTRIBUTE:
-      return "EGL_BAD_ATTRIBUTE";
-    case EGL_BAD_CONTEXT:
-      return "EGL_BAD_CONTEXT";
-    case EGL_BAD_CONFIG:
-      return "EGL_BAD_CONFIG";
-    case EGL_BAD_CURRENT_SURFACE:
-      return "EGL_BAD_CURRENT_SURFACE";
-    case EGL_BAD_DISPLAY:
-      return "EGL_BAD_DISPLAY";
-    case EGL_BAD_SURFACE:
-      return "EGL_BAD_SURFACE";
-    case EGL_BAD_MATCH:
-      return "EGL_BAD_MATCH";
-    case EGL_BAD_PARAMETER:
-      return "EGL_BAD_PARAMETER";
-    case EGL_BAD_NATIVE_PIXMAP:
-      return "EGL_BAD_NATIVE_PIXMAP";
-    case EGL_BAD_NATIVE_WINDOW:
-      return "EGL_BAD_NATIVE_WINDOW";
-    case EGL_CONTEXT_LOST:
-      return "EGL_CONTEXT_LOST";
-    default:
-      return "Unknown error";
-  }
-}
-
-static bool has_extension(const char *extension, const char *extensions) {
-  const char *start, *where, *terminator;
-  start = extensions;
-  for (;;) {
-    where = (char *)strstr((const char *)start, extension);
-    if (!where)
-      break;
-    terminator = where + strlen(extension);
-    if (where == start || *(where - 1) == ' ')
-      if (*terminator == ' ' || *terminator == '\0')
-        return true;
-    start = terminator;
-  }
-  return false;
-}
-
 }  // namespace android
diff --git a/gl_compositor.h b/gl_compositor.h
index 528d8ac..450ca67 100644
--- a/gl_compositor.h
+++ b/gl_compositor.h
@@ -48,7 +48,7 @@
   int BeginContext();
   int EndContext();
   int GenerateShaders();
-  int DoComposition(const GLComposition &composition);
+  int DoComposition(GLComposition *composition);
   int DoFenceWait(int acquireFenceFd);
   int CreateTextureFromHandle(buffer_handle_t handle,
                               struct texture_from_handle *tex);
diff --git a/glworker.cpp b/glworker.cpp
new file mode 100644
index 0000000..b2deb3e
--- /dev/null
+++ b/glworker.cpp
@@ -0,0 +1,846 @@
+/*
+ * 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.
+ */
+
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#define LOG_TAG "GLWorker"
+
+#include <string>
+#include <sstream>
+
+#include <sys/resource.h>
+
+#include <sync/sync.h>
+#include <sw_sync.h>
+
+#include <hardware/hardware.h>
+#include <hardware/hwcomposer.h>
+
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
+
+#include <utils/Trace.h>
+
+#include "glworker.h"
+
+#include "seperate_rects.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
+
+#define MAX_OVERLAPPING_LAYERS 64
+
+namespace android {
+
+typedef seperate_rects::Rect<float> FRect;
+typedef seperate_rects::RectSet<uint64_t, float> FRectSet;
+
+static const char *GetGLError(void) {
+  switch (glGetError()) {
+    case GL_NO_ERROR:
+      return "GL_NO_ERROR";
+    case GL_INVALID_ENUM:
+      return "GL_INVALID_ENUM";
+    case GL_INVALID_VALUE:
+      return "GL_INVALID_VALUE";
+    case GL_INVALID_OPERATION:
+      return "GL_INVALID_OPERATION";
+    case GL_INVALID_FRAMEBUFFER_OPERATION:
+      return "GL_INVALID_FRAMEBUFFER_OPERATION";
+    case GL_OUT_OF_MEMORY:
+      return "GL_OUT_OF_MEMORY";
+    default:
+      return "Unknown error";
+  }
+}
+
+static const char *GetGLFramebufferError(void) {
+  switch (glCheckFramebufferStatus(GL_FRAMEBUFFER)) {
+    case GL_FRAMEBUFFER_COMPLETE:
+      return "GL_FRAMEBUFFER_COMPLETE";
+    case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+      return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
+    case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+      return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
+    case GL_FRAMEBUFFER_UNSUPPORTED:
+      return "GL_FRAMEBUFFER_UNSUPPORTED";
+    case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
+      return "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
+    default:
+      return "Unknown error";
+  }
+}
+
+static const char *GetEGLError(void) {
+  switch (eglGetError()) {
+    case EGL_SUCCESS:
+      return "EGL_SUCCESS";
+    case EGL_NOT_INITIALIZED:
+      return "EGL_NOT_INITIALIZED";
+    case EGL_BAD_ACCESS:
+      return "EGL_BAD_ACCESS";
+    case EGL_BAD_ALLOC:
+      return "EGL_BAD_ALLOC";
+    case EGL_BAD_ATTRIBUTE:
+      return "EGL_BAD_ATTRIBUTE";
+    case EGL_BAD_CONTEXT:
+      return "EGL_BAD_CONTEXT";
+    case EGL_BAD_CONFIG:
+      return "EGL_BAD_CONFIG";
+    case EGL_BAD_CURRENT_SURFACE:
+      return "EGL_BAD_CURRENT_SURFACE";
+    case EGL_BAD_DISPLAY:
+      return "EGL_BAD_DISPLAY";
+    case EGL_BAD_SURFACE:
+      return "EGL_BAD_SURFACE";
+    case EGL_BAD_MATCH:
+      return "EGL_BAD_MATCH";
+    case EGL_BAD_PARAMETER:
+      return "EGL_BAD_PARAMETER";
+    case EGL_BAD_NATIVE_PIXMAP:
+      return "EGL_BAD_NATIVE_PIXMAP";
+    case EGL_BAD_NATIVE_WINDOW:
+      return "EGL_BAD_NATIVE_WINDOW";
+    case EGL_CONTEXT_LOST:
+      return "EGL_CONTEXT_LOST";
+    default:
+      return "Unknown error";
+  }
+}
+
+static bool HasExtension(const char *extension, const char *extensions) {
+  const char *start, *where, *terminator;
+  start = extensions;
+  for (;;) {
+    where = (char *)strstr((const char *)start, extension);
+    if (!where)
+      break;
+    terminator = where + strlen(extension);
+    if (where == start || *(where - 1) == ' ')
+      if (*terminator == ' ' || *terminator == '\0')
+        return true;
+    start = terminator;
+  }
+  return false;
+}
+
+static AutoGLShader CompileAndCheckShader(GLenum type, unsigned source_count,
+                                          const GLchar **sources,
+                                          std::string *shader_log) {
+  GLint status;
+  AutoGLShader shader(glCreateShader(type));
+  if (shader.get() == 0) {
+    *shader_log = "glCreateShader failed";
+    return 0;
+  }
+  glShaderSource(shader.get(), source_count, sources, NULL);
+  glCompileShader(shader.get());
+  glGetShaderiv(shader.get(), GL_COMPILE_STATUS, &status);
+  if (!status) {
+    if (shader_log) {
+      GLint log_length;
+      glGetShaderiv(shader.get(), GL_INFO_LOG_LENGTH, &log_length);
+      shader_log->resize(log_length);
+      glGetShaderInfoLog(shader.get(), log_length, NULL, &(*shader_log)[0]);
+    }
+    return 0;
+  }
+
+  return shader;
+}
+
+static int GenerateShaders(std::vector<AutoGLProgram> *blend_programs) {
+  // Limits: GL_MAX_VARYING_COMPONENTS, GL_MAX_TEXTURE_IMAGE_UNITS,
+  // GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
+  // clang-format off
+  const GLchar *shader_preamble = "#version 300 es\n#define LAYER_COUNT ";
+
+  const GLchar *vertex_shader_source =
+"\n"
+"precision mediump int;                                                     \n"
+"uniform vec4 uViewport;                                                    \n"
+"uniform sampler2D uLayerTextures[LAYER_COUNT];                             \n"
+"uniform vec4 uLayerCrop[LAYER_COUNT];                                      \n"
+"in vec2 vPosition;                                                         \n"
+"in vec2 vTexCoords;                                                        \n"
+"out vec2 fTexCoords[LAYER_COUNT];                                          \n"
+"void main() {                                                              \n"
+"  for (int i = 0; i < LAYER_COUNT; i++) {                                  \n"
+"    fTexCoords[i] = (uLayerCrop[i].xy + vTexCoords * uLayerCrop[i].zw) /   \n"
+"                     vec2(textureSize(uLayerTextures[i], 0));              \n"
+"  }                                                                        \n"
+"  vec2 scaledPosition = uViewport.xy + vPosition * uViewport.zw;           \n"
+"  gl_Position = vec4(scaledPosition * vec2(2.0) - vec2(1.0), 0.0, 1.0);    \n"
+"}                                                                          \n";
+
+  const GLchar *fragment_shader_source =
+"\n"
+"precision mediump float;                                                   \n"
+"uniform sampler2D uLayerTextures[LAYER_COUNT];                             \n"
+"uniform float uLayerAlpha[LAYER_COUNT];                                    \n"
+"in vec2 fTexCoords[LAYER_COUNT];                                           \n"
+"out vec4 oFragColor;                                                       \n"
+"void main() {                                                              \n"
+"  vec3 color = vec3(0.0, 0.0, 0.0);                                        \n"
+"  float alphaCover = 1.0;                                                  \n"
+"  for (int i = 0; i < LAYER_COUNT; i++) {                                  \n"
+"    vec4 texSample = texture(uLayerTextures[i], fTexCoords[i]);            \n"
+"    float a = texSample.a * uLayerAlpha[i];                                \n"
+"    color += a * alphaCover * texSample.rgb;                               \n"
+"    alphaCover *= 1.0 - a;                                                 \n"
+"    if (alphaCover <= 0.5/255.0)                                           \n"
+"      break;                                                               \n"
+"  }                                                                        \n"
+"  oFragColor = vec4(color, 1.0 - alphaCover);                              \n"
+"}                                                                          \n";
+  // clang-format on
+
+  int i, ret = 1;
+  GLint max_texture_images, status;
+  AutoGLShader vertex_shader, fragment_shader;
+  AutoGLProgram program;
+  std::string shader_log;
+
+  glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_images);
+
+  for (i = 1; i <= max_texture_images; i++) {
+    std::ostringstream layer_count_formatter;
+    layer_count_formatter << i;
+    std::string layer_count(layer_count_formatter.str());
+    const GLchar *shader_sources[3] = {shader_preamble, layer_count.c_str(),
+                                       NULL};
+
+    shader_sources[2] = vertex_shader_source;
+    vertex_shader = CompileAndCheckShader(GL_VERTEX_SHADER, 3, shader_sources,
+                                          ret ? &shader_log : NULL);
+    if (!vertex_shader.get()) {
+      if (ret)
+        ALOGE("Failed to make vertex shader:\n%s", shader_log.c_str());
+      break;
+    }
+
+    shader_sources[2] = fragment_shader_source;
+    fragment_shader = CompileAndCheckShader(
+        GL_FRAGMENT_SHADER, 3, shader_sources, ret ? &shader_log : NULL);
+    if (!fragment_shader.get()) {
+      if (ret)
+        ALOGE("Failed to make fragment shader:\n%s", shader_log.c_str());
+      break;
+    }
+
+    program = AutoGLProgram(glCreateProgram());
+    if (!program.get()) {
+      if (ret)
+        ALOGE("Failed to create program %s", GetGLError());
+      break;
+    }
+
+    glAttachShader(program.get(), vertex_shader.get());
+    glAttachShader(program.get(), fragment_shader.get());
+    glBindAttribLocation(program.get(), 0, "vPosition");
+    glBindAttribLocation(program.get(), 1, "vTexCoords");
+    glLinkProgram(program.get());
+    glDetachShader(program.get(), vertex_shader.get());
+    glDetachShader(program.get(), fragment_shader.get());
+
+    glGetProgramiv(program.get(), GL_LINK_STATUS, &status);
+    if (!status) {
+      if (ret) {
+        GLint log_length;
+        glGetProgramiv(program.get(), GL_INFO_LOG_LENGTH, &log_length);
+        std::string program_log(log_length, ' ');
+        glGetProgramInfoLog(program.get(), log_length, NULL, &program_log[0]);
+        ALOGE("Failed to link program: \n%s", program_log.c_str());
+      }
+      break;
+    }
+
+    ret = 0;
+    blend_programs->emplace_back(std::move(program));
+  }
+
+  return ret;
+}
+
+struct RenderingCommand {
+  struct TextureSource {
+    unsigned texture_index;
+    float crop_bounds[4];
+    float alpha;
+  };
+
+  float bounds[4];
+  unsigned texture_count;
+  TextureSource textures[MAX_OVERLAPPING_LAYERS];
+
+  RenderingCommand() : texture_count(0) {
+  }
+};
+
+static void ConstructCommands(const hwc_layer_1 *layers, size_t num_layers,
+                              std::vector<RenderingCommand> *commands) {
+  std::vector<FRect> in_rects;
+  std::vector<FRectSet> out_rects;
+  int i;
+
+  for (unsigned rect_index = 0; rect_index < num_layers; rect_index++) {
+    const hwc_layer_1 &layer = layers[rect_index];
+    FRect rect;
+    in_rects.push_back(FRect(layer.displayFrame.left, layer.displayFrame.top,
+                             layer.displayFrame.right,
+                             layer.displayFrame.bottom));
+  }
+
+  seperate_frects_64(in_rects, &out_rects);
+
+  for (unsigned rect_index = 0; rect_index < out_rects.size(); rect_index++) {
+    const FRectSet &out_rect = out_rects[rect_index];
+    commands->push_back(RenderingCommand());
+    RenderingCommand &cmd = commands->back();
+
+    memcpy(cmd.bounds, out_rect.rect.bounds, sizeof(cmd.bounds));
+
+    uint64_t tex_set = out_rect.id_set.getBits();
+    for (unsigned i = num_layers - 1; tex_set != 0x0; i--) {
+      if (tex_set & (0x1 << i)) {
+        tex_set &= ~(0x1 << i);
+
+        const hwc_layer_1 &layer = layers[i];
+
+        FRect display_rect(layer.displayFrame.left, layer.displayFrame.top,
+                           layer.displayFrame.right, layer.displayFrame.bottom);
+        float display_size[2] = {
+            display_rect.bounds[2] - display_rect.bounds[0],
+            display_rect.bounds[3] - display_rect.bounds[1]};
+
+        FRect crop_rect(layer.sourceCropf.left, layer.sourceCropf.top,
+                        layer.sourceCropf.right, layer.sourceCropf.bottom);
+        float crop_size[2] = {crop_rect.bounds[2] - crop_rect.bounds[0],
+                              crop_rect.bounds[3] - crop_rect.bounds[1]};
+
+        RenderingCommand::TextureSource &src = cmd.textures[cmd.texture_count];
+        cmd.texture_count++;
+        src.texture_index = i;
+
+        for (int b = 0; b < 4; b++) {
+          float bound_percent = (cmd.bounds[b] - display_rect.bounds[b % 2]) /
+                                display_size[b % 2];
+          src.crop_bounds[b] =
+              crop_rect.bounds[b % 2] + bound_percent * crop_size[b % 2];
+        }
+
+        if (layer.blending == HWC_BLENDING_NONE) {
+          src.alpha = 1.0f;
+          // This layer is opaque. There is no point in using layers below this
+          // one.
+          break;
+        }
+
+        src.alpha = layer.planeAlpha / 255.0f;
+      }
+    }
+  }
+}
+
+static int EGLFenceWait(EGLDisplay egl_display, int acquireFenceFd) {
+  int ret = 0;
+
+  EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, acquireFenceFd,
+                      EGL_NONE};
+  EGLSyncKHR egl_sync =
+      eglCreateSyncKHR(egl_display, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
+  if (egl_sync == EGL_NO_SYNC_KHR) {
+    ALOGE("Failed to make EGLSyncKHR from acquireFenceFd: %s", GetEGLError());
+    close(acquireFenceFd);
+    return 1;
+  }
+
+  EGLint success = eglWaitSyncKHR(egl_display, egl_sync, 0);
+  if (success == EGL_FALSE) {
+    ALOGE("Failed to wait for acquire: %s", GetEGLError());
+    ret = 1;
+  }
+  eglDestroySyncKHR(egl_display, egl_sync);
+
+  return ret;
+}
+
+static int CreateTextureFromHandle(EGLDisplay egl_display,
+                                   buffer_handle_t handle,
+                                   AutoEGLImageAndGLTexture *out) {
+  EGLImageKHR image = eglCreateImageKHR(
+      egl_display, EGL_NO_CONTEXT, EGL_NATIVE_HANDLE_ANDROID_NVX,
+      (EGLClientBuffer)handle, NULL /* no attribs */);
+
+  if (image == EGL_NO_IMAGE_KHR) {
+    ALOGE("Failed to make image %s %p", GetEGLError(), handle);
+    return -EINVAL;
+  }
+
+  GLuint texture;
+  glGenTextures(1, &texture);
+  glBindTexture(GL_TEXTURE_2D, texture);
+  glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+  glBindTexture(GL_TEXTURE_2D, 0);
+
+  out->image.reset(image);
+  out->texture.reset(texture);
+
+  return 0;
+}
+
+GLWorker::Compositor::Compositor()
+    : egl_display_(EGL_NO_DISPLAY), egl_ctx_(EGL_NO_CONTEXT) {
+}
+
+int GLWorker::Compositor::Init() {
+  int ret = 0;
+  const char *egl_extensions;
+  const char *gl_extensions;
+  EGLint num_configs;
+  EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE};
+  EGLConfig egl_config;
+
+  // clang-format off
+  const GLfloat verts[] = {
+    0.0f,  0.0f,    0.0f, 0.0f,
+    0.0f,  2.0f,    0.0f, 2.0f,
+    2.0f,  0.0f,    2.0f, 0.0f
+  };
+  // clang-format on
+
+  const EGLint config_attribs[] = {EGL_RENDERABLE_TYPE,
+                                   EGL_OPENGL_ES2_BIT,
+                                   EGL_RED_SIZE,
+                                   8,
+                                   EGL_GREEN_SIZE,
+                                   8,
+                                   EGL_BLUE_SIZE,
+                                   8,
+                                   EGL_NONE};
+
+  const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
+
+  egl_display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+  if (egl_display_ == EGL_NO_DISPLAY) {
+    ALOGE("Failed to get egl display");
+    return 1;
+  }
+
+  if (!eglInitialize(egl_display_, NULL, NULL)) {
+    ALOGE("Failed to initialize egl: %s", GetEGLError());
+    return 1;
+  }
+
+  egl_extensions = eglQueryString(egl_display_, EGL_EXTENSIONS);
+
+  // These extensions are all technically required but not always reported due
+  // to meta EGL filtering them out.
+  if (!HasExtension("EGL_KHR_image_base", egl_extensions))
+    ALOGW("EGL_KHR_image_base extension not supported");
+
+  if (!HasExtension("EGL_ANDROID_image_native_buffer", egl_extensions))
+    ALOGW("EGL_ANDROID_image_native_buffer extension not supported");
+
+  if (!HasExtension("EGL_ANDROID_native_fence_sync", egl_extensions))
+    ALOGW("EGL_ANDROID_native_fence_sync extension not supported");
+
+  if (!eglChooseConfig(egl_display_, config_attribs, &egl_config, 1,
+                       &num_configs)) {
+    ALOGE("eglChooseConfig() failed with error: %s", GetEGLError());
+    return 1;
+  }
+
+  egl_ctx_ =
+      eglCreateContext(egl_display_, egl_config,
+                       EGL_NO_CONTEXT /* No shared context */, context_attribs);
+
+  if (egl_ctx_ == EGL_NO_CONTEXT) {
+    ALOGE("Failed to create OpenGL ES Context: %s", GetEGLError());
+    return 1;
+  }
+
+  if (!eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_ctx_)) {
+    ALOGE("Failed to make the OpenGL ES Context current: %s", GetEGLError());
+    return 1;
+  }
+
+  gl_extensions = (const char *)glGetString(GL_EXTENSIONS);
+
+  if (!HasExtension("GL_OES_EGL_image", gl_extensions))
+    ALOGW("GL_OES_EGL_image extension not supported");
+
+  GLuint vertex_buffer;
+  glGenBuffers(1, &vertex_buffer);
+  glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
+  glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
+  glBindBuffer(GL_ARRAY_BUFFER, 0);
+  vertex_buffer_.reset(vertex_buffer);
+
+  if (GenerateShaders(&blend_programs_)) {
+    return 1;
+  }
+
+  return 0;
+}
+
+GLWorker::Compositor::~Compositor() {
+  if (egl_display_ != EGL_NO_DISPLAY && egl_ctx_ != EGL_NO_CONTEXT)
+    if (eglDestroyContext(egl_display_, egl_ctx_) == EGL_FALSE)
+      ALOGE("Failed to destroy OpenGL ES Context: %s", GetEGLError());
+}
+
+int GLWorker::Compositor::Composite(hwc_layer_1 *layers, size_t num_layers,
+                                    sp<GraphicBuffer> framebuffer) {
+  ATRACE_CALL();
+  int ret = 0;
+  size_t i;
+  std::vector<AutoEGLImageAndGLTexture> layer_textures;
+  std::vector<RenderingCommand> commands;
+
+  if (num_layers == 0) {
+    return -EALREADY;
+  }
+
+  GLint frame_width = framebuffer->getWidth();
+  GLint frame_height = framebuffer->getHeight();
+  EGLSyncKHR finished_sync;
+
+  AutoEGLImageKHR egl_fb_image(
+      eglCreateImageKHR(egl_display_, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
+                        (EGLClientBuffer)framebuffer->getNativeBuffer(),
+                        NULL /* no attribs */),
+      EGLImageDeleter(egl_display_));
+
+  if (egl_fb_image.get() == EGL_NO_IMAGE_KHR) {
+    ALOGE("Failed to make image from target buffer: %s", GetEGLError());
+    return -EINVAL;
+  }
+
+  GLuint gl_fb_tex;
+  glGenTextures(1, &gl_fb_tex);
+  AutoGLTexture gl_fb_tex_auto(gl_fb_tex);
+  glBindTexture(GL_TEXTURE_2D, gl_fb_tex);
+  glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
+                               (GLeglImageOES)egl_fb_image.get());
+  glBindTexture(GL_TEXTURE_2D, 0);
+
+  GLuint gl_fb;
+  glGenFramebuffers(1, &gl_fb);
+  AutoGLFramebuffer gl_fb_auto(gl_fb);
+  glBindFramebuffer(GL_FRAMEBUFFER, gl_fb);
+  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+                         gl_fb_tex, 0);
+
+  if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+    ALOGE("Failed framebuffer check for created target buffer: %s",
+          GetGLFramebufferError());
+    return -EINVAL;
+  }
+
+  for (i = 0; i < num_layers; i++) {
+    const struct hwc_layer_1 *layer = &layers[i];
+
+    if (ret) {
+      if (layer->acquireFenceFd >= 0)
+        close(layer->acquireFenceFd);
+      continue;
+    }
+
+    layer_textures.emplace_back(egl_display_);
+    ret = CreateTextureFromHandle(egl_display_, layer->handle,
+                                  &layer_textures.back());
+    if (!ret) {
+      ret = EGLFenceWait(egl_display_, layer->acquireFenceFd);
+    }
+    if (ret) {
+      layer_textures.pop_back();
+      ret = -EINVAL;
+    }
+  }
+
+  if (ret)
+    return ret;
+
+  ConstructCommands(layers, num_layers, &commands);
+
+  glViewport(0, 0, frame_width, frame_height);
+
+  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+  glClear(GL_COLOR_BUFFER_BIT);
+
+  glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_.get());
+  glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, NULL);
+  glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4,
+                        (void *)(sizeof(float) * 2));
+  glEnableVertexAttribArray(0);
+  glEnableVertexAttribArray(1);
+  glEnable(GL_SCISSOR_TEST);
+
+  for (const RenderingCommand &cmd : commands) {
+    if (cmd.texture_count <= 0) {
+      continue;
+    }
+
+    // TODO(zachr): handle the case of too many overlapping textures for one
+    // area by falling back to rendering as many layers as possible using
+    // multiple blending passes.
+    if (cmd.texture_count > blend_programs_.size()) {
+      ALOGE("Too many layers to render in one area");
+      continue;
+    }
+
+    GLint program = blend_programs_[cmd.texture_count - 1].get();
+    glUseProgram(program);
+    GLint gl_viewport_loc = glGetUniformLocation(program, "uViewport");
+    GLint gl_tex_loc = glGetUniformLocation(program, "uLayerTextures");
+    GLint gl_crop_loc = glGetUniformLocation(program, "uLayerCrop");
+    GLint gl_alpha_loc = glGetUniformLocation(program, "uLayerAlpha");
+    glUniform4f(gl_viewport_loc, cmd.bounds[0] / (float)frame_width,
+                cmd.bounds[1] / (float)frame_height,
+                (cmd.bounds[2] - cmd.bounds[0]) / (float)frame_width,
+                (cmd.bounds[3] - cmd.bounds[1]) / (float)frame_height);
+
+    for (unsigned src_index = 0; src_index < cmd.texture_count; src_index++) {
+      const RenderingCommand::TextureSource &src = cmd.textures[src_index];
+      glUniform1f(gl_alpha_loc + src_index, src.alpha);
+      glUniform4f(gl_crop_loc + src_index, src.crop_bounds[0],
+                  src.crop_bounds[1], src.crop_bounds[2] - src.crop_bounds[0],
+                  src.crop_bounds[3] - src.crop_bounds[1]);
+
+      glUniform1i(gl_tex_loc + src_index, src_index);
+      glActiveTexture(GL_TEXTURE0 + src_index);
+      glBindTexture(GL_TEXTURE_2D,
+                    layer_textures[src.texture_index].texture.get());
+    }
+
+    glScissor(cmd.bounds[0], cmd.bounds[1], cmd.bounds[2] - cmd.bounds[0],
+              cmd.bounds[3] - cmd.bounds[1]);
+    glDrawArrays(GL_TRIANGLES, 0, 3);
+
+    for (unsigned src_index = 0; src_index < cmd.texture_count; src_index++) {
+      glActiveTexture(GL_TEXTURE0 + src_index);
+      glBindTexture(GL_TEXTURE_2D, 0);
+    }
+  }
+
+  glDisable(GL_SCISSOR_TEST);
+  glActiveTexture(GL_TEXTURE0);
+  glDisableVertexAttribArray(0);
+  glDisableVertexAttribArray(1);
+  glBindBuffer(GL_ARRAY_BUFFER, 0);
+  glUseProgram(0);
+
+  glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+  return ret;
+}
+
+int GLWorker::DoComposition(Compositor &compositor, Work *work) {
+  int ret =
+      compositor.Composite(work->layers, work->num_layers, work->framebuffer);
+
+  int timeline_fd = work->timeline_fd;
+  work->timeline_fd = -1;
+
+  if (ret) {
+    worker_ret_ = ret;
+    glFinish();
+    sw_sync_timeline_inc(timeline_fd, work->num_layers);
+    close(timeline_fd);
+    return pthread_cond_signal(&work_done_cond_);
+  }
+
+  unsigned timeline_count = work->num_layers + 1;
+  worker_ret_ = sw_sync_fence_create(timeline_fd, "GLComposition done fence",
+                                     timeline_count);
+  ret = pthread_cond_signal(&work_done_cond_);
+
+  glFinish();
+
+  sw_sync_timeline_inc(timeline_fd, timeline_count);
+  close(timeline_fd);
+
+  return ret;
+}
+
+GLWorker::GLWorker() : initialized_(false) {
+}
+
+GLWorker::~GLWorker() {
+  if (!initialized_)
+    return;
+
+  if (SignalWorker(NULL, true) != 0 || pthread_join(thread_, NULL) != 0)
+    pthread_kill(thread_, SIGTERM);
+
+  pthread_cond_destroy(&work_ready_cond_);
+  pthread_cond_destroy(&work_done_cond_);
+  pthread_mutex_destroy(&lock_);
+}
+
+#define TRY(x, n, g)                  \
+  ret = x;                            \
+  if (ret) {                          \
+    ALOGE("Failed to " n " %d", ret); \
+    g;                                \
+  }
+
+#define TRY_RETURN(x, n) TRY(x, n, return ret)
+
+int GLWorker::Init() {
+  int ret = 0;
+
+  worker_work_ = NULL;
+  worker_exit_ = false;
+  worker_ret_ = -1;
+
+  ret = pthread_cond_init(&work_ready_cond_, NULL);
+  if (ret) {
+    ALOGE("Failed to int GLThread condition %d", ret);
+    return ret;
+  }
+
+  ret = pthread_cond_init(&work_done_cond_, NULL);
+  if (ret) {
+    ALOGE("Failed to int GLThread condition %d", ret);
+    pthread_cond_destroy(&work_ready_cond_);
+    return ret;
+  }
+
+  ret = pthread_mutex_init(&lock_, NULL);
+  if (ret) {
+    ALOGE("Failed to init GLThread lock %d", ret);
+    pthread_cond_destroy(&work_ready_cond_);
+    pthread_cond_destroy(&work_done_cond_);
+    return ret;
+  }
+
+  ret = pthread_create(&thread_, NULL, StartRoutine, this);
+  if (ret) {
+    ALOGE("Failed to create GLThread %d", ret);
+    pthread_cond_destroy(&work_ready_cond_);
+    pthread_cond_destroy(&work_done_cond_);
+    pthread_mutex_destroy(&lock_);
+    return ret;
+  }
+
+  initialized_ = true;
+
+  TRY_RETURN(pthread_mutex_lock(&lock_), "lock GLThread");
+
+  while (!worker_exit_ && worker_ret_ != 0)
+    TRY(pthread_cond_wait(&work_done_cond_, &lock_), "wait on condition",
+        goto out_unlock);
+
+  ret = worker_ret_;
+
+out_unlock:
+  int unlock_ret = pthread_mutex_unlock(&lock_);
+  if (unlock_ret) {
+    ret = unlock_ret;
+    ALOGE("Failed to unlock GLThread %d", unlock_ret);
+  }
+  return ret;
+}
+
+int GLWorker::SignalWorker(Work *work, bool worker_exit) {
+  int ret = 0;
+  if (worker_exit_)
+    return -EINVAL;
+  TRY_RETURN(pthread_mutex_lock(&lock_), "lock GLThread");
+  worker_work_ = work;
+  worker_exit_ = worker_exit;
+  ret = pthread_cond_signal(&work_ready_cond_);
+  if (ret) {
+    ALOGE("Failed to signal GLThread caller %d", ret);
+    pthread_mutex_unlock(&lock_);
+    return ret;
+  }
+  ret = pthread_cond_wait(&work_done_cond_, &lock_);
+  if (ret) {
+    ALOGE("Failed to wait on GLThread %d", ret);
+    pthread_mutex_unlock(&lock_);
+    return ret;
+  }
+
+  ret = worker_ret_;
+  if (ret) {
+    pthread_mutex_unlock(&lock_);
+    return ret;
+  }
+  TRY_RETURN(pthread_mutex_unlock(&lock_), "unlock GLThread");
+  return ret;
+}
+
+int GLWorker::DoWork(Work *work) {
+  return SignalWorker(work, false);
+}
+
+void GLWorker::WorkerRoutine() {
+  int ret = 0;
+
+  TRY(pthread_mutex_lock(&lock_), "lock GLThread", return );
+
+  Compositor compositor;
+
+  TRY(compositor.Init(), "initialize GL", goto out_signal_done);
+
+  worker_ret_ = 0;
+  TRY(pthread_cond_signal(&work_done_cond_), "signal GLThread caller",
+      goto out_signal_done);
+
+  while (true) {
+    while (worker_work_ == NULL && !worker_exit_)
+      TRY(pthread_cond_wait(&work_ready_cond_, &lock_), "wait on condition",
+          goto out_signal_done);
+
+    if (worker_exit_) {
+      ret = 0;
+      break;
+    }
+
+    ret = DoComposition(compositor, worker_work_);
+
+    worker_work_ = NULL;
+    if (ret) {
+      break;
+    }
+  }
+
+out_signal_done:
+  worker_exit_ = true;
+  worker_ret_ = ret;
+  TRY(pthread_cond_signal(&work_done_cond_), "signal GLThread caller",
+      goto out_unlock);
+out_unlock:
+  TRY(pthread_mutex_unlock(&lock_), "unlock GLThread", return );
+}
+
+/* static */
+void *GLWorker::StartRoutine(void *arg) {
+  setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
+  GLWorker *worker = (GLWorker *)arg;
+  worker->WorkerRoutine();
+  return NULL;
+}
+
+}  // namespace android
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
