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/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 49a6800..11e9702 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2793,7 +2793,6 @@
*/
Region transparentRegion;
-
// handle hidden surfaces by setting the visible region to empty
if (CC_LIKELY(layer->isVisible())) {
const bool translucent = !layer->isOpaque(s);
@@ -2826,7 +2825,6 @@
}
if (visibleRegion.isEmpty()) {
- layer->clearVisibilityRegions();
return;
}
@@ -2839,12 +2837,21 @@
// subtract the opaque region covered by the layers above us
visibleRegion.subtractSelf(aboveOpaqueLayers);
+ // Get coverage information for the layer as previously displayed
+ auto prevOutputLayer = display->getOutputLayerForLayer(compositionLayer.get());
+ // TODO(b/121291683): Define this as a constant in Region.h
+ const Region kEmptyRegion;
+ const Region& oldVisibleRegion =
+ prevOutputLayer ? prevOutputLayer->getState().visibleRegion : kEmptyRegion;
+ const Region& oldCoveredRegion =
+ prevOutputLayer ? prevOutputLayer->getState().coveredRegion : kEmptyRegion;
+
// compute this layer's dirty region
if (layer->contentDirty) {
// we need to invalidate the whole region
dirty = visibleRegion;
// as well, as the old visible region
- dirty.orSelf(layer->visibleRegion);
+ dirty.orSelf(oldVisibleRegion);
layer->contentDirty = false;
} else {
/* compute the exposed region:
@@ -2860,8 +2867,6 @@
* exposed because of a resize.
*/
const Region newExposed = visibleRegion - coveredRegion;
- const Region oldVisibleRegion = layer->visibleRegion;
- const Region oldCoveredRegion = layer->coveredRegion;
const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
}
@@ -2873,16 +2878,13 @@
// Update aboveOpaqueLayers for next (lower) layer
aboveOpaqueLayers.orSelf(opaqueRegion);
- // Store the visible region in screen space
- layer->setVisibleRegion(visibleRegion);
- layer->setCoveredRegion(coveredRegion);
- layer->setVisibleNonTransparentRegion(
- visibleRegion.subtract(transparentRegion));
+ // Compute the visible non-transparent region
+ Region visibleNonTransparentRegion = visibleRegion.subtract(transparentRegion);
- // Setup an output layer for this output if the layer is
- // visible on this output
+ // Setup an output layer for this output if the layer is visible on this
+ // output
const auto& displayState = display->getState();
- Region drawRegion(displayState.transform.transform(layer->visibleNonTransparentRegion));
+ Region drawRegion(displayState.transform.transform(visibleNonTransparentRegion));
drawRegion.andSelf(displayState.bounds);
if (drawRegion.isEmpty()) {
return;
@@ -2895,8 +2897,11 @@
outLayersSortedByZ.emplace_back(
display->getOrCreateOutputLayer(displayId, compositionLayer, layerFE));
auto& outputLayerState = outLayersSortedByZ.back()->editState();
- outputLayerState.visibleRegion = displayState.transform.transform(
- layer->visibleRegion.intersect(displayState.viewport));
+ outputLayerState.visibleRegion = std::move(visibleRegion);
+ outputLayerState.visibleNonTransparentRegion = std::move(visibleNonTransparentRegion);
+ outputLayerState.coveredRegion = std::move(coveredRegion);
+ outputLayerState.outputSpaceVisibleRegion = displayState.transform.transform(
+ outputLayerState.visibleRegion.intersect(displayState.viewport));
});
outOpaqueRegion = aboveOpaqueLayers;