Disallow negative scale matrices in merged Bitmap drawing

bug:10622962

Change-Id: I55ac18ad56b53dc9e6e6ea14cd3ec4bdafa98ac3
diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp
index fd9257a..0131be3 100644
--- a/libs/hwui/DeferredDisplayList.cpp
+++ b/libs/hwui/DeferredDisplayList.cpp
@@ -275,6 +275,11 @@
         DisplayListLogBuffer& buffer = DisplayListLogBuffer::getInstance();
         buffer.writeCommand(0, "multiDraw");
         buffer.writeCommand(1, op->name());
+
+#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
+        renderer.eventMark("multiDraw");
+        renderer.eventMark(op->name());
+#endif
         status_t status = op->multiDraw(renderer, dirty, mOps, mBounds);
 
 #if DEBUG_MERGE_BEHAVIOR
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index a17942e..b052461 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -813,12 +813,15 @@
     virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
             const DeferredDisplayState& state) {
         deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
-        deferInfo.mergeId = getAtlasEntry() ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
+        deferInfo.mergeId = getAtlasEntry() ?
+                (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
 
+        // Don't merge non-simply transformed or neg scale ops, SET_TEXTURE doesn't handle rotation
         // Don't merge A8 bitmaps - the paint's color isn't compared by mergeId, or in
         // MergingDrawBatch::canMergeWith()
         // TODO: support clipped bitmaps by handling them in SET_TEXTURE
-        deferInfo.mergeable = state.mMatrix.isSimple() && !state.mClipSideFlags &&
+        deferInfo.mergeable = state.mMatrix.isSimple() && state.mMatrix.positiveScale() &&
+                !state.mClipSideFlags &&
                 OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode &&
                 (mBitmap->getConfig() != SkBitmap::kA8_Config);
     }
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index 65e7eae..1948778 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -110,6 +110,10 @@
                 mType |= kTypeRectToRect;
             }
         }
+
+        if (m00 > 0.0f && m11 > 0.0f) {
+            mType |= kTypePositiveScale;
+        }
     }
     return mType;
 }
@@ -122,6 +126,10 @@
     return getType() & kTypeRectToRect;
 }
 
+bool Matrix4::positiveScale() const {
+    return getType() & kTypePositiveScale;
+}
+
 bool Matrix4::changesBounds() const {
     return getType() & (kTypeScale | kTypeAffine | kTypePerspective);
 }
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h
index 5116203..e2c5b20 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -64,7 +64,8 @@
         kTypeAffine = 0x4,
         kTypePerspective = 0x8,
         kTypeRectToRect = 0x10,
-        kTypeUnknown = 0x20,
+        kTypePositiveScale = 0x20,
+        kTypeUnknown = 0x40,
     };
 
     static const int sGeometryMask = 0xf;
@@ -183,6 +184,7 @@
     bool isIdentity() const;
     bool isPerspective() const;
     bool rectToRect() const;
+    bool positiveScale() const;
 
     bool changesBounds() const;