Merge "Add robustness for permissions errors to Surface APIs." into sc-dev am: a3d681c3fa am: ad33bb7dc5

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/14466581

Change-Id: I46aa5cfcb01d4196e0a1c3d0018c74ca674bd0ca
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 9f6ecaa..47c330f 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -725,6 +725,14 @@
         return BAD_VALUE;
     }
 
+    // setup color filter if necessary
+    sk_sp<SkColorFilter> displayColorTransform;
+    if (display.colorTransform != mat4()) {
+        displayColorTransform = SkColorFilters::Matrix(toSkColorMatrix(display.colorTransform));
+    }
+    const bool ctModifiesAlpha =
+            displayColorTransform && !displayColorTransform->isAlphaUnchanged();
+
     // Find if any layers have requested blur, we'll use that info to decide when to render to an
     // offscreen buffer and when to render to the native buffer.
     sk_sp<SkSurface> activeSurface(dstSurface);
@@ -734,6 +742,10 @@
     if (mBlurFilter) {
         bool requiresCompositionLayer = false;
         for (const auto& layer : layers) {
+            // if the layer doesn't have blur or it is not visible then continue
+            if (!layerHasBlur(layer, ctModifiesAlpha)) {
+                continue;
+            }
             if (layer->backgroundBlurRadius > 0 &&
                 layer->backgroundBlurRadius < BlurFilter::kMaxCrossFadeRadius) {
                 requiresCompositionLayer = true;
@@ -779,12 +791,6 @@
         canvas->drawRegion(clearRegion, paint);
     }
 
-    // setup color filter if necessary
-    sk_sp<SkColorFilter> displayColorTransform;
-    if (display.colorTransform != mat4()) {
-        displayColorTransform = SkColorFilters::Matrix(toSkColorMatrix(display.colorTransform));
-    }
-
     for (const auto& layer : layers) {
         ATRACE_NAME("DrawLayer");
 
@@ -850,7 +856,7 @@
         const auto [bounds, roundRectClip] =
                 getBoundsAndClip(layer->geometry.boundaries, layer->geometry.roundedCornersCrop,
                                  layer->geometry.roundedCornersRadius);
-        if (mBlurFilter && layerHasBlur(layer)) {
+        if (mBlurFilter && layerHasBlur(layer, ctModifiesAlpha)) {
             std::unordered_map<uint32_t, sk_sp<SkImage>> cachedBlurs;
 
             // if multiple layers have blur, then we need to take a snapshot now because
@@ -1188,8 +1194,15 @@
     return {SkRRect::MakeRect(bounds), clip};
 }
 
-inline bool SkiaGLRenderEngine::layerHasBlur(const LayerSettings* layer) {
-    return layer->backgroundBlurRadius > 0 || layer->blurRegions.size();
+inline bool SkiaGLRenderEngine::layerHasBlur(const LayerSettings* layer,
+                                             bool colorTransformModifiesAlpha) {
+    if (layer->backgroundBlurRadius > 0 || layer->blurRegions.size()) {
+        // return false if the content is opaque and would therefore occlude the blur
+        const bool opaqueContent = !layer->source.buffer.buffer || layer->source.buffer.isOpaque;
+        const bool opaqueAlpha = layer->alpha == 1.0f && !colorTransformModifiesAlpha;
+        return layer->skipContentDraw || !(opaqueContent && opaqueAlpha);
+    }
+    return false;
 }
 
 inline SkColor SkiaGLRenderEngine::getSkColor(const vec4& color) {
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h
index 4265c08..97d3b72 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.h
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.h
@@ -90,7 +90,7 @@
     inline SkRect getSkRect(const Rect& layer);
     inline std::pair<SkRRect, SkRRect> getBoundsAndClip(const FloatRect& bounds,
                                                         const FloatRect& crop, float cornerRadius);
-    inline bool layerHasBlur(const LayerSettings* layer);
+    inline bool layerHasBlur(const LayerSettings* layer, bool colorTransformModifiesAlpha);
     inline SkColor getSkColor(const vec4& color);
     inline SkM44 getSkM44(const mat4& matrix);
     inline SkPoint3 getSkPoint3(const vec3& vector);
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
index 2f2cc06..297c0b2 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
@@ -30,10 +30,11 @@
 namespace android::compositionengine::impl::planner {
 
 Planner::Planner()
-      : mFlattener(base::GetBoolProperty(std::string("debug.sf.enable_hole_punch_pip"), false)) {
-    // Implicitly, layer caching must also be enabled.
-    // E.g., setprop debug.sf.enable_layer_caching 1, or
-    // adb shell service call SurfaceFlinger 1040 i32 1 [i64 <display ID>]
+      // Implicitly, layer caching must also be enabled for the hole punch or
+      // predictor to have any effect.
+      // E.g., setprop debug.sf.enable_layer_caching 1, or
+      // adb shell service call SurfaceFlinger 1040 i32 1 [i64 <display ID>]
+      : mFlattener(base::GetBoolProperty(std::string("debug.sf.enable_hole_punch_pip"), true)) {
     mPredictorEnabled =
             base::GetBoolProperty(std::string("debug.sf.enable_planner_prediction"), false);
 }