Rounded corners

Test: visual
Test: /data/nativetest64/SurfaceFlinger_test/SurfaceFlinger_test
Fixes: 111514493
Change-Id: Ie8f400bbcea3e9653295ea7b75c7eef568fd76c4
diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
index 740d2fa..e506757 100644
--- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
+++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
@@ -44,6 +44,7 @@
 constexpr uint32_t STACK_UPDATE = 1;
 constexpr uint64_t DEFERRED_UPDATE = 0;
 constexpr float ALPHA_UPDATE = 0.29f;
+constexpr float CORNER_RADIUS_UPDATE = 0.2f;
 constexpr float POSITION_UPDATE = 121;
 const Rect CROP_UPDATE(16, 16, 32, 32);
 
@@ -167,6 +168,7 @@
     bool alphaUpdateFound(const SurfaceChange& change, bool foundAlpha);
     bool layerUpdateFound(const SurfaceChange& change, bool foundLayer);
     bool cropUpdateFound(const SurfaceChange& change, bool foundCrop);
+    bool cornerRadiusUpdateFound(const SurfaceChange& change, bool foundCornerRadius);
     bool matrixUpdateFound(const SurfaceChange& change, bool foundMatrix);
     bool scalingModeUpdateFound(const SurfaceChange& change, bool foundScalingMode);
     bool transparentRegionHintUpdateFound(const SurfaceChange& change, bool foundTransparentRegion);
@@ -198,6 +200,7 @@
     void alphaUpdate(Transaction&);
     void layerUpdate(Transaction&);
     void cropUpdate(Transaction&);
+    void cornerRadiusUpdate(Transaction&);
     void matrixUpdate(Transaction&);
     void overrideScalingModeUpdate(Transaction&);
     void transparentRegionHintUpdate(Transaction&);
@@ -313,6 +316,10 @@
     t.setAlpha(mBGSurfaceControl, ALPHA_UPDATE);
 }
 
+void SurfaceInterceptorTest::cornerRadiusUpdate(Transaction& t) {
+    t.setCornerRadius(mBGSurfaceControl, CORNER_RADIUS_UPDATE);
+}
+
 void SurfaceInterceptorTest::layerUpdate(Transaction& t) {
     t.setLayer(mBGSurfaceControl, LAYER_UPDATE);
 }
@@ -369,6 +376,7 @@
     runInTransaction(&SurfaceInterceptorTest::positionUpdate);
     runInTransaction(&SurfaceInterceptorTest::sizeUpdate);
     runInTransaction(&SurfaceInterceptorTest::alphaUpdate);
+    runInTransaction(&SurfaceInterceptorTest::cornerRadiusUpdate);
     runInTransaction(&SurfaceInterceptorTest::layerUpdate);
     runInTransaction(&SurfaceInterceptorTest::cropUpdate);
     runInTransaction(&SurfaceInterceptorTest::matrixUpdate);
@@ -430,6 +438,17 @@
     return foundAlpha;
 }
 
+bool SurfaceInterceptorTest::cornerRadiusUpdateFound(const SurfaceChange &change,
+                                                     bool foundCornerRadius) {
+    bool hasCornerRadius(change.corner_radius().corner_radius() == CORNER_RADIUS_UPDATE);
+    if (hasCornerRadius && !foundCornerRadius) {
+        foundCornerRadius = true;
+    } else if (hasCornerRadius && foundCornerRadius) {
+        [] () { FAIL(); }();
+    }
+    return foundCornerRadius;
+}
+
 bool SurfaceInterceptorTest::layerUpdateFound(const SurfaceChange& change, bool foundLayer) {
     bool hasLayer(change.layer().layer() == LAYER_UPDATE);
     if (hasLayer && !foundLayer) {
@@ -572,6 +591,9 @@
                         case SurfaceChange::SurfaceChangeCase::kCrop:
                             foundUpdate = cropUpdateFound(change, foundUpdate);
                             break;
+                        case SurfaceChange::SurfaceChangeCase::kCornerRadius:
+                            foundUpdate = cornerRadiusUpdateFound(change, foundUpdate);
+                            break;
                         case SurfaceChange::SurfaceChangeCase::kMatrix:
                             foundUpdate = matrixUpdateFound(change, foundUpdate);
                             break;
@@ -730,6 +752,11 @@
     captureTest(&SurfaceInterceptorTest::cropUpdate, SurfaceChange::SurfaceChangeCase::kCrop);
 }
 
+TEST_F(SurfaceInterceptorTest, InterceptCornerRadiusUpdateWorks) {
+    captureTest(&SurfaceInterceptorTest::cornerRadiusUpdate,
+            SurfaceChange::SurfaceChangeCase::kCornerRadius);
+}
+
 TEST_F(SurfaceInterceptorTest, InterceptMatrixUpdateWorks) {
     captureTest(&SurfaceInterceptorTest::matrixUpdate, SurfaceChange::SurfaceChangeCase::kMatrix);
 }
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index 7e95d99..e414991 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -1225,6 +1225,28 @@
     }
 }
 
+TEST_P(LayerTypeTransactionTest, SetCornerRadius) {
+    sp<SurfaceControl> layer;
+    const uint8_t size = 64;
+    const uint8_t testArea = 4;
+    const float cornerRadius = 16.0f;
+    ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", size, size));
+    ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, size, size));
+
+    Transaction()
+            .setCornerRadius(layer, cornerRadius)
+            .apply();
+    {
+        auto shot = screenshot();
+        // Transparent corners
+        shot->expectColor(Rect(0, 0, testArea, testArea), Color::BLACK);
+        shot->expectColor(Rect(0, size - testArea, testArea, testArea), Color::BLACK);
+        shot->expectColor(Rect(size - testArea, 0, testArea, testArea), Color::BLACK);
+        shot->expectColor(Rect(size - testArea, size - testArea, testArea, testArea),
+            Color::BLACK);
+    }
+}
+
 TEST_F(LayerTransactionTest, SetColorBasic) {
     sp<SurfaceControl> bufferLayer;
     sp<SurfaceControl> colorLayer;
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index cfaf495..5a6aa92 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -580,7 +580,8 @@
         EXPECT_CALL(*test->mRenderEngine,
                     setupLayerBlending(true, false, false,
                                        half4(LayerProperties::COLOR[0], LayerProperties::COLOR[1],
-                                             LayerProperties::COLOR[2], LayerProperties::COLOR[3])))
+                                             LayerProperties::COLOR[2], LayerProperties::COLOR[3]),
+                                       0.0f))
                 .Times(1);
 
         EXPECT_CALL(*test->mRenderEngine, createImage())
@@ -626,7 +627,8 @@
         EXPECT_CALL(*test->mRenderEngine,
                     setupLayerBlending(true, false, true,
                                        half4(LayerProperties::COLOR[0], LayerProperties::COLOR[1],
-                                             LayerProperties::COLOR[2], LayerProperties::COLOR[3])))
+                                             LayerProperties::COLOR[2], LayerProperties::COLOR[3]),
+                                       0.0f))
                 .Times(1);
         EXPECT_CALL(*test->mRenderEngine, drawMesh(_)).Times(1);
         EXPECT_CALL(*test->mRenderEngine, disableBlending()).Times(1);
@@ -690,7 +692,7 @@
         EXPECT_CALL(*test->mRenderEngine,
                     setupLayerBlending(true, false, false,
                                        half4(Base::COLOR[0], Base::COLOR[1], Base::COLOR[2],
-                                             Base::COLOR[3])))
+                                             Base::COLOR[3]), 0.0f))
                 .Times(1);
         EXPECT_CALL(*test->mRenderEngine, setSourceDataSpace(ui::Dataspace::UNKNOWN)).Times(1);
         EXPECT_CALL(*test->mRenderEngine, drawMesh(_)).Times(1);
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
index 90c3c20..a416808 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
+++ b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
@@ -56,10 +56,11 @@
     MOCK_CONST_METHOD0(checkErrors, void());
     MOCK_METHOD4(setViewportAndProjection,
                  void(size_t, size_t, Rect, ui::Transform::orientation_flags));
-    MOCK_METHOD4(setupLayerBlending, void(bool, bool, bool, const half4&));
+    MOCK_METHOD5(setupLayerBlending, void(bool, bool, bool, const half4&, float));
     MOCK_METHOD1(setupLayerTexturing, void(const Texture&));
     MOCK_METHOD0(setupLayerBlackedOut, void());
     MOCK_METHOD4(setupFillWithColor, void(float, float, float, float));
+    MOCK_METHOD2(setupCornerRadiusCropSize, void(float, float));
     MOCK_METHOD1(setColorTransform, void(const mat4&));
     MOCK_METHOD1(setSaturationMatrix, void(const mat4&));
     MOCK_METHOD0(disableTexturing, void());