Quick optimization for committing Layers
Layer::commitChildList is a traversal by itself. Running it inside a
traversal results in an undesired n^2 traversal time.
commitChildList is swapping the common state with the drawing state and executes the assignment multiple times / Layer, which could become quite costly.
Change-Id: I15f670b7766a3c2a16abbd3ae20bb8a7c76ec852
Test: atest SurfaceFlinger_test - all tests pass.
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index db6f1ad..45e9f2a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3027,15 +3027,19 @@
// clear the "changed" flags in current state
mCurrentState.colorMatrixChanged = false;
- mDrawingState.traverse([&](Layer* layer) {
- layer->commitChildList();
-
- // 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);
- }
- });
+ for (const auto& rootLayer : mDrawingState.layersSortedByZ) {
+ rootLayer->commitChildList();
+ }
+ // 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(); });