Retrieve a list of composition settings from front end layer

Replace prepareClientComposition and prepareShadowClientComposition
calls with one that provides a list of composition settings in z-order
to handle layers that renders shadows wihtout any content.
If the EffectLayer is called with an invalid color, skip the color fill.

Test: atest libcompositionengine_test
Test: LayerTransactionTest.SetFlagsSecureEUidSystem
Test: go/wm-smoke
Change-Id: Iad16931341fc2e58247f4439a322c0ad1e8750f8
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index a389bf3..e792f45 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -963,11 +963,16 @@
         // rectangle, as by definition the layer must blend with whatever is
         // underneath. We also skip the first layer as the buffer target is
         // guaranteed to start out cleared.
-        bool clearClientComposition =
+        const bool clearClientComposition =
                 layerState.clearClientTarget && layerFEState->isOpaque && !firstLayer;
 
         ALOGV("  Composition type: client %d clear %d", clientComposition, clearClientComposition);
 
+        // If the layer casts a shadow but the content casting the shadow is occluded, skip
+        // composing the non-shadow content and only draw the shadows.
+        const bool realContentIsVisible = clientComposition &&
+                !layerState.visibleRegion.subtract(layerState.shadowRegion).isEmpty();
+
         if (clientComposition || clearClientComposition) {
             compositionengine::LayerFE::ClientCompositionTargetSettings targetSettings{
                     clip,
@@ -976,35 +981,21 @@
                     outputState.isSecure,
                     supportsProtectedContent,
                     clientComposition ? clearRegion : dummyRegion,
+                    outputState.viewport,
+                    outputDataspace,
+                    realContentIsVisible,
+                    !clientComposition, /* clearContent  */
             };
-            if (std::optional<LayerFE::LayerSettings> result =
-                        layerFE.prepareClientComposition(targetSettings)) {
-                if (!clientComposition) {
-                    LayerFE::LayerSettings& layerSettings = *result;
-                    layerSettings.source.buffer.buffer = nullptr;
-                    layerSettings.source.solidColor = half3(0.0, 0.0, 0.0);
-                    layerSettings.alpha = half(0.0);
-                    layerSettings.disableBlending = true;
-                    layerSettings.frameNumber = 0;
-                } else {
-                    std::optional<LayerFE::LayerSettings> shadowLayer =
-                            layerFE.prepareShadowClientComposition(*result, outputState.viewport,
-                                                                   outputDataspace);
-                    if (shadowLayer) {
-                        clientCompositionLayers.push_back(*shadowLayer);
-                    }
-                }
-
-                // If the layer casts a shadow but the content casting the shadow is occluded, skip
-                // composing the non-shadow content and only draw the shadows.
-                const bool skipNonShadowContentComposition = clientComposition &&
-                        layerState.visibleRegion.subtract(layerState.shadowRegion).isEmpty();
-
-                if (!skipNonShadowContentComposition) {
-                    layer->editState().clientCompositionTimestamp = systemTime();
-                    clientCompositionLayers.push_back(*result);
-                }
+            std::vector<LayerFE::LayerSettings> results =
+                    layerFE.prepareClientCompositionList(targetSettings);
+            if (realContentIsVisible && !results.empty()) {
+                layer->editState().clientCompositionTimestamp = systemTime();
             }
+
+            clientCompositionLayers.insert(clientCompositionLayers.end(),
+                                           std::make_move_iterator(results.begin()),
+                                           std::make_move_iterator(results.end()));
+            results.clear();
         }
 
         firstLayer = false;