Loading services/surfaceflinger/Scheduler/Scheduler.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -192,7 +192,8 @@ void Scheduler::onFrameSignal(ICompositor& compositor, VsyncId vsyncId, .vsyncId = vsyncId, // TODO(b/255601557): Calculate per display. .expectedVsyncTime = expectedVsyncTime, .sfWorkDuration = mVsyncModulator->getVsyncConfig().sfWorkDuration}; .sfWorkDuration = mVsyncModulator->getVsyncConfig().sfWorkDuration, .hwcMinWorkDuration = mVsyncConfiguration->getCurrentConfigs().hwcMinWorkDuration}; ftl::NonNull<const Display*> pacesetterPtr = pacesetterPtrLocked(); pacesetterPtr->targeterPtr->beginFrame(beginFrameArgs, *pacesetterPtr->schedulePtr); Loading services/surfaceflinger/Scheduler/Scheduler.h +1 −3 Original line number Diff line number Diff line Loading @@ -514,9 +514,7 @@ private: : displayId(displayId), selectorPtr(std::move(selectorPtr)), schedulePtr(std::move(schedulePtr)), targeterPtr(std::make_unique< FrameTargeter>(displayId, features.test(Feature::kBackpressureGpuComposition))) {} targeterPtr(std::make_unique<FrameTargeter>(displayId, features)) {} const PhysicalDisplayId displayId; Loading services/surfaceflinger/Scheduler/include/scheduler/Features.h +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ enum class Feature : std::uint8_t { kTracePredictedVsync = 1 << 3, kBackpressureGpuComposition = 1 << 4, kSmallDirtyContentDetection = 1 << 5, kExpectedPresentTime = 1 << 6, }; using FeatureFlags = ftl::Flags<Feature>; Loading services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h +23 −10 Original line number Diff line number Diff line Loading @@ -19,11 +19,13 @@ #include <array> #include <atomic> #include <memory> #include <optional> #include <ui/DisplayId.h> #include <ui/Fence.h> #include <ui/FenceTime.h> #include <scheduler/Features.h> #include <scheduler/Time.h> #include <scheduler/VsyncId.h> #include <scheduler/interface/CompositeResult.h> Loading @@ -49,14 +51,11 @@ public: TimePoint expectedPresentTime() const { return mExpectedPresentTime; } std::optional<TimePoint> earliestPresentTime() const { return mEarliestPresentTime; } // The time of the VSYNC that preceded this frame. See `presentFenceForPastVsync` for details. TimePoint pastVsyncTime(Period minFramePeriod) const; // Equivalent to `pastVsyncTime` unless running N VSYNCs ahead. TimePoint previousFrameVsyncTime(Period minFramePeriod) const { return mExpectedPresentTime - minFramePeriod; } // 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 Loading @@ -69,8 +68,6 @@ public: return mPresentFences.front().fenceTime; } bool wouldPresentEarly(Period minFramePeriod) const; bool isFramePending() const { return mFramePending; } bool didMissFrame() const { return mFrameMissed; } bool didMissHwcFrame() const { return mHwcFrameMissed && !mGpuFrameMissed; } Loading @@ -79,9 +76,17 @@ protected: explicit FrameTarget(const std::string& displayLabel); ~FrameTarget() = default; bool wouldPresentEarly(Period minFramePeriod) const; // Equivalent to `pastVsyncTime` unless running N VSYNCs ahead. TimePoint previousFrameVsyncTime(Period minFramePeriod) const { return mExpectedPresentTime - minFramePeriod; } VsyncId mVsyncId; TimePoint mFrameBeginTime; TimePoint mExpectedPresentTime; std::optional<TimePoint> mEarliestPresentTime; TracedOrdinal<bool> mFramePending; TracedOrdinal<bool> mFrameMissed; Loading @@ -95,6 +100,8 @@ protected: std::array<FenceWithFenceTime, 2> mPresentFences; private: friend class FrameTargeterTestBase; template <int N> inline bool targetsVsyncsAhead(Period minFramePeriod) const { static_assert(N > 1); Loading @@ -105,9 +112,10 @@ private: // Computes a display's per-frame metrics about past/upcoming targeting of present deadlines. class FrameTargeter final : private FrameTarget { public: FrameTargeter(PhysicalDisplayId displayId, bool backpressureGpuComposition) FrameTargeter(PhysicalDisplayId displayId, FeatureFlags flags) : FrameTarget(to_string(displayId)), mBackpressureGpuComposition(backpressureGpuComposition) {} mBackpressureGpuComposition(flags.test(Feature::kBackpressureGpuComposition)), mSupportsExpectedPresentTime(flags.test(Feature::kExpectedPresentTime)) {} const FrameTarget& target() const { return *this; } Loading @@ -116,10 +124,14 @@ public: VsyncId vsyncId; TimePoint expectedVsyncTime; Duration sfWorkDuration; Duration hwcMinWorkDuration; }; void beginFrame(const BeginFrameArgs&, const IVsyncSource&); std::optional<TimePoint> computeEarliestPresentTime(Period minFramePeriod, Duration hwcMinWorkDuration); // TODO(b/241285191): Merge with FrameTargeter::endFrame. FenceTimePtr setPresentFence(sp<Fence>); Loading @@ -128,7 +140,7 @@ public: void dump(utils::Dumper&) const; private: friend class FrameTargeterTest; friend class FrameTargeterTestBase; // For tests. using IsFencePendingFuncPtr = bool (*)(const FenceTimePtr&, int graceTimeMs); Loading @@ -138,6 +150,7 @@ private: static bool isFencePending(const FenceTimePtr&, int graceTimeMs); const bool mBackpressureGpuComposition; const bool mSupportsExpectedPresentTime; TimePoint mScheduledPresentTime; CompositionCoverageFlags mCompositionCoverage; Loading services/surfaceflinger/Scheduler/src/FrameTargeter.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,10 @@ void FrameTargeter::beginFrame(const BeginFrameArgs& args, const IVsyncSource& v } } if (!mSupportsExpectedPresentTime) { mEarliestPresentTime = computeEarliestPresentTime(minFramePeriod, args.hwcMinWorkDuration); } ATRACE_FORMAT("%s %" PRId64 " vsyncIn %.2fms%s", __func__, ftl::to_underlying(args.vsyncId), ticks<std::milli, float>(mExpectedPresentTime - TimePoint::now()), mExpectedPresentTime == args.expectedVsyncTime ? "" : " (adjusted)"); Loading Loading @@ -121,6 +125,14 @@ void FrameTargeter::beginFrame(const BeginFrameArgs& args, const IVsyncSource& v if (mGpuFrameMissed) mGpuFrameMissedCount++; } std::optional<TimePoint> FrameTargeter::computeEarliestPresentTime(Period minFramePeriod, Duration hwcMinWorkDuration) { if (wouldPresentEarly(minFramePeriod)) { return previousFrameVsyncTime(minFramePeriod) - hwcMinWorkDuration; } return {}; } void FrameTargeter::endFrame(const CompositeResult& result) { mCompositionCoverage = result.compositionCoverage; } Loading Loading
services/surfaceflinger/Scheduler/Scheduler.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -192,7 +192,8 @@ void Scheduler::onFrameSignal(ICompositor& compositor, VsyncId vsyncId, .vsyncId = vsyncId, // TODO(b/255601557): Calculate per display. .expectedVsyncTime = expectedVsyncTime, .sfWorkDuration = mVsyncModulator->getVsyncConfig().sfWorkDuration}; .sfWorkDuration = mVsyncModulator->getVsyncConfig().sfWorkDuration, .hwcMinWorkDuration = mVsyncConfiguration->getCurrentConfigs().hwcMinWorkDuration}; ftl::NonNull<const Display*> pacesetterPtr = pacesetterPtrLocked(); pacesetterPtr->targeterPtr->beginFrame(beginFrameArgs, *pacesetterPtr->schedulePtr); Loading
services/surfaceflinger/Scheduler/Scheduler.h +1 −3 Original line number Diff line number Diff line Loading @@ -514,9 +514,7 @@ private: : displayId(displayId), selectorPtr(std::move(selectorPtr)), schedulePtr(std::move(schedulePtr)), targeterPtr(std::make_unique< FrameTargeter>(displayId, features.test(Feature::kBackpressureGpuComposition))) {} targeterPtr(std::make_unique<FrameTargeter>(displayId, features)) {} const PhysicalDisplayId displayId; Loading
services/surfaceflinger/Scheduler/include/scheduler/Features.h +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ enum class Feature : std::uint8_t { kTracePredictedVsync = 1 << 3, kBackpressureGpuComposition = 1 << 4, kSmallDirtyContentDetection = 1 << 5, kExpectedPresentTime = 1 << 6, }; using FeatureFlags = ftl::Flags<Feature>; Loading
services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h +23 −10 Original line number Diff line number Diff line Loading @@ -19,11 +19,13 @@ #include <array> #include <atomic> #include <memory> #include <optional> #include <ui/DisplayId.h> #include <ui/Fence.h> #include <ui/FenceTime.h> #include <scheduler/Features.h> #include <scheduler/Time.h> #include <scheduler/VsyncId.h> #include <scheduler/interface/CompositeResult.h> Loading @@ -49,14 +51,11 @@ public: TimePoint expectedPresentTime() const { return mExpectedPresentTime; } std::optional<TimePoint> earliestPresentTime() const { return mEarliestPresentTime; } // The time of the VSYNC that preceded this frame. See `presentFenceForPastVsync` for details. TimePoint pastVsyncTime(Period minFramePeriod) const; // Equivalent to `pastVsyncTime` unless running N VSYNCs ahead. TimePoint previousFrameVsyncTime(Period minFramePeriod) const { return mExpectedPresentTime - minFramePeriod; } // 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 Loading @@ -69,8 +68,6 @@ public: return mPresentFences.front().fenceTime; } bool wouldPresentEarly(Period minFramePeriod) const; bool isFramePending() const { return mFramePending; } bool didMissFrame() const { return mFrameMissed; } bool didMissHwcFrame() const { return mHwcFrameMissed && !mGpuFrameMissed; } Loading @@ -79,9 +76,17 @@ protected: explicit FrameTarget(const std::string& displayLabel); ~FrameTarget() = default; bool wouldPresentEarly(Period minFramePeriod) const; // Equivalent to `pastVsyncTime` unless running N VSYNCs ahead. TimePoint previousFrameVsyncTime(Period minFramePeriod) const { return mExpectedPresentTime - minFramePeriod; } VsyncId mVsyncId; TimePoint mFrameBeginTime; TimePoint mExpectedPresentTime; std::optional<TimePoint> mEarliestPresentTime; TracedOrdinal<bool> mFramePending; TracedOrdinal<bool> mFrameMissed; Loading @@ -95,6 +100,8 @@ protected: std::array<FenceWithFenceTime, 2> mPresentFences; private: friend class FrameTargeterTestBase; template <int N> inline bool targetsVsyncsAhead(Period minFramePeriod) const { static_assert(N > 1); Loading @@ -105,9 +112,10 @@ private: // Computes a display's per-frame metrics about past/upcoming targeting of present deadlines. class FrameTargeter final : private FrameTarget { public: FrameTargeter(PhysicalDisplayId displayId, bool backpressureGpuComposition) FrameTargeter(PhysicalDisplayId displayId, FeatureFlags flags) : FrameTarget(to_string(displayId)), mBackpressureGpuComposition(backpressureGpuComposition) {} mBackpressureGpuComposition(flags.test(Feature::kBackpressureGpuComposition)), mSupportsExpectedPresentTime(flags.test(Feature::kExpectedPresentTime)) {} const FrameTarget& target() const { return *this; } Loading @@ -116,10 +124,14 @@ public: VsyncId vsyncId; TimePoint expectedVsyncTime; Duration sfWorkDuration; Duration hwcMinWorkDuration; }; void beginFrame(const BeginFrameArgs&, const IVsyncSource&); std::optional<TimePoint> computeEarliestPresentTime(Period minFramePeriod, Duration hwcMinWorkDuration); // TODO(b/241285191): Merge with FrameTargeter::endFrame. FenceTimePtr setPresentFence(sp<Fence>); Loading @@ -128,7 +140,7 @@ public: void dump(utils::Dumper&) const; private: friend class FrameTargeterTest; friend class FrameTargeterTestBase; // For tests. using IsFencePendingFuncPtr = bool (*)(const FenceTimePtr&, int graceTimeMs); Loading @@ -138,6 +150,7 @@ private: static bool isFencePending(const FenceTimePtr&, int graceTimeMs); const bool mBackpressureGpuComposition; const bool mSupportsExpectedPresentTime; TimePoint mScheduledPresentTime; CompositionCoverageFlags mCompositionCoverage; Loading
services/surfaceflinger/Scheduler/src/FrameTargeter.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,10 @@ void FrameTargeter::beginFrame(const BeginFrameArgs& args, const IVsyncSource& v } } if (!mSupportsExpectedPresentTime) { mEarliestPresentTime = computeEarliestPresentTime(minFramePeriod, args.hwcMinWorkDuration); } ATRACE_FORMAT("%s %" PRId64 " vsyncIn %.2fms%s", __func__, ftl::to_underlying(args.vsyncId), ticks<std::milli, float>(mExpectedPresentTime - TimePoint::now()), mExpectedPresentTime == args.expectedVsyncTime ? "" : " (adjusted)"); Loading Loading @@ -121,6 +125,14 @@ void FrameTargeter::beginFrame(const BeginFrameArgs& args, const IVsyncSource& v if (mGpuFrameMissed) mGpuFrameMissedCount++; } std::optional<TimePoint> FrameTargeter::computeEarliestPresentTime(Period minFramePeriod, Duration hwcMinWorkDuration) { if (wouldPresentEarly(minFramePeriod)) { return previousFrameVsyncTime(minFramePeriod) - hwcMinWorkDuration; } return {}; } void FrameTargeter::endFrame(const CompositeResult& result) { mCompositionCoverage = result.compositionCoverage; } Loading