summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdy Abraham <adyabr@google.com>2021-06-18 17:35:28 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2021-06-18 17:35:28 +0000
commita785b9a9c362954c3d136cba1f30ff4bd9edf49c (patch)
treecf8d76bc7bed3616494430accec40f9d4814120f
parenta9e4e2fb7aea58d18c230e9fb8d40da72537997e (diff)
parentcaba2983ca1c2b2b4ca393900602f856b12e0199 (diff)
downloadnative-a785b9a9c362954c3d136cba1f30ff4bd9edf49c.tar.gz
Merge "SF: introduce debug.sf.hwc.min.duration" into sc-dev
-rw-r--r--services/surfaceflinger/Scheduler/VsyncConfiguration.cpp29
-rw-r--r--services/surfaceflinger/Scheduler/VsyncConfiguration.h9
-rw-r--r--services/surfaceflinger/Scheduler/VsyncModulator.h5
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp4
-rw-r--r--services/surfaceflinger/tests/unittests/FakeVsyncConfiguration.h3
-rw-r--r--services/surfaceflinger/tests/unittests/VsyncConfigurationTest.cpp41
-rw-r--r--services/surfaceflinger/tests/unittests/VsyncModulatorTest.cpp4
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)); }