diff options
| author | 2024-03-29 01:00:51 +0000 | |
|---|---|---|
| committer | 2024-03-29 01:00:51 +0000 | |
| commit | ea6843b308c4207b2237e91b85ca8b331c637029 (patch) | |
| tree | beb929671457384d590c15fc6f424d472cb92aae | |
| parent | 66ca790e05386186333e8a6e4cfc63033cd00133 (diff) | |
| parent | e4ef87f02e22a40daafe508e98d9aa8e061fc5ff (diff) | |
Merge "Track the last release fence per layer stack" into main
| -rw-r--r-- | libs/ui/include/ui/LayerStack.h | 4 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.cpp | 39 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.h | 10 |
3 files changed, 25 insertions, 28 deletions
diff --git a/libs/ui/include/ui/LayerStack.h b/libs/ui/include/ui/LayerStack.h index d6ffeb7fad..f4c8ba250e 100644 --- a/libs/ui/include/ui/LayerStack.h +++ b/libs/ui/include/ui/LayerStack.h @@ -55,6 +55,10 @@ inline bool operator>(LayerStack lhs, LayerStack rhs) { return lhs.id > rhs.id; } +inline bool operator<(LayerStack lhs, LayerStack rhs) { + return lhs.id < rhs.id; +} + // A LayerFilter determines if a layer is included for output to a display. struct LayerFilter { LayerStack layerStack; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 4cc2f9e1e7..80eee15cea 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -15,7 +15,7 @@ */ // TODO(b/129481165): remove the #pragma below and fix conversion issues -#include "TransactionCallbackInvoker.h" + #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wconversion" @@ -24,8 +24,6 @@ #define LOG_TAG "Layer" #define ATRACE_TAG ATRACE_TAG_GRAPHICS -#include "Layer.h" - #include <android-base/properties.h> #include <android-base/stringprintf.h> #include <binder/IPCThreadState.h> @@ -73,10 +71,12 @@ #include "FrameTracer/FrameTracer.h" #include "FrontEnd/LayerCreationArgs.h" #include "FrontEnd/LayerHandle.h" +#include "Layer.h" #include "LayerProtoHelper.h" #include "MutexUtils.h" #include "SurfaceFlinger.h" #include "TimeStats/TimeStats.h" +#include "TransactionCallbackInvoker.h" #include "TunnelModeEnabledReporter.h" #include "Utils/FenceUtils.h" @@ -2889,26 +2889,13 @@ void Layer::prepareReleaseCallbacks(ftl::Future<FenceResult> futureFenceResult, ch->previousReleaseFences.emplace_back(std::move(futureFenceResult)); ch->name = mName; } else { - // If we didn't get a release callback yet, e.g. some scenarios when capturing - // screenshots asynchronously, then make sure we don't drop the fence. - mAdditionalPreviousReleaseFences.emplace_back(std::move(futureFenceResult)); - std::vector<ftl::Future<FenceResult>> mergedFences; - sp<Fence> prevFence = nullptr; - // For a layer that's frequently screenshotted, try to merge fences to make sure we - // don't grow unbounded. - for (auto& futureReleaseFence : mAdditionalPreviousReleaseFences) { - auto result = futureReleaseFence.wait_for(0s); - if (result != std::future_status::ready) { - mergedFences.emplace_back(std::move(futureReleaseFence)); - continue; - } - mergeFence(getDebugName(), futureReleaseFence.get().value_or(Fence::NO_FENCE), - prevFence); - } - if (prevFence != nullptr) { - mergedFences.emplace_back(ftl::yield(FenceResult(std::move(prevFence)))); - } - mAdditionalPreviousReleaseFences.swap(mergedFences); + // If we didn't get a release callback yet (e.g. some scenarios when capturing + // screenshots asynchronously) then make sure we don't drop the fence. + // Older fences for the same layer stack can be dropped when a new fence arrives. + // An assumption here is that RenderEngine performs work sequentially, so an + // incoming fence will not fire before an existing fence. + mAdditionalPreviousReleaseFences.emplace_or_replace(layerStack, + std::move(futureFenceResult)); } if (mBufferInfo.mBuffer) { @@ -3458,10 +3445,10 @@ bool Layer::setTransactionCompletedListeners(const std::vector<sp<CallbackHandle handle->previousFrameNumber = mDrawingState.previousFrameNumber; if (FlagManager::getInstance().ce_fence_promise() && mPreviousReleaseBufferEndpoint == handle->listener) { - // Add fences from previous screenshots now so that they can be dispatched to the + // Add fence from previous screenshot now so that it can be dispatched to the // client. - for (auto& futureReleaseFence : mAdditionalPreviousReleaseFences) { - handle->previousReleaseFences.emplace_back(std::move(futureReleaseFence)); + for (auto& [_, future] : mAdditionalPreviousReleaseFences) { + handle->previousReleaseFences.emplace_back(std::move(future)); } mAdditionalPreviousReleaseFences.clear(); } else if (FlagManager::getInstance().screenshot_fence_preservation() && diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index edf2ae260b..c094aa1656 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -18,6 +18,7 @@ #include <android/gui/DropInputMode.h> #include <android/gui/ISurfaceComposerClient.h> +#include <ftl/small_map.h> #include <gui/BufferQueue.h> #include <gui/LayerState.h> #include <gui/WindowInfo.h> @@ -25,9 +26,11 @@ #include <math/vec4.h> #include <sys/types.h> #include <ui/BlurRegion.h> +#include <ui/DisplayMap.h> #include <ui/FloatRect.h> #include <ui/FrameStats.h> #include <ui/GraphicBuffer.h> +#include <ui/LayerStack.h> #include <ui/PixelFormat.h> #include <ui/Region.h> #include <ui/StretchEffect.h> @@ -952,8 +955,11 @@ public: // screenshots asynchronously. There may be no buffer update for the // layer, but the layer will still be composited on the screen in every // frame. Kepping track of these fences ensures that they are not dropped - // and can be dispatched to the client at a later time. - std::vector<ftl::Future<FenceResult>> mAdditionalPreviousReleaseFences; + // and can be dispatched to the client at a later time. Older fences are + // dropped when a layer stack receives a new fence. + // TODO(b/300533018): Track fence per multi-instance RenderEngine + ftl::SmallMap<ui::LayerStack, ftl::Future<FenceResult>, ui::kDisplayCapacity> + mAdditionalPreviousReleaseFences; // Exposed so SurfaceFlinger can assert that it's held const sp<SurfaceFlinger> mFlinger; |