diff options
| author | 2023-05-12 17:41:32 +0000 | |
|---|---|---|
| committer | 2023-05-12 17:41:32 +0000 | |
| commit | abf1ff29d0dbb200b7482686aab0f91a89d27ece (patch) | |
| tree | 088487b81a1a1f9d561d77c20fd67bde9edab8aa | |
| parent | b5284f578e4e6cddc0a766570b14a2fdfc52be6d (diff) | |
| parent | 4530ad4d4d82a89693200345a08c5258bcef0987 (diff) | |
Merge "[sf] avoid traversals for cursor updates and buffer udpates" into udc-dev am: 4530ad4d4d
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/23147418
Change-Id: I9fc3458d6fa0168906ef3995ae574c49af960349
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
4 files changed, 29 insertions, 2 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 1acaf48fad..d55ec990d9 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -8185,7 +8185,7 @@ std::vector<std::pair<Layer*, LayerFE*>> SurfaceFlinger::moveSnapshotsToComposit }); } 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 != @@ -8196,7 +8196,22 @@ std::vector<std::pair<Layer*, LayerFE*>> SurfaceFlinger::moveSnapshotsToComposit 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 1dbfbeb33f..e2691ab39a 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -1204,6 +1204,11 @@ private: 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 6ca21bd458..e8a9cfe9d7 100644 --- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp +++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp @@ -680,6 +680,9 @@ struct SidebandLayerProperties : public BaseLayerProperties<SidebandLayerPropert 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 @@ struct BaseLayerVariant { Mock::VerifyAndClear(test->mComposer); test->mFlinger.mutableDrawingState().layersSortedByZ.add(layer); + test->mFlinger.mutableVisibleRegionsDirty() = true; } static void cleanupInjectedLayers(CompositionTest* test) { @@ -822,6 +826,7 @@ struct BaseLayerVariant { 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 bea1916b43..945e48842d 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -587,6 +587,7 @@ public: 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; } @@ -598,6 +599,7 @@ public: 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; |