1 /* 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 23 namespace android { 24 using namespace android::sysprop; 25 26 namespace scheduler { 27 28 PhaseOffsets::~PhaseOffsets() = default; 29 30 namespace impl { 31 PhaseOffsets::PhaseOffsets() { 32 int64_t vsyncPhaseOffsetNs = vsync_event_phase_offset_ns(1000000); 33 34 int64_t sfVsyncPhaseOffsetNs = vsync_sf_event_phase_offset_ns(1000000); 35 36 char value[PROPERTY_VALUE_MAX]; 37 property_get("debug.sf.early_phase_offset_ns", value, "-1"); 38 const int earlySfOffsetNs = atoi(value); 39 40 property_get("debug.sf.early_gl_phase_offset_ns", value, "-1"); 41 const int earlyGlSfOffsetNs = atoi(value); 42 43 property_get("debug.sf.early_app_phase_offset_ns", value, "-1"); 44 const int earlyAppOffsetNs = atoi(value); 45 46 property_get("debug.sf.early_gl_app_phase_offset_ns", value, "-1"); 47 const int earlyGlAppOffsetNs = atoi(value); 48 49 property_get("debug.sf.high_fps_early_phase_offset_ns", value, "-1"); 50 const int highFpsEarlySfOffsetNs = atoi(value); 51 52 property_get("debug.sf.high_fps_early_gl_phase_offset_ns", value, "-1"); 53 const int highFpsEarlyGlSfOffsetNs = atoi(value); 54 55 property_get("debug.sf.high_fps_early_app_phase_offset_ns", value, "-1"); 56 const int highFpsEarlyAppOffsetNs = atoi(value); 57 58 property_get("debug.sf.high_fps_early_gl_app_phase_offset_ns", value, "-1"); 59 const int highFpsEarlyGlAppOffsetNs = atoi(value); 60 61 // TODO(b/122905996): Define these in device.mk. 62 property_get("debug.sf.high_fps_late_app_phase_offset_ns", value, "2000000"); 63 const int highFpsLateAppOffsetNs = atoi(value); 64 65 property_get("debug.sf.high_fps_late_sf_phase_offset_ns", value, "1000000"); 66 const int highFpsLateSfOffsetNs = atoi(value); 67 68 // Below defines the threshold when an offset is considered to be negative, i.e. targeting 69 // for the N+2 vsync instead of N+1. This means that: 70 // For offset < threshold, SF wake up (vsync_duration - offset) before HW vsync. 71 // For offset >= threshold, SF wake up (2 * vsync_duration - offset) before HW vsync. 72 property_get("debug.sf.phase_offset_threshold_for_next_vsync_ns", value, "-1"); 73 const int phaseOffsetThresholdForNextVsyncNs = atoi(value); 74 75 mDefaultRefreshRateOffsets.early = {earlySfOffsetNs != -1 ? earlySfOffsetNs 76 : sfVsyncPhaseOffsetNs, 77 earlyAppOffsetNs != -1 ? earlyAppOffsetNs 78 : vsyncPhaseOffsetNs}; 79 mDefaultRefreshRateOffsets.earlyGl = {earlyGlSfOffsetNs != -1 ? earlyGlSfOffsetNs 80 : sfVsyncPhaseOffsetNs, 81 earlyGlAppOffsetNs != -1 ? earlyGlAppOffsetNs 82 : vsyncPhaseOffsetNs}; 83 mDefaultRefreshRateOffsets.late = {sfVsyncPhaseOffsetNs, vsyncPhaseOffsetNs}; 84 85 mHighRefreshRateOffsets.early = {highFpsEarlySfOffsetNs != -1 ? highFpsEarlySfOffsetNs 86 : highFpsLateSfOffsetNs, 87 highFpsEarlyAppOffsetNs != -1 ? highFpsEarlyAppOffsetNs 88 : highFpsLateAppOffsetNs}; 89 mHighRefreshRateOffsets.earlyGl = {highFpsEarlyGlSfOffsetNs != -1 ? highFpsEarlyGlSfOffsetNs 90 : highFpsLateSfOffsetNs, 91 highFpsEarlyGlAppOffsetNs != -1 ? highFpsEarlyGlAppOffsetNs 92 : highFpsLateAppOffsetNs}; 93 mHighRefreshRateOffsets.late = {highFpsLateSfOffsetNs, highFpsLateAppOffsetNs}; 94 95 mOffsetThresholdForNextVsync = phaseOffsetThresholdForNextVsyncNs != -1 96 ? phaseOffsetThresholdForNextVsyncNs 97 : std::numeric_limits<nsecs_t>::max(); 98 } 99 100 PhaseOffsets::Offsets PhaseOffsets::getOffsetsForRefreshRate( 101 android::scheduler::RefreshRateConfigs::RefreshRateType refreshRateType) const { 102 switch (refreshRateType) { 103 case RefreshRateConfigs::RefreshRateType::PERFORMANCE: 104 return mHighRefreshRateOffsets; 105 default: 106 return mDefaultRefreshRateOffsets; 107 } 108 } 109 110 void PhaseOffsets::dump(std::string& result) const { 111 const auto [early, earlyGl, late] = getCurrentOffsets(); 112 base::StringAppendF(&result, 113 " app phase: %9" PRId64 " ns\t SF phase: %9" PRId64 " ns\n" 114 " early app phase: %9" PRId64 " ns\t early SF phase: %9" PRId64 " ns\n" 115 "GL early app phase: %9" PRId64 " ns\tGL early SF phase: %9" PRId64 " ns\n", 116 late.app, late.sf, early.app, early.sf, earlyGl.app, earlyGl.sf); 117 } 118 119 nsecs_t PhaseOffsets::getCurrentAppOffset() { 120 return getCurrentOffsets().late.app; 121 } 122 123 nsecs_t PhaseOffsets::getCurrentSfOffset() { 124 return getCurrentOffsets().late.sf; 125 } 126 127 } // namespace impl 128 } // namespace scheduler 129 } // namespace android 130