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

Commit 32a88b18 authored by ramindani's avatar ramindani
Browse files

[SF] Send NotifyExpectedPresentHint at the transaction time

BUG: 314199179
BUG: 315989692
BUG: 284845445

Test: atest NotifyExpectedPresentTest
Change-Id: Ief7fff69e8b92f0affd228b2bdcdc5009806f905
parent 87173832
Loading
Loading
Loading
Loading
+8 −11
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS

#include <binder/IPCThreadState.h>
#include <gui/DisplayEventReceiver.h>
#include <utils/Log.h>
#include <utils/Timers.h>
#include <utils/threads.h>
@@ -66,7 +65,7 @@ void MessageQueue::vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, ns
    {
        std::lock_guard lock(mVsync.mutex);
        mVsync.lastCallbackTime = expectedVsyncTime;
        mVsync.scheduledFrameTime.reset();
        mVsync.scheduledFrameTimeOpt.reset();
    }

    const auto vsyncId = VsyncId{mVsync.tokenManager->generateTokenForPredictions(
@@ -122,7 +121,7 @@ std::unique_ptr<scheduler::VSyncCallbackRegistration> MessageQueue::onNewVsyncSc
                                                            std::placeholders::_3),
                                                  "sf");
    if (reschedule) {
        mVsync.scheduledFrameTime =
        mVsync.scheduledFrameTimeOpt =
                mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(),
                                               .readyDuration = 0,
                                               .lastVsync = mVsync.lastCallbackTime.ns()});
@@ -140,7 +139,7 @@ void MessageQueue::setDuration(std::chrono::nanoseconds workDuration) {
    ATRACE_CALL();
    std::lock_guard lock(mVsync.mutex);
    mVsync.workDuration = workDuration;
    mVsync.scheduledFrameTime =
    mVsync.scheduledFrameTimeOpt =
            mVsync.registration->update({.workDuration = mVsync.workDuration.get().count(),
                                         .readyDuration = 0,
                                         .lastVsync = mVsync.lastCallbackTime.ns()});
@@ -193,22 +192,20 @@ void MessageQueue::scheduleFrame() {
    ATRACE_CALL();

    std::lock_guard lock(mVsync.mutex);
    mVsync.scheduledFrameTime =
    mVsync.scheduledFrameTimeOpt =
            mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(),
                                           .readyDuration = 0,
                                           .lastVsync = mVsync.lastCallbackTime.ns()});
}

auto MessageQueue::getScheduledFrameTime() const -> std::optional<Clock::time_point> {
std::optional<scheduler::ScheduleResult> MessageQueue::getScheduledFrameResult() const {
    if (mHandler->isFramePending()) {
        return Clock::now();
        return scheduler::ScheduleResult{TimePoint::now(), mHandler->getExpectedVsyncTime()};
    }

    std::lock_guard lock(mVsync.mutex);
    if (const auto time = mVsync.scheduledFrameTime) {
        return Clock::time_point(std::chrono::nanoseconds(*time));
    if (const auto scheduledFrameTimeline = mVsync.scheduledFrameTimeOpt) {
        return scheduledFrameTimeline;
    }

    return std::nullopt;
}

+6 −5
Original line number Diff line number Diff line
@@ -76,8 +76,7 @@ public:
    virtual void scheduleConfigure() = 0;
    virtual void scheduleFrame() = 0;

    using Clock = std::chrono::steady_clock;
    virtual std::optional<Clock::time_point> getScheduledFrameTime() const = 0;
    virtual std::optional<scheduler::ScheduleResult> getScheduledFrameResult() const = 0;
};

namespace impl {
@@ -95,7 +94,9 @@ protected:
        explicit Handler(MessageQueue& queue) : mQueue(queue) {}
        void handleMessage(const Message& message) override;

        bool isFramePending() const;
        virtual TimePoint getExpectedVsyncTime() const { return mExpectedVsyncTime.load(); }

        virtual bool isFramePending() const;

        virtual void dispatchFrame(VsyncId, TimePoint expectedVsyncTime);
    };
@@ -124,7 +125,7 @@ private:
        TracedOrdinal<std::chrono::nanoseconds> workDuration
                GUARDED_BY(mutex) = {"VsyncWorkDuration-sf", std::chrono::nanoseconds(0)};
        TimePoint lastCallbackTime GUARDED_BY(mutex);
        std::optional<nsecs_t> scheduledFrameTime GUARDED_BY(mutex);
        std::optional<scheduler::ScheduleResult> scheduledFrameTimeOpt GUARDED_BY(mutex);
        TracedOrdinal<int> value = {"VSYNC-sf", 0};
    };

@@ -150,7 +151,7 @@ public:
    void scheduleConfigure() override;
    void scheduleFrame() override;

    std::optional<Clock::time_point> getScheduledFrameTime() const override;
    std::optional<scheduler::ScheduleResult> getScheduledFrameResult() const override;
};

} // namespace impl
+1 −1
Original line number Diff line number Diff line
@@ -133,9 +133,9 @@ public:

    void initVsync(frametimeline::TokenManager&, std::chrono::nanoseconds workDuration);

    using Impl::getScheduledFrameTime;
    using Impl::setDuration;

    using Impl::getScheduledFrameResult;
    using Impl::scheduleConfigure;
    using Impl::scheduleFrame;

+15 −7
Original line number Diff line number Diff line
@@ -21,11 +21,15 @@
#include <string>

#include <ftl/mixins.h>
#include <scheduler/Time.h>
#include <utils/Timers.h>

namespace android::scheduler {

using ScheduleResult = std::optional<nsecs_t>;
struct ScheduleResult {
    TimePoint callbackTime;
    TimePoint vsyncTime;
};

enum class CancelResult { Cancelled, TooLate, Error };

@@ -124,10 +128,12 @@ public:
     *
     * \param [in] token           The callback to schedule.
     * \param [in] scheduleTiming  The timing information for this schedule call
     * \return                     The expected callback time if a callback was scheduled.
     * \return                     The expected callback time if a callback was scheduled,
     *                             along with VSYNC time for the callback scheduled.
     *                             std::nullopt if the callback is not registered.
     */
    virtual ScheduleResult schedule(CallbackToken token, ScheduleTiming scheduleTiming) = 0;
    virtual std::optional<ScheduleResult> schedule(CallbackToken token,
                                                   ScheduleTiming scheduleTiming) = 0;

    /*
     * Update the timing information for a scheduled callback.
@@ -135,10 +141,12 @@ public:
     *
     * \param [in] token           The callback to schedule.
     * \param [in] scheduleTiming  The timing information for this schedule call
     * \return                     The expected callback time if a callback was scheduled.
     * \return                     The expected callback time if a callback was scheduled,
     *                             along with VSYNC time for the callback scheduled.
     *                             std::nullopt if the callback is not registered.
     */
    virtual ScheduleResult update(CallbackToken token, ScheduleTiming scheduleTiming) = 0;
    virtual std::optional<ScheduleResult> update(CallbackToken token,
                                                 ScheduleTiming scheduleTiming) = 0;

    /* Cancels a scheduled callback, if possible.
     *
@@ -168,10 +176,10 @@ public:
    VSyncCallbackRegistration& operator=(VSyncCallbackRegistration&&);

    // See documentation for VSyncDispatch::schedule.
    ScheduleResult schedule(VSyncDispatch::ScheduleTiming scheduleTiming);
    std::optional<ScheduleResult> schedule(VSyncDispatch::ScheduleTiming scheduleTiming);

    // See documentation for VSyncDispatch::update.
    ScheduleResult update(VSyncDispatch::ScheduleTiming scheduleTiming);
    std::optional<ScheduleResult> update(VSyncDispatch::ScheduleTiming scheduleTiming);

    // See documentation for VSyncDispatch::cancel.
    CancelResult cancel();
+24 −19
Original line number Diff line number Diff line
@@ -38,9 +38,10 @@ using base::StringAppendF;

namespace {

nsecs_t getExpectedCallbackTime(nsecs_t nextVsyncTime,
ScheduleResult getExpectedCallbackTime(nsecs_t nextVsyncTime,
                                       const VSyncDispatch::ScheduleTiming& timing) {
    return nextVsyncTime - timing.readyDuration - timing.workDuration;
    return {TimePoint::fromNs(nextVsyncTime - timing.readyDuration - timing.workDuration),
            TimePoint::fromNs(nextVsyncTime)};
}

} // namespace
@@ -84,8 +85,8 @@ std::optional<nsecs_t> VSyncDispatchTimerQueueEntry::targetVsync() const {
    return {mArmedInfo->mActualVsyncTime};
}

ScheduleResult VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTiming timing,
                                                      VSyncTracker& tracker, nsecs_t now) {
std::optional<ScheduleResult> VSyncDispatchTimerQueueEntry::schedule(
        VSyncDispatch::ScheduleTiming timing, VSyncTracker& tracker, nsecs_t now) {
    auto nextVsyncTime =
            tracker.nextAnticipatedVSyncTimeFrom(std::max(timing.lastVsync,
                                                          now + timing.workDuration +
@@ -115,14 +116,15 @@ ScheduleResult VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTim
    auto const nextReadyTime = nextVsyncTime - timing.readyDuration;
    mScheduleTiming = timing;
    mArmedInfo = {nextWakeupTime, nextVsyncTime, nextReadyTime};
    return nextWakeupTime;
    return ScheduleResult{TimePoint::fromNs(nextWakeupTime), TimePoint::fromNs(nextVsyncTime)};
}

nsecs_t VSyncDispatchTimerQueueEntry::addPendingWorkloadUpdate(
ScheduleResult VSyncDispatchTimerQueueEntry::addPendingWorkloadUpdate(
        VSyncTracker& tracker, nsecs_t now, VSyncDispatch::ScheduleTiming timing) {
    mWorkloadUpdateInfo = timing;
    const auto armedInfo = update(tracker, now, timing, mArmedInfo);
    return armedInfo.mActualWakeupTime;
    return {TimePoint::fromNs(armedInfo.mActualWakeupTime),
            TimePoint::fromNs(armedInfo.mActualVsyncTime)};
}

bool VSyncDispatchTimerQueueEntry::hasPendingWorkloadUpdate() const {
@@ -383,14 +385,14 @@ void VSyncDispatchTimerQueue::unregisterCallback(CallbackToken token) {
    }
}

ScheduleResult VSyncDispatchTimerQueue::schedule(CallbackToken token,
std::optional<ScheduleResult> VSyncDispatchTimerQueue::schedule(CallbackToken token,
                                                                ScheduleTiming scheduleTiming) {
    std::lock_guard lock(mMutex);
    return scheduleLocked(token, scheduleTiming);
}

ScheduleResult VSyncDispatchTimerQueue::scheduleLocked(CallbackToken token,
                                                       ScheduleTiming scheduleTiming) {
std::optional<ScheduleResult> VSyncDispatchTimerQueue::scheduleLocked(
        CallbackToken token, ScheduleTiming scheduleTiming) {
    auto it = mCallbacks.find(token);
    if (it == mCallbacks.end()) {
        return {};
@@ -405,19 +407,20 @@ ScheduleResult VSyncDispatchTimerQueue::scheduleLocked(CallbackToken token,
        return callback->addPendingWorkloadUpdate(*mTracker, now, scheduleTiming);
    }

    const ScheduleResult result = callback->schedule(scheduleTiming, *mTracker, now);
    if (!result.has_value()) {
    const auto resultOpt = callback->schedule(scheduleTiming, *mTracker, now);

    if (!resultOpt) {
        return {};
    }

    if (callback->wakeupTime() < mIntendedWakeupTime - mTimerSlack) {
        rearmTimerSkippingUpdateFor(now, it);
    }

    return result;
    return resultOpt;
}

ScheduleResult VSyncDispatchTimerQueue::update(CallbackToken token, ScheduleTiming scheduleTiming) {
std::optional<ScheduleResult> VSyncDispatchTimerQueue::update(CallbackToken token,
                                                              ScheduleTiming scheduleTiming) {
    std::lock_guard lock(mMutex);
    const auto it = mCallbacks.find(token);
    if (it == mCallbacks.end()) {
@@ -494,14 +497,16 @@ VSyncCallbackRegistration::~VSyncCallbackRegistration() {
    if (mToken) mDispatch->unregisterCallback(*mToken);
}

ScheduleResult VSyncCallbackRegistration::schedule(VSyncDispatch::ScheduleTiming scheduleTiming) {
std::optional<ScheduleResult> VSyncCallbackRegistration::schedule(
        VSyncDispatch::ScheduleTiming scheduleTiming) {
    if (!mToken) {
        return std::nullopt;
    }
    return mDispatch->schedule(*mToken, scheduleTiming);
}

ScheduleResult VSyncCallbackRegistration::update(VSyncDispatch::ScheduleTiming scheduleTiming) {
std::optional<ScheduleResult> VSyncCallbackRegistration::update(
        VSyncDispatch::ScheduleTiming scheduleTiming) {
    if (!mToken) {
        return std::nullopt;
    }
Loading