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

Commit 9953e060 authored by Ady Abraham's avatar Ady Abraham
Browse files

SF: add a work duration slack when missing a frame

When missing a frame, SF usually ends up waiting 1ms for the
previous fence to fire. This causes sometimes skipping the next frame
as the work duration with the 1ms pushes the vsync one more frame.

Bug: 354007767
Flag: com.android.graphics.surfaceflinger.flags.allow_n_vsyncs_in_targeter
Test: SF unit tests

Change-Id: Ia4e2791c420c17bcbe123bd61cc569695702a40c
parent ed1283a5
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -188,12 +188,13 @@ void MessageQueue::scheduleConfigure() {
    postMessage(sp<ConfigureHandler>::make(mCompositor));
}

void MessageQueue::scheduleFrame() {
void MessageQueue::scheduleFrame(Duration workDurationSlack) {
    SFTRACE_CALL();

    std::lock_guard lock(mVsync.mutex);
    const auto workDuration = Duration(mVsync.workDuration.get() - workDurationSlack);
    mVsync.scheduledFrameTimeOpt =
            mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(),
            mVsync.registration->schedule({.workDuration = workDuration.ns(),
                                           .readyDuration = 0,
                                           .lastVsync = mVsync.lastCallbackTime.ns()});
}
+2 −2
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ public:
    virtual void postMessage(sp<MessageHandler>&&) = 0;
    virtual void postMessageDelayed(sp<MessageHandler>&&, nsecs_t uptimeDelay) = 0;
    virtual void scheduleConfigure() = 0;
    virtual void scheduleFrame() = 0;
    virtual void scheduleFrame(Duration workDurationSlack = Duration::fromNs(0)) = 0;

    virtual std::optional<scheduler::ScheduleResult> getScheduledFrameResult() const = 0;
};
@@ -149,7 +149,7 @@ public:
    void postMessageDelayed(sp<MessageHandler>&&, nsecs_t uptimeDelay) override;

    void scheduleConfigure() override;
    void scheduleFrame() override;
    void scheduleFrame(Duration workDurationSlack = Duration::fromNs(0)) override;

    std::optional<scheduler::ScheduleResult> getScheduledFrameResult() const override;
};
+6 −3
Original line number Diff line number Diff line
@@ -2164,12 +2164,12 @@ sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
    return mScheduler->createDisplayEventConnection(cycle, eventRegistration, layerHandle);
}

void SurfaceFlinger::scheduleCommit(FrameHint hint) {
void SurfaceFlinger::scheduleCommit(FrameHint hint, Duration workDurationSlack) {
    if (hint == FrameHint::kActive) {
        mScheduler->resetIdleTimer();
    }
    mPowerAdvisor->notifyDisplayUpdateImminentAndCpuReset();
    mScheduler->scheduleFrame();
    mScheduler->scheduleFrame(workDurationSlack);
}

void SurfaceFlinger::scheduleComposite(FrameHint hint) {
@@ -2629,7 +2629,10 @@ bool SurfaceFlinger::commit(PhysicalDisplayId pacesetterId,
                mScheduler->getVsyncSchedule()->getTracker().onFrameMissed(
                        pacesetterFrameTarget.expectedPresentTime());
            }
            scheduleCommit(FrameHint::kNone);
            const Duration slack = FlagManager::getInstance().allow_n_vsyncs_in_targeter()
                    ? TimePoint::now() - pacesetterFrameTarget.frameBeginTime()
                    : Duration::fromNs(0);
            scheduleCommit(FrameHint::kNone, slack);
            return false;
        }
    }
+1 −1
Original line number Diff line number Diff line
@@ -273,7 +273,7 @@ public:
    enum class FrameHint { kNone, kActive };

    // Schedule commit of transactions on the main thread ahead of the next VSYNC.
    void scheduleCommit(FrameHint);
    void scheduleCommit(FrameHint, Duration workDurationSlack = Duration::fromNs(0));
    // As above, but also force composite regardless if transactions were committed.
    void scheduleComposite(FrameHint);
    // As above, but also force dirty geometry to repaint.
+5 −4
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@

namespace android {

using testing::_;
using testing::DoAll;
using testing::Mock;
using testing::SetArgPointee;
@@ -91,7 +92,7 @@ INSTANTIATE_TEST_SUITE_P(PerLayerType, FrameRateSelectionStrategyTest,
                         PrintToStringParamName);

TEST_P(FrameRateSelectionStrategyTest, SetAndGet) {
    EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
    EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);

    const auto& layerFactory = GetParam();
    auto layer = mLayers.emplace_back(layerFactory->createLayer(mFlinger));
@@ -104,7 +105,7 @@ TEST_P(FrameRateSelectionStrategyTest, SetAndGet) {
}

TEST_P(FrameRateSelectionStrategyTest, SetChildOverrideChildren) {
    EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
    EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);

    const auto& layerFactory = GetParam();
    auto parent = mLayers.emplace_back(layerFactory->createLayer(mFlinger));
@@ -128,7 +129,7 @@ TEST_P(FrameRateSelectionStrategyTest, SetChildOverrideChildren) {
}

TEST_P(FrameRateSelectionStrategyTest, SetParentOverrideChildren) {
    EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
    EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);

    const auto& layerFactory = GetParam();
    auto layer1 = mLayers.emplace_back(layerFactory->createLayer(mFlinger));
@@ -169,7 +170,7 @@ TEST_P(FrameRateSelectionStrategyTest, SetParentOverrideChildren) {
}

TEST_P(FrameRateSelectionStrategyTest, OverrideChildrenAndSelf) {
    EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
    EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);

    const auto& layerFactory = GetParam();
    auto layer1 = mLayers.emplace_back(layerFactory->createLayer(mFlinger));
Loading