diff options
author | Ady Abraham <adyabr@google.com> | 2019-09-19 11:32:43 -0700 |
---|---|---|
committer | Ady Abraham <adyabr@google.com> | 2019-09-19 19:47:07 +0000 |
commit | b40b0269dfbd4a259bc604e84392c3984c300932 (patch) | |
tree | 974492d524b9d0463ef5e92e2981806a1b268eaa | |
parent | 5726d926a9eb0ccbe00236ff9e1303f4ea542396 (diff) | |
download | native-b40b0269dfbd4a259bc604e84392c3984c300932.tar.gz |
SurfaceFlinger: add grace time for present fence to signal
To avoid racing with HWVsync when SF wakeup at a small offset from vsync,
we want to give a small grace period for the present fence to fire
instead of just giving up on this frame.
Bug: 141312250
Test: Set SF offset to 0 and observe systrace
Change-Id: I713fad164fa2f4e0f00a2b4efaae063ac8f4a2b7
Merged-In: I713fad164fa2f4e0f00a2b4efaae063ac8f4a2b7
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 23 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 2 |
2 files changed, 21 insertions, 4 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index d91b0e7db7..fe09c9c3d2 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1676,7 +1676,8 @@ void SurfaceFlinger::updateVrFlinger() { setTransactionFlags(eDisplayTransactionNeeded); } -bool SurfaceFlinger::previousFrameMissed() NO_THREAD_SAFETY_ANALYSIS { +bool SurfaceFlinger::previousFrameMissed(int graceTimeMs) NO_THREAD_SAFETY_ANALYSIS { + ATRACE_CALL(); // We are storing the last 2 present fences. If sf's phase offset is to be // woken up before the actual vsync but targeting the next vsync, we need to check // fence N-2 @@ -1685,7 +1686,15 @@ bool SurfaceFlinger::previousFrameMissed() NO_THREAD_SAFETY_ANALYSIS { ? mPreviousPresentFences[0] : mPreviousPresentFences[1]; - return fence != Fence::NO_FENCE && (fence->getStatus() == Fence::Status::Unsignaled); + if (fence == Fence::NO_FENCE) { + return false; + } + + if (graceTimeMs > 0 && fence->getStatus() == Fence::Status::Unsignaled) { + fence->wait(graceTimeMs); + } + + return (fence->getStatus() == Fence::Status::Unsignaled); } void SurfaceFlinger::populateExpectedPresentTime() NO_THREAD_SAFETY_ANALYSIS { @@ -1708,7 +1717,15 @@ void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS { // seeing this same value. populateExpectedPresentTime(); - bool frameMissed = previousFrameMissed(); + // When Backpressure propagation is enabled we want to give a small grace period + // for the present fence to fire instead of just giving up on this frame to handle cases + // where present fence is just about to get signaled. + const int graceTimeForPresentFenceMs = + (mPropagateBackpressure && + (mPropagateBackpressureClientComposition || !mHadClientComposition)) + ? 1 + : 0; + bool frameMissed = previousFrameMissed(graceTimeForPresentFenceMs); bool hwcFrameMissed = mHadDeviceComposition && frameMissed; bool gpuFrameMissed = mHadClientComposition && frameMissed; ATRACE_INT("FrameMissed", static_cast<int>(frameMissed)); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 74882f3909..484b719f22 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -851,7 +851,7 @@ private: return hwcDisplayId ? getHwComposer().toPhysicalDisplayId(*hwcDisplayId) : std::nullopt; } - bool previousFrameMissed(); + bool previousFrameMissed(int graceTimeMs = 0); void setVsyncEnabledInHWC(DisplayId displayId, HWC2::Vsync enabled); /* |