blob: 8a2604f4a3b8105a929d7d0b1b820c2278885344 [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
17#include "PhaseOffsets.h"
18
19#include <cutils/properties.h>
20
21#include "SurfaceFlingerProperties.h"
22
23namespace android {
24using namespace android::sysprop;
25
26namespace scheduler {
27
Alec Mourid7599d82019-05-22 19:58:00 -070028using RefreshRateType = RefreshRateConfigs::RefreshRateType;
Ana Krulec757f63a2019-01-25 10:46:18 -080029PhaseOffsets::~PhaseOffsets() = default;
30
31namespace impl {
32PhaseOffsets::PhaseOffsets() {
33 int64_t vsyncPhaseOffsetNs = vsync_event_phase_offset_ns(1000000);
34
35 int64_t sfVsyncPhaseOffsetNs = vsync_sf_event_phase_offset_ns(1000000);
36
37 char value[PROPERTY_VALUE_MAX];
38 property_get("debug.sf.early_phase_offset_ns", value, "-1");
39 const int earlySfOffsetNs = atoi(value);
40
41 property_get("debug.sf.early_gl_phase_offset_ns", value, "-1");
42 const int earlyGlSfOffsetNs = atoi(value);
43
44 property_get("debug.sf.early_app_phase_offset_ns", value, "-1");
45 const int earlyAppOffsetNs = atoi(value);
46
47 property_get("debug.sf.early_gl_app_phase_offset_ns", value, "-1");
48 const int earlyGlAppOffsetNs = atoi(value);
49
50 property_get("debug.sf.high_fps_early_phase_offset_ns", value, "-1");
51 const int highFpsEarlySfOffsetNs = atoi(value);
52
53 property_get("debug.sf.high_fps_early_gl_phase_offset_ns", value, "-1");
54 const int highFpsEarlyGlSfOffsetNs = atoi(value);
55
56 property_get("debug.sf.high_fps_early_app_phase_offset_ns", value, "-1");
57 const int highFpsEarlyAppOffsetNs = atoi(value);
58
59 property_get("debug.sf.high_fps_early_gl_app_phase_offset_ns", value, "-1");
60 const int highFpsEarlyGlAppOffsetNs = atoi(value);
61
62 // TODO(b/122905996): Define these in device.mk.
Ady Abraham482b4b12019-02-07 19:01:25 -080063 property_get("debug.sf.high_fps_late_app_phase_offset_ns", value, "2000000");
Ana Krulec757f63a2019-01-25 10:46:18 -080064 const int highFpsLateAppOffsetNs = atoi(value);
65
Ady Abraham482b4b12019-02-07 19:01:25 -080066 property_get("debug.sf.high_fps_late_sf_phase_offset_ns", value, "1000000");
Ana Krulec757f63a2019-01-25 10:46:18 -080067 const int highFpsLateSfOffsetNs = atoi(value);
68
Ady Abrahambe0f9482019-04-24 15:41:53 -070069 // Below defines the threshold when an offset is considered to be negative, i.e. targeting
70 // for the N+2 vsync instead of N+1. This means that:
71 // For offset < threshold, SF wake up (vsync_duration - offset) before HW vsync.
72 // For offset >= threshold, SF wake up (2 * vsync_duration - offset) before HW vsync.
73 property_get("debug.sf.phase_offset_threshold_for_next_vsync_ns", value, "-1");
74 const int phaseOffsetThresholdForNextVsyncNs = atoi(value);
75
Alec Mourid7599d82019-05-22 19:58:00 -070076 Offsets defaultOffsets;
77 Offsets highFpsOffsets;
78 defaultOffsets.early = {RefreshRateType::DEFAULT,
79 earlySfOffsetNs != -1 ? earlySfOffsetNs : sfVsyncPhaseOffsetNs,
80 earlyAppOffsetNs != -1 ? earlyAppOffsetNs : vsyncPhaseOffsetNs};
81 defaultOffsets.earlyGl = {RefreshRateType::DEFAULT,
82 earlyGlSfOffsetNs != -1 ? earlyGlSfOffsetNs : sfVsyncPhaseOffsetNs,
83 earlyGlAppOffsetNs != -1 ? earlyGlAppOffsetNs : vsyncPhaseOffsetNs};
84 defaultOffsets.late = {RefreshRateType::DEFAULT, sfVsyncPhaseOffsetNs, vsyncPhaseOffsetNs};
Ana Krulec757f63a2019-01-25 10:46:18 -080085
Alec Mourid7599d82019-05-22 19:58:00 -070086 highFpsOffsets.early = {RefreshRateType::PERFORMANCE,
87 highFpsEarlySfOffsetNs != -1 ? highFpsEarlySfOffsetNs
88 : highFpsLateSfOffsetNs,
89 highFpsEarlyAppOffsetNs != -1 ? highFpsEarlyAppOffsetNs
90 : highFpsLateAppOffsetNs};
91 highFpsOffsets.earlyGl = {RefreshRateType::PERFORMANCE,
92 highFpsEarlyGlSfOffsetNs != -1 ? highFpsEarlyGlSfOffsetNs
93 : highFpsLateSfOffsetNs,
94 highFpsEarlyGlAppOffsetNs != -1 ? highFpsEarlyGlAppOffsetNs
95 : highFpsLateAppOffsetNs};
96 highFpsOffsets.late = {RefreshRateType::PERFORMANCE, highFpsLateSfOffsetNs,
97 highFpsLateAppOffsetNs};
98
99 mOffsets.insert({RefreshRateType::POWER_SAVING, defaultOffsets});
100 mOffsets.insert({RefreshRateType::DEFAULT, defaultOffsets});
101 mOffsets.insert({RefreshRateType::PERFORMANCE, highFpsOffsets});
Ady Abrahambe0f9482019-04-24 15:41:53 -0700102
103 mOffsetThresholdForNextVsync = phaseOffsetThresholdForNextVsyncNs != -1
104 ? phaseOffsetThresholdForNextVsyncNs
105 : std::numeric_limits<nsecs_t>::max();
Ana Krulec757f63a2019-01-25 10:46:18 -0800106}
107
Ady Abraham796beb02019-04-11 15:23:07 -0700108PhaseOffsets::Offsets PhaseOffsets::getOffsetsForRefreshRate(
109 android::scheduler::RefreshRateConfigs::RefreshRateType refreshRateType) const {
Alec Mourid7599d82019-05-22 19:58:00 -0700110 return mOffsets.at(refreshRateType);
Ana Krulec757f63a2019-01-25 10:46:18 -0800111}
112
113void PhaseOffsets::dump(std::string& result) const {
114 const auto [early, earlyGl, late] = getCurrentOffsets();
115 base::StringAppendF(&result,
116 " app phase: %9" PRId64 " ns\t SF phase: %9" PRId64 " ns\n"
117 " early app phase: %9" PRId64 " ns\t early SF phase: %9" PRId64 " ns\n"
118 "GL early app phase: %9" PRId64 " ns\tGL early SF phase: %9" PRId64 " ns\n",
119 late.app, late.sf, early.app, early.sf, earlyGl.app, earlyGl.sf);
120}
121
122nsecs_t PhaseOffsets::getCurrentAppOffset() {
123 return getCurrentOffsets().late.app;
124}
125
126nsecs_t PhaseOffsets::getCurrentSfOffset() {
127 return getCurrentOffsets().late.sf;
128}
129
130} // namespace impl
131} // namespace scheduler
132} // namespace android