Create FBOs in LayerCache.

This moves a bit of code away from OpenGLRenderer and matches
what happens with the TextureCache.

Change-Id: I3c67f54f83d7240770daa015861c0e75a1dd8c42
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index ae7719c..027ed79 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -34,9 +34,6 @@
 // Defines
 ///////////////////////////////////////////////////////////////////////////////
 
-// Debug
-#define DEBUG_LAYERS 0
-
 // These properties are defined in mega-bytes
 #define PROPERTY_TEXTURE_CACHE_SIZE "ro.hwui.texture_cache_size"
 #define PROPERTY_LAYER_CACHE_SIZE "ro.hwui.layer_cache_size"
@@ -51,13 +48,6 @@
 #define SV(x, y) { { x, y } }
 #define FV(x, y, u, v) { { x, y }, { u, v } }
 
-// Debug
-#if DEBUG_LAYERS
-    #define LAYER_LOGD(...) LOGD(__VA_ARGS__)
-#else
-    #define LAYER_LOGD(...)
-#endif
-
 ///////////////////////////////////////////////////////////////////////////////
 // Globals
 ///////////////////////////////////////////////////////////////////////////////
@@ -253,6 +243,8 @@
             layer->texture, layer->alpha, layer->mode, layer->blend, true);
 
     LayerSize size(rect.getWidth(), rect.getHeight());
+    // Failing to add the layer to the cache should happen only if the
+    // layer is too large
     if (!mLayerCache.put(size, layer)) {
         LAYER_LOGD("Deleting layer");
 
@@ -300,63 +292,20 @@
 bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top,
         float right, float bottom, int alpha, SkXfermode::Mode mode,int flags) {
 
-    LayerSize size(right - left, bottom - top);
-    Layer* layer = mLayerCache.get(size);
-
     LAYER_LOGD("Requesting layer %dx%d", size.width, size.height);
     LAYER_LOGD("Layer cache size = %d", mLayerCache.getSize());
 
+    GLuint previousFbo = snapshot->previous.get() ? snapshot->previous->fbo : 0;
+    LayerSize size(right - left, bottom - top);
+
+    // TODO VERY IMPORTANT: Fix TextView to not call saveLayer() all the time
+    Layer* layer = mLayerCache.get(size, previousFbo);
     if (!layer) {
-        LAYER_LOGD("Creating new layer");
-
-        layer = new Layer;
-        layer->blend = true;
-
-        // Generate the FBO and attach the texture
-        glGenFramebuffers(1, &layer->fbo);
-        glBindFramebuffer(GL_FRAMEBUFFER, layer->fbo);
-
-        // Generate the texture in which the FBO will draw
-        glGenTextures(1, &layer->texture);
-        glBindTexture(GL_TEXTURE_2D, layer->texture);
-
-        // The FBO will not be scaled, so we can use lower quality filtering
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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);
-
-        // TODO VERY IMPORTANT: Fix TextView to not call saveLayer() all the time
-
-        const GLsizei width = right - left;
-        const GLsizei height = bottom - top;
-
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-        glBindTexture(GL_TEXTURE_2D, 0);
-
-        // Bind texture to FBO
-        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-                layer->texture, 0);
-
-        GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-        if (status != GL_FRAMEBUFFER_COMPLETE) {
-            LOGD("Framebuffer incomplete (GL error code 0x%x)", status);
-
-            GLuint previousFbo = snapshot->previous.get() ? snapshot->previous->fbo : 0;
-            glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
-
-            glDeleteFramebuffers(1, &layer->fbo);
-            glDeleteTextures(1, &layer->texture);
-            delete layer;
-
-            return false;
-        }
-    } else {
-        LAYER_LOGD("Reusing layer");
-        glBindFramebuffer(GL_FRAMEBUFFER, layer->fbo);
+        return false;
     }
 
+    glBindFramebuffer(GL_FRAMEBUFFER, layer->fbo);
+
     // Clear the FBO
     glDisable(GL_SCISSOR_TEST);
     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);