Loading services/surfaceflinger/Scheduler/VsyncConfiguration.cpp +20 −9 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ PhaseOffsets::VsyncConfigSet VsyncConfiguration::getConfigsForRefreshRateLocked( } void VsyncConfiguration::dump(std::string& result) const { const auto [early, earlyGpu, late] = getCurrentConfigs(); const auto [early, earlyGpu, late, hwcMinWorkDuration] = getCurrentConfigs(); using base::StringAppendF; StringAppendF(&result, " app phase: %9" PRId64 " ns\t SF phase: %9" PRId64 Loading @@ -70,7 +70,8 @@ void VsyncConfiguration::dump(std::string& result) const { " early app duration: %9lld ns\t early SF duration: %9lld ns\n" " GL early app phase: %9" PRId64 " ns\tGL early SF phase: %9" PRId64 " ns\n" " GL early app duration: %9lld ns\tGL early SF duration: %9lld ns\n", " GL early app duration: %9lld ns\tGL early SF duration: %9lld ns\n" " HWC min duration: %9lld ns\n", late.appOffset, late.sfOffset, late.appWorkDuration.count(), late.sfWorkDuration.count(), Loading @@ -81,7 +82,9 @@ void VsyncConfiguration::dump(std::string& result) const { earlyGpu.appOffset, earlyGpu.sfOffset, earlyGpu.appWorkDuration.count(), earlyGpu.sfWorkDuration.count()); earlyGpu.appWorkDuration.count(), earlyGpu.sfWorkDuration.count(), hwcMinWorkDuration.count()); } PhaseOffsets::PhaseOffsets(Fps currentRefreshRate) Loading @@ -103,7 +106,8 @@ PhaseOffsets::PhaseOffsets(Fps currentRefreshRate) // offset >= threshold, SF wake up (2 * vsync_duration - offset) before HW // vsync. getProperty("debug.sf.phase_offset_threshold_for_next_vsync_ns") .value_or(std::numeric_limits<nsecs_t>::max())) {} .value_or(std::numeric_limits<nsecs_t>::max()), getProperty("debug.sf.hwc.min.duration").value_or(0)) {} PhaseOffsets::PhaseOffsets(Fps currentFps, nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs, std::optional<nsecs_t> earlySfOffsetNs, Loading @@ -115,7 +119,7 @@ PhaseOffsets::PhaseOffsets(Fps currentFps, nsecs_t vsyncPhaseOffsetNs, nsecs_t s std::optional<nsecs_t> highFpsEarlyGpuSfOffsetNs, std::optional<nsecs_t> highFpsEarlyAppOffsetNs, std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs, nsecs_t thresholdForNextVsync) nsecs_t thresholdForNextVsync, nsecs_t hwcMinWorkDuration) : VsyncConfiguration(currentFps), mVSyncPhaseOffsetNs(vsyncPhaseOffsetNs), mSfVSyncPhaseOffsetNs(sfVSyncPhaseOffsetNs), Loading @@ -129,7 +133,8 @@ PhaseOffsets::PhaseOffsets(Fps currentFps, nsecs_t vsyncPhaseOffsetNs, nsecs_t s mHighFpsEarlyGpuSfOffsetNs(highFpsEarlyGpuSfOffsetNs), mHighFpsEarlyAppOffsetNs(highFpsEarlyAppOffsetNs), mHighFpsEarlyGpuAppOffsetNs(highFpsEarlyGpuAppOffsetNs), mThresholdForNextVsync(thresholdForNextVsync) {} mThresholdForNextVsync(thresholdForNextVsync), mHwcMinWorkDuration(hwcMinWorkDuration) {} PhaseOffsets::VsyncConfigSet PhaseOffsets::constructOffsets(nsecs_t vsyncDuration) const { if (vsyncDuration < std::chrono::nanoseconds(15ms).count()) { Loading Loading @@ -189,6 +194,7 @@ PhaseOffsets::VsyncConfigSet PhaseOffsets::getDefaultOffsets(nsecs_t vsyncDurati .sfWorkDuration = sfOffsetToDuration(lateSfOffset, vsyncDuration), .appWorkDuration = appOffsetToDuration(lateAppOffset, lateSfOffset, vsyncDuration)}, .hwcMinWorkDuration = std::chrono::nanoseconds(mHwcMinWorkDuration), }; } Loading Loading @@ -234,6 +240,7 @@ PhaseOffsets::VsyncConfigSet PhaseOffsets::getHighFpsOffsets(nsecs_t vsyncDurati .appWorkDuration = appOffsetToDuration(lateAppOffset, lateSfOffset, vsyncDuration), }, .hwcMinWorkDuration = std::chrono::nanoseconds(mHwcMinWorkDuration), }; } Loading Loading @@ -342,6 +349,7 @@ WorkDuration::VsyncConfigSet WorkDuration::constructOffsets(nsecs_t vsyncDuratio .sfWorkDuration = sfDuration, .appWorkDuration = appDuration, }, .hwcMinWorkDuration = std::chrono::nanoseconds(mHwcMinWorkDuration), }; } Loading @@ -351,19 +359,22 @@ WorkDuration::WorkDuration(Fps currentRefreshRate) getProperty("debug.sf.early.sf.duration").value_or(mSfDuration), getProperty("debug.sf.early.app.duration").value_or(mAppDuration), getProperty("debug.sf.earlyGl.sf.duration").value_or(mSfDuration), getProperty("debug.sf.earlyGl.app.duration").value_or(mAppDuration)) { getProperty("debug.sf.earlyGl.app.duration").value_or(mAppDuration), getProperty("debug.sf.hwc.min.duration").value_or(0)) { validateSysprops(); } WorkDuration::WorkDuration(Fps currentRefreshRate, nsecs_t sfDuration, nsecs_t appDuration, nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration, nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration) nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration, nsecs_t hwcMinWorkDuration) : VsyncConfiguration(currentRefreshRate), mSfDuration(sfDuration), mAppDuration(appDuration), mSfEarlyDuration(sfEarlyDuration), mAppEarlyDuration(appEarlyDuration), mSfEarlyGpuDuration(sfEarlyGpuDuration), mAppEarlyGpuDuration(appEarlyGpuDuration) {} mAppEarlyGpuDuration(appEarlyGpuDuration), mHwcMinWorkDuration(hwcMinWorkDuration) {} } // namespace android::scheduler::impl services/surfaceflinger/Scheduler/VsyncConfiguration.h +7 −2 Original line number Diff line number Diff line Loading @@ -111,7 +111,8 @@ protected: nsecs_t highFpsSfVSyncPhaseOffsetNs, std::optional<nsecs_t> highFpsEarlySfOffsetNs, std::optional<nsecs_t> highFpsEarlyGpuSfOffsetNs, std::optional<nsecs_t> highFpsEarlyAppOffsetNs, std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs, nsecs_t thresholdForNextVsync); std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs, nsecs_t thresholdForNextVsync, nsecs_t hwcMinWorkDuration); private: VsyncConfiguration::VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const override; Loading @@ -134,6 +135,7 @@ private: const std::optional<nsecs_t> mHighFpsEarlyGpuAppOffsetNs; const nsecs_t mThresholdForNextVsync; const nsecs_t mHwcMinWorkDuration; }; /* Loading @@ -148,7 +150,8 @@ public: protected: // Used for unit tests WorkDuration(Fps currentFps, nsecs_t sfDuration, nsecs_t appDuration, nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration, nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration); nsecs_t appEarlyDuration, nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration, nsecs_t hwcMinWorkDuration); private: VsyncConfiguration::VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const override; Loading @@ -161,6 +164,8 @@ private: const nsecs_t mSfEarlyGpuDuration; const nsecs_t mAppEarlyGpuDuration; const nsecs_t mHwcMinWorkDuration; }; } // namespace impl Loading services/surfaceflinger/Scheduler/VsyncModulator.h +4 −1 Original line number Diff line number Diff line Loading @@ -69,9 +69,12 @@ public: VsyncConfig early; // Used for early transactions, and during refresh rate change. VsyncConfig earlyGpu; // Used during GPU composition. VsyncConfig late; // Default. std::chrono::nanoseconds hwcMinWorkDuration; // Used for calculating the // earliest present time bool operator==(const VsyncConfigSet& other) const { return early == other.early && earlyGpu == other.earlyGpu && late == other.late; return early == other.early && earlyGpu == other.earlyGpu && late == other.late && hwcMinWorkDuration == other.hwcMinWorkDuration; } bool operator!=(const VsyncConfigSet& other) const { return !(*this == other); } Loading services/surfaceflinger/SurfaceFlinger.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -2066,7 +2066,9 @@ void SurfaceFlinger::onMessageRefresh() { std::chrono::milliseconds(mDebugRegion > 1 ? mDebugRegion : 0); } refreshArgs.earliestPresentTime = mScheduler->getPreviousVsyncFrom(mExpectedPresentTime); const auto prevVsyncTime = mScheduler->getPreviousVsyncFrom(mExpectedPresentTime); const auto hwcMinWorkDuration = mVsyncConfiguration->getCurrentConfigs().hwcMinWorkDuration; refreshArgs.earliestPresentTime = prevVsyncTime - hwcMinWorkDuration; refreshArgs.nextInvalidateTime = mEventQueue->nextExpectedInvalidate(); mGeometryInvalid = false; Loading services/surfaceflinger/tests/unittests/FakeVsyncConfiguration.h +2 −1 Original line number Diff line number Diff line Loading @@ -34,7 +34,8 @@ struct FakePhaseOffsets : VsyncConfiguration { {FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS, FAKE_DURATION_OFFSET_NS, FAKE_DURATION_OFFSET_NS}, {FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS, FAKE_DURATION_OFFSET_NS, FAKE_DURATION_OFFSET_NS}}; FAKE_DURATION_OFFSET_NS}, FAKE_DURATION_OFFSET_NS}; } void reset() override {} Loading Loading
services/surfaceflinger/Scheduler/VsyncConfiguration.cpp +20 −9 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ PhaseOffsets::VsyncConfigSet VsyncConfiguration::getConfigsForRefreshRateLocked( } void VsyncConfiguration::dump(std::string& result) const { const auto [early, earlyGpu, late] = getCurrentConfigs(); const auto [early, earlyGpu, late, hwcMinWorkDuration] = getCurrentConfigs(); using base::StringAppendF; StringAppendF(&result, " app phase: %9" PRId64 " ns\t SF phase: %9" PRId64 Loading @@ -70,7 +70,8 @@ void VsyncConfiguration::dump(std::string& result) const { " early app duration: %9lld ns\t early SF duration: %9lld ns\n" " GL early app phase: %9" PRId64 " ns\tGL early SF phase: %9" PRId64 " ns\n" " GL early app duration: %9lld ns\tGL early SF duration: %9lld ns\n", " GL early app duration: %9lld ns\tGL early SF duration: %9lld ns\n" " HWC min duration: %9lld ns\n", late.appOffset, late.sfOffset, late.appWorkDuration.count(), late.sfWorkDuration.count(), Loading @@ -81,7 +82,9 @@ void VsyncConfiguration::dump(std::string& result) const { earlyGpu.appOffset, earlyGpu.sfOffset, earlyGpu.appWorkDuration.count(), earlyGpu.sfWorkDuration.count()); earlyGpu.appWorkDuration.count(), earlyGpu.sfWorkDuration.count(), hwcMinWorkDuration.count()); } PhaseOffsets::PhaseOffsets(Fps currentRefreshRate) Loading @@ -103,7 +106,8 @@ PhaseOffsets::PhaseOffsets(Fps currentRefreshRate) // offset >= threshold, SF wake up (2 * vsync_duration - offset) before HW // vsync. getProperty("debug.sf.phase_offset_threshold_for_next_vsync_ns") .value_or(std::numeric_limits<nsecs_t>::max())) {} .value_or(std::numeric_limits<nsecs_t>::max()), getProperty("debug.sf.hwc.min.duration").value_or(0)) {} PhaseOffsets::PhaseOffsets(Fps currentFps, nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs, std::optional<nsecs_t> earlySfOffsetNs, Loading @@ -115,7 +119,7 @@ PhaseOffsets::PhaseOffsets(Fps currentFps, nsecs_t vsyncPhaseOffsetNs, nsecs_t s std::optional<nsecs_t> highFpsEarlyGpuSfOffsetNs, std::optional<nsecs_t> highFpsEarlyAppOffsetNs, std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs, nsecs_t thresholdForNextVsync) nsecs_t thresholdForNextVsync, nsecs_t hwcMinWorkDuration) : VsyncConfiguration(currentFps), mVSyncPhaseOffsetNs(vsyncPhaseOffsetNs), mSfVSyncPhaseOffsetNs(sfVSyncPhaseOffsetNs), Loading @@ -129,7 +133,8 @@ PhaseOffsets::PhaseOffsets(Fps currentFps, nsecs_t vsyncPhaseOffsetNs, nsecs_t s mHighFpsEarlyGpuSfOffsetNs(highFpsEarlyGpuSfOffsetNs), mHighFpsEarlyAppOffsetNs(highFpsEarlyAppOffsetNs), mHighFpsEarlyGpuAppOffsetNs(highFpsEarlyGpuAppOffsetNs), mThresholdForNextVsync(thresholdForNextVsync) {} mThresholdForNextVsync(thresholdForNextVsync), mHwcMinWorkDuration(hwcMinWorkDuration) {} PhaseOffsets::VsyncConfigSet PhaseOffsets::constructOffsets(nsecs_t vsyncDuration) const { if (vsyncDuration < std::chrono::nanoseconds(15ms).count()) { Loading Loading @@ -189,6 +194,7 @@ PhaseOffsets::VsyncConfigSet PhaseOffsets::getDefaultOffsets(nsecs_t vsyncDurati .sfWorkDuration = sfOffsetToDuration(lateSfOffset, vsyncDuration), .appWorkDuration = appOffsetToDuration(lateAppOffset, lateSfOffset, vsyncDuration)}, .hwcMinWorkDuration = std::chrono::nanoseconds(mHwcMinWorkDuration), }; } Loading Loading @@ -234,6 +240,7 @@ PhaseOffsets::VsyncConfigSet PhaseOffsets::getHighFpsOffsets(nsecs_t vsyncDurati .appWorkDuration = appOffsetToDuration(lateAppOffset, lateSfOffset, vsyncDuration), }, .hwcMinWorkDuration = std::chrono::nanoseconds(mHwcMinWorkDuration), }; } Loading Loading @@ -342,6 +349,7 @@ WorkDuration::VsyncConfigSet WorkDuration::constructOffsets(nsecs_t vsyncDuratio .sfWorkDuration = sfDuration, .appWorkDuration = appDuration, }, .hwcMinWorkDuration = std::chrono::nanoseconds(mHwcMinWorkDuration), }; } Loading @@ -351,19 +359,22 @@ WorkDuration::WorkDuration(Fps currentRefreshRate) getProperty("debug.sf.early.sf.duration").value_or(mSfDuration), getProperty("debug.sf.early.app.duration").value_or(mAppDuration), getProperty("debug.sf.earlyGl.sf.duration").value_or(mSfDuration), getProperty("debug.sf.earlyGl.app.duration").value_or(mAppDuration)) { getProperty("debug.sf.earlyGl.app.duration").value_or(mAppDuration), getProperty("debug.sf.hwc.min.duration").value_or(0)) { validateSysprops(); } WorkDuration::WorkDuration(Fps currentRefreshRate, nsecs_t sfDuration, nsecs_t appDuration, nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration, nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration) nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration, nsecs_t hwcMinWorkDuration) : VsyncConfiguration(currentRefreshRate), mSfDuration(sfDuration), mAppDuration(appDuration), mSfEarlyDuration(sfEarlyDuration), mAppEarlyDuration(appEarlyDuration), mSfEarlyGpuDuration(sfEarlyGpuDuration), mAppEarlyGpuDuration(appEarlyGpuDuration) {} mAppEarlyGpuDuration(appEarlyGpuDuration), mHwcMinWorkDuration(hwcMinWorkDuration) {} } // namespace android::scheduler::impl
services/surfaceflinger/Scheduler/VsyncConfiguration.h +7 −2 Original line number Diff line number Diff line Loading @@ -111,7 +111,8 @@ protected: nsecs_t highFpsSfVSyncPhaseOffsetNs, std::optional<nsecs_t> highFpsEarlySfOffsetNs, std::optional<nsecs_t> highFpsEarlyGpuSfOffsetNs, std::optional<nsecs_t> highFpsEarlyAppOffsetNs, std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs, nsecs_t thresholdForNextVsync); std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs, nsecs_t thresholdForNextVsync, nsecs_t hwcMinWorkDuration); private: VsyncConfiguration::VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const override; Loading @@ -134,6 +135,7 @@ private: const std::optional<nsecs_t> mHighFpsEarlyGpuAppOffsetNs; const nsecs_t mThresholdForNextVsync; const nsecs_t mHwcMinWorkDuration; }; /* Loading @@ -148,7 +150,8 @@ public: protected: // Used for unit tests WorkDuration(Fps currentFps, nsecs_t sfDuration, nsecs_t appDuration, nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration, nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration); nsecs_t appEarlyDuration, nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration, nsecs_t hwcMinWorkDuration); private: VsyncConfiguration::VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const override; Loading @@ -161,6 +164,8 @@ private: const nsecs_t mSfEarlyGpuDuration; const nsecs_t mAppEarlyGpuDuration; const nsecs_t mHwcMinWorkDuration; }; } // namespace impl Loading
services/surfaceflinger/Scheduler/VsyncModulator.h +4 −1 Original line number Diff line number Diff line Loading @@ -69,9 +69,12 @@ public: VsyncConfig early; // Used for early transactions, and during refresh rate change. VsyncConfig earlyGpu; // Used during GPU composition. VsyncConfig late; // Default. std::chrono::nanoseconds hwcMinWorkDuration; // Used for calculating the // earliest present time bool operator==(const VsyncConfigSet& other) const { return early == other.early && earlyGpu == other.earlyGpu && late == other.late; return early == other.early && earlyGpu == other.earlyGpu && late == other.late && hwcMinWorkDuration == other.hwcMinWorkDuration; } bool operator!=(const VsyncConfigSet& other) const { return !(*this == other); } Loading
services/surfaceflinger/SurfaceFlinger.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -2066,7 +2066,9 @@ void SurfaceFlinger::onMessageRefresh() { std::chrono::milliseconds(mDebugRegion > 1 ? mDebugRegion : 0); } refreshArgs.earliestPresentTime = mScheduler->getPreviousVsyncFrom(mExpectedPresentTime); const auto prevVsyncTime = mScheduler->getPreviousVsyncFrom(mExpectedPresentTime); const auto hwcMinWorkDuration = mVsyncConfiguration->getCurrentConfigs().hwcMinWorkDuration; refreshArgs.earliestPresentTime = prevVsyncTime - hwcMinWorkDuration; refreshArgs.nextInvalidateTime = mEventQueue->nextExpectedInvalidate(); mGeometryInvalid = false; Loading
services/surfaceflinger/tests/unittests/FakeVsyncConfiguration.h +2 −1 Original line number Diff line number Diff line Loading @@ -34,7 +34,8 @@ struct FakePhaseOffsets : VsyncConfiguration { {FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS, FAKE_DURATION_OFFSET_NS, FAKE_DURATION_OFFSET_NS}, {FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS, FAKE_DURATION_OFFSET_NS, FAKE_DURATION_OFFSET_NS}}; FAKE_DURATION_OFFSET_NS}, FAKE_DURATION_OFFSET_NS}; } void reset() override {} Loading