SurfaceFlinger: expose duration as part of phase offsets

expose app/sf duration together with the offset configs. These
will be used in the next CLs to calculate when to wake up the
corresponding EventThread.

Test: examine offsets and duration via dumpsys SurfaceFlinger
Bug: 162888874
Change-Id: Ifc1848358823570a34760f29ea975c286fbd8837
diff --git a/services/surfaceflinger/Scheduler/VsyncConfiguration.cpp b/services/surfaceflinger/Scheduler/VsyncConfiguration.cpp
index 5373742..aac2569 100644
--- a/services/surfaceflinger/Scheduler/VsyncConfiguration.cpp
+++ b/services/surfaceflinger/Scheduler/VsyncConfiguration.cpp
@@ -51,145 +51,13 @@
 
 } // namespace
 
-namespace android::scheduler {
+namespace android::scheduler::impl {
 
-PhaseConfiguration::~PhaseConfiguration() = default;
+VsyncConfiguration::VsyncConfiguration(float currentFps) : mRefreshRateFps(currentFps) {}
 
-namespace impl {
-
-PhaseOffsets::PhaseOffsets(const scheduler::RefreshRateConfigs& refreshRateConfigs)
-      : PhaseOffsets(getRefreshRatesFromConfigs(refreshRateConfigs),
-                     refreshRateConfigs.getCurrentRefreshRate().getFps(),
-                     sysprop::vsync_event_phase_offset_ns(1000000),
-                     sysprop::vsync_sf_event_phase_offset_ns(1000000),
-                     getProperty("debug.sf.early_phase_offset_ns"),
-                     getProperty("debug.sf.early_gl_phase_offset_ns"),
-                     getProperty("debug.sf.early_app_phase_offset_ns"),
-                     getProperty("debug.sf.early_gl_app_phase_offset_ns"),
-                     // Below defines the threshold when an offset is considered to be negative,
-                     // i.e. targeting for the N+2 vsync instead of N+1. This means that: For offset
-                     // < threshold, SF wake up (vsync_duration - offset) before HW vsync. For
-                     // 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())) {}
-
-PhaseOffsets::PhaseOffsets(const std::vector<float>& refreshRates, float currentFps,
-                           nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs,
-                           std::optional<nsecs_t> earlySfOffsetNs,
-                           std::optional<nsecs_t> earlyGlSfOffsetNs,
-                           std::optional<nsecs_t> earlyAppOffsetNs,
-                           std::optional<nsecs_t> earlyGlAppOffsetNs, nsecs_t thresholdForNextVsync)
-      : mVSyncPhaseOffsetNs(vsyncPhaseOffsetNs),
-        mSfVSyncPhaseOffsetNs(sfVSyncPhaseOffsetNs),
-        mEarlySfOffsetNs(earlySfOffsetNs),
-        mEarlyGlSfOffsetNs(earlyGlSfOffsetNs),
-        mEarlyAppOffsetNs(earlyAppOffsetNs),
-        mEarlyGlAppOffsetNs(earlyGlAppOffsetNs),
-        mThresholdForNextVsync(thresholdForNextVsync),
-        mOffsets(initializeOffsets(refreshRates)),
-        mRefreshRateFps(currentFps) {}
-
-void PhaseOffsets::dump(std::string& result) const {
-    const auto [early, earlyGl, late] = getCurrentOffsets();
-    using base::StringAppendF;
-    StringAppendF(&result,
-                  "           app phase: %9" PRId64 " ns\t         SF phase: %9" PRId64 " ns\n"
-                  "     early app phase: %9" PRId64 " ns\t   early SF phase: %9" PRId64 " ns\n"
-                  "  GL early app phase: %9" PRId64 " ns\tGL early SF phase: %9" PRId64 " ns\n"
-                  "next VSYNC threshold: %9" PRId64 " ns\n",
-                  late.app, late.sf, early.app, early.sf, earlyGl.app, earlyGl.sf,
-                  mThresholdForNextVsync);
-}
-
-std::unordered_map<float, PhaseOffsets::Offsets> PhaseOffsets::initializeOffsets(
-        const std::vector<float>& refreshRates) const {
-    std::unordered_map<float, Offsets> offsets;
-
-    for (const auto& refreshRate : refreshRates) {
-        offsets.emplace(refreshRate,
-                        getPhaseOffsets(refreshRate, static_cast<nsecs_t>(1e9f / refreshRate)));
-    }
-    return offsets;
-}
-
-PhaseOffsets::Offsets PhaseOffsets::getPhaseOffsets(float fps, nsecs_t vsyncPeriod) const {
-    if (fps > 65.0f) {
-        return getHighFpsOffsets(vsyncPeriod);
-    } else {
-        return getDefaultOffsets(vsyncPeriod);
-    }
-}
-
-PhaseOffsets::Offsets PhaseOffsets::getDefaultOffsets(nsecs_t vsyncDuration) const {
-    return {
-            {
-                    mEarlySfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) < mThresholdForNextVsync
-                            ? mEarlySfOffsetNs.value_or(mSfVSyncPhaseOffsetNs)
-                            : mEarlySfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) - vsyncDuration,
-
-                    mEarlyAppOffsetNs.value_or(mVSyncPhaseOffsetNs),
-            },
-            {
-                    mEarlyGlSfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) < mThresholdForNextVsync
-                            ? mEarlyGlSfOffsetNs.value_or(mSfVSyncPhaseOffsetNs)
-                            : mEarlyGlSfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) - vsyncDuration,
-
-                    mEarlyGlAppOffsetNs.value_or(mVSyncPhaseOffsetNs),
-            },
-            {
-                    mSfVSyncPhaseOffsetNs < mThresholdForNextVsync
-                            ? mSfVSyncPhaseOffsetNs
-                            : mSfVSyncPhaseOffsetNs - vsyncDuration,
-
-                    mVSyncPhaseOffsetNs,
-            },
-    };
-}
-
-PhaseOffsets::Offsets PhaseOffsets::getHighFpsOffsets(nsecs_t vsyncDuration) const {
-    const auto highFpsLateAppOffsetNs =
-            getProperty("debug.sf.high_fps_late_app_phase_offset_ns").value_or(2000000);
-    const auto highFpsLateSfOffsetNs =
-            getProperty("debug.sf.high_fps_late_sf_phase_offset_ns").value_or(1000000);
-
-    const auto highFpsEarlySfOffsetNs = getProperty("debug.sf.high_fps_early_phase_offset_ns");
-    const auto highFpsEarlyGlSfOffsetNs = getProperty("debug.sf.high_fps_early_gl_phase_offset_ns");
-    const auto highFpsEarlyAppOffsetNs = getProperty("debug.sf.high_fps_early_app_phase_offset_ns");
-    const auto highFpsEarlyGlAppOffsetNs =
-            getProperty("debug.sf.high_fps_early_gl_app_phase_offset_ns");
-
-    return {
-            {
-                    highFpsEarlySfOffsetNs.value_or(highFpsLateSfOffsetNs) < mThresholdForNextVsync
-                            ? highFpsEarlySfOffsetNs.value_or(highFpsLateSfOffsetNs)
-                            : highFpsEarlySfOffsetNs.value_or(highFpsLateSfOffsetNs) -
-                                    vsyncDuration,
-
-                    highFpsEarlyAppOffsetNs.value_or(highFpsLateAppOffsetNs),
-            },
-            {
-                    highFpsEarlyGlSfOffsetNs.value_or(highFpsLateSfOffsetNs) <
-                                    mThresholdForNextVsync
-                            ? highFpsEarlyGlSfOffsetNs.value_or(highFpsLateSfOffsetNs)
-                            : highFpsEarlyGlSfOffsetNs.value_or(highFpsLateSfOffsetNs) -
-                                    vsyncDuration,
-
-                    highFpsEarlyGlAppOffsetNs.value_or(highFpsLateAppOffsetNs),
-            },
-            {
-                    highFpsLateSfOffsetNs < mThresholdForNextVsync
-                            ? highFpsLateSfOffsetNs
-                            : highFpsLateSfOffsetNs - vsyncDuration,
-
-                    highFpsLateAppOffsetNs,
-            },
-    };
-}
-
-PhaseOffsets::Offsets PhaseOffsets::getOffsetsForRefreshRate(float fps) const {
+PhaseOffsets::VsyncConfigSet VsyncConfiguration::getConfigsForRefreshRate(float fps) const {
     const auto iter = std::find_if(mOffsets.begin(), mOffsets.end(),
-                                   [&fps](const std::pair<float, Offsets>& candidateFps) {
+                                   [&fps](const std::pair<float, VsyncConfigSet>& candidateFps) {
                                        return fpsEqualsWithMargin(fps, candidateFps.first);
                                    });
 
@@ -200,7 +68,194 @@
     // Unknown refresh rate. This might happen if we get a hotplug event for an external display.
     // In this case just construct the offset.
     ALOGW("Can't find offset for %.2f fps", fps);
-    return getPhaseOffsets(fps, static_cast<nsecs_t>(1e9f / fps));
+    return constructOffsets(static_cast<nsecs_t>(1e9f / fps));
+}
+
+void VsyncConfiguration::initializeOffsets(const std::vector<float>& refreshRates) {
+    for (const auto fps : refreshRates) {
+        mOffsets.emplace(fps, constructOffsets(static_cast<nsecs_t>(1e9f / fps)));
+    }
+}
+
+void VsyncConfiguration::dump(std::string& result) const {
+    const auto [early, earlyGpu, late] = getCurrentConfigs();
+    using base::StringAppendF;
+    StringAppendF(&result,
+                  "           app phase:    %9" PRId64 " ns\t         SF phase:    %9" PRId64
+                  " ns\n"
+                  "           app duration: %9lld ns\t         SF duration: %9lld ns\n"
+                  "     early app phase:    %9" PRId64 " ns\t   early SF phase:    %9" PRId64
+                  " ns\n"
+                  "     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",
+                  late.appOffset, late.sfOffset,
+
+                  late.appWorkDuration.count(), late.sfWorkDuration.count(),
+
+                  early.appOffset, early.sfOffset,
+
+                  early.appWorkDuration.count(), early.sfWorkDuration.count(),
+
+                  earlyGpu.appOffset, earlyGpu.sfOffset,
+
+                  earlyGpu.appWorkDuration.count(), earlyGpu.sfWorkDuration.count());
+}
+
+PhaseOffsets::PhaseOffsets(const scheduler::RefreshRateConfigs& refreshRateConfigs)
+      : PhaseOffsets(getRefreshRatesFromConfigs(refreshRateConfigs),
+                     refreshRateConfigs.getCurrentRefreshRate().getFps(),
+                     sysprop::vsync_event_phase_offset_ns(1000000),
+                     sysprop::vsync_sf_event_phase_offset_ns(1000000),
+                     getProperty("debug.sf.early_phase_offset_ns"),
+                     getProperty("debug.sf.early_gl_phase_offset_ns"),
+                     getProperty("debug.sf.early_app_phase_offset_ns"),
+                     getProperty("debug.sf.early_gl_app_phase_offset_ns"),
+                     getProperty("debug.sf.high_fps_late_app_phase_offset_ns").value_or(2000000),
+                     getProperty("debug.sf.high_fps_late_sf_phase_offset_ns").value_or(1000000),
+                     getProperty("debug.sf.high_fps_early_phase_offset_ns"),
+                     getProperty("debug.sf.high_fps_early_gl_phase_offset_ns"),
+                     getProperty("debug.sf.high_fps_early_app_phase_offset_ns"),
+                     getProperty("debug.sf.high_fps_early_gl_app_phase_offset_ns"),
+                     // Below defines the threshold when an offset is considered to be negative,
+                     // i.e. targeting for the N+2 vsync instead of N+1. This means that: For offset
+                     // < threshold, SF wake up (vsync_duration - offset) before HW vsync. For
+                     // 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())) {}
+
+PhaseOffsets::PhaseOffsets(
+        const std::vector<float>& refreshRates, float currentFps, nsecs_t vsyncPhaseOffsetNs,
+        nsecs_t sfVSyncPhaseOffsetNs, std::optional<nsecs_t> earlySfOffsetNs,
+        std::optional<nsecs_t> earlyGpuSfOffsetNs, std::optional<nsecs_t> earlyAppOffsetNs,
+        std::optional<nsecs_t> earlyGpuAppOffsetNs, nsecs_t highFpsVsyncPhaseOffsetNs,
+        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)
+      : VsyncConfiguration(currentFps),
+        mVSyncPhaseOffsetNs(vsyncPhaseOffsetNs),
+        mSfVSyncPhaseOffsetNs(sfVSyncPhaseOffsetNs),
+        mEarlySfOffsetNs(earlySfOffsetNs),
+        mEarlyGpuSfOffsetNs(earlyGpuSfOffsetNs),
+        mEarlyAppOffsetNs(earlyAppOffsetNs),
+        mEarlyGpuAppOffsetNs(earlyGpuAppOffsetNs),
+        mHighFpsVSyncPhaseOffsetNs(highFpsVsyncPhaseOffsetNs),
+        mHighFpsSfVSyncPhaseOffsetNs(highFpsSfVSyncPhaseOffsetNs),
+        mHighFpsEarlySfOffsetNs(highFpsEarlySfOffsetNs),
+        mHighFpsEarlyGpuSfOffsetNs(highFpsEarlyGpuSfOffsetNs),
+        mHighFpsEarlyAppOffsetNs(highFpsEarlyAppOffsetNs),
+        mHighFpsEarlyGpuAppOffsetNs(highFpsEarlyGpuAppOffsetNs),
+        mThresholdForNextVsync(thresholdForNextVsync) {
+    initializeOffsets(refreshRates);
+}
+
+PhaseOffsets::VsyncConfigSet PhaseOffsets::constructOffsets(nsecs_t vsyncDuration) const {
+    if (vsyncDuration < std::chrono::nanoseconds(15ms).count()) {
+        return getHighFpsOffsets(vsyncDuration);
+    } else {
+        return getDefaultOffsets(vsyncDuration);
+    }
+}
+
+namespace {
+std::chrono::nanoseconds sfOffsetToDuration(nsecs_t sfOffset, nsecs_t vsyncDuration) {
+    return std::chrono::nanoseconds(vsyncDuration - sfOffset);
+}
+
+std::chrono::nanoseconds appOffsetToDuration(nsecs_t appOffset, nsecs_t sfOffset,
+                                             nsecs_t vsyncDuration) {
+    auto duration = vsyncDuration + (sfOffset - appOffset);
+    if (duration < vsyncDuration) {
+        duration += vsyncDuration;
+    }
+
+    return std::chrono::nanoseconds(duration);
+}
+} // namespace
+
+PhaseOffsets::VsyncConfigSet PhaseOffsets::getDefaultOffsets(nsecs_t vsyncDuration) const {
+    const auto earlySfOffset =
+            mEarlySfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) < mThresholdForNextVsync
+
+            ? mEarlySfOffsetNs.value_or(mSfVSyncPhaseOffsetNs)
+            : mEarlySfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) - vsyncDuration;
+    const auto earlyAppOffset = mEarlyAppOffsetNs.value_or(mVSyncPhaseOffsetNs);
+    const auto earlyGpuSfOffset =
+            mEarlyGpuSfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) < mThresholdForNextVsync
+
+            ? mEarlyGpuSfOffsetNs.value_or(mSfVSyncPhaseOffsetNs)
+            : mEarlyGpuSfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) - vsyncDuration;
+    const auto earlyGpuAppOffset = mEarlyGpuAppOffsetNs.value_or(mVSyncPhaseOffsetNs);
+    const auto lateSfOffset = mSfVSyncPhaseOffsetNs < mThresholdForNextVsync
+            ? mSfVSyncPhaseOffsetNs
+            : mSfVSyncPhaseOffsetNs - vsyncDuration;
+    const auto lateAppOffset = mVSyncPhaseOffsetNs;
+
+    return {
+            .early = {.sfOffset = earlySfOffset,
+                      .appOffset = earlyAppOffset,
+                      .sfWorkDuration = sfOffsetToDuration(earlySfOffset, vsyncDuration),
+                      .appWorkDuration =
+                              appOffsetToDuration(earlyAppOffset, earlySfOffset, vsyncDuration)},
+            .earlyGpu = {.sfOffset = earlyGpuSfOffset,
+                         .appOffset = earlyGpuAppOffset,
+                         .sfWorkDuration = sfOffsetToDuration(earlyGpuSfOffset, vsyncDuration),
+                         .appWorkDuration = appOffsetToDuration(earlyGpuAppOffset, earlyGpuSfOffset,
+                                                                vsyncDuration)},
+            .late = {.sfOffset = lateSfOffset,
+                     .appOffset = lateAppOffset,
+                     .sfWorkDuration = sfOffsetToDuration(lateSfOffset, vsyncDuration),
+                     .appWorkDuration =
+                             appOffsetToDuration(lateAppOffset, lateSfOffset, vsyncDuration)},
+    };
+}
+
+PhaseOffsets::VsyncConfigSet PhaseOffsets::getHighFpsOffsets(nsecs_t vsyncDuration) const {
+    const auto earlySfOffset =
+            mHighFpsEarlySfOffsetNs.value_or(mHighFpsSfVSyncPhaseOffsetNs) < mThresholdForNextVsync
+            ? mHighFpsEarlySfOffsetNs.value_or(mHighFpsSfVSyncPhaseOffsetNs)
+            : mHighFpsEarlySfOffsetNs.value_or(mHighFpsSfVSyncPhaseOffsetNs) - vsyncDuration;
+    const auto earlyAppOffset = mHighFpsEarlyAppOffsetNs.value_or(mHighFpsVSyncPhaseOffsetNs);
+    const auto earlyGpuSfOffset = mHighFpsEarlyGpuSfOffsetNs.value_or(
+                                          mHighFpsSfVSyncPhaseOffsetNs) < mThresholdForNextVsync
+
+            ? mHighFpsEarlyGpuSfOffsetNs.value_or(mHighFpsSfVSyncPhaseOffsetNs)
+            : mHighFpsEarlyGpuSfOffsetNs.value_or(mHighFpsSfVSyncPhaseOffsetNs) - vsyncDuration;
+    const auto earlyGpuAppOffset = mHighFpsEarlyGpuAppOffsetNs.value_or(mHighFpsVSyncPhaseOffsetNs);
+    const auto lateSfOffset = mHighFpsSfVSyncPhaseOffsetNs < mThresholdForNextVsync
+            ? mHighFpsSfVSyncPhaseOffsetNs
+            : mHighFpsSfVSyncPhaseOffsetNs - vsyncDuration;
+    const auto lateAppOffset = mHighFpsVSyncPhaseOffsetNs;
+
+    return {
+            .early =
+                    {
+                            .sfOffset = earlySfOffset,
+                            .appOffset = earlyAppOffset,
+                            .sfWorkDuration = sfOffsetToDuration(earlySfOffset, vsyncDuration),
+                            .appWorkDuration = appOffsetToDuration(earlyAppOffset, earlySfOffset,
+                                                                   vsyncDuration),
+                    },
+            .earlyGpu =
+                    {
+                            .sfOffset = earlyGpuSfOffset,
+                            .appOffset = earlyGpuAppOffset,
+                            .sfWorkDuration = sfOffsetToDuration(earlyGpuSfOffset, vsyncDuration),
+                            .appWorkDuration = appOffsetToDuration(earlyGpuAppOffset,
+                                                                   earlyGpuSfOffset, vsyncDuration),
+                    },
+            .late =
+                    {
+                            .sfOffset = lateSfOffset,
+                            .appOffset = lateAppOffset,
+                            .sfWorkDuration = sfOffsetToDuration(lateSfOffset, vsyncDuration),
+                            .appWorkDuration =
+                                    appOffsetToDuration(lateAppOffset, lateSfOffset, vsyncDuration),
+                    },
+    };
 }
 
 static void validateSysprops() {
@@ -236,123 +291,105 @@
     validateProperty("debug.sf.high_fps_early_gl_app_phase_offset_ns");
 }
 
-static nsecs_t sfDurationToOffset(nsecs_t sfDuration, nsecs_t vsyncDuration) {
-    return sfDuration == -1 ? 1'000'000 : vsyncDuration - sfDuration % vsyncDuration;
+namespace {
+nsecs_t sfDurationToOffset(std::chrono::nanoseconds sfDuration, nsecs_t vsyncDuration) {
+    return vsyncDuration - sfDuration.count() % vsyncDuration;
 }
 
-static nsecs_t appDurationToOffset(nsecs_t appDuration, nsecs_t sfDuration, nsecs_t vsyncDuration) {
-    return sfDuration == -1 ? 1'000'000
-                            : vsyncDuration - (appDuration + sfDuration) % vsyncDuration;
+nsecs_t appDurationToOffset(std::chrono::nanoseconds appDuration,
+                            std::chrono::nanoseconds sfDuration, nsecs_t vsyncDuration) {
+    return vsyncDuration - (appDuration + sfDuration).count() % vsyncDuration;
 }
+} // namespace
 
-PhaseDurations::Offsets PhaseDurations::constructOffsets(nsecs_t vsyncDuration) const {
-    return Offsets{
-            {
-                    mSfEarlyDuration < vsyncDuration
-                            ? sfDurationToOffset(mSfEarlyDuration, vsyncDuration)
-                            : sfDurationToOffset(mSfEarlyDuration, vsyncDuration) - vsyncDuration,
+WorkDuration::VsyncConfigSet WorkDuration::constructOffsets(nsecs_t vsyncDuration) const {
+    const auto sfDurationFixup = [vsyncDuration](nsecs_t duration) {
+        return duration == -1 ? std::chrono::nanoseconds(vsyncDuration) - 1ms
+                              : std::chrono::nanoseconds(duration);
+    };
 
-                    appDurationToOffset(mAppEarlyDuration, mSfEarlyDuration, vsyncDuration),
-            },
-            {
-                    mSfEarlyGlDuration < vsyncDuration
-                            ? sfDurationToOffset(mSfEarlyGlDuration, vsyncDuration)
-                            : sfDurationToOffset(mSfEarlyGlDuration, vsyncDuration) - vsyncDuration,
+    const auto appDurationFixup = [vsyncDuration](nsecs_t duration) {
+        return duration == -1 ? std::chrono::nanoseconds(vsyncDuration)
+                              : std::chrono::nanoseconds(duration);
+    };
 
-                    appDurationToOffset(mAppEarlyGlDuration, mSfEarlyGlDuration, vsyncDuration),
-            },
-            {
-                    mSfDuration < vsyncDuration
-                            ? sfDurationToOffset(mSfDuration, vsyncDuration)
-                            : sfDurationToOffset(mSfDuration, vsyncDuration) - vsyncDuration,
+    const auto sfEarlyDuration = sfDurationFixup(mSfEarlyDuration);
+    const auto appEarlyDuration = appDurationFixup(mAppEarlyDuration);
+    const auto sfEarlyGpuDuration = sfDurationFixup(mSfEarlyGpuDuration);
+    const auto appEarlyGpuDuration = appDurationFixup(mAppEarlyGpuDuration);
+    const auto sfDuration = sfDurationFixup(mSfDuration);
+    const auto appDuration = appDurationFixup(mAppDuration);
 
-                    appDurationToOffset(mAppDuration, mSfDuration, vsyncDuration),
-            },
+    return {
+            .early =
+                    {
+
+                            .sfOffset = sfEarlyDuration.count() < vsyncDuration
+                                    ? sfDurationToOffset(sfEarlyDuration, vsyncDuration)
+                                    : sfDurationToOffset(sfEarlyDuration, vsyncDuration) -
+                                            vsyncDuration,
+
+                            .appOffset = appDurationToOffset(appEarlyDuration, sfEarlyDuration,
+                                                             vsyncDuration),
+
+                            .sfWorkDuration = sfEarlyDuration,
+                            .appWorkDuration = appEarlyDuration,
+                    },
+            .earlyGpu =
+                    {
+
+                            .sfOffset = sfEarlyGpuDuration.count() < vsyncDuration
+
+                                    ? sfDurationToOffset(sfEarlyGpuDuration, vsyncDuration)
+                                    : sfDurationToOffset(sfEarlyGpuDuration, vsyncDuration) -
+                                            vsyncDuration,
+
+                            .appOffset = appDurationToOffset(appEarlyGpuDuration,
+                                                             sfEarlyGpuDuration, vsyncDuration),
+                            .sfWorkDuration = sfEarlyGpuDuration,
+                            .appWorkDuration = appEarlyGpuDuration,
+                    },
+            .late =
+                    {
+
+                            .sfOffset = sfDuration.count() < vsyncDuration
+
+                                    ? sfDurationToOffset(sfDuration, vsyncDuration)
+                                    : sfDurationToOffset(sfDuration, vsyncDuration) - vsyncDuration,
+
+                            .appOffset =
+                                    appDurationToOffset(appDuration, sfDuration, vsyncDuration),
+
+                            .sfWorkDuration = sfDuration,
+                            .appWorkDuration = appDuration,
+                    },
     };
 }
 
-std::unordered_map<float, PhaseDurations::Offsets> PhaseDurations::initializeOffsets(
-        const std::vector<float>& refreshRates) const {
-    std::unordered_map<float, Offsets> offsets;
-
-    for (const auto fps : refreshRates) {
-        offsets.emplace(fps, constructOffsets(static_cast<nsecs_t>(1e9f / fps)));
-    }
-    return offsets;
-}
-
-PhaseDurations::PhaseDurations(const scheduler::RefreshRateConfigs& refreshRateConfigs)
-      : PhaseDurations(getRefreshRatesFromConfigs(refreshRateConfigs),
-                       refreshRateConfigs.getCurrentRefreshRate().getFps(),
-                       getProperty("debug.sf.late.sf.duration").value_or(-1),
-                       getProperty("debug.sf.late.app.duration").value_or(-1),
-                       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)) {
+WorkDuration::WorkDuration(const scheduler::RefreshRateConfigs& refreshRateConfigs)
+      : WorkDuration(getRefreshRatesFromConfigs(refreshRateConfigs),
+                     refreshRateConfigs.getCurrentRefreshRate().getFps(),
+                     getProperty("debug.sf.late.sf.duration").value_or(-1),
+                     getProperty("debug.sf.late.app.duration").value_or(-1),
+                     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)) {
     validateSysprops();
 }
 
-PhaseDurations::PhaseDurations(const std::vector<float>& refreshRates, float currentFps,
-                               nsecs_t sfDuration, nsecs_t appDuration, nsecs_t sfEarlyDuration,
-                               nsecs_t appEarlyDuration, nsecs_t sfEarlyGlDuration,
-                               nsecs_t appEarlyGlDuration)
-      : mSfDuration(sfDuration),
+WorkDuration::WorkDuration(const std::vector<float>& refreshRates, float currentFps,
+                           nsecs_t sfDuration, nsecs_t appDuration, nsecs_t sfEarlyDuration,
+                           nsecs_t appEarlyDuration, nsecs_t sfEarlyGpuDuration,
+                           nsecs_t appEarlyGpuDuration)
+      : VsyncConfiguration(currentFps),
+        mSfDuration(sfDuration),
         mAppDuration(appDuration),
         mSfEarlyDuration(sfEarlyDuration),
         mAppEarlyDuration(appEarlyDuration),
-        mSfEarlyGlDuration(sfEarlyGlDuration),
-        mAppEarlyGlDuration(appEarlyGlDuration),
-        mOffsets(initializeOffsets(refreshRates)),
-        mRefreshRateFps(currentFps) {}
-
-PhaseOffsets::Offsets PhaseDurations::getOffsetsForRefreshRate(float fps) const {
-    const auto iter = std::find_if(mOffsets.begin(), mOffsets.end(), [=](const auto& candidateFps) {
-        return fpsEqualsWithMargin(fps, candidateFps.first);
-    });
-
-    if (iter != mOffsets.end()) {
-        return iter->second;
-    }
-
-    // Unknown refresh rate. This might happen if we get a hotplug event for an external display.
-    // In this case just construct the offset.
-    ALOGW("Can't find offset for %.2f fps", fps);
-    return constructOffsets(static_cast<nsecs_t>(1e9f / fps));
+        mSfEarlyGpuDuration(sfEarlyGpuDuration),
+        mAppEarlyGpuDuration(appEarlyGpuDuration) {
+    initializeOffsets(refreshRates);
 }
 
-void PhaseDurations::dump(std::string& result) const {
-    const auto [early, earlyGl, late] = getCurrentOffsets();
-    using base::StringAppendF;
-    StringAppendF(&result,
-                  "           app phase:    %9" PRId64 " ns\t         SF phase:    %9" PRId64
-                  " ns\n"
-                  "           app duration: %9" PRId64 " ns\t         SF duration: %9" PRId64
-                  " ns\n"
-                  "     early app phase:    %9" PRId64 " ns\t   early SF phase:    %9" PRId64
-                  " ns\n"
-                  "     early app duration: %9" PRId64 " ns\t   early SF duration: %9" PRId64
-                  " ns\n"
-                  "  GL early app phase:    %9" PRId64 " ns\tGL early SF phase:    %9" PRId64
-                  " ns\n"
-                  "  GL early app duration: %9" PRId64 " ns\tGL early SF duration: %9" PRId64
-                  " ns\n",
-                  late.app,
-
-                  late.sf,
-
-                  mAppDuration, mSfDuration,
-
-                  early.app, early.sf,
-
-                  mAppEarlyDuration, mSfEarlyDuration,
-
-                  earlyGl.app,
-
-                  earlyGl.sf,
-
-                  mAppEarlyGlDuration, mSfEarlyGlDuration);
-}
-
-} // namespace impl
-} // namespace android::scheduler
+} // namespace android::scheduler::impl
diff --git a/services/surfaceflinger/Scheduler/VsyncConfiguration.h b/services/surfaceflinger/Scheduler/VsyncConfiguration.h
index 0ae9fef..c27a25d 100644
--- a/services/surfaceflinger/Scheduler/VsyncConfiguration.h
+++ b/services/surfaceflinger/Scheduler/VsyncConfiguration.h
@@ -24,19 +24,18 @@
 namespace android::scheduler {
 
 /*
- * This class encapsulates offsets for different refresh rates. Depending
+ * This class encapsulates vsync configurations for different refresh rates. Depending
  * on what refresh rate we are using, and wheter we are composing in GL,
  * different offsets will help us with latency. This class keeps track of
  * which mode the device is on, and returns approprate offsets when needed.
  */
-class PhaseConfiguration {
+class VsyncConfiguration {
 public:
-    using Offsets = VsyncModulator::OffsetsConfig;
+    using VsyncConfigSet = VsyncModulator::VsyncConfigSet;
 
-    virtual ~PhaseConfiguration();
-
-    virtual Offsets getCurrentOffsets() const = 0;
-    virtual Offsets getOffsetsForRefreshRate(float fps) const = 0;
+    virtual ~VsyncConfiguration() = default;
+    virtual VsyncConfigSet getCurrentConfigs() const = 0;
+    virtual VsyncConfigSet getConfigsForRefreshRate(float fps) const = 0;
 
     virtual void setRefreshRateFps(float fps) = 0;
 
@@ -46,18 +45,21 @@
 namespace impl {
 
 /*
- * This is the old implementation of phase offsets and considered as deprecated.
- * PhaseDurations is the new implementation.
+ * This is a common implementation for both phase offsets and durations.
+ * PhaseOffsets and WorkDuration derive from this class and implement the
+ * constructOffsets method
  */
-class PhaseOffsets : public scheduler::PhaseConfiguration {
+class VsyncConfiguration : public scheduler::VsyncConfiguration {
 public:
-    PhaseOffsets(const scheduler::RefreshRateConfigs&);
+    explicit VsyncConfiguration(float currentFps);
 
     // Returns early, early GL, and late offsets for Apps and SF for a given refresh rate.
-    Offsets getOffsetsForRefreshRate(float fps) const override;
+    VsyncConfigSet getConfigsForRefreshRate(float fps) const override;
 
     // Returns early, early GL, and late offsets for Apps and SF.
-    Offsets getCurrentOffsets() const override { return getOffsetsForRefreshRate(mRefreshRateFps); }
+    VsyncConfigSet getCurrentConfigs() const override {
+        return getConfigsForRefreshRate(mRefreshRateFps);
+    }
 
     // This function should be called when the device is switching between different
     // refresh rates, to properly update the offsets.
@@ -67,61 +69,73 @@
     void dump(std::string& result) const override;
 
 protected:
+    void initializeOffsets(const std::vector<float>& refreshRates);
+    virtual VsyncConfiguration::VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const = 0;
+
+    std::unordered_map<float, VsyncConfigSet> mOffsets;
+    std::atomic<float> mRefreshRateFps;
+};
+
+/*
+ * This is the old implementation of phase offsets and considered as deprecated.
+ * WorkDuration is the new implementation.
+ */
+class PhaseOffsets : public VsyncConfiguration {
+public:
+    explicit PhaseOffsets(const scheduler::RefreshRateConfigs&);
+
+protected:
     // Used for unit tests
     PhaseOffsets(const std::vector<float>& refreshRates, float currentFps,
                  nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs,
-                 std::optional<nsecs_t> earlySfOffsetNs, std::optional<nsecs_t> earlyGlSfOffsetNs,
-                 std::optional<nsecs_t> earlyAppOffsetNs, std::optional<nsecs_t> earlyGlAppOffsetNs,
-                 nsecs_t thresholdForNextVsync);
-    std::unordered_map<float, Offsets> initializeOffsets(
-            const std::vector<float>& refreshRates) const;
-    Offsets getDefaultOffsets(nsecs_t vsyncPeriod) const;
-    Offsets getHighFpsOffsets(nsecs_t vsyncPeriod) const;
-    Offsets getPhaseOffsets(float fps, nsecs_t vsyncPeriod) const;
+                 std::optional<nsecs_t> earlySfOffsetNs, std::optional<nsecs_t> earlyGpuSfOffsetNs,
+                 std::optional<nsecs_t> earlyAppOffsetNs,
+                 std::optional<nsecs_t> earlyGpuAppOffsetNs, nsecs_t highFpsVsyncPhaseOffsetNs,
+                 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);
+
+private:
+    VsyncConfiguration::VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const override;
+
+    VsyncConfigSet getDefaultOffsets(nsecs_t vsyncPeriod) const;
+    VsyncConfigSet getHighFpsOffsets(nsecs_t vsyncPeriod) const;
 
     const nsecs_t mVSyncPhaseOffsetNs;
     const nsecs_t mSfVSyncPhaseOffsetNs;
     const std::optional<nsecs_t> mEarlySfOffsetNs;
-    const std::optional<nsecs_t> mEarlyGlSfOffsetNs;
+    const std::optional<nsecs_t> mEarlyGpuSfOffsetNs;
     const std::optional<nsecs_t> mEarlyAppOffsetNs;
-    const std::optional<nsecs_t> mEarlyGlAppOffsetNs;
-    const nsecs_t mThresholdForNextVsync;
-    const std::unordered_map<float, Offsets> mOffsets;
+    const std::optional<nsecs_t> mEarlyGpuAppOffsetNs;
 
-    std::atomic<float> mRefreshRateFps;
+    const nsecs_t mHighFpsVSyncPhaseOffsetNs;
+    const nsecs_t mHighFpsSfVSyncPhaseOffsetNs;
+    const std::optional<nsecs_t> mHighFpsEarlySfOffsetNs;
+    const std::optional<nsecs_t> mHighFpsEarlyGpuSfOffsetNs;
+    const std::optional<nsecs_t> mHighFpsEarlyAppOffsetNs;
+    const std::optional<nsecs_t> mHighFpsEarlyGpuAppOffsetNs;
+
+    const nsecs_t mThresholdForNextVsync;
 };
 
 /*
  * Class that encapsulates the phase offsets for SurfaceFlinger and App.
- * The offsets are calculated from durations for each one of the (late, early, earlyGL)
+ * The offsets are calculated from durations for each one of the (late, early, earlyGpu)
  * offset types.
  */
-class PhaseDurations : public scheduler::PhaseConfiguration {
+class WorkDuration : public VsyncConfiguration {
 public:
-    PhaseDurations(const scheduler::RefreshRateConfigs&);
-
-    // Returns early, early GL, and late offsets for Apps and SF for a given refresh rate.
-    Offsets getOffsetsForRefreshRate(float fps) const override;
-
-    // Returns early, early GL, and late offsets for Apps and SF.
-    Offsets getCurrentOffsets() const override { return getOffsetsForRefreshRate(mRefreshRateFps); }
-
-    // This function should be called when the device is switching between different
-    // refresh rates, to properly update the offsets.
-    void setRefreshRateFps(float fps) override { mRefreshRateFps = fps; }
-
-    // Returns current offsets in human friendly format.
-    void dump(std::string& result) const override;
+    explicit WorkDuration(const scheduler::RefreshRateConfigs&);
 
 protected:
     // Used for unit tests
-    PhaseDurations(const std::vector<float>& refreshRates, float currentFps, nsecs_t sfDuration,
-                   nsecs_t appDuration, nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration,
-                   nsecs_t sfEarlyGlDuration, nsecs_t appEarlyGlDuration);
+    WorkDuration(const std::vector<float>& refreshRates, float currentFps, nsecs_t sfDuration,
+                 nsecs_t appDuration, nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration,
+                 nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration);
 
 private:
-    std::unordered_map<float, Offsets> initializeOffsets(const std::vector<float>&) const;
-    PhaseDurations::Offsets constructOffsets(nsecs_t vsyncDuration) const;
+    VsyncConfiguration::VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const override;
 
     const nsecs_t mSfDuration;
     const nsecs_t mAppDuration;
@@ -129,12 +143,8 @@
     const nsecs_t mSfEarlyDuration;
     const nsecs_t mAppEarlyDuration;
 
-    const nsecs_t mSfEarlyGlDuration;
-    const nsecs_t mAppEarlyGlDuration;
-
-    const std::unordered_map<float, Offsets> mOffsets;
-
-    std::atomic<float> mRefreshRateFps;
+    const nsecs_t mSfEarlyGpuDuration;
+    const nsecs_t mAppEarlyGpuDuration;
 };
 
 } // namespace impl
diff --git a/services/surfaceflinger/Scheduler/VsyncModulator.cpp b/services/surfaceflinger/Scheduler/VsyncModulator.cpp
index 7a1b7e4..1f821be 100644
--- a/services/surfaceflinger/Scheduler/VsyncModulator.cpp
+++ b/services/surfaceflinger/Scheduler/VsyncModulator.cpp
@@ -35,18 +35,19 @@
 
 const std::chrono::nanoseconds VsyncModulator::MIN_EARLY_TRANSACTION_TIME = 1ms;
 
-VsyncModulator::VsyncModulator(const OffsetsConfig& config, Now now)
-      : mOffsetsConfig(config),
+VsyncModulator::VsyncModulator(const VsyncConfigSet& config, Now now)
+      : mVsyncConfigSet(config),
         mNow(now),
         mTraceDetailedInfo(base::GetBoolProperty("debug.sf.vsync_trace_detailed_info", false)) {}
 
-VsyncModulator::Offsets VsyncModulator::setPhaseOffsets(const OffsetsConfig& config) {
+VsyncModulator::VsyncConfig VsyncModulator::setVsyncConfigSet(const VsyncConfigSet& config) {
     std::lock_guard<std::mutex> lock(mMutex);
-    mOffsetsConfig = config;
-    return updateOffsetsLocked();
+    mVsyncConfigSet = config;
+    return updateVsyncConfigLocked();
 }
 
-VsyncModulator::OffsetsOpt VsyncModulator::setTransactionSchedule(TransactionSchedule schedule) {
+VsyncModulator::VsyncConfigOpt VsyncModulator::setTransactionSchedule(
+        TransactionSchedule schedule) {
     switch (schedule) {
         case Schedule::EarlyStart:
             ALOGW_IF(mExplicitEarlyWakeup, "%s: Duplicate EarlyStart", __FUNCTION__);
@@ -76,29 +77,29 @@
         return std::nullopt;
     }
     mTransactionSchedule = schedule;
-    return updateOffsets();
+    return updateVsyncConfig();
 }
 
-VsyncModulator::OffsetsOpt VsyncModulator::onTransactionCommit() {
+VsyncModulator::VsyncConfigOpt VsyncModulator::onTransactionCommit() {
     mLastTransactionCommitTime = mNow();
     if (mTransactionSchedule == Schedule::Late) return std::nullopt;
     mTransactionSchedule = Schedule::Late;
-    return updateOffsets();
+    return updateVsyncConfig();
 }
 
-VsyncModulator::OffsetsOpt VsyncModulator::onRefreshRateChangeInitiated() {
+VsyncModulator::VsyncConfigOpt VsyncModulator::onRefreshRateChangeInitiated() {
     if (mRefreshRateChangePending) return std::nullopt;
     mRefreshRateChangePending = true;
-    return updateOffsets();
+    return updateVsyncConfig();
 }
 
-VsyncModulator::OffsetsOpt VsyncModulator::onRefreshRateChangeCompleted() {
+VsyncModulator::VsyncConfigOpt VsyncModulator::onRefreshRateChangeCompleted() {
     if (!mRefreshRateChangePending) return std::nullopt;
     mRefreshRateChangePending = false;
-    return updateOffsets();
+    return updateVsyncConfig();
 }
 
-VsyncModulator::OffsetsOpt VsyncModulator::onDisplayRefresh(bool usedGpuComposition) {
+VsyncModulator::VsyncConfigOpt VsyncModulator::onDisplayRefresh(bool usedGpuComposition) {
     bool updateOffsetsNeeded = false;
 
     if (mEarlyTransactionStartTime.load() + MIN_EARLY_TRANSACTION_TIME <=
@@ -117,40 +118,40 @@
     }
 
     if (!updateOffsetsNeeded) return std::nullopt;
-    return updateOffsets();
+    return updateVsyncConfig();
 }
 
-VsyncModulator::Offsets VsyncModulator::getOffsets() const {
+VsyncModulator::VsyncConfig VsyncModulator::getVsyncConfig() const {
     std::lock_guard<std::mutex> lock(mMutex);
-    return mOffsets;
+    return mVsyncConfig;
 }
 
-const VsyncModulator::Offsets& VsyncModulator::getNextOffsets() const {
+const VsyncModulator::VsyncConfig& VsyncModulator::getNextVsyncConfig() const {
     // Early offsets are used if we're in the middle of a refresh rate
     // change, or if we recently begin a transaction.
     if (mExplicitEarlyWakeup || mTransactionSchedule == Schedule::EarlyEnd ||
         mEarlyTransactionFrames > 0 || mRefreshRateChangePending) {
-        return mOffsetsConfig.early;
+        return mVsyncConfigSet.early;
     } else if (mEarlyGpuFrames > 0) {
-        return mOffsetsConfig.earlyGpu;
+        return mVsyncConfigSet.earlyGpu;
     } else {
-        return mOffsetsConfig.late;
+        return mVsyncConfigSet.late;
     }
 }
 
-VsyncModulator::Offsets VsyncModulator::updateOffsets() {
+VsyncModulator::VsyncConfig VsyncModulator::updateVsyncConfig() {
     std::lock_guard<std::mutex> lock(mMutex);
-    return updateOffsetsLocked();
+    return updateVsyncConfigLocked();
 }
 
-VsyncModulator::Offsets VsyncModulator::updateOffsetsLocked() {
-    const Offsets& offsets = getNextOffsets();
-    mOffsets = offsets;
+VsyncModulator::VsyncConfig VsyncModulator::updateVsyncConfigLocked() {
+    const VsyncConfig& offsets = getNextVsyncConfig();
+    mVsyncConfig = offsets;
 
     if (mTraceDetailedInfo) {
-        const bool isEarly = &offsets == &mOffsetsConfig.early;
-        const bool isEarlyGpu = &offsets == &mOffsetsConfig.earlyGpu;
-        const bool isLate = &offsets == &mOffsetsConfig.late;
+        const bool isEarly = &offsets == &mVsyncConfigSet.early;
+        const bool isEarlyGpu = &offsets == &mVsyncConfigSet.earlyGpu;
+        const bool isLate = &offsets == &mVsyncConfigSet.late;
 
         ATRACE_INT("Vsync-EarlyOffsetsOn", isEarly);
         ATRACE_INT("Vsync-EarlyGpuOffsetsOn", isEarlyGpu);
diff --git a/services/surfaceflinger/Scheduler/VsyncModulator.h b/services/surfaceflinger/Scheduler/VsyncModulator.h
index f920bd2..355a14a 100644
--- a/services/surfaceflinger/Scheduler/VsyncModulator.h
+++ b/services/surfaceflinger/Scheduler/VsyncModulator.h
@@ -48,62 +48,69 @@
     // This may keep early offsets for an extra frame, but avoids a race with transaction commit.
     static const std::chrono::nanoseconds MIN_EARLY_TRANSACTION_TIME;
 
-    // Phase offsets for SF and app deadlines from VSYNC.
-    struct Offsets {
-        nsecs_t sf;
-        nsecs_t app;
+    // Phase offsets and work durations for SF and app deadlines from VSYNC.
+    struct VsyncConfig {
+        nsecs_t sfOffset;
+        nsecs_t appOffset;
+        std::chrono::nanoseconds sfWorkDuration;
+        std::chrono::nanoseconds appWorkDuration;
 
-        bool operator==(const Offsets& other) const { return sf == other.sf && app == other.app; }
-        bool operator!=(const Offsets& other) const { return !(*this == other); }
+        bool operator==(const VsyncConfig& other) const {
+            return sfOffset == other.sfOffset && appOffset == other.appOffset &&
+                    sfWorkDuration == other.sfWorkDuration &&
+                    appWorkDuration == other.appWorkDuration;
+        }
+
+        bool operator!=(const VsyncConfig& other) const { return !(*this == other); }
     };
 
-    using OffsetsOpt = std::optional<Offsets>;
+    using VsyncConfigOpt = std::optional<VsyncConfig>;
 
-    struct OffsetsConfig {
-        Offsets early;    // Used for early transactions, and during refresh rate change.
-        Offsets earlyGpu; // Used during GPU composition.
-        Offsets late;     // Default.
+    struct VsyncConfigSet {
+        VsyncConfig early;    // Used for early transactions, and during refresh rate change.
+        VsyncConfig earlyGpu; // Used during GPU composition.
+        VsyncConfig late;     // Default.
 
-        bool operator==(const OffsetsConfig& other) const {
+        bool operator==(const VsyncConfigSet& other) const {
             return early == other.early && earlyGpu == other.earlyGpu && late == other.late;
         }
 
-        bool operator!=(const OffsetsConfig& other) const { return !(*this == other); }
+        bool operator!=(const VsyncConfigSet& other) const { return !(*this == other); }
     };
 
     using Clock = std::chrono::steady_clock;
     using TimePoint = Clock::time_point;
     using Now = TimePoint (*)();
 
-    explicit VsyncModulator(const OffsetsConfig&, Now = Clock::now);
+    explicit VsyncModulator(const VsyncConfigSet&, Now = Clock::now);
 
-    Offsets getOffsets() const EXCLUDES(mMutex);
+    VsyncConfig getVsyncConfig() const EXCLUDES(mMutex);
 
-    [[nodiscard]] Offsets setPhaseOffsets(const OffsetsConfig&) EXCLUDES(mMutex);
+    [[nodiscard]] VsyncConfig setVsyncConfigSet(const VsyncConfigSet&) EXCLUDES(mMutex);
 
     // Changes offsets in response to transaction flags or commit.
-    [[nodiscard]] OffsetsOpt setTransactionSchedule(TransactionSchedule);
-    [[nodiscard]] OffsetsOpt onTransactionCommit();
+    [[nodiscard]] VsyncConfigOpt setTransactionSchedule(TransactionSchedule);
+    [[nodiscard]] VsyncConfigOpt onTransactionCommit();
 
     // Called when we send a refresh rate change to hardware composer, so that
     // we can move into early offsets.
-    [[nodiscard]] OffsetsOpt onRefreshRateChangeInitiated();
+    [[nodiscard]] VsyncConfigOpt onRefreshRateChangeInitiated();
 
     // Called when we detect from VSYNC signals that the refresh rate changed.
     // This way we can move out of early offsets if no longer necessary.
-    [[nodiscard]] OffsetsOpt onRefreshRateChangeCompleted();
+    [[nodiscard]] VsyncConfigOpt onRefreshRateChangeCompleted();
 
-    [[nodiscard]] OffsetsOpt onDisplayRefresh(bool usedGpuComposition);
+    [[nodiscard]] VsyncConfigOpt onDisplayRefresh(bool usedGpuComposition);
 
 private:
-    const Offsets& getNextOffsets() const REQUIRES(mMutex);
-    [[nodiscard]] Offsets updateOffsets() EXCLUDES(mMutex);
-    [[nodiscard]] Offsets updateOffsetsLocked() REQUIRES(mMutex);
+    const VsyncConfig& getNextVsyncConfig() const REQUIRES(mMutex);
+    [[nodiscard]] VsyncConfig updateVsyncConfig() EXCLUDES(mMutex);
+    [[nodiscard]] VsyncConfig updateVsyncConfigLocked() REQUIRES(mMutex);
 
     mutable std::mutex mMutex;
-    OffsetsConfig mOffsetsConfig GUARDED_BY(mMutex);
+    VsyncConfigSet mVsyncConfigSet GUARDED_BY(mMutex);
 
-    Offsets mOffsets GUARDED_BY(mMutex){mOffsetsConfig.late};
+    VsyncConfig mVsyncConfig GUARDED_BY(mMutex){mVsyncConfigSet.late};
 
     using Schedule = TransactionSchedule;
     std::atomic<Schedule> mTransactionSchedule = Schedule::Late;