Discard framebuffer rendering queues when discarding layers
Bug #5581817

Change-Id: Ie30700a29059d2ea60eb7bd3f8bd20ac48a149ab
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 6bf6004..e2d9ea3 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -305,8 +305,10 @@
         LAYER_RENDERER_LOGD("Recycling layer, %dx%d fbo = %d",
                 layer->getWidth(), layer->getHeight(), layer->getFbo());
 
-        if (layer->getFbo()) {
-            Caches::getInstance().fboCache.put(layer->getFbo());
+        GLuint fbo = layer->getFbo();
+        if (fbo) {
+            flushLayer(layer);
+            Caches::getInstance().fboCache.put(fbo);
         }
 
         if (!Caches::getInstance().layerCache.put(layer)) {
@@ -331,6 +333,26 @@
     }
 }
 
+void LayerRenderer::flushLayer(Layer* layer) {
+#ifdef GL_EXT_discard_framebuffer
+    GLuint fbo = layer->getFbo();
+    if (layer && fbo) {
+        // If possible, discard any enqueud operations on deferred
+        // rendering architectures
+        if (Caches::getInstance().extensions.hasDiscardFramebuffer()) {
+            GLuint previousFbo;
+            glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo);
+
+            GLenum attachments = GL_COLOR_ATTACHMENT0;
+            if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+            glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, &attachments);
+
+            if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
+        }
+    }
+#endif
+}
+
 bool LayerRenderer::copyLayer(Layer* layer, SkBitmap* bitmap) {
     Caches& caches = Caches::getInstance();
     if (layer && layer->isTextureLayer() && bitmap->width() <= caches.maxTextureSize &&