SF: Use last call time to rate limit resyncs
SurfaceFlinger has a method which tells it to resync to hardware vsync
as long as it hasn't resynced too recently. This is used when we
receive a request for a Choreographer wakeup since if it has been a
while since we animated, we have likely drifted.
To determine whether we should actually resync or whether we should
instead rate-limit the call, we compare the current time to the last
time we drew, but this is problematic. When we first start animating
after a period of inactivity, this triggers a resync every time the
method is called until we receive the first frame and draw it, even if
we are already mid-resync, which delays the time until we can lock onto
the hardware vsync phase and has the side-effect of causing weird wakeup
times in both Choreographer and SurfaceFlinger.
This change instead keeps a local timestamp which is updated every time
the method is called and therefore effectively rate limits even before
the first frame is received.
Bug: 38117777
Test: ApiDemos/ListView + manual inspection of systraces
Change-Id: I7210594f9ed6ed5397bb0f3f14a8966503454643
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 45cac6f..2237ee1 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1116,9 +1116,14 @@
void SurfaceFlinger::resyncWithRateLimit() {
static constexpr nsecs_t kIgnoreDelay = ms2ns(500);
- if (systemTime() - mLastSwapTime > kIgnoreDelay) {
+
+ // No explicit locking is needed here since EventThread holds a lock while calling this method
+ static nsecs_t sLastResyncAttempted = 0;
+ const nsecs_t now = systemTime();
+ if (now - sLastResyncAttempted > kIgnoreDelay) {
resyncToHardwareVsync(false);
}
+ sLastResyncAttempted = now;
}
void SurfaceFlinger::onVSyncReceived(HWComposer* composer, int32_t type,