am 9613e9b7: Merge "New setLocalMatrix() operation for HWUI" into mnc-dev

* commit '9613e9b76410b15b7f2700080a17476bf9f3461c':
  New setLocalMatrix() operation for HWUI
diff --git a/libs/hwui/Canvas.h b/libs/hwui/Canvas.h
index 562bb80..160d9a8 100644
--- a/libs/hwui/Canvas.h
+++ b/libs/hwui/Canvas.h
@@ -80,6 +80,10 @@
     virtual void getMatrix(SkMatrix* outMatrix) const = 0;
     virtual void setMatrix(const SkMatrix& matrix) = 0;
 
+    /// Like setMatrix(), but to be translated into local / view-relative coordinates
+    /// rather than executed in global / device coordinates at rendering time.
+    virtual void setLocalMatrix(const SkMatrix& matrix) = 0;
+
     virtual void concat(const SkMatrix& matrix) = 0;
     virtual void rotate(float degrees) = 0;
     virtual void scale(float sx, float sy) = 0;
diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp
index b08187b..aeb1a3d 100644
--- a/libs/hwui/DisplayListCanvas.cpp
+++ b/libs/hwui/DisplayListCanvas.cpp
@@ -176,6 +176,11 @@
     mState.setMatrix(matrix);
 }
 
+void DisplayListCanvas::setLocalMatrix(const SkMatrix& matrix) {
+    addStateOp(new (alloc()) SetLocalMatrixOp(matrix));
+    mState.setMatrix(matrix);
+}
+
 void DisplayListCanvas::concat(const SkMatrix& matrix) {
     addStateOp(new (alloc()) ConcatMatrixOp(matrix));
     mState.concatMatrix(matrix);
diff --git a/libs/hwui/DisplayListCanvas.h b/libs/hwui/DisplayListCanvas.h
index edfda62..4982cc9 100644
--- a/libs/hwui/DisplayListCanvas.h
+++ b/libs/hwui/DisplayListCanvas.h
@@ -165,6 +165,7 @@
     // Matrix
     virtual void getMatrix(SkMatrix* outMatrix) const override { mState.getMatrix(outMatrix); }
     virtual void setMatrix(const SkMatrix& matrix) override;
+    virtual void setLocalMatrix(const SkMatrix& matrix) override;
 
     virtual void concat(const SkMatrix& matrix) override;
     virtual void rotate(float degrees) override;
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index d2bf138..8b4b4ba 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -489,6 +489,25 @@
     const SkMatrix mMatrix;
 };
 
+class SetLocalMatrixOp : public StateOp {
+public:
+    SetLocalMatrixOp(const SkMatrix& matrix)
+            : mMatrix(matrix) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override {
+        renderer.setLocalMatrix(mMatrix);
+    }
+
+    virtual void output(int level, uint32_t logFlags) const override {
+        OP_LOG("SetLocalMatrix " SK_MATRIX_STRING, SK_MATRIX_ARGS(&mMatrix));
+    }
+
+    virtual const char* name() override { return "SetLocalMatrix"; }
+
+private:
+    const SkMatrix mMatrix;
+};
+
 class ConcatMatrixOp : public StateOp {
 public:
     ConcatMatrixOp(const SkMatrix& matrix)
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index ed2a4db..2292ef4 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2148,6 +2148,7 @@
     mState.restoreToCount(saveCount);
 }
 
+
 void OpenGLRenderer::translate(float dx, float dy, float dz) {
     mState.translate(dx, dy, dz);
 }
@@ -2168,6 +2169,11 @@
     mState.setMatrix(matrix);
 }
 
+void OpenGLRenderer::setLocalMatrix(const SkMatrix& matrix) {
+    mState.setMatrix(mBaseTransform);
+    mState.concatMatrix(matrix);
+}
+
 void OpenGLRenderer::concatMatrix(const Matrix4& matrix) {
     mState.concatMatrix(matrix);
 }
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 800a9f9..402f6ed 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -368,6 +368,7 @@
 
     void getMatrix(SkMatrix* outMatrix) const { mState.getMatrix(outMatrix); }
     void setMatrix(const SkMatrix& matrix) { mState.setMatrix(matrix); }
+    void setLocalMatrix(const SkMatrix& matrix);
     void concatMatrix(const SkMatrix& matrix) { mState.concatMatrix(matrix); }
 
     void translate(float dx, float dy, float dz = 0.0f);
@@ -418,6 +419,8 @@
         return returnPath;
     }
 
+    void setBaseTransform(const Matrix4& matrix) { mBaseTransform = matrix; }
+
 protected:
     /**
      * Perform the setup specific to a frame. This method does not
@@ -877,6 +880,16 @@
     // Paths kept alive for the duration of the frame
     std::vector<std::unique_ptr<SkPath>> mTempPaths;
 
+    /**
+     * Initial transform for a rendering pass; transform from global device
+     * coordinates to the current RenderNode's drawing content coordinates,
+     * with the RenderNode's RenderProperty transforms already applied.
+     * Calling setMatrix(mBaseTransform) will result in drawing at the origin
+     * of the DisplayList's recorded surface prior to any Canvas
+     * transformation.
+     */
+    Matrix4 mBaseTransform;
+
     friend class Layer;
     friend class TextDrawFunctor;
     friend class DrawBitmapOp;
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index fc18491..80f349a 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -887,6 +887,7 @@
             && renderer.quickRejectConservative(0, 0, properties().getWidth(), properties().getHeight());
     if (!quickRejected) {
         Matrix4 initialTransform(*(renderer.currentTransform()));
+        renderer.setBaseTransform(initialTransform);
 
         if (drawLayer) {
             handler(new (alloc) DrawLayerOp(mLayer, 0, 0),
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 6cf66cd..644a4f3 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -67,6 +67,7 @@
 
     virtual void getMatrix(SkMatrix* outMatrix) const override;
     virtual void setMatrix(const SkMatrix& matrix) override;
+    virtual void setLocalMatrix(const SkMatrix& matrix) override { this->setMatrix(matrix); }
     virtual void concat(const SkMatrix& matrix) override;
     virtual void rotate(float degrees) override;
     virtual void scale(float sx, float sy) override;
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
index 8a6c8c5..d96ca2a 100644
--- a/libs/hwui/SkiaCanvasProxy.cpp
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -115,7 +115,7 @@
 void SkiaCanvasProxy::onDrawSprite(const SkBitmap& bitmap, int left, int top,
         const SkPaint* paint) {
     mCanvas->save(SkCanvas::kMatrixClip_SaveFlag);
-    mCanvas->setMatrix(SkMatrix::I());
+    mCanvas->setLocalMatrix(SkMatrix::I());
     mCanvas->drawBitmap(bitmap, left, top, paint);
     mCanvas->restore();
 }
@@ -165,7 +165,9 @@
 }
 
 void SkiaCanvasProxy::didSetMatrix(const SkMatrix& matrix) {
-    mCanvas->setMatrix(matrix);
+    // SkCanvas setMatrix() is relative to the Canvas origin, but OpenGLRenderer's
+    // setMatrix() is relative to device origin; call setLocalMatrix() instead.
+    mCanvas->setLocalMatrix(matrix);
 }
 
 void SkiaCanvasProxy::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,