blob: 43e02979c1f90442dd8ee2e8a2e23152bd563568 [file] [log] [blame]
Ana Krulec757f63a2019-01-25 10:46:18 -08001/*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Ady Abrahamc581d3c2020-08-06 17:34:27 -070017#include "VsyncConfiguration.h"
Ana Krulec757f63a2019-01-25 10:46:18 -080018
Marin Shalamanov526c3382020-12-10 15:22:29 +010019#include <chrono>
20#include <cinttypes>
Dominik Laskowskieddeda12019-07-19 11:54:13 -070021#include <optional>
22
Marin Shalamanov526c3382020-12-10 15:22:29 +010023#include <cutils/properties.h>
24#include <log/log.h>
25
Ana Krulec757f63a2019-01-25 10:46:18 -080026#include "SurfaceFlingerProperties.h"
27
Dominik Laskowskieddeda12019-07-19 11:54:13 -070028namespace {
Ana Krulec757f63a2019-01-25 10:46:18 -080029
Marin Shalamanov526c3382020-12-10 15:22:29 +010030using namespace std::chrono_literals;
31
Dominik Laskowskif83570c2019-08-26 12:04:07 -070032std::optional<nsecs_t> getProperty(const char* name) {
Dominik Laskowskieddeda12019-07-19 11:54:13 -070033 char value[PROPERTY_VALUE_MAX];
34 property_get(name, value, "-1");
35 if (const int i = atoi(value); i != -1) return i;
36 return std::nullopt;
37}
Ana Krulec757f63a2019-01-25 10:46:18 -080038
Dominik Laskowskieddeda12019-07-19 11:54:13 -070039} // namespace
40
Ady Abraham8287e852020-08-12 14:44:58 -070041namespace android::scheduler::impl {
Dominik Laskowskieddeda12019-07-19 11:54:13 -070042
Marin Shalamanove8a663d2020-11-24 17:48:00 +010043VsyncConfiguration::VsyncConfiguration(Fps currentFps) : mRefreshRateFps(currentFps) {}
Ana Krulec757f63a2019-01-25 10:46:18 -080044
Marin Shalamanove8a663d2020-11-24 17:48:00 +010045PhaseOffsets::VsyncConfigSet VsyncConfiguration::getConfigsForRefreshRate(Fps fps) const {
Marin Shalamanov526c3382020-12-10 15:22:29 +010046 std::lock_guard lock(mLock);
47 return getConfigsForRefreshRateLocked(fps);
48}
Sushil Chauhanbdb9e6d2020-03-19 16:15:46 -070049
Marin Shalamanov526c3382020-12-10 15:22:29 +010050PhaseOffsets::VsyncConfigSet VsyncConfiguration::getConfigsForRefreshRateLocked(Fps fps) const {
51 const auto iter = mOffsetsCache.find(fps);
52 if (iter != mOffsetsCache.end()) {
Sushil Chauhanbdb9e6d2020-03-19 16:15:46 -070053 return iter->second;
54 }
55
Marin Shalamanov526c3382020-12-10 15:22:29 +010056 const auto offset = constructOffsets(fps.getPeriodNsecs());
57 mOffsetsCache[fps] = offset;
58 return offset;
Ady Abraham8287e852020-08-12 14:44:58 -070059}
60
61void VsyncConfiguration::dump(std::string& result) const {
Ady Abrahamcaba2982021-06-16 16:45:04 -070062 const auto [early, earlyGpu, late, hwcMinWorkDuration] = getCurrentConfigs();
Ady Abraham8287e852020-08-12 14:44:58 -070063 using base::StringAppendF;
64 StringAppendF(&result,
65 " app phase: %9" PRId64 " ns\t SF phase: %9" PRId64
66 " ns\n"
67 " app duration: %9lld ns\t SF duration: %9lld ns\n"
68 " early app phase: %9" PRId64 " ns\t early SF phase: %9" PRId64
69 " ns\n"
70 " early app duration: %9lld ns\t early SF duration: %9lld ns\n"
71 " GL early app phase: %9" PRId64 " ns\tGL early SF phase: %9" PRId64
72 " ns\n"
Ady Abrahamcaba2982021-06-16 16:45:04 -070073 " GL early app duration: %9lld ns\tGL early SF duration: %9lld ns\n"
74 " HWC min duration: %9lld ns\n",
Ady Abraham8287e852020-08-12 14:44:58 -070075 late.appOffset, late.sfOffset,
76
77 late.appWorkDuration.count(), late.sfWorkDuration.count(),
78
79 early.appOffset, early.sfOffset,
80
81 early.appWorkDuration.count(), early.sfWorkDuration.count(),
82
83 earlyGpu.appOffset, earlyGpu.sfOffset,
84
Ady Abrahamcaba2982021-06-16 16:45:04 -070085 earlyGpu.appWorkDuration.count(), earlyGpu.sfWorkDuration.count(),
86
87 hwcMinWorkDuration.count());
Ady Abraham8287e852020-08-12 14:44:58 -070088}
89
Marin Shalamanov526c3382020-12-10 15:22:29 +010090PhaseOffsets::PhaseOffsets(Fps currentRefreshRate)
91 : PhaseOffsets(currentRefreshRate, sysprop::vsync_event_phase_offset_ns(1000000),
Ady Abraham8287e852020-08-12 14:44:58 -070092 sysprop::vsync_sf_event_phase_offset_ns(1000000),
93 getProperty("debug.sf.early_phase_offset_ns"),
94 getProperty("debug.sf.early_gl_phase_offset_ns"),
95 getProperty("debug.sf.early_app_phase_offset_ns"),
96 getProperty("debug.sf.early_gl_app_phase_offset_ns"),
97 getProperty("debug.sf.high_fps_late_app_phase_offset_ns").value_or(2000000),
98 getProperty("debug.sf.high_fps_late_sf_phase_offset_ns").value_or(1000000),
99 getProperty("debug.sf.high_fps_early_phase_offset_ns"),
100 getProperty("debug.sf.high_fps_early_gl_phase_offset_ns"),
101 getProperty("debug.sf.high_fps_early_app_phase_offset_ns"),
102 getProperty("debug.sf.high_fps_early_gl_app_phase_offset_ns"),
103 // Below defines the threshold when an offset is considered to be negative,
104 // i.e. targeting for the N+2 vsync instead of N+1. This means that: For offset
105 // < threshold, SF wake up (vsync_duration - offset) before HW vsync. For
106 // offset >= threshold, SF wake up (2 * vsync_duration - offset) before HW
107 // vsync.
108 getProperty("debug.sf.phase_offset_threshold_for_next_vsync_ns")
Ady Abrahamcaba2982021-06-16 16:45:04 -0700109 .value_or(std::numeric_limits<nsecs_t>::max()),
110 getProperty("debug.sf.hwc.min.duration").value_or(0)) {}
Ady Abraham8287e852020-08-12 14:44:58 -0700111
Marin Shalamanov526c3382020-12-10 15:22:29 +0100112PhaseOffsets::PhaseOffsets(Fps currentFps, nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs,
113 std::optional<nsecs_t> earlySfOffsetNs,
114 std::optional<nsecs_t> earlyGpuSfOffsetNs,
115 std::optional<nsecs_t> earlyAppOffsetNs,
116 std::optional<nsecs_t> earlyGpuAppOffsetNs,
117 nsecs_t highFpsVsyncPhaseOffsetNs, nsecs_t highFpsSfVSyncPhaseOffsetNs,
118 std::optional<nsecs_t> highFpsEarlySfOffsetNs,
119 std::optional<nsecs_t> highFpsEarlyGpuSfOffsetNs,
120 std::optional<nsecs_t> highFpsEarlyAppOffsetNs,
121 std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs,
Ady Abrahamcaba2982021-06-16 16:45:04 -0700122 nsecs_t thresholdForNextVsync, nsecs_t hwcMinWorkDuration)
Ady Abraham8287e852020-08-12 14:44:58 -0700123 : VsyncConfiguration(currentFps),
124 mVSyncPhaseOffsetNs(vsyncPhaseOffsetNs),
125 mSfVSyncPhaseOffsetNs(sfVSyncPhaseOffsetNs),
126 mEarlySfOffsetNs(earlySfOffsetNs),
127 mEarlyGpuSfOffsetNs(earlyGpuSfOffsetNs),
128 mEarlyAppOffsetNs(earlyAppOffsetNs),
129 mEarlyGpuAppOffsetNs(earlyGpuAppOffsetNs),
130 mHighFpsVSyncPhaseOffsetNs(highFpsVsyncPhaseOffsetNs),
131 mHighFpsSfVSyncPhaseOffsetNs(highFpsSfVSyncPhaseOffsetNs),
132 mHighFpsEarlySfOffsetNs(highFpsEarlySfOffsetNs),
133 mHighFpsEarlyGpuSfOffsetNs(highFpsEarlyGpuSfOffsetNs),
134 mHighFpsEarlyAppOffsetNs(highFpsEarlyAppOffsetNs),
135 mHighFpsEarlyGpuAppOffsetNs(highFpsEarlyGpuAppOffsetNs),
Ady Abrahamcaba2982021-06-16 16:45:04 -0700136 mThresholdForNextVsync(thresholdForNextVsync),
137 mHwcMinWorkDuration(hwcMinWorkDuration) {}
Ady Abraham8287e852020-08-12 14:44:58 -0700138
139PhaseOffsets::VsyncConfigSet PhaseOffsets::constructOffsets(nsecs_t vsyncDuration) const {
140 if (vsyncDuration < std::chrono::nanoseconds(15ms).count()) {
141 return getHighFpsOffsets(vsyncDuration);
142 } else {
143 return getDefaultOffsets(vsyncDuration);
144 }
145}
146
147namespace {
148std::chrono::nanoseconds sfOffsetToDuration(nsecs_t sfOffset, nsecs_t vsyncDuration) {
149 return std::chrono::nanoseconds(vsyncDuration - sfOffset);
150}
151
152std::chrono::nanoseconds appOffsetToDuration(nsecs_t appOffset, nsecs_t sfOffset,
153 nsecs_t vsyncDuration) {
154 auto duration = vsyncDuration + (sfOffset - appOffset);
155 if (duration < vsyncDuration) {
156 duration += vsyncDuration;
157 }
158
159 return std::chrono::nanoseconds(duration);
160}
161} // namespace
162
163PhaseOffsets::VsyncConfigSet PhaseOffsets::getDefaultOffsets(nsecs_t vsyncDuration) const {
164 const auto earlySfOffset =
165 mEarlySfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) < mThresholdForNextVsync
166
167 ? mEarlySfOffsetNs.value_or(mSfVSyncPhaseOffsetNs)
168 : mEarlySfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) - vsyncDuration;
169 const auto earlyAppOffset = mEarlyAppOffsetNs.value_or(mVSyncPhaseOffsetNs);
170 const auto earlyGpuSfOffset =
171 mEarlyGpuSfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) < mThresholdForNextVsync
172
173 ? mEarlyGpuSfOffsetNs.value_or(mSfVSyncPhaseOffsetNs)
174 : mEarlyGpuSfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) - vsyncDuration;
175 const auto earlyGpuAppOffset = mEarlyGpuAppOffsetNs.value_or(mVSyncPhaseOffsetNs);
176 const auto lateSfOffset = mSfVSyncPhaseOffsetNs < mThresholdForNextVsync
177 ? mSfVSyncPhaseOffsetNs
178 : mSfVSyncPhaseOffsetNs - vsyncDuration;
179 const auto lateAppOffset = mVSyncPhaseOffsetNs;
180
181 return {
182 .early = {.sfOffset = earlySfOffset,
183 .appOffset = earlyAppOffset,
184 .sfWorkDuration = sfOffsetToDuration(earlySfOffset, vsyncDuration),
185 .appWorkDuration =
186 appOffsetToDuration(earlyAppOffset, earlySfOffset, vsyncDuration)},
187 .earlyGpu = {.sfOffset = earlyGpuSfOffset,
188 .appOffset = earlyGpuAppOffset,
189 .sfWorkDuration = sfOffsetToDuration(earlyGpuSfOffset, vsyncDuration),
190 .appWorkDuration = appOffsetToDuration(earlyGpuAppOffset, earlyGpuSfOffset,
191 vsyncDuration)},
192 .late = {.sfOffset = lateSfOffset,
193 .appOffset = lateAppOffset,
194 .sfWorkDuration = sfOffsetToDuration(lateSfOffset, vsyncDuration),
195 .appWorkDuration =
196 appOffsetToDuration(lateAppOffset, lateSfOffset, vsyncDuration)},
Ady Abrahamcaba2982021-06-16 16:45:04 -0700197 .hwcMinWorkDuration = std::chrono::nanoseconds(mHwcMinWorkDuration),
Ady Abraham8287e852020-08-12 14:44:58 -0700198 };
199}
200
201PhaseOffsets::VsyncConfigSet PhaseOffsets::getHighFpsOffsets(nsecs_t vsyncDuration) const {
202 const auto earlySfOffset =
203 mHighFpsEarlySfOffsetNs.value_or(mHighFpsSfVSyncPhaseOffsetNs) < mThresholdForNextVsync
204 ? mHighFpsEarlySfOffsetNs.value_or(mHighFpsSfVSyncPhaseOffsetNs)
205 : mHighFpsEarlySfOffsetNs.value_or(mHighFpsSfVSyncPhaseOffsetNs) - vsyncDuration;
206 const auto earlyAppOffset = mHighFpsEarlyAppOffsetNs.value_or(mHighFpsVSyncPhaseOffsetNs);
207 const auto earlyGpuSfOffset = mHighFpsEarlyGpuSfOffsetNs.value_or(
208 mHighFpsSfVSyncPhaseOffsetNs) < mThresholdForNextVsync
209
210 ? mHighFpsEarlyGpuSfOffsetNs.value_or(mHighFpsSfVSyncPhaseOffsetNs)
211 : mHighFpsEarlyGpuSfOffsetNs.value_or(mHighFpsSfVSyncPhaseOffsetNs) - vsyncDuration;
212 const auto earlyGpuAppOffset = mHighFpsEarlyGpuAppOffsetNs.value_or(mHighFpsVSyncPhaseOffsetNs);
213 const auto lateSfOffset = mHighFpsSfVSyncPhaseOffsetNs < mThresholdForNextVsync
214 ? mHighFpsSfVSyncPhaseOffsetNs
215 : mHighFpsSfVSyncPhaseOffsetNs - vsyncDuration;
216 const auto lateAppOffset = mHighFpsVSyncPhaseOffsetNs;
217
218 return {
219 .early =
220 {
221 .sfOffset = earlySfOffset,
222 .appOffset = earlyAppOffset,
223 .sfWorkDuration = sfOffsetToDuration(earlySfOffset, vsyncDuration),
224 .appWorkDuration = appOffsetToDuration(earlyAppOffset, earlySfOffset,
225 vsyncDuration),
226 },
227 .earlyGpu =
228 {
229 .sfOffset = earlyGpuSfOffset,
230 .appOffset = earlyGpuAppOffset,
231 .sfWorkDuration = sfOffsetToDuration(earlyGpuSfOffset, vsyncDuration),
232 .appWorkDuration = appOffsetToDuration(earlyGpuAppOffset,
233 earlyGpuSfOffset, vsyncDuration),
234 },
235 .late =
236 {
237 .sfOffset = lateSfOffset,
238 .appOffset = lateAppOffset,
239 .sfWorkDuration = sfOffsetToDuration(lateSfOffset, vsyncDuration),
240 .appWorkDuration =
241 appOffsetToDuration(lateAppOffset, lateSfOffset, vsyncDuration),
242 },
Ady Abrahamcaba2982021-06-16 16:45:04 -0700243 .hwcMinWorkDuration = std::chrono::nanoseconds(mHwcMinWorkDuration),
Ady Abraham8287e852020-08-12 14:44:58 -0700244 };
Ady Abraham090d42c2020-01-08 12:08:11 -0800245}
246
Ady Abraham9e16a482019-12-03 17:19:41 -0800247static void validateSysprops() {
248 const auto validatePropertyBool = [](const char* prop) {
249 LOG_ALWAYS_FATAL_IF(!property_get_bool(prop, false), "%s is false", prop);
250 };
251
252 validatePropertyBool("debug.sf.use_phase_offsets_as_durations");
253
254 LOG_ALWAYS_FATAL_IF(sysprop::vsync_event_phase_offset_ns(-1) != -1,
255 "ro.surface_flinger.vsync_event_phase_offset_ns is set but expecting "
256 "duration");
257
258 LOG_ALWAYS_FATAL_IF(sysprop::vsync_sf_event_phase_offset_ns(-1) != -1,
259 "ro.surface_flinger.vsync_sf_event_phase_offset_ns is set but expecting "
260 "duration");
261
262 const auto validateProperty = [](const char* prop) {
263 LOG_ALWAYS_FATAL_IF(getProperty(prop).has_value(),
264 "%s is set to %" PRId64 " but expecting duration", prop,
265 getProperty(prop).value_or(-1));
266 };
267
268 validateProperty("debug.sf.early_phase_offset_ns");
269 validateProperty("debug.sf.early_gl_phase_offset_ns");
270 validateProperty("debug.sf.early_app_phase_offset_ns");
271 validateProperty("debug.sf.early_gl_app_phase_offset_ns");
272 validateProperty("debug.sf.high_fps_late_app_phase_offset_ns");
273 validateProperty("debug.sf.high_fps_late_sf_phase_offset_ns");
274 validateProperty("debug.sf.high_fps_early_phase_offset_ns");
275 validateProperty("debug.sf.high_fps_early_gl_phase_offset_ns");
276 validateProperty("debug.sf.high_fps_early_app_phase_offset_ns");
277 validateProperty("debug.sf.high_fps_early_gl_app_phase_offset_ns");
278}
279
Ady Abraham8287e852020-08-12 14:44:58 -0700280namespace {
281nsecs_t sfDurationToOffset(std::chrono::nanoseconds sfDuration, nsecs_t vsyncDuration) {
282 return vsyncDuration - sfDuration.count() % vsyncDuration;
Ady Abraham9e16a482019-12-03 17:19:41 -0800283}
284
Ady Abraham8287e852020-08-12 14:44:58 -0700285nsecs_t appDurationToOffset(std::chrono::nanoseconds appDuration,
286 std::chrono::nanoseconds sfDuration, nsecs_t vsyncDuration) {
287 return vsyncDuration - (appDuration + sfDuration).count() % vsyncDuration;
Ady Abraham9e16a482019-12-03 17:19:41 -0800288}
Ady Abraham8287e852020-08-12 14:44:58 -0700289} // namespace
Ady Abraham9e16a482019-12-03 17:19:41 -0800290
Ady Abraham8287e852020-08-12 14:44:58 -0700291WorkDuration::VsyncConfigSet WorkDuration::constructOffsets(nsecs_t vsyncDuration) const {
292 const auto sfDurationFixup = [vsyncDuration](nsecs_t duration) {
293 return duration == -1 ? std::chrono::nanoseconds(vsyncDuration) - 1ms
294 : std::chrono::nanoseconds(duration);
295 };
Ady Abrahamdfa37362020-01-21 18:02:39 -0800296
Ady Abraham8287e852020-08-12 14:44:58 -0700297 const auto appDurationFixup = [vsyncDuration](nsecs_t duration) {
298 return duration == -1 ? std::chrono::nanoseconds(vsyncDuration)
299 : std::chrono::nanoseconds(duration);
300 };
Ady Abrahamdfa37362020-01-21 18:02:39 -0800301
Ady Abraham8287e852020-08-12 14:44:58 -0700302 const auto sfEarlyDuration = sfDurationFixup(mSfEarlyDuration);
303 const auto appEarlyDuration = appDurationFixup(mAppEarlyDuration);
304 const auto sfEarlyGpuDuration = sfDurationFixup(mSfEarlyGpuDuration);
305 const auto appEarlyGpuDuration = appDurationFixup(mAppEarlyGpuDuration);
306 const auto sfDuration = sfDurationFixup(mSfDuration);
307 const auto appDuration = appDurationFixup(mAppDuration);
Ady Abrahamdfa37362020-01-21 18:02:39 -0800308
Ady Abraham8287e852020-08-12 14:44:58 -0700309 return {
310 .early =
311 {
312
313 .sfOffset = sfEarlyDuration.count() < vsyncDuration
314 ? sfDurationToOffset(sfEarlyDuration, vsyncDuration)
315 : sfDurationToOffset(sfEarlyDuration, vsyncDuration) -
316 vsyncDuration,
317
318 .appOffset = appDurationToOffset(appEarlyDuration, sfEarlyDuration,
319 vsyncDuration),
320
321 .sfWorkDuration = sfEarlyDuration,
322 .appWorkDuration = appEarlyDuration,
323 },
324 .earlyGpu =
325 {
326
327 .sfOffset = sfEarlyGpuDuration.count() < vsyncDuration
328
329 ? sfDurationToOffset(sfEarlyGpuDuration, vsyncDuration)
330 : sfDurationToOffset(sfEarlyGpuDuration, vsyncDuration) -
331 vsyncDuration,
332
333 .appOffset = appDurationToOffset(appEarlyGpuDuration,
334 sfEarlyGpuDuration, vsyncDuration),
335 .sfWorkDuration = sfEarlyGpuDuration,
336 .appWorkDuration = appEarlyGpuDuration,
337 },
338 .late =
339 {
340
341 .sfOffset = sfDuration.count() < vsyncDuration
342
343 ? sfDurationToOffset(sfDuration, vsyncDuration)
344 : sfDurationToOffset(sfDuration, vsyncDuration) - vsyncDuration,
345
346 .appOffset =
347 appDurationToOffset(appDuration, sfDuration, vsyncDuration),
348
349 .sfWorkDuration = sfDuration,
350 .appWorkDuration = appDuration,
351 },
Ady Abrahamcaba2982021-06-16 16:45:04 -0700352 .hwcMinWorkDuration = std::chrono::nanoseconds(mHwcMinWorkDuration),
Ady Abrahamdfa37362020-01-21 18:02:39 -0800353 };
354}
355
Marin Shalamanov526c3382020-12-10 15:22:29 +0100356WorkDuration::WorkDuration(Fps currentRefreshRate)
357 : WorkDuration(currentRefreshRate, getProperty("debug.sf.late.sf.duration").value_or(-1),
Ady Abraham8287e852020-08-12 14:44:58 -0700358 getProperty("debug.sf.late.app.duration").value_or(-1),
359 getProperty("debug.sf.early.sf.duration").value_or(mSfDuration),
360 getProperty("debug.sf.early.app.duration").value_or(mAppDuration),
361 getProperty("debug.sf.earlyGl.sf.duration").value_or(mSfDuration),
Ady Abrahamcaba2982021-06-16 16:45:04 -0700362 getProperty("debug.sf.earlyGl.app.duration").value_or(mAppDuration),
363 getProperty("debug.sf.hwc.min.duration").value_or(0)) {
Ady Abraham9e16a482019-12-03 17:19:41 -0800364 validateSysprops();
365}
366
Marin Shalamanov526c3382020-12-10 15:22:29 +0100367WorkDuration::WorkDuration(Fps currentRefreshRate, nsecs_t sfDuration, nsecs_t appDuration,
368 nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration,
Ady Abrahamcaba2982021-06-16 16:45:04 -0700369 nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration,
370 nsecs_t hwcMinWorkDuration)
Marin Shalamanov526c3382020-12-10 15:22:29 +0100371 : VsyncConfiguration(currentRefreshRate),
Ady Abraham8287e852020-08-12 14:44:58 -0700372 mSfDuration(sfDuration),
Ady Abraham9e16a482019-12-03 17:19:41 -0800373 mAppDuration(appDuration),
374 mSfEarlyDuration(sfEarlyDuration),
375 mAppEarlyDuration(appEarlyDuration),
Ady Abraham8287e852020-08-12 14:44:58 -0700376 mSfEarlyGpuDuration(sfEarlyGpuDuration),
Ady Abrahamcaba2982021-06-16 16:45:04 -0700377 mAppEarlyGpuDuration(appEarlyGpuDuration),
378 mHwcMinWorkDuration(hwcMinWorkDuration) {}
Ady Abraham9e16a482019-12-03 17:19:41 -0800379
Ady Abraham8287e852020-08-12 14:44:58 -0700380} // namespace android::scheduler::impl