Merge "Cache hole punch, and flipped image shaders from pip" into sc-dev
diff --git a/libs/renderengine/skia/Cache.cpp b/libs/renderengine/skia/Cache.cpp
index d9d2496..081de2e 100644
--- a/libs/renderengine/skia/Cache.cpp
+++ b/libs/renderengine/skia/Cache.cpp
@@ -41,6 +41,10 @@
                                    0.f,  1.1f, 0.f, 0.f,
                                    0.f,  0.f,  1.f, 0.f,
                                    0.f,  0.f,  0.f, 1.f);
+const auto kFlip = mat4(1.1f, -0.1f,  0.f, 0.f,
+                        0.1f,  1.1f,  0.f, 0.f,
+                        0.f,    0.f,  1.f, 0.f,
+                        2.f,    2.f,  0.f, 1.f);
 // clang-format on
 // When setting layer.sourceDataspace, whether it matches the destination or not determines whether
 // a color correction effect is added to the shader.
@@ -115,6 +119,8 @@
     auto layers = std::vector<const LayerSettings*>{&layer};
     for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) {
         layer.sourceDataspace = dataspace;
+        // Cache shaders for both rects and round rects.
+        // In reduced shader mode, all non-zero round rect radii get the same code path.
         for (float roundedCornersRadius : {0.0f, 50.0f}) {
             // roundedCornersCrop is always set, but the radius triggers the behavior
             layer.geometry.roundedCornersRadius = roundedCornersRadius;
@@ -217,11 +223,9 @@
         layer.source = pixelSource;
         for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) {
             layer.sourceDataspace = dataspace;
-            // Produce a CircularRRect clip and an EllipticalRRect clip
+            // Produce a CircularRRect clip and an EllipticalRRect clip.
             for (auto transform : {kScaleAndTranslate, kScaleAsymmetric}) {
                 layer.geometry.positionTransform = transform;
-                // In real use, I saw alpha of 1.0 and 0.999, probably a mistake, but cache both
-                // shaders.
                 for (float alpha : {0.5f, 1.f}) {
                     layer.alpha = alpha,
                     renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
@@ -232,6 +236,69 @@
     }
 }
 
+static void drawPIPImageLayer(SkiaRenderEngine* renderengine, const DisplaySettings& display,
+                            const std::shared_ptr<ExternalTexture>& dstTexture,
+                            const std::shared_ptr<ExternalTexture>& srcTexture) {
+    const Rect& displayRect = display.physicalDisplay;
+    FloatRect rect(0, 0, displayRect.width(), displayRect.height());
+    LayerSettings layer{
+            .geometry =
+                    Geometry{
+                            // Note that this flip matrix only makes a difference when clipping,
+                            // which happens in this layer because the roundrect crop is just a bit
+                            // larger than the layer bounds.
+                            .positionTransform = kFlip,
+                            .boundaries = rect,
+                            .roundedCornersRadius = 94.2551,
+                            .roundedCornersCrop = FloatRect(
+                                -93.75, 0, displayRect.width() + 93.75, displayRect.height()),
+                    },
+            .source = PixelSource{.buffer =
+                                          Buffer{
+                                                  .buffer = srcTexture,
+                                                  .maxLuminanceNits = 1000.f,
+                                                  .isOpaque = 0,
+                                                  .usePremultipliedAlpha = 1,
+                                          }},
+            .sourceDataspace = kOtherDataSpace,
+            .alpha = 1,
+
+    };
+
+    auto layers = std::vector<const LayerSettings*>{&layer};
+    renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
+                             base::unique_fd(), nullptr);
+}
+
+static void drawHolePunchLayer(SkiaRenderEngine* renderengine, const DisplaySettings& display,
+                            const std::shared_ptr<ExternalTexture>& dstTexture) {
+    const Rect& displayRect = display.physicalDisplay;
+    FloatRect rect(0, 0, displayRect.width(), displayRect.height());
+    FloatRect small(0, 0, displayRect.width()-20, displayRect.height()+20);
+    LayerSettings layer{
+            .geometry =
+                    Geometry{
+                            .positionTransform = kScaleAndTranslate,
+                            // the boundaries have to be smaller than the rounded crop so that
+                            // clipRRect is used instead of drawRRect
+                            .boundaries = small,
+                            .roundedCornersRadius = 50.f,
+                            .roundedCornersCrop = rect,
+                    },
+            .source = PixelSource{
+                            .solidColor = half3(0.f, 0.f, 0.f),
+                    },
+            .sourceDataspace = kDestDataSpace,
+            .alpha = 0,
+            .disableBlending = true,
+
+    };
+
+    auto layers = std::vector<const LayerSettings*>{&layer};
+    renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
+                            base::unique_fd(), nullptr);
+}
+
 //
 // The collection of shaders cached here were found by using perfetto to record shader compiles
 // during actions that involve RenderEngine, logging the layer settings, and the shader code
@@ -243,8 +310,6 @@
 //    kFlushAfterEveryLayer = true
 // in external/skia/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
 //    gPrintSKSL = true
-//
-// TODO(b/184631553) cache the shader involved in youtube pip return.
 void Cache::primeShaderCache(SkiaRenderEngine* renderengine) {
     const int previousCount = renderengine->reportShadersCompiled();
     if (previousCount) {
@@ -286,7 +351,7 @@
                 std::make_shared<ExternalTexture>(srcBuffer, *renderengine,
                                                   ExternalTexture::Usage::READABLE |
                                                           ExternalTexture::Usage::WRITEABLE);
-
+        drawHolePunchLayer(renderengine, display, dstTexture);
         drawSolidLayers(renderengine, display, dstTexture);
         drawShadowLayers(renderengine, display, srcTexture);
 
@@ -325,6 +390,8 @@
             drawClippedLayers(renderengine, display, dstTexture, texture);
         }
 
+        drawPIPImageLayer(renderengine, display, dstTexture, externalTexture);
+
         const nsecs_t timeAfter = systemTime();
         const float compileTimeMs = static_cast<float>(timeAfter - timeBefore) / 1.0E6;
         const int shadersCompiled = renderengine->reportShadersCompiled();