Don't send override buffer down to HWC if the layer would be skipped
Consider a set of five cached layers. Because ComposerResources' caches
are scoped per-layer and does not globally track buffers, the override
buffer for each layer needs to be re-imported, and a previous override
buffer needs to be freed, if the new override buffer changed between
frames. This causes a lot of churn in validate(), up to double CPU time
in the hot path.
Instead, we shouldn't override the buffer if a layer would be skipped.
In the aforementioned example, this would cause 1 buffers-worth of chrun
when importing, rather than 5.
Bug: 190654391
Test: Perfetto trace
Change-Id: I907b0c4c340fd99a0023429a8ad740ecc9208815
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
index 5bd1216..e9ecf3e 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
@@ -699,6 +699,7 @@
Hwc2::IComposerClient::BlendMode::PREMULTIPLIED;
static constexpr float kAlpha = 51.f;
static constexpr float kOverrideAlpha = 1.f;
+ static constexpr float kSkipAlpha = 0.f;
static constexpr ui::Dataspace kDataspace = static_cast<ui::Dataspace>(71);
static constexpr ui::Dataspace kOverrideDataspace = static_cast<ui::Dataspace>(72);
static constexpr int kSupportedPerFrameMetadata = 101;
@@ -1055,6 +1056,22 @@
/*zIsOverridden*/ false, /*isPeekingThrough*/ false);
}
+TEST_F(OutputLayerWriteStateToHWCTest, overriddenSkipLayerDoesNotSendBuffer) {
+ mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::DEVICE;
+ includeOverrideInfo();
+
+ expectGeometryCommonCalls(kOverrideDisplayFrame, kOverrideSourceCrop, kOverrideBufferTransform,
+ kOverrideBlendMode, kSkipAlpha);
+ expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace, kOverrideVisibleRegion,
+ kOverrideSurfaceDamage);
+ expectSetHdrMetadataAndBufferCalls();
+ expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE);
+ EXPECT_CALL(*mLayerFE, hasRoundedCorners()).WillRepeatedly(Return(false));
+
+ mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, 0,
+ /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
+}
+
TEST_F(OutputLayerWriteStateToHWCTest, includesOverrideInfoIfPresent) {
mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::DEVICE;
includeOverrideInfo();