SF: Ignore rounded corners if the layer can peek through

Bug: 163076219
Test: manual
Test: I53fc851eca876d44ba7cb9347f1c62d659c38932

In Layer::preparePerFrameCompositionState, no longer set
forceClientComposition to true based on the presence of rounded corners.
This will be determined later, based on whether the Layer will peek
through a Layer with a hole-punch.

In CachedSet::requiresHolePunch, return false if the layer must be
client composited for reasons other than rounded corners (which no
longer force client composition). While we could still use a hole punch,
it would not provide the desired effect (preventing waking up the GPU).

Add an extra field to overrideInfo, denoting whether this layer will
peek through another layer. Set it on a peekThroughLayer before sending
it to the HWC. If it's not set, and the layer has rounded corners, the
layer must be client composited, as before.

Change-Id: I3b4341d049c0fa5020dfd89ca9e765588a457eb1
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
index 356965c..3ecbb60 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
@@ -103,6 +103,11 @@
         // be visible through it. Unowned - the OutputLayer's lifetime will
         // outlast this.)
         OutputLayer* peekThroughLayer = nullptr;
+
+        // True if the OutputLayer represented by this CompositionState is
+        // peeking through another layer, so it can be device composited even if
+        // it should visually have rounded corners.
+        bool isPeekingThrough = false;
     } overrideInfo;
 
     /*
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 2953476..5c2a148 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -720,7 +720,7 @@
             continue;
         }
         bool skipLayer = false;
-        auto& overrideInfo = layer->getState().overrideInfo;
+        const auto& overrideInfo = layer->getState().overrideInfo;
         if (overrideInfo.buffer != nullptr) {
             if (previousOverride && overrideInfo.buffer->getBuffer() == previousOverride) {
                 ALOGV("Skipping redundant buffer");
@@ -729,6 +729,8 @@
                 // First layer with the override buffer.
                 if (overrideInfo.peekThroughLayer) {
                     peekThroughLayer = overrideInfo.peekThroughLayer;
+                    peekThroughLayer->editState().overrideInfo.isPeekingThrough = true;
+
                     // Draw peekThroughLayer first.
                     const bool includeGeometry = refreshArgs.updatingGeometryThisFrame;
                     peekThroughLayer->writeStateToHWC(includeGeometry, false, z++);
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index 89d5a23..444ac46 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -567,7 +567,8 @@
     auto& outputDependentState = editState();
 
     // If we are forcing client composition, we need to tell the HWC
-    if (outputDependentState.forceClientComposition) {
+    if (outputDependentState.forceClientComposition ||
+        (!getState().overrideInfo.isPeekingThrough && getLayerFE().hasRoundedCorners())) {
         requestedCompositionType = hal::Composition::CLIENT;
     }
 
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
index 6f66499..989b155 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
@@ -271,6 +271,10 @@
     }
 
     const auto& layerFE = mLayers[0].getState()->getOutputLayer()->getLayerFE();
+    if (layerFE.getCompositionState()->forceClientComposition) {
+        return false;
+    }
+
     return layerFE.hasRoundedCorners();
 }
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index cf215ad..4461420 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -531,7 +531,9 @@
             isOpaque(drawingState) && !usesRoundedCorners && getAlpha() == 1.0_hf;
 
     // Force client composition for special cases known only to the front-end.
-    if (isHdrY410() || usesRoundedCorners || drawShadows() || drawingState.blurRegions.size() > 0 ||
+    // Rounded corners no longer force client composition, since we may use a
+    // hole punch so that the layer will appear to have rounded corners.
+    if (isHdrY410() || drawShadows() || drawingState.blurRegions.size() > 0 ||
         compositionState->stretchEffect.hasEffect()) {
         compositionState->forceClientComposition = true;
     }