|
78 | 78 | #include "SurfaceFlinger.h" |
79 | 79 | #include "TimeStats/TimeStats.h" |
80 | 80 | #include "TunnelModeEnabledReporter.h" |
| 81 | +#include "Utils/FenceUtils.h" |
81 | 82 |
|
82 | 83 | #define DEBUG_RESIZE 0 |
83 | 84 | #define EARLY_RELEASE_ENABLED false |
84 | 85 |
|
85 | 86 | namespace android { |
| 87 | +using namespace std::chrono_literals; |
86 | 88 | namespace { |
87 | 89 | constexpr int kDumpTableRowLength = 159; |
88 | 90 |
|
@@ -2911,7 +2913,8 @@ void Layer::callReleaseBufferCallback(const sp<ITransactionCompletedListener>& l |
2911 | 2913 | } |
2912 | 2914 |
|
2913 | 2915 | void Layer::onLayerDisplayed(ftl::SharedFuture<FenceResult> futureFenceResult, |
2914 | | - ui::LayerStack layerStack) { |
| 2916 | + ui::LayerStack layerStack, |
| 2917 | + std::function<FenceResult(FenceResult)>&& continuation) { |
2915 | 2918 | // If we are displayed on multiple displays in a single composition cycle then we would |
2916 | 2919 | // need to do careful tracking to enable the use of the mLastClientCompositionFence. |
2917 | 2920 | // For example we can only use it if all the displays are client comp, and we need |
@@ -2946,11 +2949,41 @@ void Layer::onLayerDisplayed(ftl::SharedFuture<FenceResult> futureFenceResult, |
2946 | 2949 | break; |
2947 | 2950 | } |
2948 | 2951 | } |
| 2952 | + |
| 2953 | + if (!FlagManager::getInstance().screenshot_fence_preservation() && continuation) { |
| 2954 | + futureFenceResult = ftl::Future(futureFenceResult).then(std::move(continuation)).share(); |
| 2955 | + } |
| 2956 | + |
2949 | 2957 | if (ch != nullptr) { |
2950 | 2958 | ch->previousReleaseCallbackId = mPreviousReleaseCallbackId; |
2951 | 2959 | ch->previousReleaseFences.emplace_back(std::move(futureFenceResult)); |
2952 | 2960 | ch->name = mName; |
| 2961 | + } else if (FlagManager::getInstance().screenshot_fence_preservation()) { |
| 2962 | + // If we didn't get a release callback yet, e.g. some scenarios when capturing screenshots |
| 2963 | + // asynchronously, then make sure we don't drop the fence. |
| 2964 | + mAdditionalPreviousReleaseFences.emplace_back(std::move(futureFenceResult), |
| 2965 | + std::move(continuation)); |
| 2966 | + std::vector<FenceAndContinuation> mergedFences; |
| 2967 | + sp<Fence> prevFence = nullptr; |
| 2968 | + // For a layer that's frequently screenshotted, try to merge fences to make sure we don't |
| 2969 | + // grow unbounded. |
| 2970 | + for (const auto& futureAndContinution : mAdditionalPreviousReleaseFences) { |
| 2971 | + auto result = futureAndContinution.future.wait_for(0s); |
| 2972 | + if (result != std::future_status::ready) { |
| 2973 | + mergedFences.emplace_back(futureAndContinution); |
| 2974 | + continue; |
| 2975 | + } |
| 2976 | + |
| 2977 | + mergeFence(getDebugName(), futureAndContinution.chain().get().value_or(Fence::NO_FENCE), |
| 2978 | + prevFence); |
| 2979 | + } |
| 2980 | + if (prevFence != nullptr) { |
| 2981 | + mergedFences.emplace_back(ftl::yield(FenceResult(std::move(prevFence))).share()); |
| 2982 | + } |
| 2983 | + |
| 2984 | + mAdditionalPreviousReleaseFences.swap(mergedFences); |
2953 | 2985 | } |
| 2986 | + |
2954 | 2987 | if (mBufferInfo.mBuffer) { |
2955 | 2988 | mPreviouslyPresentedLayerStacks.push_back(layerStack); |
2956 | 2989 | } |
@@ -3440,6 +3473,15 @@ bool Layer::setTransactionCompletedListeners(const std::vector<sp<CallbackHandle |
3440 | 3473 | handle->acquireTimeOrFence = mCallbackHandleAcquireTimeOrFence; |
3441 | 3474 | handle->frameNumber = mDrawingState.frameNumber; |
3442 | 3475 | handle->previousFrameNumber = mDrawingState.previousFrameNumber; |
| 3476 | + if (FlagManager::getInstance().screenshot_fence_preservation() && |
| 3477 | + mPreviousReleaseBufferEndpoint == handle->listener) { |
| 3478 | + // Add fences from previous screenshots now so that they can be dispatched to the |
| 3479 | + // client. |
| 3480 | + for (const auto& futureAndContinution : mAdditionalPreviousReleaseFences) { |
| 3481 | + handle->previousReleaseFences.emplace_back(futureAndContinution.chain()); |
| 3482 | + } |
| 3483 | + mAdditionalPreviousReleaseFences.clear(); |
| 3484 | + } |
3443 | 3485 |
|
3444 | 3486 | // Store so latched time and release fence can be set |
3445 | 3487 | mDrawingState.callbackHandles.push_back(handle); |
|
0 commit comments