summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdy Abraham <adyabr@google.com>2019-09-19 11:32:43 -0700
committerAdy Abraham <adyabr@google.com>2019-09-19 19:47:07 +0000
commitb40b0269dfbd4a259bc604e84392c3984c300932 (patch)
tree974492d524b9d0463ef5e92e2981806a1b268eaa
parent5726d926a9eb0ccbe00236ff9e1303f4ea542396 (diff)
downloadnative-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.cpp23
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h2
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);
/*