drm_hwcomposer: cache the framebuffers given to the GLWorker

This saves some work in EGL/GL that would normally get repeated every frame.
Because the same framebuffers are generally used every frame, this CL adds a
cache containing all the EGL/GL objects that correspond to the given
GraphicBuffer. The cache initially holds a strong reference while rendering,
but once glFinish is called, only a weak reference is held until rendering
to that same GraphicBuffer starts again. The weak reference is used to check
if that GraphicBuffer has been destroyed, which means the corresponding EGL/GL
resources should be destroyed.

The cache can be disabled with the following command:
$ adb shell setprop hwc.drm.use_framebuffer_cache 0

Change-Id: Iddee1efc5bad67f6c4479e7f402354e229c3b0a2
diff --git a/glworker.h b/glworker.h
index 11f4bd9..ce41444 100644
--- a/glworker.h
+++ b/glworker.h
@@ -39,18 +39,39 @@
   ~GLWorkerCompositor();
 
   int Init();
-
   int Composite(hwc_layer_1 *layers, size_t num_layers,
-                sp<GraphicBuffer> framebuffer);
-  int CompositeAndFinish(hwc_layer_1 *layers, size_t num_layers,
-                         sp<GraphicBuffer> framebuffer);
+                const sp<GraphicBuffer> &framebuffer);
+  void Finish();
 
  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();
+  };
+
+  CachedFramebuffer *FindCachedFramebuffer(
+      const sp<GraphicBuffer> &framebuffer);
+  CachedFramebuffer *PrepareAndCacheFramebuffer(
+      const sp<GraphicBuffer> &framebuffer);
+
   EGLDisplay egl_display_;
   EGLContext egl_ctx_;
 
   std::vector<AutoGLProgram> blend_programs_;
   AutoGLBuffer vertex_buffer_;
+
+  std::vector<CachedFramebuffer> cached_framebuffers_;
 };
 }