SF: add a solid background when hole punching a cached set

When we punch a hole to round the corners on a PIP window we need
to make sure that the cached set is opaque to prevent blending of the
rounded corner edges with random opaque buffers.

Bug: 194307461
Test: PIP window on solid color wallpaper
Change-Id: I5ab80103dc5b43db85c4f12c9efd5ba2a1dfd076
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
index b24274e..835f6bf 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
@@ -218,6 +218,7 @@
     }
 
     renderengine::LayerSettings holePunchSettings;
+    renderengine::LayerSettings holePunchBackgroundSettings;
     if (mHolePunchLayer) {
         auto clientCompositionList =
                 mHolePunchLayer->getOutputLayer()->getLayerFE().prepareClientCompositionList(
@@ -232,6 +233,15 @@
         holePunchSettings.alpha = 0.0f;
         holePunchSettings.name = std::string("hole punch layer");
         layerSettingsPointers.push_back(&holePunchSettings);
+
+        // Add a solid background as the first layer in case there is no opaque
+        // buffer behind the punch hole
+        holePunchBackgroundSettings.alpha = 1.0f;
+        holePunchBackgroundSettings.name = std::string("holePunchBackground");
+        holePunchBackgroundSettings.geometry.boundaries = holePunchSettings.geometry.boundaries;
+        holePunchBackgroundSettings.geometry.positionTransform =
+                holePunchSettings.geometry.positionTransform;
+        layerSettingsPointers.insert(layerSettingsPointers.begin(), &holePunchBackgroundSettings);
     }
 
     if (sDebugHighlighLayers) {
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
index b05a594..5db27fa 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
@@ -590,12 +590,22 @@
                                 base::unique_fd&&, base::unique_fd*) -> size_t {
         // If the highlight layer is enabled, it will increase the size by 1.
         // We're interested in the third layer either way.
-        EXPECT_GE(layers.size(), 3u);
-        const auto* holePunchSettings = layers[2];
-        EXPECT_EQ(nullptr, holePunchSettings->source.buffer.buffer);
-        EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchSettings->source.solidColor);
-        EXPECT_TRUE(holePunchSettings->disableBlending);
-        EXPECT_EQ(0.0f, holePunchSettings->alpha);
+        EXPECT_GE(layers.size(), 4u);
+        {
+            const auto* holePunchSettings = layers[3];
+            EXPECT_EQ(nullptr, holePunchSettings->source.buffer.buffer);
+            EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchSettings->source.solidColor);
+            EXPECT_TRUE(holePunchSettings->disableBlending);
+            EXPECT_EQ(0.0f, holePunchSettings->alpha);
+        }
+
+        {
+            const auto* holePunchBackgroundSettings = layers[0];
+            EXPECT_EQ(nullptr, holePunchBackgroundSettings->source.buffer.buffer);
+            EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchBackgroundSettings->source.solidColor);
+            EXPECT_FALSE(holePunchBackgroundSettings->disableBlending);
+            EXPECT_EQ(1.0f, holePunchBackgroundSettings->alpha);
+        }
 
         return NO_ERROR;
     };
@@ -640,12 +650,23 @@
                                 base::unique_fd&&, base::unique_fd*) -> size_t {
         // If the highlight layer is enabled, it will increase the size by 1.
         // We're interested in the third layer either way.
-        EXPECT_GE(layers.size(), 3u);
-        const auto* holePunchSettings = layers[2];
-        EXPECT_EQ(nullptr, holePunchSettings->source.buffer.buffer);
-        EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchSettings->source.solidColor);
-        EXPECT_TRUE(holePunchSettings->disableBlending);
-        EXPECT_EQ(0.0f, holePunchSettings->alpha);
+        EXPECT_GE(layers.size(), 4u);
+
+        {
+            const auto* holePunchSettings = layers[3];
+            EXPECT_EQ(nullptr, holePunchSettings->source.buffer.buffer);
+            EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchSettings->source.solidColor);
+            EXPECT_TRUE(holePunchSettings->disableBlending);
+            EXPECT_EQ(0.0f, holePunchSettings->alpha);
+        }
+
+        {
+            const auto* holePunchBackgroundSettings = layers[0];
+            EXPECT_EQ(nullptr, holePunchBackgroundSettings->source.buffer.buffer);
+            EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchBackgroundSettings->source.solidColor);
+            EXPECT_FALSE(holePunchBackgroundSettings->disableBlending);
+            EXPECT_EQ(1.0f, holePunchBackgroundSettings->alpha);
+        }
 
         return NO_ERROR;
     };