blob: 12832a690ad73f3b75ff5f98397c35da0d3ca3a7 [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
Dominik Laskowskieddeda12019-07-19 11:54:13 -070021#include <optional>
22
Ana Krulec757f63a2019-01-25 10:46:18 -080023#include "SurfaceFlingerProperties.h"
24
Dominik Laskowskieddeda12019-07-19 11:54:13 -070025namespace {
Ana Krulec757f63a2019-01-25 10:46:18 -080026
Dominik Laskowskif83570c2019-08-26 12:04:07 -070027std::optional<nsecs_t> getProperty(const char* name) {
Dominik Laskowskieddeda12019-07-19 11:54:13 -070028 char value[PROPERTY_VALUE_MAX];
29 property_get(name, value, "-1");
30 if (const int i = atoi(value); i != -1) return i;
31 return std::nullopt;
32}
Ana Krulec757f63a2019-01-25 10:46:18 -080033
Dominik Laskowskieddeda12019-07-19 11:54:13 -070034} // namespace
35
36namespace android::scheduler {
37
Ana Krulec757f63a2019-01-25 10:46:18 -080038PhaseOffsets::~PhaseOffsets() = default;
39
40namespace impl {
Dominik Laskowskieddeda12019-07-19 11:54:13 -070041
Ana Krulec757f63a2019-01-25 10:46:18 -080042PhaseOffsets::PhaseOffsets() {
Ady Abrahambe0f9482019-04-24 15:41:53 -070043 // Below defines the threshold when an offset is considered to be negative, i.e. targeting
44 // for the N+2 vsync instead of N+1. This means that:
45 // For offset < threshold, SF wake up (vsync_duration - offset) before HW vsync.
46 // For offset >= threshold, SF wake up (2 * vsync_duration - offset) before HW vsync.
Dominik Laskowskieddeda12019-07-19 11:54:13 -070047 const nsecs_t thresholdForNextVsync =
48 getProperty("debug.sf.phase_offset_threshold_for_next_vsync_ns")
49 .value_or(std::numeric_limits<nsecs_t>::max());
Ady Abrahambe0f9482019-04-24 15:41:53 -070050
Ady Abraham2139f732019-11-13 18:56:40 -080051 mDefaultOffsets = getDefaultOffsets(thresholdForNextVsync);
52 mHighFpsOffsets = getHighFpsOffsets(thresholdForNextVsync);
Ana Krulec757f63a2019-01-25 10:46:18 -080053}
54
Ady Abraham2139f732019-11-13 18:56:40 -080055PhaseOffsets::Offsets PhaseOffsets::getOffsetsForRefreshRate(float fps) const {
56 // TODO(145561086): Once offsets are common for all refresh rates we can remove the magic
57 // number for refresh rate
58 if (fps > 65.0f) {
59 return mHighFpsOffsets;
60 } else {
61 return mDefaultOffsets;
62 }
Ana Krulec757f63a2019-01-25 10:46:18 -080063}
64
65void PhaseOffsets::dump(std::string& result) const {
Dominik Laskowskieddeda12019-07-19 11:54:13 -070066 const auto [early, earlyGl, late, threshold] = getCurrentOffsets();
Dominik Laskowski98041832019-08-01 18:35:59 -070067 using base::StringAppendF;
68 StringAppendF(&result,
69 " app phase: %9" PRId64 " ns\t SF phase: %9" PRId64 " ns\n"
70 " early app phase: %9" PRId64 " ns\t early SF phase: %9" PRId64 " ns\n"
71 " GL early app phase: %9" PRId64 " ns\tGL early SF phase: %9" PRId64 " ns\n"
72 "next VSYNC threshold: %9" PRId64 " ns\n",
73 late.app, late.sf, early.app, early.sf, earlyGl.app, earlyGl.sf, threshold);
Ana Krulec757f63a2019-01-25 10:46:18 -080074}
75
Dominik Laskowskieddeda12019-07-19 11:54:13 -070076PhaseOffsets::Offsets PhaseOffsets::getDefaultOffsets(nsecs_t thresholdForNextVsync) {
77 const int64_t vsyncPhaseOffsetNs = sysprop::vsync_event_phase_offset_ns(1000000);
78 const int64_t sfVsyncPhaseOffsetNs = sysprop::vsync_sf_event_phase_offset_ns(1000000);
79
80 const auto earlySfOffsetNs = getProperty("debug.sf.early_phase_offset_ns");
81 const auto earlyGlSfOffsetNs = getProperty("debug.sf.early_gl_phase_offset_ns");
82 const auto earlyAppOffsetNs = getProperty("debug.sf.early_app_phase_offset_ns");
83 const auto earlyGlAppOffsetNs = getProperty("debug.sf.early_gl_app_phase_offset_ns");
84
Ady Abraham2139f732019-11-13 18:56:40 -080085 return {{earlySfOffsetNs.value_or(sfVsyncPhaseOffsetNs),
Dominik Laskowskieddeda12019-07-19 11:54:13 -070086 earlyAppOffsetNs.value_or(vsyncPhaseOffsetNs)},
87
Ady Abraham2139f732019-11-13 18:56:40 -080088 {earlyGlSfOffsetNs.value_or(sfVsyncPhaseOffsetNs),
Dominik Laskowskieddeda12019-07-19 11:54:13 -070089 earlyGlAppOffsetNs.value_or(vsyncPhaseOffsetNs)},
90
Ady Abraham2139f732019-11-13 18:56:40 -080091 {sfVsyncPhaseOffsetNs, vsyncPhaseOffsetNs},
Dominik Laskowskieddeda12019-07-19 11:54:13 -070092
93 thresholdForNextVsync};
Ana Krulec757f63a2019-01-25 10:46:18 -080094}
95
Dominik Laskowskieddeda12019-07-19 11:54:13 -070096PhaseOffsets::Offsets PhaseOffsets::getHighFpsOffsets(nsecs_t thresholdForNextVsync) {
97 // TODO(b/122905996): Define these in device.mk.
98 const int highFpsLateAppOffsetNs =
99 getProperty("debug.sf.high_fps_late_app_phase_offset_ns").value_or(2000000);
100 const int highFpsLateSfOffsetNs =
101 getProperty("debug.sf.high_fps_late_sf_phase_offset_ns").value_or(1000000);
102
103 const auto highFpsEarlySfOffsetNs = getProperty("debug.sf.high_fps_early_phase_offset_ns");
104 const auto highFpsEarlyGlSfOffsetNs = getProperty("debug.sf.high_fps_early_gl_phase_offset_ns");
105 const auto highFpsEarlyAppOffsetNs = getProperty("debug.sf.high_fps_early_app_phase_offset_ns");
106 const auto highFpsEarlyGlAppOffsetNs =
107 getProperty("debug.sf.high_fps_early_gl_app_phase_offset_ns");
108
Ady Abraham2139f732019-11-13 18:56:40 -0800109 return {{highFpsEarlySfOffsetNs.value_or(highFpsLateSfOffsetNs),
Dominik Laskowskieddeda12019-07-19 11:54:13 -0700110 highFpsEarlyAppOffsetNs.value_or(highFpsLateAppOffsetNs)},
111
Ady Abraham2139f732019-11-13 18:56:40 -0800112 {highFpsEarlyGlSfOffsetNs.value_or(highFpsLateSfOffsetNs),
Dominik Laskowskieddeda12019-07-19 11:54:13 -0700113 highFpsEarlyGlAppOffsetNs.value_or(highFpsLateAppOffsetNs)},
114
Ady Abraham2139f732019-11-13 18:56:40 -0800115 {highFpsLateSfOffsetNs, highFpsLateAppOffsetNs},
Dominik Laskowskieddeda12019-07-19 11:54:13 -0700116
117 thresholdForNextVsync};
Ana Krulec757f63a2019-01-25 10:46:18 -0800118}
119
120} // namespace impl
Dominik Laskowskieddeda12019-07-19 11:54:13 -0700121} // namespace android::scheduler