diff options
author | Ady Abraham <adyabr@google.com> | 2021-06-18 17:35:28 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-06-18 17:35:28 +0000 |
commit | a785b9a9c362954c3d136cba1f30ff4bd9edf49c (patch) | |
tree | cf8d76bc7bed3616494430accec40f9d4814120f | |
parent | a9e4e2fb7aea58d18c230e9fb8d40da72537997e (diff) | |
parent | caba2983ca1c2b2b4ca393900602f856b12e0199 (diff) | |
download | native-a785b9a9c362954c3d136cba1f30ff4bd9edf49c.tar.gz |
Merge "SF: introduce debug.sf.hwc.min.duration" into sc-dev
7 files changed, 67 insertions, 28 deletions
diff --git a/services/surfaceflinger/Scheduler/VsyncConfiguration.cpp b/services/surfaceflinger/Scheduler/VsyncConfiguration.cpp index cb57aeace5..43e02979c1 100644 --- a/services/surfaceflinger/Scheduler/VsyncConfiguration.cpp +++ b/services/surfaceflinger/Scheduler/VsyncConfiguration.cpp @@ -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 @@ -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(), @@ -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) @@ -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, @@ -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), @@ -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()) { @@ -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), }; } @@ -234,6 +240,7 @@ PhaseOffsets::VsyncConfigSet PhaseOffsets::getHighFpsOffsets(nsecs_t vsyncDurati .appWorkDuration = appOffsetToDuration(lateAppOffset, lateSfOffset, vsyncDuration), }, + .hwcMinWorkDuration = std::chrono::nanoseconds(mHwcMinWorkDuration), }; } @@ -342,6 +349,7 @@ WorkDuration::VsyncConfigSet WorkDuration::constructOffsets(nsecs_t vsyncDuratio .sfWorkDuration = sfDuration, .appWorkDuration = appDuration, }, + .hwcMinWorkDuration = std::chrono::nanoseconds(mHwcMinWorkDuration), }; } @@ -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 diff --git a/services/surfaceflinger/Scheduler/VsyncConfiguration.h b/services/surfaceflinger/Scheduler/VsyncConfiguration.h index d9d206dd76..3e53b3faa2 100644 --- a/services/surfaceflinger/Scheduler/VsyncConfiguration.h +++ b/services/surfaceflinger/Scheduler/VsyncConfiguration.h @@ -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; @@ -134,6 +135,7 @@ private: const std::optional<nsecs_t> mHighFpsEarlyGpuAppOffsetNs; const nsecs_t mThresholdForNextVsync; + const nsecs_t mHwcMinWorkDuration; }; /* @@ -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; @@ -161,6 +164,8 @@ private: const nsecs_t mSfEarlyGpuDuration; const nsecs_t mAppEarlyGpuDuration; + + const nsecs_t mHwcMinWorkDuration; }; } // namespace impl diff --git a/services/surfaceflinger/Scheduler/VsyncModulator.h b/services/surfaceflinger/Scheduler/VsyncModulator.h index fcde279070..9410768b2d 100644 --- a/services/surfaceflinger/Scheduler/VsyncModulator.h +++ b/services/surfaceflinger/Scheduler/VsyncModulator.h @@ -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); } diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index fddec1b6fd..e7187b1381 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -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; diff --git a/services/surfaceflinger/tests/unittests/FakeVsyncConfiguration.h b/services/surfaceflinger/tests/unittests/FakeVsyncConfiguration.h index e890a62955..f6f3c07c79 100644 --- a/services/surfaceflinger/tests/unittests/FakeVsyncConfiguration.h +++ b/services/surfaceflinger/tests/unittests/FakeVsyncConfiguration.h @@ -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 {} diff --git a/services/surfaceflinger/tests/unittests/VsyncConfigurationTest.cpp b/services/surfaceflinger/tests/unittests/VsyncConfigurationTest.cpp index bb7578d744..41a4d308ce 100644 --- a/services/surfaceflinger/tests/unittests/VsyncConfigurationTest.cpp +++ b/services/surfaceflinger/tests/unittests/VsyncConfigurationTest.cpp @@ -34,16 +34,18 @@ class TestableWorkDuration : public impl::WorkDuration { public: TestableWorkDuration(Fps currentFps, nsecs_t sfDuration, nsecs_t appDuration, nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration, - nsecs_t sfEarlyGlDuration, nsecs_t appEarlyGlDuration) + nsecs_t sfEarlyGlDuration, nsecs_t appEarlyGlDuration, + nsecs_t hwcMinWorkDuration) : impl::WorkDuration(currentFps, sfDuration, appDuration, sfEarlyDuration, - appEarlyDuration, sfEarlyGlDuration, appEarlyGlDuration) {} + appEarlyDuration, sfEarlyGlDuration, appEarlyGlDuration, + hwcMinWorkDuration) {} }; class WorkDurationTest : public testing::Test { protected: WorkDurationTest() : mWorkDuration(Fps(60.0f), 10'500'000, 20'500'000, 16'000'000, 16'500'000, 13'500'000, - 21'000'000) {} + 21'000'000, 1234) {} ~WorkDurationTest() = default; @@ -104,7 +106,7 @@ TEST_F(WorkDurationTest, getConfigsForRefreshRate_90Hz) { } TEST_F(WorkDurationTest, getConfigsForRefreshRate_DefaultOffsets) { - TestableWorkDuration phaseOffsetsWithDefaultValues(Fps(60.0f), -1, -1, -1, -1, -1, -1); + TestableWorkDuration phaseOffsetsWithDefaultValues(Fps(60.0f), -1, -1, -1, -1, -1, -1, 0); auto validateOffsets = [](const auto& offsets, std::chrono::nanoseconds vsyncPeriod) { EXPECT_EQ(offsets.late.sfOffset, 1'000'000); @@ -124,6 +126,8 @@ TEST_F(WorkDurationTest, getConfigsForRefreshRate_DefaultOffsets) { EXPECT_EQ(offsets.earlyGpu.sfWorkDuration, vsyncPeriod - 1'000'000ns); EXPECT_EQ(offsets.earlyGpu.appWorkDuration, vsyncPeriod); + + EXPECT_EQ(offsets.hwcMinWorkDuration, 0ns); }; const auto testForRefreshRate = [&](Fps refreshRate) { @@ -160,6 +164,10 @@ TEST_F(WorkDurationTest, getConfigsForRefreshRate_unknownRefreshRate) { EXPECT_EQ(offsets.earlyGpu.appWorkDuration, 21'000'000ns); } +TEST_F(WorkDurationTest, minHwcWorkDuration) { + EXPECT_EQ(mWorkDuration.getCurrentConfigs().hwcMinWorkDuration, 1234ns); +} + class TestablePhaseOffsets : public impl::PhaseOffsets { public: TestablePhaseOffsets(nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs, @@ -172,13 +180,14 @@ public: std::optional<nsecs_t> highFpsEarlyGpuSfOffsetNs, std::optional<nsecs_t> highFpsEarlyAppOffsetNs, std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs, - nsecs_t thresholdForNextVsync) + nsecs_t thresholdForNextVsync, nsecs_t hwcMinWorkDuration) : impl::PhaseOffsets(Fps(60.0f), vsyncPhaseOffsetNs, sfVSyncPhaseOffsetNs, earlySfOffsetNs, earlyGpuSfOffsetNs, earlyAppOffsetNs, earlyGpuAppOffsetNs, highFpsVsyncPhaseOffsetNs, highFpsSfVSyncPhaseOffsetNs, highFpsEarlySfOffsetNs, highFpsEarlyGpuSfOffsetNs, highFpsEarlyAppOffsetNs, - highFpsEarlyGpuAppOffsetNs, thresholdForNextVsync) {} + highFpsEarlyGpuAppOffsetNs, thresholdForNextVsync, + hwcMinWorkDuration) {} }; class PhaseOffsetsTest : public testing::Test { @@ -186,9 +195,9 @@ protected: PhaseOffsetsTest() = default; ~PhaseOffsetsTest() = default; - TestablePhaseOffsets mPhaseOffsets{2'000'000, 6'000'000, 7'000'000, 8'000'000, 3'000'000, - 4'000'000, 2'000'000, 1'000'000, 2'000'000, 3'000'000, - 3'000'000, 4'000'000, 10'000'000}; + TestablePhaseOffsets mPhaseOffsets{2'000'000, 6'000'000, 7'000'000, 8'000'000, 3'000'000, + 4'000'000, 2'000'000, 1'000'000, 2'000'000, 3'000'000, + 3'000'000, 4'000'000, 10'000'000, 1234}; }; TEST_F(PhaseOffsetsTest, getConfigsForRefreshRate_unknownRefreshRate) { @@ -258,8 +267,8 @@ TEST_F(PhaseOffsetsTest, getConfigsForRefreshRate_90Hz) { } TEST_F(PhaseOffsetsTest, getConfigsForRefreshRate_DefaultValues_60Hz) { - TestablePhaseOffsets phaseOffsets{1'000'000, 1'000'000, {}, {}, {}, {}, 2'000'000, - 1'000'000, {}, {}, {}, {}, 10'000'000}; + TestablePhaseOffsets phaseOffsets{1'000'000, 1'000'000, {}, {}, {}, {}, 2'000'000, + 1'000'000, {}, {}, {}, {}, 10'000'000, 1234}; auto offsets = phaseOffsets.getConfigsForRefreshRate(Fps(60.0f)); EXPECT_EQ(offsets.late.sfOffset, 1'000'000); @@ -282,8 +291,8 @@ TEST_F(PhaseOffsetsTest, getConfigsForRefreshRate_DefaultValues_60Hz) { } TEST_F(PhaseOffsetsTest, getConfigsForRefreshRate_DefaultValues_90Hz) { - TestablePhaseOffsets phaseOffsets{1'000'000, 1'000'000, {}, {}, {}, {}, 2'000'000, - 1'000'000, {}, {}, {}, {}, 10'000'000}; + TestablePhaseOffsets phaseOffsets{1'000'000, 1'000'000, {}, {}, {}, {}, 2'000'000, + 1'000'000, {}, {}, {}, {}, 10'000'000, 1234}; auto offsets = phaseOffsets.getConfigsForRefreshRate(Fps(90.0f)); EXPECT_EQ(offsets.late.sfOffset, 1'000'000); @@ -305,4 +314,10 @@ TEST_F(PhaseOffsetsTest, getConfigsForRefreshRate_DefaultValues_90Hz) { EXPECT_EQ(offsets.earlyGpu.appWorkDuration, 21'222'222ns); } +TEST_F(PhaseOffsetsTest, minHwcWorkDuration) { + TestablePhaseOffsets phaseOffsets{1'000'000, 1'000'000, {}, {}, {}, {}, 2'000'000, + 1'000'000, {}, {}, {}, {}, 10'000'000, 1234}; + EXPECT_EQ(phaseOffsets.getCurrentConfigs().hwcMinWorkDuration, 1234ns); +} + } // namespace android::scheduler diff --git a/services/surfaceflinger/tests/unittests/VsyncModulatorTest.cpp b/services/surfaceflinger/tests/unittests/VsyncModulatorTest.cpp index 17648d532e..60952bfa2f 100644 --- a/services/surfaceflinger/tests/unittests/VsyncModulatorTest.cpp +++ b/services/surfaceflinger/tests/unittests/VsyncModulatorTest.cpp @@ -35,6 +35,7 @@ class VsyncModulatorTest : public testing::Test { APP_OFFSET_EARLY_GPU, SF_DURATION_EARLY_GPU, APP_DURATION_EARLY_GPU, + HWC_MIN_WORK_DURATION, }; static VsyncModulator::TimePoint Now() { @@ -57,7 +58,8 @@ protected: nanos(SF_DURATION_EARLY_GPU), nanos(APP_DURATION_EARLY_GPU)}; - const VsyncModulator::VsyncConfigSet mOffsets = {kEarly, kEarlyGpu, kLate}; + const VsyncModulator::VsyncConfigSet mOffsets = {kEarly, kEarlyGpu, kLate, + nanos(HWC_MIN_WORK_DURATION)}; VsyncModulator mVsyncModulator{mOffsets, Now}; void SetUp() override { EXPECT_EQ(kLate, mVsyncModulator.setVsyncConfigSet(mOffsets)); } |