Added crop rect to LayerDrawable to not crop TextureView.
Verified manually with ExoPlayer that TextureView isn't cropping.

Test: Did the manual test and
atest TextureViewCameraTest
atest TextureViewSnapshotTest
atest TextureViewStressTest
atest TextureViewTest
atest PixelCopyTest
atest BitmapTest
atest HardwareBitmapTests

and with HwAccelerationTest
Added crop test at ag/15430851

BUG=152621633

Change-Id: If1f448a94908cbf51272bc0d1bbbe1e113fd15f3
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 8d112d1..6cb53206 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -21,7 +21,6 @@
 // TODO: Use public SurfaceTexture APIs once available and include public NDK header file instead.
 #include <surfacetexture/surface_texture_platform.h>
 #include "AutoBackendTextureRelease.h"
-#include "Matrix.h"
 #include "Properties.h"
 #include "renderstate/RenderState.h"
 #include "renderthread/EglManager.h"
@@ -145,16 +144,17 @@
         }
         if (mUpdateTexImage) {
             mUpdateTexImage = false;
-            float transformMatrix[16];
             android_dataspace dataspace;
             int slot;
             bool newContent = false;
+            ARect rect;
+            uint32_t textureTransform;
             // Note: ASurfaceTexture_dequeueBuffer discards all but the last frame. This
             // is necessary if the SurfaceTexture queue is in synchronous mode, and we
             // cannot tell which mode it is in.
             AHardwareBuffer* hardwareBuffer = ASurfaceTexture_dequeueBuffer(
-                    mSurfaceTexture.get(), &slot, &dataspace, transformMatrix, &newContent,
-                    createReleaseFence, fenceWait, this);
+                    mSurfaceTexture.get(), &slot, &dataspace, &newContent, createReleaseFence,
+                    fenceWait, this, &rect, &textureTransform);
 
             if (hardwareBuffer) {
                 mCurrentSlot = slot;
@@ -165,12 +165,12 @@
                 // (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 cropRect =
+                            SkRect::MakeLTRB(rect.left, rect.top, rect.right, rect.bottom);
+                    updateLayer(forceFilter, textureTransform, cropRect, layerImage);
                 }
             }
         }
@@ -182,12 +182,13 @@
     }
 }
 
-void DeferredLayerUpdater::updateLayer(bool forceFilter, const SkMatrix& textureTransform,
-                                       const sk_sp<SkImage>& layerImage) {
+void DeferredLayerUpdater::updateLayer(bool forceFilter, const uint32_t textureTransform,
+                                       const SkRect cropRect, const sk_sp<SkImage>& layerImage) {
     mLayer->setBlend(mBlend);
     mLayer->setForceFilter(forceFilter);
     mLayer->setSize(mWidth, mHeight);
-    mLayer->getTexTransform() = textureTransform;
+    mLayer->setTextureTransform(textureTransform);
+    mLayer->setCropRect(cropRect);
     mLayer->setImage(layerImage);
 }
 
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index 8f79c4e..7a63ccd 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -90,7 +90,7 @@
 
     void detachSurfaceTexture();
 
-    void updateLayer(bool forceFilter, const SkMatrix& textureTransform,
+    void updateLayer(bool forceFilter, const uint32_t textureTransform, const SkRect cropRect,
                      const sk_sp<SkImage>& layerImage);
 
     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..656a817 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 getCropRect() { return mCropRect; }
+
+    inline void setCropRect(const SkRect cropRect) { mCropRect = cropRect; }
+
+    inline void setTextureTransform(uint32_t textureTransform) {
+        mTextureTransform = textureTransform;
+    }
+
+    inline uint32_t getTextureTransform() { return mTextureTransform; }
+
     /**
      * 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 mCropRect;
+
+    /**
+     * Optional transform
+     */
+    uint32_t mTextureTransform;
+
+    /**
      * An image backing the layer.
      */
     sk_sp<SkImage> layerImage;
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index a743d30..386c88a 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -251,8 +251,6 @@
 
     Rect srcRect;
     Matrix4 transform;
-    transform.loadScale(1, -1, 1);
-    transform.translate(0, -1);
 
     return copyImageInto(hwBitmap->makeImage(), transform, srcRect, bitmap);
 }
@@ -280,8 +278,6 @@
 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);
 }
 
@@ -320,7 +316,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/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
index e32788c..b28277c 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.cpp
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -18,9 +18,11 @@
 #include <utils/MathUtils.h>
 
 #include "GrBackendSurface.h"
+#include "Matrix.h"
 #include "SkColorFilter.h"
 #include "SkSurface.h"
 #include "gl/GrGLTypes.h"
+#include "system/window.h"
 
 namespace android {
 namespace uirenderer {
@@ -29,7 +31,8 @@
 void LayerDrawable::onDraw(SkCanvas* canvas) {
     Layer* layer = mLayerUpdater->backingLayer();
     if (layer) {
-        DrawLayer(canvas->recordingContext(), canvas, layer, nullptr, nullptr, true);
+        SkRect srcRect = layer->getCropRect();
+        DrawLayer(canvas->recordingContext(), canvas, layer, &srcRect, nullptr, true);
     }
 }
 
@@ -79,33 +82,16 @@
         return false;
     }
     // transform the matrix based on the layer
-    SkMatrix layerTransform = layer->getTransform();
+    const uint32_t transform = layer->getTextureTransform();
     sk_sp<SkImage> layerImage = layer->getImage();
     const int layerWidth = layer->getWidth();
     const int layerHeight = layer->getHeight();
-
+    SkMatrix layerTransform = layer->getTransform();
     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;
-        }
-
         SkMatrix matrix;
         if (useLayerTransform) {
-            matrix = SkMatrix::Concat(layerTransform, textureMatrix);
-        } else {
-            matrix = textureMatrix;
+            matrix = layerTransform;
         }
-
         SkPaint paint;
         paint.setAlpha(layer->getAlpha());
         paint.setBlendMode(layer->getMode());
@@ -115,39 +101,54 @@
             canvas->save();
             canvas->concat(matrix);
         }
-        const SkMatrix& totalMatrix = canvas->getTotalMatrix();
+        const SkMatrix totalMatrix = canvas->getTotalMatrix();
         if (dstRect || srcRect) {
             SkMatrix matrixInv;
             if (!matrix.invert(&matrixInv)) {
                 matrixInv = matrix;
             }
             SkRect skiaSrcRect;
-            if (srcRect) {
+            if (srcRect && !srcRect->isEmpty()) {
                 skiaSrcRect = *srcRect;
             } else {
-                skiaSrcRect = SkRect::MakeIWH(layerWidth, layerHeight);
+                skiaSrcRect = (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
+                                      ? SkRect::MakeIWH(layerHeight, layerWidth)
+                                      : SkRect::MakeIWH(layerWidth, layerHeight);
             }
             matrixInv.mapRect(&skiaSrcRect);
             SkRect skiaDestRect;
-            if (dstRect) {
+            if (dstRect && !dstRect->isEmpty()) {
                 skiaDestRect = *dstRect;
             } else {
                 skiaDestRect = SkRect::MakeIWH(layerWidth, layerHeight);
             }
             matrixInv.mapRect(&skiaDestRect);
-            // If (matrix is a rect-to-rect transform)
-            // and (src/dst buffers size match in screen coordinates)
-            // and (src/dst corners align fractionally),
-            // then use nearest neighbor, otherwise use bilerp sampling.
-            // Skia TextureOp has the above logic build-in, but not NonAAFillRectOp. TextureOp works
-            // only for SrcOver blending and without color filter (readback uses Src blending).
             SkSamplingOptions sampling(SkFilterMode::kNearest);
             if (layer->getForceFilter() ||
                 shouldFilterRect(totalMatrix, skiaSrcRect, skiaDestRect)) {
                 sampling = SkSamplingOptions(SkFilterMode::kLinear);
             }
+
+            const float px = skiaDestRect.centerX();
+            const float py = skiaDestRect.centerY();
+            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H) {
+                matrix.postScale(-1.f, 1.f, px, py);
+            }
+            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V) {
+                matrix.postScale(1.f, -1.f, px, py);
+            }
+            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+                matrix.postRotate(90, 0, 0);
+                matrix.postTranslate(skiaDestRect.height(), 0);
+            }
+            auto constraint = SkCanvas::kFast_SrcRectConstraint;
+            if (srcRect && srcRect->isEmpty()) {
+                constraint = SkCanvas::kStrict_SrcRectConstraint;
+            }
+            matrix.postConcat(SkMatrix::MakeRectToRect(skiaSrcRect, skiaDestRect,
+                                                       SkMatrix::kFill_ScaleToFit));
             canvas->drawImageRect(layerImage.get(), skiaSrcRect, skiaDestRect, sampling, &paint,
-                                  SkCanvas::kFast_SrcRectConstraint);
+                                  constraint);
         } else {
             SkRect imageRect = SkRect::MakeIWH(layerImage->width(), layerImage->height());
             SkSamplingOptions sampling(SkFilterMode::kNearest);
@@ -161,7 +162,6 @@
             canvas->restore();
         }
     }
-
     return layerImage != nullptr;
 }
 
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index e8ba15f..1bfdc47 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, 0, SkRect::MakeEmpty(), nullptr);
     return layerUpdater;
 }
 
diff --git a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp
index 955a5e7..ca84aee 100644
--- a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp
+++ b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp
@@ -36,19 +36,20 @@
     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);
+    uint32_t textureTransform = 1;
     SkBitmap bitmap;
     bitmap.allocN32Pixels(16, 16);
+    SkRect cropRect = SkRect::MakeIWH(10, 10);
     sk_sp<SkImage> layerImage = SkImage::MakeFromBitmap(bitmap);
-    layerUpdater->updateLayer(true, scaledMatrix, layerImage);
+    layerUpdater->updateLayer(true, textureTransform, cropRect, layerImage);
 
     // 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());
+    EXPECT_EQ(textureTransform, layerUpdater->backingLayer()->getTextureTransform());
+    EXPECT_EQ(cropRect, layerUpdater->backingLayer()->getCropRect());
 }