Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 57164302 authored by Dan Stoza's avatar Dan Stoza
Browse files

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
parent 584bc3ce
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -1116,9 +1116,14 @@ void SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {

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,