diff options
author | Jen-Chih Chang <jen-chih.chang@mediatek.com> | 2022-08-03 11:31:30 +0800 |
---|---|---|
committer | Hung-ying Tyan <tyanh@google.com> | 2022-08-11 11:03:04 +0000 |
commit | 1febfb87aadcdc59be95c0fd2d821ba89bc933ec (patch) | |
tree | 08627554eaa51daffe4acabed4009e62831870eb | |
parent | da19cdb36e714c9e5affb91d5d078c5365a4b03c (diff) | |
download | native-1febfb87aadcdc59be95c0fd2d821ba89bc933ec.tar.gz |
DO NOT MERGE Extend mPreviousPresentFences for high refresh rate
To provide hardware enough time to display a frame under high refresh
rate with long sf-duration, we extend mPreviousPresentFences by storing
extra slots. We check proper present fence at different moment
according to vsync period and sf-duration.
Bug: 241193992
Change-Id: I618dd7abdb1f9ca2cb92623cc4d423389d62e402
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 17 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 3 |
2 files changed, 16 insertions, 4 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 6a17cd8881..e9fbf6ea7b 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1955,8 +1955,16 @@ SurfaceFlinger::FenceWithFenceTime SurfaceFlinger::previousFrameFence() { const auto now = systemTime(); const auto vsyncPeriod = mScheduler->getDisplayStatInfo(now).vsyncPeriod; const bool expectedPresentTimeIsTheNextVsync = mExpectedPresentTime - now <= vsyncPeriod; - return expectedPresentTimeIsTheNextVsync ? mPreviousPresentFences[0] - : mPreviousPresentFences[1]; + + size_t shift = 0; + if (!expectedPresentTimeIsTheNextVsync) { + shift = static_cast<size_t>((mExpectedPresentTime - now) / vsyncPeriod); + if (shift >= mPreviousPresentFences.size()) { + shift = mPreviousPresentFences.size() - 1; + } + } + ATRACE_FORMAT("previousFrameFence shift=%zu", shift); + return mPreviousPresentFences[shift]; } bool SurfaceFlinger::previousFramePending(int graceTimeMs) { @@ -2425,7 +2433,10 @@ void SurfaceFlinger::postComposition() { glCompositionDoneFenceTime = FenceTime::NO_FENCE; } - mPreviousPresentFences[1] = mPreviousPresentFences[0]; + for (size_t i = mPreviousPresentFences.size()-1; i >= 1; i--) { + mPreviousPresentFences[i] = mPreviousPresentFences[i-1]; + } + mPreviousPresentFences[0].fence = display ? getHwComposer().getPresentFence(display->getPhysicalId()) : Fence::NO_FENCE; mPreviousPresentFences[0].fenceTime = diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index f14c755c2b..46f0e6ba83 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -1224,7 +1224,8 @@ private: std::unordered_set<sp<Layer>, SpHash<Layer>> mLayersWithQueuedFrames; // Tracks layers that need to update a display's dirty region. std::vector<sp<Layer>> mLayersPendingRefresh; - std::array<FenceWithFenceTime, 2> mPreviousPresentFences; + // size should be longest sf-duration / shortest vsync period and round up + std::array<FenceWithFenceTime, 5> mPreviousPresentFences; // currently consider 166hz. // True if in the previous frame at least one layer was composed via the GPU. bool mHadClientComposition = false; // True if in the previous frame at least one layer was composed via HW Composer. |