Avoid over-damaging layer area for multidraws

bug:19608961

Change-Id: Ib7495f155da62a352e9a010a362fd40ec0acad21
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 433e178..3d48fa69 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1097,7 +1097,7 @@
 }
 
 void OpenGLRenderer::dirtyLayerUnchecked(Rect& bounds, Region* region) {
-    if (bounds.intersect(mState.currentClipRect())) {
+    if (CC_LIKELY(!bounds.isEmpty() && bounds.intersect(mState.currentClipRect()))) {
         bounds.snapToPixelBoundaries();
         android::Rect dirty(bounds.left, bounds.top, bounds.right, bounds.bottom);
         if (!dirty.isEmpty()) {
@@ -1146,7 +1146,7 @@
                 .setTransform(*currentSnapshot(), transformFlags)
                 .setModelViewOffsetRect(0, 0, Rect(currentSnapshot()->getClipRect()))
                 .build();
-        renderGlop(glop, false);
+        renderGlop(glop, GlopRenderType::LayerClear);
 
         if (scissorChanged) mRenderState.scissor().setEnabled(true);
     } else {
@@ -1454,10 +1454,15 @@
 #endif
 }
 
-void OpenGLRenderer::renderGlop(const Glop& glop, bool clearLayer) {
+void OpenGLRenderer::renderGlop(const Glop& glop, GlopRenderType type) {
     // TODO: It would be best if we could do this before quickRejectSetupScissor()
     //       changes the scissor test state
-    if (clearLayer) clearLayerRegions();
+    if (type != GlopRenderType::LayerClear) {
+        // Regular draws need to clear the dirty area on the layer before they start drawing on top
+        // of it. If this draw *is* a layer clear, it skips the clear step (since it would
+        // infinitely recurse)
+        clearLayerRegions();
+    }
 
     if (mState.getDirtyClip()) {
         if (mRenderState.scissor().isEnabled()) {
@@ -1467,7 +1472,7 @@
         setStencilFromClip();
     }
     mRenderState.render(glop);
-    if (!mRenderState.stencil().isWriteEnabled()) {
+    if (type == GlopRenderType::Standard && !mRenderState.stencil().isWriteEnabled()) {
         // TODO: specify more clearly when a draw should dirty the layer.
         // is writing to the stencil the only time we should ignore this?
         dirtyLayer(glop.bounds.left, glop.bounds.top, glop.bounds.right, glop.bounds.bottom);
@@ -1540,7 +1545,7 @@
             .setTransform(*currentSnapshot(), transformFlags)
             .setModelViewOffsetRectOptionalSnap(snap, x, y, Rect(0, 0, bounds.getWidth(), bounds.getHeight()))
             .build();
-    renderGlop(glop);
+    renderGlop(glop, GlopRenderType::Multi);
 }
 
 void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
@@ -1738,7 +1743,7 @@
             .setTransform(*currentSnapshot(), transformFlags)
             .setModelViewOffsetRect(0, 0, Rect(0, 0, 0, 0))
             .build();
-    renderGlop(glop);
+    renderGlop(glop, GlopRenderType::Multi);
 }
 
 void OpenGLRenderer::drawVertexBuffer(float translateX, float translateY,
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 5850dc6..800a9f9 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -535,7 +535,13 @@
     RenderState& mRenderState;
 
 private:
-    void renderGlop(const Glop& glop, bool clearLayer = true);
+    enum class GlopRenderType {
+        Standard,
+        Multi,
+        LayerClear
+    };
+
+    void renderGlop(const Glop& glop, GlopRenderType type = GlopRenderType::Standard);
 
     /**
      * Discards the content of the framebuffer if supported by the driver.