Do not blur opaque layers
If a layer is opaque, there's no reason to send it to client composition
due to blurs.
Bug: 196828055
Test: atest OutputUpdateAndWriteCompositionStateTest
Test: atest OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
Test: perfetto trace
Change-Id: I55461cbad0008351c15e7dd8d2da20e0b1c59f70
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 3310a71..95ae5e5 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -789,6 +789,9 @@
if (compState->sidebandStream != nullptr) {
return nullptr;
}
+ if (compState->isOpaque) {
+ continue;
+ }
if (compState->backgroundBlurRadius > 0 || compState->blurRegions.size() > 0) {
layerRequestingBgComposition = layer;
}
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index ee73cfc..09f5a5e 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -3606,6 +3606,7 @@
: public OutputComposeSurfacesTest_SetsExpensiveRendering {
OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
mLayer.layerFEState.backgroundBlurRadius = 10;
+ mLayer.layerFEState.isOpaque = false;
mOutput.editState().isEnabled = true;
EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
@@ -4225,6 +4226,37 @@
kDisplayDataspace));
}
+TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
+ InjectedLayer layer1;
+ InjectedLayer layer2;
+
+ uint32_t z = 0;
+ // Layer requesting blur, or below, should request client composition, unless opaque.
+ EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
+ EXPECT_CALL(*layer1.outputLayer,
+ writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
+ /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
+ EXPECT_CALL(*layer2.outputLayer,
+ writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
+ /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+
+ layer2.layerFEState.backgroundBlurRadius = 10;
+ layer2.layerFEState.isOpaque = true;
+
+ injectOutputLayer(layer1);
+ injectOutputLayer(layer2);
+
+ mOutput->editState().isEnabled = true;
+
+ CompositionRefreshArgs args;
+ args.updatingGeometryThisFrame = false;
+ args.devOptForceClientComposition = false;
+ mOutput->updateCompositionState(args);
+ mOutput->planComposition();
+ mOutput->writeCompositionState(args);
+}
+
TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
InjectedLayer layer1;
InjectedLayer layer2;
@@ -4246,6 +4278,7 @@
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
layer2.layerFEState.backgroundBlurRadius = 10;
+ layer2.layerFEState.isOpaque = false;
injectOutputLayer(layer1);
injectOutputLayer(layer2);
@@ -4283,6 +4316,7 @@
BlurRegion region;
layer2.layerFEState.blurRegions.push_back(region);
+ layer2.layerFEState.isOpaque = false;
injectOutputLayer(layer1);
injectOutputLayer(layer2);