Prevent crash when a single layer is enqueued several times for updates
Bug #8504687

Change-Id: I9b01bbc4e3f37af23dfe5e68d3d03ad3d238b94a
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index aeabe366..4a5785c 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -540,13 +540,7 @@
         }
 
         if (CC_UNLIKELY(inFrame || mCaches.drawDeferDisabled)) {
-            OpenGLRenderer* renderer = layer->renderer;
-            renderer->setViewport(layer->layer.getWidth(), layer->layer.getHeight());
-            renderer->prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom,
-                    !layer->isBlend());
-            renderer->drawDisplayList(layer->displayList, dirty,
-                    DisplayList::kReplayFlag_ClipChildren);
-            renderer->finish();
+            layer->render();
         } else {
             layer->defer();
         }
@@ -556,13 +550,6 @@
             startTiling(mSnapshot);
         }
 
-        if (CC_UNLIKELY(inFrame || mCaches.drawDeferDisabled)) {
-            dirty.setEmpty();
-            layer->renderer = NULL;
-        }
-
-        layer->deferredUpdateScheduled = false;
-        layer->displayList = NULL;
         layer->debugDrawUpdate = mCaches.debugLayersUpdates;
 
         return true;
@@ -609,11 +596,12 @@
         // Note: it is very important to update the layers in reverse order
         for (int i = count - 1; i >= 0; i--) {
             sprintf(layerName, "Layer #%d", i);
-            startMark(layerName); {
-                Layer* layer = mLayerUpdates.itemAt(i);
-                layer->flush();
-                mCaches.resourceCache.decrementRefcount(layer);
-            }
+            startMark(layerName);
+
+            Layer* layer = mLayerUpdates.itemAt(i);
+            layer->flush();
+            mCaches.resourceCache.decrementRefcount(layer);
+
             endMark();
         }
 
@@ -626,6 +614,15 @@
 
 void OpenGLRenderer::pushLayerUpdate(Layer* layer) {
     if (layer) {
+        // Make sure we don't introduce duplicates.
+        // SortedVector would do this automatically but we need to respect
+        // the insertion order. The linear search is not an issue since
+        // this list is usually very short (typically one item, at most a few)
+        for (int i = mLayerUpdates.size() - 1; i >= 0; i--) {
+            if (mLayerUpdates.itemAt(i) == layer) {
+                return;
+            }
+        }
         mLayerUpdates.push_back(layer);
         mCaches.resourceCache.incrementRefcount(layer);
     }