Optimize offscreen layer management
Now that we manage reparenting on the main thread, we can directly
manipulate the offscreen layers list rather than updating it
in a later traversal.
Bug: 186200583
Test: Existing tests pass
Change-Id: I9b101544c272b60d2d93d09b3cc6074098181cf3
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9c04fbf..7fe8525 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3253,17 +3253,6 @@
}
}
- // TODO(b/163019109): See if this traversal is needed at all...
- if (!mOffscreenLayers.empty()) {
- mDrawingState.traverse([&](Layer* layer) {
- // If the layer can be reached when traversing mDrawingState, then the layer is no
- // longer offscreen. Remove the layer from the offscreenLayer set.
- if (mOffscreenLayers.count(layer)) {
- mOffscreenLayers.erase(layer);
- }
- });
- }
-
commitOffscreenLayers();
mDrawingState.traverse([&](Layer* layer) { layer->updateMirrorInfo(); });
}
@@ -6622,7 +6611,7 @@
void SurfaceFlinger::onLayerDestroyed(Layer* layer) {
mNumLayers--;
- removeFromOffscreenLayers(layer);
+ removeHierarchyFromOffscreenLayers(layer);
if (!layer->isRemovedFromCurrentState()) {
mScheduler->deregisterLayer(layer);
}
@@ -6635,13 +6624,17 @@
// from dangling children layers such that they are not reachable from the
// Drawing state nor the offscreen layer list
// See b/141111965
-void SurfaceFlinger::removeFromOffscreenLayers(Layer* layer) {
+void SurfaceFlinger::removeHierarchyFromOffscreenLayers(Layer* layer) {
for (auto& child : layer->getCurrentChildren()) {
mOffscreenLayers.emplace(child.get());
}
mOffscreenLayers.erase(layer);
}
+void SurfaceFlinger::removeFromOffscreenLayers(Layer* layer) {
+ mOffscreenLayers.erase(layer);
+}
+
status_t SurfaceFlinger::setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor,
float lightPosY, float lightPosZ,
float lightRadius) {