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

Commit 2968afc9 authored by Kevin DuBois's avatar Kevin DuBois
Browse files

SF: VSyncReactor: correct distribute timestamp

Timestamp being distributed via the choreographer callback was the
anticipated vsync timestamp. This might make sense in the future, but
the correct legacy behavior was to distribute the event timestamp.

(code with problem was flagged off)

Test: correction of 2 unit tests
Test: boot to home
Test: uibench scroll, jitter not observed.

Fixes: 147487378

Change-Id: I142a6eaf849479dfe5b754db138f55d9e5870afd
parent c095d637
Loading
Loading
Loading
Loading
+10 −2
Original line number Original line Diff line number Diff line
@@ -38,6 +38,14 @@ public:


    virtual ~VSyncDispatch();
    virtual ~VSyncDispatch();


    /*
     * A callback that can be registered to be awoken at a given time relative to a vsync event.
     * \param [in] vsyncTime The timestamp of the vsync the callback is for.
     * \param [in] targetWakeupTime The timestamp of intended wakeup time of the cb.
     *
     */
    using Callback = std::function<void(nsecs_t vsyncTime, nsecs_t targetWakeupTime)>;

    /*
    /*
     * Registers a callback that will be called at designated points on the vsync timeline.
     * Registers a callback that will be called at designated points on the vsync timeline.
     * The callback can be scheduled, rescheduled targeting vsync times, or cancelled.
     * The callback can be scheduled, rescheduled targeting vsync times, or cancelled.
@@ -51,7 +59,7 @@ public:
     *                          invocation of callbackFn.
     *                          invocation of callbackFn.
     *
     *
     */
     */
    virtual CallbackToken registerCallback(std::function<void(nsecs_t)> const& callbackFn,
    virtual CallbackToken registerCallback(Callback const& callbackFn,
                                           std::string callbackName) = 0;
                                           std::string callbackName) = 0;


    /*
    /*
@@ -112,7 +120,7 @@ protected:
 */
 */
class VSyncCallbackRegistration {
class VSyncCallbackRegistration {
public:
public:
    VSyncCallbackRegistration(VSyncDispatch&, std::function<void(nsecs_t)> const& callbackFn,
    VSyncCallbackRegistration(VSyncDispatch&, VSyncDispatch::Callback const& callbackFn,
                              std::string const& callbackName);
                              std::string const& callbackName);
    VSyncCallbackRegistration(VSyncCallbackRegistration&&);
    VSyncCallbackRegistration(VSyncCallbackRegistration&&);
    VSyncCallbackRegistration& operator=(VSyncCallbackRegistration&&);
    VSyncCallbackRegistration& operator=(VSyncCallbackRegistration&&);
+9 −8
Original line number Original line Diff line number Diff line
@@ -29,7 +29,7 @@ VSyncTracker::~VSyncTracker() = default;
TimeKeeper::~TimeKeeper() = default;
TimeKeeper::~TimeKeeper() = default;


VSyncDispatchTimerQueueEntry::VSyncDispatchTimerQueueEntry(std::string const& name,
VSyncDispatchTimerQueueEntry::VSyncDispatchTimerQueueEntry(std::string const& name,
                                                           std::function<void(nsecs_t)> const& cb,
                                                           VSyncDispatch::Callback const& cb,
                                                           nsecs_t minVsyncDistance)
                                                           nsecs_t minVsyncDistance)
      : mName(name),
      : mName(name),
        mCallback(cb),
        mCallback(cb),
@@ -97,13 +97,13 @@ nsecs_t VSyncDispatchTimerQueueEntry::executing() {
    return *mLastDispatchTime;
    return *mLastDispatchTime;
}
}


void VSyncDispatchTimerQueueEntry::callback(nsecs_t t) {
void VSyncDispatchTimerQueueEntry::callback(nsecs_t vsyncTimestamp, nsecs_t wakeupTimestamp) {
    {
    {
        std::lock_guard<std::mutex> lk(mRunningMutex);
        std::lock_guard<std::mutex> lk(mRunningMutex);
        mRunning = true;
        mRunning = true;
    }
    }


    mCallback(t);
    mCallback(vsyncTimestamp, wakeupTimestamp);


    std::lock_guard<std::mutex> lk(mRunningMutex);
    std::lock_guard<std::mutex> lk(mRunningMutex);
    mRunning = false;
    mRunning = false;
@@ -171,7 +171,8 @@ void VSyncDispatchTimerQueue::rearmTimerSkippingUpdateFor(
void VSyncDispatchTimerQueue::timerCallback() {
void VSyncDispatchTimerQueue::timerCallback() {
    struct Invocation {
    struct Invocation {
        std::shared_ptr<VSyncDispatchTimerQueueEntry> callback;
        std::shared_ptr<VSyncDispatchTimerQueueEntry> callback;
        nsecs_t timestamp;
        nsecs_t vsyncTimestamp;
        nsecs_t wakeupTimestamp;
    };
    };
    std::vector<Invocation> invocations;
    std::vector<Invocation> invocations;
    {
    {
@@ -186,7 +187,7 @@ void VSyncDispatchTimerQueue::timerCallback() {
            if (*wakeupTime < mIntendedWakeupTime + mTimerSlack) {
            if (*wakeupTime < mIntendedWakeupTime + mTimerSlack) {
                callback->executing();
                callback->executing();
                invocations.emplace_back(
                invocations.emplace_back(
                        Invocation{callback, *callback->lastExecutedVsyncTarget()});
                        Invocation{callback, *callback->lastExecutedVsyncTarget(), *wakeupTime});
            }
            }
        }
        }


@@ -195,12 +196,12 @@ void VSyncDispatchTimerQueue::timerCallback() {
    }
    }


    for (auto const& invocation : invocations) {
    for (auto const& invocation : invocations) {
        invocation.callback->callback(invocation.timestamp);
        invocation.callback->callback(invocation.vsyncTimestamp, invocation.wakeupTimestamp);
    }
    }
}
}


VSyncDispatchTimerQueue::CallbackToken VSyncDispatchTimerQueue::registerCallback(
VSyncDispatchTimerQueue::CallbackToken VSyncDispatchTimerQueue::registerCallback(
        std::function<void(nsecs_t)> const& callbackFn, std::string callbackName) {
        Callback const& callbackFn, std::string callbackName) {
    std::lock_guard<decltype(mMutex)> lk(mMutex);
    std::lock_guard<decltype(mMutex)> lk(mMutex);
    return CallbackToken{
    return CallbackToken{
            mCallbacks
            mCallbacks
@@ -271,7 +272,7 @@ CancelResult VSyncDispatchTimerQueue::cancel(CallbackToken token) {
}
}


VSyncCallbackRegistration::VSyncCallbackRegistration(VSyncDispatch& dispatch,
VSyncCallbackRegistration::VSyncCallbackRegistration(VSyncDispatch& dispatch,
                                                     std::function<void(nsecs_t)> const& callbackFn,
                                                     VSyncDispatch::Callback const& callbackFn,
                                                     std::string const& callbackName)
                                                     std::string const& callbackName)
      : mDispatch(dispatch),
      : mDispatch(dispatch),
        mToken(dispatch.registerCallback(callbackFn, callbackName)),
        mToken(dispatch.registerCallback(callbackFn, callbackName)),
+5 −6
Original line number Original line Diff line number Diff line
@@ -36,7 +36,7 @@ public:
    // Valid transition: disarmed -> armed ( when scheduled )
    // Valid transition: disarmed -> armed ( when scheduled )
    // Valid transition: armed -> running -> disarmed ( when timer is called)
    // Valid transition: armed -> running -> disarmed ( when timer is called)
    // Valid transition: armed -> disarmed ( when cancelled )
    // Valid transition: armed -> disarmed ( when cancelled )
    VSyncDispatchTimerQueueEntry(std::string const& name, std::function<void(nsecs_t)> const& fn,
    VSyncDispatchTimerQueueEntry(std::string const& name, VSyncDispatch::Callback const& fn,
                                 nsecs_t minVsyncDistance);
                                 nsecs_t minVsyncDistance);
    std::string_view name() const;
    std::string_view name() const;


@@ -62,14 +62,14 @@ public:
    nsecs_t executing();
    nsecs_t executing();
    // End: functions that are not threadsafe.
    // End: functions that are not threadsafe.


    // Invoke the callback with the timestamp, moving the state from running->disarmed.
    // Invoke the callback with the two given timestamps, moving the state from running->disarmed.
    void callback(nsecs_t timestamp);
    void callback(nsecs_t vsyncTimestamp, nsecs_t wakeupTimestamp);
    // Block calling thread while the callback is executing.
    // Block calling thread while the callback is executing.
    void ensureNotRunning();
    void ensureNotRunning();


private:
private:
    std::string const mName;
    std::string const mName;
    std::function<void(nsecs_t)> const mCallback;
    VSyncDispatch::Callback const mCallback;


    nsecs_t mWorkDuration;
    nsecs_t mWorkDuration;
    nsecs_t mEarliestVsync;
    nsecs_t mEarliestVsync;
@@ -104,8 +104,7 @@ public:
                                     nsecs_t timerSlack, nsecs_t minVsyncDistance);
                                     nsecs_t timerSlack, nsecs_t minVsyncDistance);
    ~VSyncDispatchTimerQueue();
    ~VSyncDispatchTimerQueue();


    CallbackToken registerCallback(std::function<void(nsecs_t)> const& callbackFn,
    CallbackToken registerCallback(Callback const& callbackFn, std::string callbackName) final;
                                   std::string callbackName) final;
    void unregisterCallback(CallbackToken token) final;
    void unregisterCallback(CallbackToken token) final;
    ScheduleResult schedule(CallbackToken token, nsecs_t workDuration, nsecs_t earliestVsync) final;
    ScheduleResult schedule(CallbackToken token, nsecs_t workDuration, nsecs_t earliestVsync) final;
    CancelResult cancel(CallbackToken token) final;
    CancelResult cancel(CallbackToken token) final;
+4 −5
Original line number Original line Diff line number Diff line
@@ -48,7 +48,8 @@ public:
                     nsecs_t period, nsecs_t offset, nsecs_t notBefore)
                     nsecs_t period, nsecs_t offset, nsecs_t notBefore)
          : mCallback(cb),
          : mCallback(cb),
            mRegistration(dispatch,
            mRegistration(dispatch,
                          std::bind(&CallbackRepeater::callback, this, std::placeholders::_1),
                          std::bind(&CallbackRepeater::callback, this, std::placeholders::_1,
                                    std::placeholders::_2),
                          std::string(name)),
                          std::string(name)),
            mPeriod(period),
            mPeriod(period),
            mOffset(offset),
            mOffset(offset),
@@ -85,15 +86,13 @@ public:
    }
    }


private:
private:
    void callback(nsecs_t vsynctime) {
    void callback(nsecs_t vsynctime, nsecs_t wakeupTime) {
        nsecs_t period = 0;
        {
        {
            std::lock_guard<std::mutex> lk(mMutex);
            std::lock_guard<std::mutex> lk(mMutex);
            period = mPeriod;
            mLastCallTime = vsynctime;
            mLastCallTime = vsynctime;
        }
        }


        mCallback->onDispSyncEvent(vsynctime - period);
        mCallback->onDispSyncEvent(wakeupTime);


        {
        {
            std::lock_guard<std::mutex> lk(mMutex);
            std::lock_guard<std::mutex> lk(mMutex);
+1 −1
Original line number Original line Diff line number Diff line
@@ -101,7 +101,7 @@ public:
    RepeatingCallbackReceiver(VSyncDispatch& dispatch, nsecs_t wl)
    RepeatingCallbackReceiver(VSyncDispatch& dispatch, nsecs_t wl)
          : mWorkload(wl),
          : mWorkload(wl),
            mCallback(
            mCallback(
                    dispatch, [&](auto time) { callback_called(time); }, "repeat0") {}
                    dispatch, [&](auto time, auto) { callback_called(time); }, "repeat0") {}


    void repeatedly_schedule(size_t iterations, std::function<void(nsecs_t)> const& onEachFrame) {
    void repeatedly_schedule(size_t iterations, std::function<void(nsecs_t)> const& onEachFrame) {
        mCallbackTimes.reserve(iterations);
        mCallbackTimes.reserve(iterations);
Loading