Allow for solid color layers to start some candidate cached sets.
This is for letterboxed holepunch: a typical layer stack would be:
1. A solid color letterbox in back
2. A solid color layer for SurfaceView's background protection
3. A game's SurfaceView which has rounded corners
One of the constraints for creating a CachedSet is that it cannot begin
with a solid color layer, under the assumption that if there is an idle
layer on top of a solid color layer, then those two layers should not be
merged into a cached set since displaying the color layer separately is
already cheap. But, for the example layer stack above, this means that
there cannot be a candidate cached set behind the game's SurfaceView,
meaning that there is no hole punch generated, so the game is always in
client composition.
So, let's remove the constraint that a CachedSet cannot start with a solid
color layer for hole punches, which resolves the issue.
Bug: 208780233
Test: Hill Climb Racing with letterboxed rounded corners
Test: libcompositionengine_test
Change-Id: Ia5bcdec363f4401b9b9738c5f6ce335497d6362b
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index e958549..cf76183 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -347,6 +347,10 @@
auto requestedCompositionType = outputIndependentState->compositionType;
+ if (requestedCompositionType == hal::Composition::SOLID_COLOR && state.overrideInfo.buffer) {
+ requestedCompositionType = hal::Composition::DEVICE;
+ }
+
// TODO(b/181172795): We now update geometry for all flattened layers. We should update it
// only when the geometry actually changes
const bool isOverridden =
@@ -359,13 +363,15 @@
}
writeOutputDependentPerFrameStateToHWC(hwcLayer.get());
- writeOutputIndependentPerFrameStateToHWC(hwcLayer.get(), *outputIndependentState, skipLayer);
+ writeOutputIndependentPerFrameStateToHWC(hwcLayer.get(), *outputIndependentState,
+ requestedCompositionType, skipLayer);
writeCompositionTypeToHWC(hwcLayer.get(), requestedCompositionType, isPeekingThrough,
skipLayer);
- // Always set the layer color after setting the composition type.
- writeSolidColorStateToHWC(hwcLayer.get(), *outputIndependentState);
+ if (requestedCompositionType == hal::Composition::SOLID_COLOR) {
+ writeSolidColorStateToHWC(hwcLayer.get(), *outputIndependentState);
+ }
editState().hwc->stateOverridden = isOverridden;
editState().hwc->layerSkipped = skipLayer;
@@ -477,7 +483,7 @@
void OutputLayer::writeOutputIndependentPerFrameStateToHWC(
HWC2::Layer* hwcLayer, const LayerFECompositionState& outputIndependentState,
- bool skipLayer) {
+ hal::Composition compositionType, bool skipLayer) {
switch (auto error = hwcLayer->setColorTransform(outputIndependentState.colorTransform)) {
case hal::Error::NONE:
break;
@@ -501,7 +507,7 @@
}
// Content-specific per-frame state
- switch (outputIndependentState.compositionType) {
+ switch (compositionType) {
case hal::Composition::SOLID_COLOR:
// For compatibility, should be written AFTER the composition type.
break;
@@ -521,10 +527,6 @@
void OutputLayer::writeSolidColorStateToHWC(HWC2::Layer* hwcLayer,
const LayerFECompositionState& outputIndependentState) {
- if (outputIndependentState.compositionType != hal::Composition::SOLID_COLOR) {
- return;
- }
-
hal::Color color = {static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.r)),
static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.g)),
static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.b)),