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

Commit fc690e2a authored by Cheng Shi's avatar Cheng Shi
Browse files

Dispatch vsync when receiving vsync timeout to handle vsync loss.



Currently we do not have a mechanism to guarantee the arrival of the vsync signal. The vsync signal loss may occur when the renderNodeAnimator is running. The render thread took a long time to perform drawing without time to read the pipe, and the pipe was filled with other signals like configChanged, causing surfaceflinger to miss a vsync signal.
If a vsync lost, causing DisplayEventDispatcher::mWaitingForVsync to be true, resulting in DisplayEventDispatcher::scheduleVsync can no longer schedule another vsync. So we need to dispatch vsync when receiving vsync timeout.

Bug: 204097701
Test: Manual
Change-Id: Ibfa7a301ea17ebd58cae6b790a61d66c3d2e43fd
Signed-off-by: default avatarshicheng <shicheng@xiaomi.com>
parent 5f852b9c
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -33,10 +33,13 @@ namespace android {
// using just a few large reads.
static const size_t EVENT_BUFFER_SIZE = 100;

static constexpr nsecs_t WAITING_FOR_VSYNC_TIMEOUT = ms2ns(300);

DisplayEventDispatcher::DisplayEventDispatcher(
        const sp<Looper>& looper, ISurfaceComposer::VsyncSource vsyncSource,
        ISurfaceComposer::EventRegistrationFlags eventRegistration)
      : mLooper(looper), mReceiver(vsyncSource, eventRegistration), mWaitingForVsync(false) {
      : mLooper(looper), mReceiver(vsyncSource, eventRegistration), mWaitingForVsync(false),
        mLastVsyncCount(0), mLastScheduleVsyncTime(0) {
    ALOGV("dispatcher %p ~ Initializing display event dispatcher.", this);
}

@@ -86,6 +89,7 @@ status_t DisplayEventDispatcher::scheduleVsync() {
        }

        mWaitingForVsync = true;
        mLastScheduleVsyncTime = systemTime(SYSTEM_TIME_MONOTONIC);
    }
    return OK;
}
@@ -124,9 +128,21 @@ int DisplayEventDispatcher::handleEvent(int, int events, void*) {
              this, ns2ms(vsyncTimestamp), to_string(vsyncDisplayId).c_str(), vsyncCount,
              vsyncEventData.id);
        mWaitingForVsync = false;
        mLastVsyncCount = vsyncCount;
        dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount, vsyncEventData);
    }

    if (mWaitingForVsync) {
        const nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
        const nsecs_t vsyncScheduleDelay = currentTime - mLastScheduleVsyncTime;
        if (vsyncScheduleDelay > WAITING_FOR_VSYNC_TIMEOUT) {
            ALOGW("Vsync time out! vsyncScheduleDelay=%" PRId64 "ms", ns2ms(vsyncScheduleDelay));
            mWaitingForVsync = false;
            dispatchVsync(currentTime, vsyncDisplayId /* displayId is not used */,
                          ++mLastVsyncCount, vsyncEventData /* empty data */);
        }
    }

    return 1; // keep the callback
}

+2 −0
Original line number Diff line number Diff line
@@ -56,6 +56,8 @@ private:
    sp<Looper> mLooper;
    DisplayEventReceiver mReceiver;
    bool mWaitingForVsync;
    uint32_t mLastVsyncCount;
    nsecs_t mLastScheduleVsyncTime;

    std::vector<FrameRateOverride> mFrameRateOverrides;