Added crop rect and removed inverse of the texture matrix.

BUG=152621633
Test: Verified manually and with
atest TextureViewCameraTest
atest TextureViewTest
atest TextureViewSnapshotTest
atest TextureViewStressTest
atest PixelCopyTest
atest BitmapTest
atest HardwareBitmapTests

Change-Id: Ie993a18fd3511576617a1eb859bf228c33d12f78
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 2b86b1e..0b3b393 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -167,12 +167,13 @@
                 // (invoked by createIfNeeded) will add a ref to the AHardwareBuffer.
                 AHardwareBuffer_release(hardwareBuffer);
                 if (layerImage.get()) {
-                    SkMatrix textureTransform;
-                    mat4(transformMatrix).copyTo(textureTransform);
                     // force filtration if buffer size != layer size
                     bool forceFilter =
                             mWidth != layerImage->width() || mHeight != layerImage->height();
-                    updateLayer(forceFilter, textureTransform, layerImage);
+                    SkRect currentCropRect =
+                            SkRect::MakeLTRB(currentCrop.left, currentCrop.top, currentCrop.right,
+                                             currentCrop.bottom);
+                    updateLayer(forceFilter, layerImage, outTransform, currentCropRect);
                 }
             }
         }
@@ -184,12 +185,13 @@
     }
 }
 
-void DeferredLayerUpdater::updateLayer(bool forceFilter, const SkMatrix& textureTransform,
-                                       const sk_sp<SkImage>& layerImage) {
+void DeferredLayerUpdater::updateLayer(bool forceFilter, const sk_sp<SkImage>& layerImage,
+                                       const uint32_t transform, SkRect currentCrop) {
     mLayer->setBlend(mBlend);
     mLayer->setForceFilter(forceFilter);
     mLayer->setSize(mWidth, mHeight);
-    mLayer->getTexTransform() = textureTransform;
+    mLayer->setCurrentCropRect(currentCrop);
+    mLayer->setWindowTransform(transform);
     mLayer->setImage(layerImage);
 }
 
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index 8f79c4e..da8041f 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -90,8 +90,8 @@
 
     void detachSurfaceTexture();
 
-    void updateLayer(bool forceFilter, const SkMatrix& textureTransform,
-                     const sk_sp<SkImage>& layerImage);
+    void updateLayer(bool forceFilter, const sk_sp<SkImage>& layerImage, const uint32_t transform,
+                     SkRect currentCrop);
 
     void destroyLayer();
 
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 47c47e0..9053c12 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -35,7 +35,6 @@
     // preserves the old inc/dec ref locations. This should be changed...
     incStrong(nullptr);
     renderState.registerLayer(this);
-    texTransform.setIdentity();
     transform.setIdentity();
 }
 
@@ -101,7 +100,6 @@
     const int layerHeight = getHeight();
     if (layerImage) {
         SkMatrix textureMatrixInv;
-        textureMatrixInv = getTexTransform();
         // TODO: after skia bug https://bugs.chromium.org/p/skia/issues/detail?id=7075 is fixed
         // use bottom left origin and remove flipV and invert transformations.
         SkMatrix flipV;
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index e99e762..0789344 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -74,10 +74,18 @@
 
     void setColorFilter(sk_sp<SkColorFilter> filter) { mColorFilter = filter; };
 
-    inline SkMatrix& getTexTransform() { return texTransform; }
-
     inline SkMatrix& getTransform() { return transform; }
 
+    inline SkRect getCurrentCropRect() { return mCurrentCropRect; }
+
+    inline void setCurrentCropRect(const SkRect currentCropRect) {
+        mCurrentCropRect = currentCropRect;
+    }
+
+    inline void setWindowTransform(uint32_t windowTransform) { mWindowTransform = windowTransform; }
+
+    inline uint32_t getWindowTransform() { return mWindowTransform; }
+
     /**
      * Posts a decStrong call to the appropriate thread.
      * Thread-safe.
@@ -116,16 +124,21 @@
     SkBlendMode mode;
 
     /**
-     * Optional texture coordinates transform.
-     */
-    SkMatrix texTransform;
-
-    /**
      * Optional transform.
      */
     SkMatrix transform;
 
     /**
+     * Optional crop
+     */
+    SkRect mCurrentCropRect;
+
+    /**
+     * Optional transform
+     */
+    uint32_t mWindowTransform;
+
+    /**
      * An image backing the layer.
      */
     sk_sp<SkImage> layerImage;
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index a743d30..4cce87a 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -243,18 +243,14 @@
             static_cast<android_dataspace>(ANativeWindow_getBuffersDataSpace(window)));
     sk_sp<SkImage> image =
             SkImage::MakeFromAHardwareBuffer(sourceBuffer.get(), kPremul_SkAlphaType, colorSpace);
-    return copyImageInto(image, texTransform, srcRect, bitmap);
+    return copyImageInto(image, srcRect, bitmap);
 }
 
 CopyResult Readback::copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap) {
     LOG_ALWAYS_FATAL_IF(!hwBitmap->isHardware());
 
     Rect srcRect;
-    Matrix4 transform;
-    transform.loadScale(1, -1, 1);
-    transform.translate(0, -1);
-
-    return copyImageInto(hwBitmap->makeImage(), transform, srcRect, bitmap);
+    return copyImageInto(hwBitmap->makeImage(), srcRect, bitmap);
 }
 
 CopyResult Readback::copyLayerInto(DeferredLayerUpdater* deferredLayer, SkBitmap* bitmap) {
@@ -279,14 +275,11 @@
 
 CopyResult Readback::copyImageInto(const sk_sp<SkImage>& image, SkBitmap* bitmap) {
     Rect srcRect;
-    Matrix4 transform;
-    transform.loadScale(1, -1, 1);
-    transform.translate(0, -1);
-    return copyImageInto(image, transform, srcRect, bitmap);
+    return copyImageInto(image, srcRect, bitmap);
 }
 
-CopyResult Readback::copyImageInto(const sk_sp<SkImage>& image, Matrix4& texTransform,
-                                   const Rect& srcRect, SkBitmap* bitmap) {
+CopyResult Readback::copyImageInto(const sk_sp<SkImage>& image, const Rect& srcRect,
+                                   SkBitmap* bitmap) {
     ATRACE_CALL();
     if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
         mRenderThread.requireGlContext();
@@ -303,11 +296,6 @@
     CopyResult copyResult = CopyResult::UnknownError;
 
     int displayedWidth = imgWidth, displayedHeight = imgHeight;
-    // If this is a 90 or 270 degree rotation we need to swap width/height to get the device
-    // size.
-    if (texTransform[Matrix4::kSkewX] >= 0.5f || texTransform[Matrix4::kSkewX] <= -0.5f) {
-        std::swap(displayedWidth, displayedHeight);
-    }
     SkRect skiaDestRect = SkRect::MakeWH(bitmap->width(), bitmap->height());
     SkRect skiaSrcRect = srcRect.toSkRect();
     if (skiaSrcRect.isEmpty()) {
@@ -320,7 +308,6 @@
 
     Layer layer(mRenderThread.renderState(), nullptr, 255, SkBlendMode::kSrc);
     layer.setSize(displayedWidth, displayedHeight);
-    texTransform.copyTo(layer.getTexTransform());
     layer.setImage(image);
     // Scaling filter is not explicitly set here, because it is done inside copyLayerInfo
     // after checking the necessity based on the src/dest rect size and the transformation.
diff --git a/libs/hwui/Readback.h b/libs/hwui/Readback.h
index da25269..d0d748f 100644
--- a/libs/hwui/Readback.h
+++ b/libs/hwui/Readback.h
@@ -56,8 +56,7 @@
 
 private:
     CopyResult copySurfaceIntoLegacy(ANativeWindow* window, const Rect& srcRect, SkBitmap* bitmap);
-    CopyResult copyImageInto(const sk_sp<SkImage>& image, Matrix4& texTransform,
-                             const Rect& srcRect, SkBitmap* bitmap);
+    CopyResult copyImageInto(const sk_sp<SkImage>& image, const Rect& srcRect, SkBitmap* bitmap);
 
     bool copyLayerInto(Layer* layer, const SkRect* srcRect, const SkRect* dstRect,
                        SkBitmap* bitmap);
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
index e32788c..6db7170 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.cpp
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -21,6 +21,7 @@
 #include "SkColorFilter.h"
 #include "SkSurface.h"
 #include "gl/GrGLTypes.h"
+#include "system/window.h"
 
 namespace android {
 namespace uirenderer {
@@ -29,7 +30,8 @@
 void LayerDrawable::onDraw(SkCanvas* canvas) {
     Layer* layer = mLayerUpdater->backingLayer();
     if (layer) {
-        DrawLayer(canvas->recordingContext(), canvas, layer, nullptr, nullptr, true);
+        SkRect srcRect = layer->getCurrentCropRect();
+        DrawLayer(canvas->recordingContext(), canvas, layer, &srcRect, nullptr, true);
     }
 }
 
@@ -79,62 +81,63 @@
         return false;
     }
     // transform the matrix based on the layer
-    SkMatrix layerTransform = layer->getTransform();
+    // SkMatrix layerTransform = layer->getTransform();
+    const uint32_t windowTransform = layer->getWindowTransform();
     sk_sp<SkImage> layerImage = layer->getImage();
     const int layerWidth = layer->getWidth();
     const int layerHeight = layer->getHeight();
 
     if (layerImage) {
-        SkMatrix textureMatrixInv;
-        textureMatrixInv = layer->getTexTransform();
-        // TODO: after skia bug https://bugs.chromium.org/p/skia/issues/detail?id=7075 is fixed
-        // use bottom left origin and remove flipV and invert transformations.
-        SkMatrix flipV;
-        flipV.setAll(1, 0, 0, 0, -1, 1, 0, 0, 1);
-        textureMatrixInv.preConcat(flipV);
-        textureMatrixInv.preScale(1.0f / layerWidth, 1.0f / layerHeight);
-        textureMatrixInv.postScale(layerImage->width(), layerImage->height());
-        SkMatrix textureMatrix;
-        if (!textureMatrixInv.invert(&textureMatrix)) {
-            textureMatrix = textureMatrixInv;
-        }
+        const int imageWidth = layerImage->width();
+        const int imageHeight = layerImage->height();
 
-        SkMatrix matrix;
         if (useLayerTransform) {
-            matrix = SkMatrix::Concat(layerTransform, textureMatrix);
-        } else {
-            matrix = textureMatrix;
+            canvas->save();
+            canvas->concat(layer->getTransform());
         }
 
         SkPaint paint;
         paint.setAlpha(layer->getAlpha());
         paint.setBlendMode(layer->getMode());
         paint.setColorFilter(layer->getColorFilter());
-        const bool nonIdentityMatrix = !matrix.isIdentity();
-        if (nonIdentityMatrix) {
-            canvas->save();
-            canvas->concat(matrix);
-        }
         const SkMatrix& totalMatrix = canvas->getTotalMatrix();
-        if (dstRect || srcRect) {
-            SkMatrix matrixInv;
-            if (!matrix.invert(&matrixInv)) {
-                matrixInv = matrix;
-            }
+        if (srcRect || dstRect) {
             SkRect skiaSrcRect;
-            if (srcRect) {
+            if (srcRect && !srcRect->isEmpty()) {
                 skiaSrcRect = *srcRect;
             } else {
-                skiaSrcRect = SkRect::MakeIWH(layerWidth, layerHeight);
+                skiaSrcRect = SkRect::MakeIWH(imageWidth, imageHeight);
             }
-            matrixInv.mapRect(&skiaSrcRect);
             SkRect skiaDestRect;
-            if (dstRect) {
+            if (dstRect && !dstRect->isEmpty()) {
                 skiaDestRect = *dstRect;
             } else {
-                skiaDestRect = SkRect::MakeIWH(layerWidth, layerHeight);
+                skiaDestRect = (windowTransform & NATIVE_WINDOW_TRANSFORM_ROT_90)
+                                       ? SkRect::MakeIWH(layerHeight, layerWidth)
+                                       : SkRect::MakeIWH(layerWidth, layerHeight);
             }
-            matrixInv.mapRect(&skiaDestRect);
+
+            const float px = skiaDestRect.centerX();
+            const float py = skiaDestRect.centerY();
+            SkMatrix m;
+            if (windowTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) {
+                m.postScale(-1.f, 1.f, px, py);
+            }
+            if (windowTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) {
+                m.postScale(1.f, -1.f, px, py);
+            }
+            if (windowTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+                m.postRotate(90, 0, 0);
+                m.postTranslate(skiaDestRect.height(), 0);
+            }
+            auto constraint = SkCanvas::kFast_SrcRectConstraint;
+            if (srcRect && !srcRect->isEmpty()) {
+                constraint = SkCanvas::kStrict_SrcRectConstraint;
+            }
+
+            canvas->save();
+            canvas->concat(m);
+
             // If (matrix is a rect-to-rect transform)
             // and (src/dst buffers size match in screen coordinates)
             // and (src/dst corners align fractionally),
@@ -146,18 +149,13 @@
                 shouldFilterRect(totalMatrix, skiaSrcRect, skiaDestRect)) {
                 sampling = SkSamplingOptions(SkFilterMode::kLinear);
             }
+
             canvas->drawImageRect(layerImage.get(), skiaSrcRect, skiaDestRect, sampling, &paint,
-                                  SkCanvas::kFast_SrcRectConstraint);
-        } else {
-            SkRect imageRect = SkRect::MakeIWH(layerImage->width(), layerImage->height());
-            SkSamplingOptions sampling(SkFilterMode::kNearest);
-            if (layer->getForceFilter() || shouldFilterRect(totalMatrix, imageRect, imageRect)) {
-                sampling = SkSamplingOptions(SkFilterMode::kLinear);
-            }
-            canvas->drawImage(layerImage.get(), 0, 0, sampling, &paint);
+                                  constraint);
+            canvas->restore();
         }
         // restore the original matrix
-        if (nonIdentityMatrix) {
+        if (useLayerTransform) {
             canvas->restore();
         }
     }
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index e8ba15f..491af43 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -74,7 +74,7 @@
     layerUpdater->setTransform(&transform);
 
     // updateLayer so it's ready to draw
-    layerUpdater->updateLayer(true, SkMatrix::I(), nullptr);
+    layerUpdater->updateLayer(true, nullptr, 0, SkRect::MakeEmpty());
     return layerUpdater;
 }
 
diff --git a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp
index 955a5e7..0c389bfe8 100644
--- a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp
+++ b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp
@@ -36,19 +36,16 @@
     EXPECT_EQ(0u, layerUpdater->backingLayer()->getHeight());
     EXPECT_FALSE(layerUpdater->backingLayer()->getForceFilter());
     EXPECT_FALSE(layerUpdater->backingLayer()->isBlend());
-    EXPECT_EQ(Matrix4::identity(), layerUpdater->backingLayer()->getTexTransform());
 
     // push the deferred updates to the layer
-    SkMatrix scaledMatrix = SkMatrix::Scale(0.5, 0.5);
     SkBitmap bitmap;
     bitmap.allocN32Pixels(16, 16);
     sk_sp<SkImage> layerImage = SkImage::MakeFromBitmap(bitmap);
-    layerUpdater->updateLayer(true, scaledMatrix, layerImage);
+    layerUpdater->updateLayer(true, layerImage, 0, SkRect::MakeEmpty());
 
     // the backing layer should now have all the properties applied.
     EXPECT_EQ(100u, layerUpdater->backingLayer()->getWidth());
     EXPECT_EQ(100u, layerUpdater->backingLayer()->getHeight());
     EXPECT_TRUE(layerUpdater->backingLayer()->getForceFilter());
     EXPECT_TRUE(layerUpdater->backingLayer()->isBlend());
-    EXPECT_EQ(scaledMatrix, layerUpdater->backingLayer()->getTexTransform());
 }