Initialize MergingDrawBatch clip with viewport bounds

This allows merged, clipped operations to behave correctly within a
savelayer, even if the base viewport has a large offset.

Additionally, disregard opaqueness when within a
complexclip/savelayer, as the coverage can't be trusted.

Change-Id: Ic908b82a4bb410bc7fac1b4295f4874ed166efc5
diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp
index 887e822..7ce15c5 100644
--- a/libs/hwui/DeferredDisplayList.cpp
+++ b/libs/hwui/DeferredDisplayList.cpp
@@ -152,8 +152,9 @@
 
 class MergingDrawBatch : public DrawBatch {
 public:
-    MergingDrawBatch(DeferInfo& deferInfo, Rect viewport) :
-           DrawBatch(deferInfo), mClipRect(viewport), mClipSideFlags(kClipSide_None) {}
+    MergingDrawBatch(DeferInfo& deferInfo, int width, int height) :
+            DrawBatch(deferInfo), mClipRect(width, height),
+            mClipSideFlags(kClipSide_None) {}
 
     /*
      * Helper for determining if a new op can merge with a MergingDrawBatch based on their bounds
@@ -489,6 +490,7 @@
     // complex clip has a complex set of expectations on the renderer state - for now, avoid taking
     // the merge path in those cases
     deferInfo.mergeable &= !recordingComplexClip();
+    deferInfo.opaqueOverBounds &= !recordingComplexClip() && mSaveStack.isEmpty();
 
     if (CC_LIKELY(mAvoidOverdraw) && mBatches.size() &&
             op->state.mClipSideFlags != kClipSide_ConservativeFull &&
@@ -570,7 +572,8 @@
 
     if (!targetBatch) {
         if (deferInfo.mergeable) {
-            targetBatch = new MergingDrawBatch(deferInfo, mBounds);
+            targetBatch = new MergingDrawBatch(deferInfo,
+                    renderer.getViewportWidth(), renderer.getViewportHeight());
             mMergingBatches[deferInfo.batchId].put(deferInfo.mergeId, targetBatch);
         } else {
             targetBatch = new DrawBatch(deferInfo);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index d6d7b7f..6f1dc6f 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -827,6 +827,7 @@
         if (!mSnapshot->isIgnored()) {
             mSnapshot->resetTransform(-bounds.left, -bounds.top, 0.0f);
             mSnapshot->resetClip(clip.left, clip.top, clip.right, clip.bottom);
+            mSnapshot->viewport.set(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight());
         }
     }
 
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 548501d..aa0f9fc 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -360,6 +360,9 @@
         return mSnapshot->clipRegion->isEmpty();
     }
 
+    int getViewportWidth() { return getSnapshot()->viewport.getWidth(); }
+    int getViewportHeight() { return getSnapshot()->viewport.getHeight(); }
+
     /**
      * Scales the alpha on the current snapshot. This alpha value will be modulated
      * with other alpha values when drawing primitives.