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;