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

Commit 44e895b7 authored by Ram Indani's avatar Ram Indani Committed by Android (Google) Code Review
Browse files

Merge "SF: Avoid adjusting the frame time when last frame is presented early" into main

parents 73469a12 7b32b3a1
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -487,13 +487,13 @@ Duration VSyncPredictor::ensureMinFrameDurationIsKept(TimePoint expectedPresentT
    return 0ns;
}

void VSyncPredictor::onFrameBegin(TimePoint expectedPresentTime,
                                  TimePoint lastConfirmedPresentTime) {
void VSyncPredictor::onFrameBegin(TimePoint expectedPresentTime, FrameTime lastSignaledFrameTime) {
    SFTRACE_NAME("VSyncPredictor::onFrameBegin");
    std::lock_guard lock(mMutex);

    if (!mDisplayModePtr->getVrrConfig()) return;

    const auto [lastConfirmedPresentTime, lastConfirmedExpectedPresentTime] = lastSignaledFrameTime;
    if (CC_UNLIKELY(mTraceOn)) {
        SFTRACE_FORMAT_INSTANT("vsync is %.2f past last signaled fence",
                               static_cast<float>(expectedPresentTime.ns() -
@@ -519,6 +519,11 @@ void VSyncPredictor::onFrameBegin(TimePoint expectedPresentTime,
        }
    }

    if (lastConfirmedExpectedPresentTime.ns() - lastConfirmedPresentTime.ns() > threshold) {
        SFTRACE_FORMAT_INSTANT("lastFramePresentedEarly");
        return;
    }

    const auto phase = ensureMinFrameDurationIsKept(expectedPresentTime, lastConfirmedPresentTime);
    if (phase > 0ns) {
        mMissedVsync = {expectedPresentTime, minFramePeriodLocked()};
+2 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <vector>

#include <android-base/thread_annotations.h>
#include <scheduler/FrameTime.h>
#include <scheduler/TimeKeeper.h>
#include <ui/DisplayId.h>

@@ -77,7 +78,7 @@ public:

    void setRenderRate(Fps, bool applyImmediately) final EXCLUDES(mMutex);

    void onFrameBegin(TimePoint expectedPresentTime, TimePoint lastConfirmedPresentTime) final
    void onFrameBegin(TimePoint expectedPresentTime, FrameTime lastSignaledFrameTime) final
            EXCLUDES(mMutex);
    void onFrameMissed(TimePoint expectedPresentTime) final EXCLUDES(mMutex);

+2 −2
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@

#include <scheduler/Fps.h>
#include <scheduler/FrameRateMode.h>
#include <scheduler/FrameTime.h>

#include "VSyncDispatch.h"

@@ -112,8 +113,7 @@ public:
     */
    virtual void setRenderRate(Fps, bool applyImmediately) = 0;

    virtual void onFrameBegin(TimePoint expectedPresentTime,
                              TimePoint lastConfirmedPresentTime) = 0;
    virtual void onFrameBegin(TimePoint expectedPresentTime, FrameTime lastSignaledFrameTime) = 0;

    virtual void onFrameMissed(TimePoint expectedPresentTime) = 0;

+18 −16
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <ui/FenceTime.h>

#include <scheduler/Features.h>
#include <scheduler/FrameTime.h>
#include <scheduler/Time.h>
#include <scheduler/VsyncId.h>
#include <scheduler/interface/CompositeResult.h>
@@ -57,13 +58,6 @@ public:
    // The time of the VSYNC that preceded this frame. See `presentFenceForPastVsync` for details.
    TimePoint pastVsyncTime(Period minFramePeriod) const;

    // The present fence for the frame that had targeted the most recent VSYNC before this frame.
    // If the target VSYNC for any given frame is more than `vsyncPeriod` in the future, then the
    // VSYNC of at least one previous frame has not yet passed. In other words, this is NOT the
    // `presentFenceForPreviousFrame` if running N VSYNCs ahead, but the one that should have been
    // signaled by now (unless that frame missed).
    FenceTimePtr presentFenceForPastVsync(Period minFramePeriod) const;

    // Equivalent to `presentFenceForPastVsync` unless running N VSYNCs ahead.
    const FenceTimePtr& presentFenceForPreviousFrame() const {
        return mPresentFences.front().fenceTime;
@@ -72,7 +66,7 @@ public:
    bool isFramePending() const { return mFramePending; }
    bool didMissFrame() const { return mFrameMissed; }
    bool didMissHwcFrame() const { return mHwcFrameMissed && !mGpuFrameMissed; }
    TimePoint lastSignaledFrameTime() const { return mLastSignaledFrameTime; };
    FrameTime lastSignaledFrameTime() const { return mLastSignaledFrameTime; }

protected:
    explicit FrameTarget(const std::string& displayLabel);
@@ -106,10 +100,17 @@ protected:
        FenceTimePtr fenceTime = FenceTime::NO_FENCE;
        TimePoint expectedPresentTime = TimePoint();
    };

    // The present fence for the frame that had targeted the most recent VSYNC before this frame.
    // If the target VSYNC for any given frame is more than `vsyncPeriod` in the future, then the
    // VSYNC of at least one previous frame has not yet passed. In other words, this is NOT the
    // `presentFenceForPreviousFrame` if running N VSYNCs ahead, but the one that should have been
    // signaled by now (unless that frame missed).
    FenceWithFenceTime presentFenceForPastVsync(Period minFramePeriod) const;
    std::array<FenceWithFenceTime, 2> mPresentFences;
    utils::RingBuffer<FenceWithFenceTime, 5> mFenceWithFenceTimes;

    TimePoint mLastSignaledFrameTime;
    FrameTime mLastSignaledFrameTime;

private:
    friend class FrameTargeterTestBase;
@@ -120,16 +121,17 @@ private:
        return expectedFrameDuration() > (N - 1) * minFramePeriod;
    }

    const FenceTimePtr pastVsyncTimePtr() const {
        auto pastFenceTimePtr = FenceTime::NO_FENCE;
    FenceWithFenceTime pastVsyncTimePtr() const {
        FenceWithFenceTime pastFenceWithFenceTime;
        for (size_t i = 0; i < mFenceWithFenceTimes.size(); i++) {
            const auto& [_, fenceTimePtr, expectedPresentTime] = mFenceWithFenceTimes[i];
            if (expectedPresentTime > mFrameBeginTime) {
                return pastFenceTimePtr;
            const auto& fenceWithFenceTime = mFenceWithFenceTimes[i];
            // TODO(b/354007767) Fix the below condition to avoid frame drop
            if (fenceWithFenceTime.expectedPresentTime > mFrameBeginTime) {
                return pastFenceWithFenceTime;
            }
            pastFenceTimePtr = fenceTimePtr;
            pastFenceWithFenceTime = fenceWithFenceTime;
        }
        return pastFenceTimePtr;
        return pastFenceWithFenceTime;
    }
};

+26 −0
Original line number Diff line number Diff line
/*
 * Copyright 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <scheduler/Time.h>

namespace android::scheduler {
struct FrameTime {
    TimePoint signalTime;
    TimePoint expectedPresentTime;
};
} // namespace android::scheduler
 No newline at end of file
Loading