libgui: Add support for post-xform crops.

This change adds support for specifying a crop rectangle to a
SurfaceTextureClient that is in post-transformed coordinate space.

Change-Id: I247901de343e71b32850f7ae3bac62dfa612ad3d
Bug: 6299171
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index b576ca5..8546fb9 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -20,6 +20,7 @@
 #include <EGL/egl.h>
 #include <gtest/gtest.h>
 #include <gui/SurfaceTextureClient.h>
+#include <system/graphics.h>
 #include <utils/Log.h>
 #include <utils/Thread.h>
 
@@ -441,6 +442,68 @@
     ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[2]));
 }
 
+TEST_F(SurfaceTextureClientTest, SetPostTransformCropUntransforms) {
+    android_native_rect_t rect = {1, 5, 4, 14};
+    native_window_set_post_transform_crop(mANW.get(), &rect);
+
+    uint32_t xforms[] = {
+        HAL_TRANSFORM_FLIP_H,
+        HAL_TRANSFORM_FLIP_V,
+        HAL_TRANSFORM_ROT_90,
+        HAL_TRANSFORM_ROT_180,
+        HAL_TRANSFORM_ROT_270,
+    };
+
+    Rect expectedRects[] = {
+        Rect(4, 5, 7, 14), // HAL_TRANSFORM_FLIP_H
+        Rect(1, 2, 4, 11), // HAL_TRANSFORM_FLIP_V
+        Rect(5, 4, 14, 7), // HAL_TRANSFORM_ROT_90
+        Rect(4, 2, 7, 11), // HAL_TRANSFORM_ROT_180
+        Rect(2, 1, 11, 4), // HAL_TRANSFORM_ROT_270
+    };
+
+    for (size_t i = 0; i < sizeof(xforms)/sizeof(xforms[0]); i++) {
+        SCOPED_TRACE(String8::format("xform=%#x", xforms[i]).string());
+
+        int w = 8, h = 16;
+        if (xforms[i] & HAL_TRANSFORM_ROT_90) {
+            w = 16;
+            h = 8;
+        }
+        ASSERT_EQ(OK, native_window_set_buffers_transform(mANW.get(), xforms[i]));
+        ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), w, h));
+
+        android_native_buffer_t* buf;
+        ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
+        ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf));
+        ASSERT_EQ(OK, mST->updateTexImage());
+
+        Rect crop = mST->getCurrentCrop();
+        EXPECT_EQ(expectedRects[i].left, crop.left);
+        EXPECT_EQ(expectedRects[i].top, crop.top);
+        EXPECT_EQ(expectedRects[i].right, crop.right);
+        EXPECT_EQ(expectedRects[i].bottom, crop.bottom);
+    }
+}
+
+TEST_F(SurfaceTextureClientTest, SetCropCropsCrop) {
+    android_native_rect_t rect = {-2, -13, 40, 18};
+    native_window_set_crop(mANW.get(), &rect);
+
+    ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 4, 4));
+
+    android_native_buffer_t* buf;
+    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
+    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf));
+    ASSERT_EQ(OK, mST->updateTexImage());
+
+    Rect crop = mST->getCurrentCrop();
+    EXPECT_EQ(0, crop.left);
+    EXPECT_EQ(0, crop.top);
+    EXPECT_EQ(4, crop.right);
+    EXPECT_EQ(4, crop.bottom);
+}
+
 // XXX: This is not expected to pass until the synchronization hacks are removed
 // from the SurfaceTexture class.
 TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeWaitRetire) {