SF: Move layer visibility state to CompositionEngine
The layer visibility/coverage state was the last bit of
display-dependent data that had not yet been moved to
OutputLayerCompositionState. This moves it, and fixes up all references
to the data to get it in a display-dependent way.
Test: atest libsurfaceflinger_unittest libcompositionengine_test
Bug: 121291683
Change-Id: Id9f314f05b743212dba3a113df2baeb38fd19eb8
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
index 6a0caf0..b066cd1 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
@@ -56,10 +56,6 @@
Region geomActiveTransparentRegion;
FloatRect geomLayerBounds;
- // TODO(lpique): b/121291683 Remove this one we are sure we don't need the
- // value recomputed / set every frame.
- Region geomVisibleRegion;
-
/*
* Presentation
*/
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/LayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/LayerCompositionState.h
index ab01c20..726c850 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/LayerCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/LayerCompositionState.h
@@ -21,6 +21,7 @@
#include <compositionengine/LayerFECompositionState.h>
#include <renderengine/Mesh.h>
+#include <ui/Region.h>
namespace android {
@@ -28,7 +29,7 @@
struct LayerCompositionState {
/*
- * State intended to be set by LayerFE::getCompositionState
+ * State set by LayerFE::getCompositionState
*/
LayerFECompositionState frontEnd;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
index de0f08a..1347449 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
@@ -40,9 +40,18 @@
namespace compositionengine::impl {
struct OutputLayerCompositionState {
- // The region of this layer which is visible on this output
+ // The portion of the layer that is not obscured by opaque layers on top
Region visibleRegion;
+ // The portion of the layer that is not obscured and is also opaque
+ Region visibleNonTransparentRegion;
+
+ // The portion of the layer that is obscured by opaque layers on top
+ Region coveredRegion;
+
+ // The visibleRegion transformed to output space
+ Region outputSpaceVisibleRegion;
+
// If true, client composition will be used on this output
bool forceClientComposition{false};
@@ -62,7 +71,7 @@
ui::Dataspace dataspace{ui::Dataspace::UNKNOWN};
// The Z order index of this layer on this output
- uint32_t z;
+ uint32_t z{0};
/*
* HWC state
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 903ca98..9f4f259 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -601,7 +601,7 @@
const auto& layerFEState = layer->getLayer().getState().frontEnd;
auto& layerFE = layer->getLayerFE();
- const Region clip(viewportRegion.intersect(layerFEState.geomVisibleRegion));
+ const Region clip(viewportRegion.intersect(layerState.visibleRegion));
ALOGV("Layer: %s", layerFE.getDebugName());
if (clip.isEmpty()) {
ALOGV(" Skipping for empty clip");
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index 73bb03b..21f0ce8 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -315,11 +315,6 @@
? outputState.targetDataspace
: layerFEState.dataspace;
- // TODO(lpique): b/121291683 Remove this one we are sure we don't need the
- // value recomputed / set every frame.
- mState.visibleRegion = outputState.transform.transform(
- layerFEState.geomVisibleRegion.intersect(outputState.viewport));
-
// These are evaluated every frame as they can potentially change at any
// time.
if (layerFEState.forceClientComposition || !profile.isDataspaceSupported(mState.dataspace)) {
@@ -421,13 +416,13 @@
void OutputLayer::writeOutputDependentPerFrameStateToHWC(HWC2::Layer* hwcLayer) {
const auto& outputDependentState = getState();
- // TODO(lpique): b/121291683 visibleRegion is output-dependent geometry
+ // TODO(lpique): b/121291683 outputSpaceVisibleRegion is output-dependent geometry
// state and should not change every frame.
- if (auto error = hwcLayer->setVisibleRegion(outputDependentState.visibleRegion);
+ if (auto error = hwcLayer->setVisibleRegion(outputDependentState.outputSpaceVisibleRegion);
error != HWC2::Error::None) {
ALOGE("[%s] Failed to set visible region: %s (%d)", mLayerFE->getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
- outputDependentState.visibleRegion.dump(LOG_TAG);
+ outputDependentState.outputSpaceVisibleRegion.dump(LOG_TAG);
}
if (auto error = hwcLayer->setDataspace(outputDependentState.dataspace);
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp
index e320bee..ad668b6 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp
@@ -42,6 +42,15 @@
dumpVal(out, "visibleRegion", visibleRegion);
out.append(" ");
+ dumpVal(out, "visibleNonTransparentRegion", visibleNonTransparentRegion);
+
+ out.append(" ");
+ dumpVal(out, "coveredRegion", coveredRegion);
+
+ out.append(" ");
+ dumpVal(out, "output visibleRegion", outputSpaceVisibleRegion);
+
+ out.append(" ");
dumpVal(out, "forceClientComposition", forceClientComposition);
dumpVal(out, "clearClientTarget", clearClientTarget);
dumpVal(out, "displayFrame", displayFrame);
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
index 75e960c..2276dc3 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
@@ -574,7 +574,7 @@
static const half4 kColor;
static const Rect kDisplayFrame;
- static const Region kVisibleRegion;
+ static const Region kOutputSpaceVisibleRegion;
static const mat4 kColorTransform;
static const Region kSurfaceDamage;
static const HdrMetadata kHdrMetadata;
@@ -590,7 +590,7 @@
outputLayerState.sourceCrop = kSourceCrop;
outputLayerState.z = kZOrder;
outputLayerState.bufferTransform = static_cast<Hwc2::Transform>(kBufferTransform);
- outputLayerState.visibleRegion = kVisibleRegion;
+ outputLayerState.outputSpaceVisibleRegion = kOutputSpaceVisibleRegion;
outputLayerState.dataspace = kDataspace;
mLayerState.frontEnd.blendMode = kBlendMode;
@@ -629,7 +629,7 @@
}
void expectPerFrameCommonCalls(SimulateUnsupported unsupported = SimulateUnsupported::None) {
- EXPECT_CALL(*mHwcLayer, setVisibleRegion(RegionEq(kVisibleRegion)))
+ EXPECT_CALL(*mHwcLayer, setVisibleRegion(RegionEq(kOutputSpaceVisibleRegion)))
.WillOnce(Return(kError));
EXPECT_CALL(*mHwcLayer, setDataspace(kDataspace)).WillOnce(Return(kError));
EXPECT_CALL(*mHwcLayer, setColorTransform(kColorTransform))
@@ -673,7 +673,8 @@
const half4 OutputLayerWriteStateToHWCTest::kColor{81.f / 255.f, 82.f / 255.f, 83.f / 255.f,
84.f / 255.f};
const Rect OutputLayerWriteStateToHWCTest::kDisplayFrame{1001, 1002, 1003, 10044};
-const Region OutputLayerWriteStateToHWCTest::kVisibleRegion{Rect{1005, 1006, 1007, 1008}};
+const Region OutputLayerWriteStateToHWCTest::kOutputSpaceVisibleRegion{
+ Rect{1005, 1006, 1007, 1008}};
const mat4 OutputLayerWriteStateToHWCTest::kColorTransform{
1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016,
1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024,
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 1d5f2f0..b0e8e36 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -661,9 +661,9 @@
impl::OutputLayerCompositionState leftOutputLayerState;
leftOutputLayerState.clearClientTarget = false;
+ leftOutputLayerState.visibleRegion = Region{Rect{0, 0, 1000, 1000}};
impl::LayerCompositionState leftLayerState;
- leftLayerState.frontEnd.geomVisibleRegion = Region{Rect{0, 0, 1000, 1000}};
leftLayerState.frontEnd.isOpaque = true;
const half3 leftLayerColor{1.f, 0.f, 0.f};
@@ -672,9 +672,9 @@
impl::OutputLayerCompositionState rightOutputLayerState;
rightOutputLayerState.clearClientTarget = false;
+ rightOutputLayerState.visibleRegion = Region{Rect{1000, 0, 2000, 1000}};
impl::LayerCompositionState rightLayerState;
- rightLayerState.frontEnd.geomVisibleRegion = Region{Rect{1000, 0, 2000, 1000}};
rightLayerState.frontEnd.isOpaque = true;
const half3 rightLayerColor{0.f, 1.f, 0.f};
@@ -735,9 +735,9 @@
impl::OutputLayerCompositionState outputLayerState;
outputLayerState.clearClientTarget = false;
+ outputLayerState.visibleRegion = Region{Rect{3000, 0, 4000, 1000}};
impl::LayerCompositionState layerState;
- layerState.frontEnd.geomVisibleRegion = Region{Rect{3000, 0, 4000, 1000}};
layerState.frontEnd.isOpaque = true;
EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
@@ -790,16 +790,16 @@
impl::OutputLayerCompositionState leftOutputLayerState;
leftOutputLayerState.clearClientTarget = true;
+ leftOutputLayerState.visibleRegion = Region{Rect{0, 0, 1000, 1000}};
impl::LayerCompositionState leftLayerState;
- leftLayerState.frontEnd.geomVisibleRegion = Region{Rect{0, 0, 1000, 1000}};
leftLayerState.frontEnd.isOpaque = true;
impl::OutputLayerCompositionState rightOutputLayerState;
rightOutputLayerState.clearClientTarget = true;
+ rightOutputLayerState.visibleRegion = Region{Rect{1000, 0, 2000, 1000}};
impl::LayerCompositionState rightLayerState;
- rightLayerState.frontEnd.geomVisibleRegion = Region{Rect{1000, 0, 2000, 1000}};
rightLayerState.frontEnd.isOpaque = true;
const half3 rightLayerColor{0.f, 1.f, 0.f};