Loading services/surfaceflinger/Scheduler/VSyncPredictor.cpp +7 −2 Original line number Diff line number Diff line Loading @@ -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() - Loading @@ -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()}; Loading services/surfaceflinger/Scheduler/VSyncPredictor.h +2 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <vector> #include <android-base/thread_annotations.h> #include <scheduler/FrameTime.h> #include <scheduler/TimeKeeper.h> #include <ui/DisplayId.h> Loading Loading @@ -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); Loading services/surfaceflinger/Scheduler/VSyncTracker.h +2 −2 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <scheduler/Fps.h> #include <scheduler/FrameRateMode.h> #include <scheduler/FrameTime.h> #include "VSyncDispatch.h" Loading Loading @@ -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; Loading services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h +18 −16 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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; Loading @@ -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); Loading Loading @@ -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; Loading @@ -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; } }; Loading services/surfaceflinger/Scheduler/include/scheduler/FrameTime.h 0 → 100644 +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
services/surfaceflinger/Scheduler/VSyncPredictor.cpp +7 −2 Original line number Diff line number Diff line Loading @@ -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() - Loading @@ -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()}; Loading
services/surfaceflinger/Scheduler/VSyncPredictor.h +2 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <vector> #include <android-base/thread_annotations.h> #include <scheduler/FrameTime.h> #include <scheduler/TimeKeeper.h> #include <ui/DisplayId.h> Loading Loading @@ -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); Loading
services/surfaceflinger/Scheduler/VSyncTracker.h +2 −2 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <scheduler/Fps.h> #include <scheduler/FrameRateMode.h> #include <scheduler/FrameTime.h> #include "VSyncDispatch.h" Loading Loading @@ -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; Loading
services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h +18 −16 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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; Loading @@ -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); Loading Loading @@ -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; Loading @@ -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; } }; Loading
services/surfaceflinger/Scheduler/include/scheduler/FrameTime.h 0 → 100644 +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