Merge "[sf] avoid traversals for cursor updates and buffer udpates" into udc-dev am: 4530ad4d4d am: 92455a5c72
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/23147418
Change-Id: I9f507e07933f1085d76f1de7024a8278309c0c85
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index ec1a394..06d6ef0 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -8092,7 +8092,7 @@
});
}
if (mLegacyFrontEndEnabled && !mLayerLifecycleManagerEnabled) {
- mDrawingState.traverseInZOrder([&refreshArgs, cursorOnly, &layers](Layer* layer) {
+ auto moveSnapshots = [&layers, &refreshArgs, cursorOnly](Layer* layer) {
if (const auto& layerFE = layer->getCompositionEngineLayerFE()) {
if (cursorOnly &&
layer->getLayerSnapshot()->compositionType !=
@@ -8103,7 +8103,22 @@
refreshArgs.layers.push_back(layerFE);
layers.emplace_back(layer, layerFE.get());
}
- });
+ };
+
+ if (cursorOnly || !mVisibleRegionsDirty) {
+ // for hot path avoid traversals by walking though the previous composition list
+ for (sp<Layer> layer : mPreviouslyComposedLayers) {
+ moveSnapshots(layer.get());
+ }
+ } else {
+ mPreviouslyComposedLayers.clear();
+ mDrawingState.traverseInZOrder(
+ [&moveSnapshots](Layer* layer) { moveSnapshots(layer); });
+ mPreviouslyComposedLayers.reserve(layers.size());
+ for (auto [layer, _] : layers) {
+ mPreviouslyComposedLayers.push_back(sp<Layer>::fromExisting(layer));
+ }
+ }
}
return layers;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index ec2da87..5a6f22c 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1182,6 +1182,11 @@
std::unordered_set<sp<Layer>, SpHash<Layer>> mLayersWithBuffersRemoved;
// Tracks layers that need to update a display's dirty region.
std::vector<sp<Layer>> mLayersPendingRefresh;
+ // Sorted list of layers that were composed during previous frame. This is used to
+ // avoid an expensive traversal of the layer hierarchy when there are no
+ // visible region changes. Because this is a list of strong pointers, this will
+ // extend the life of the layer but this list is only updated in the main thread.
+ std::vector<sp<Layer>> mPreviouslyComposedLayers;
BootStage mBootStage = BootStage::BOOTLOADER;
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 6ca21bd..e8a9cfe 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -680,6 +680,9 @@
NativeHandle::create(reinterpret_cast<native_handle_t*>(DEFAULT_SIDEBAND_STREAM),
false);
test->mFlinger.setLayerSidebandStream(layer, stream);
+ auto& layerDrawingState = test->mFlinger.mutableLayerDrawingState(layer);
+ layerDrawingState.crop =
+ Rect(0, 0, SidebandLayerProperties::HEIGHT, SidebandLayerProperties::WIDTH);
}
static void setupHwcSetSourceCropBufferCallExpectations(CompositionTest* test) {
@@ -814,6 +817,7 @@
Mock::VerifyAndClear(test->mComposer);
test->mFlinger.mutableDrawingState().layersSortedByZ.add(layer);
+ test->mFlinger.mutableVisibleRegionsDirty() = true;
}
static void cleanupInjectedLayers(CompositionTest* test) {
@@ -822,6 +826,7 @@
test->mDisplay->getCompositionDisplay()->clearOutputLayers();
test->mFlinger.mutableDrawingState().layersSortedByZ.clear();
+ test->mFlinger.mutablePreviouslyComposedLayers().clear();
// Layer should be unregistered with scheduler.
test->mFlinger.commit();
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 2a0e865..833984f 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -604,6 +604,7 @@
auto& mutablePhysicalDisplays() { return mFlinger->mPhysicalDisplays; }
auto& mutableDrawingState() { return mFlinger->mDrawingState; }
auto& mutableGeometryDirty() { return mFlinger->mGeometryDirty; }
+ auto& mutableVisibleRegionsDirty() { return mFlinger->mVisibleRegionsDirty; }
auto& mutableMainThreadId() { return mFlinger->mMainThreadId; }
auto& mutablePendingHotplugEvents() { return mFlinger->mPendingHotplugEvents; }
auto& mutableTexturePool() { return mFlinger->mTexturePool; }
@@ -615,6 +616,7 @@
auto& mutableHwcPhysicalDisplayIdMap() { return getHwComposer().mPhysicalDisplayIdMap; }
auto& mutablePrimaryHwcDisplayId() { return getHwComposer().mPrimaryHwcDisplayId; }
auto& mutableActiveDisplayId() { return mFlinger->mActiveDisplayId; }
+ auto& mutablePreviouslyComposedLayers() { return mFlinger->mPreviouslyComposedLayers; }
auto& mutableActiveDisplayRotationFlags() {
return SurfaceFlinger::sActiveDisplayRotationFlags;