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/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 8eb5c22..5073a92 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -492,13 +492,12 @@
compositionState->hasProtectedContent = isProtected();
const bool usesRoundedCorners = getRoundedCornerState().radius != 0.f;
- const bool drawsShadows = mEffectiveShadowRadius != 0.f;
compositionState->isOpaque =
isOpaque(drawingState) && !usesRoundedCorners && getAlpha() == 1.0_hf;
// Force client composition for special cases known only to the front-end.
- if (isHdrY410() || usesRoundedCorners || drawsShadows) {
+ if (isHdrY410() || usesRoundedCorners || drawShadows()) {
compositionState->forceClientComposition = true;
}
}
@@ -653,6 +652,49 @@
return shadowLayer;
}
+void Layer::prepareClearClientComposition(LayerFE::LayerSettings& layerSettings,
+ bool blackout) const {
+ layerSettings.source.buffer.buffer = nullptr;
+ layerSettings.source.solidColor = half3(0.0, 0.0, 0.0);
+ layerSettings.disableBlending = true;
+ layerSettings.frameNumber = 0;
+
+ // If layer is blacked out, force alpha to 1 so that we draw a black color layer.
+ layerSettings.alpha = blackout ? 1.0f : 0.0f;
+}
+
+std::vector<compositionengine::LayerFE::LayerSettings> Layer::prepareClientCompositionList(
+ compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) {
+ std::optional<compositionengine::LayerFE::LayerSettings> layerSettings =
+ prepareClientComposition(targetSettings);
+ // Nothing to render.
+ if (!layerSettings) {
+ return {};
+ }
+
+ // HWC requests to clear this layer.
+ if (targetSettings.clearContent) {
+ prepareClearClientComposition(*layerSettings, false /* blackout */);
+ return {*layerSettings};
+ }
+
+ std::optional<compositionengine::LayerFE::LayerSettings> shadowSettings =
+ prepareShadowClientComposition(*layerSettings, targetSettings.viewport,
+ targetSettings.dataspace);
+ // There are no shadows to render.
+ if (!shadowSettings) {
+ return {*layerSettings};
+ }
+
+ // 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.
+ if (targetSettings.realContentIsVisible) {
+ return {*shadowSettings, *layerSettings};
+ }
+
+ return {*shadowSettings};
+}
+
Hwc2::IComposerClient::Composition Layer::getCompositionType(
const sp<const DisplayDevice>& display) const {
const auto outputLayer = findOutputLayerForDisplay(display);