1 /* 2 * Copyright (C) 2023 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 package com.android.server.display.mode; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 22 import com.android.server.display.config.SupportedModeData; 23 24 import java.lang.annotation.Retention; 25 import java.lang.annotation.RetentionPolicy; 26 import java.util.ArrayList; 27 import java.util.List; 28 29 interface Vote { 30 // DEFAULT_RENDER_FRAME_RATE votes for render frame rate [0, DEFAULT]. As the lowest 31 // priority vote, it's overridden by all other considerations. It acts to set a default 32 // frame rate for a device. 33 int PRIORITY_DEFAULT_RENDER_FRAME_RATE = 0; 34 35 // PRIORITY_FLICKER_REFRESH_RATE votes for a single refresh rate like [60,60], [90,90] or 36 // null. It is used to set a preferred refresh rate value in case the higher priority votes 37 // result is a range. 38 static final int PRIORITY_FLICKER_REFRESH_RATE = 1; 39 40 // High-brightness-mode may need a specific range of refresh-rates to function properly. 41 int PRIORITY_HIGH_BRIGHTNESS_MODE = 2; 42 43 // SETTING_MIN_RENDER_FRAME_RATE is used to propose a lower bound of the render frame rate. 44 // It votes [minRefreshRate, Float.POSITIVE_INFINITY] 45 int PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE = 3; 46 47 // User setting preferred display resolution. 48 int PRIORITY_USER_SETTING_DISPLAY_PREFERRED_SIZE = 4; 49 50 // APP_REQUEST_RENDER_FRAME_RATE_RANGE is used to for internal apps to limit the render 51 // frame rate in certain cases, mostly to preserve power. 52 // @see android.view.WindowManager.LayoutParams#preferredMinRefreshRate 53 // @see android.view.WindowManager.LayoutParams#preferredMaxRefreshRate 54 // It votes to [preferredMinRefreshRate, preferredMaxRefreshRate]. 55 int PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE = 5; 56 57 // We split the app request into different priorities in case we can satisfy one desire 58 // without the other. 59 60 // Application can specify preferred refresh rate with below attrs. 61 // @see android.view.WindowManager.LayoutParams#preferredRefreshRate 62 // @see android.view.WindowManager.LayoutParams#preferredDisplayModeId 63 // 64 // When the app specifies a LayoutParams#preferredDisplayModeId, in addition to the 65 // refresh rate, it also chooses a preferred size (resolution) as part of the selected 66 // mode id. The app preference is then translated to APP_REQUEST_BASE_MODE_REFRESH_RATE and 67 // optionally to APP_REQUEST_SIZE as well, if a mode id was selected. 68 // The system also forces some apps like denylisted app to run at a lower refresh rate. 69 // @see android.R.array#config_highRefreshRateBlacklist 70 // 71 // When summarizing the votes and filtering the allowed display modes, these votes determine 72 // which mode id should be the base mode id to be sent to SurfaceFlinger: 73 // - APP_REQUEST_BASE_MODE_REFRESH_RATE is used to validate the vote summary. If a summary 74 // includes a base mode refresh rate, but it is not in the refresh rate range, then the 75 // summary is considered invalid so we could drop a lower priority vote and try again. 76 // - APP_REQUEST_SIZE is used to filter out display modes of a different size. 77 // 78 // The preferred refresh rate is set on the main surface of the app outside of 79 // DisplayModeDirector. 80 // @see com.android.server.wm.WindowState#updateFrameRateSelectionPriorityIfNeeded 81 int PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE = 6; 82 83 int PRIORITY_APP_REQUEST_SIZE = 7; 84 85 // PRIORITY_USER_SETTING_PEAK_REFRESH_RATE restricts physical refresh rate to 86 // [0, max(PEAK, MIN)], depending on user settings peakRR/minRR values 87 int PRIORITY_USER_SETTING_PEAK_REFRESH_RATE = 8; 88 89 // PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE has a higher priority than 90 // PRIORITY_USER_SETTING_PEAK_REFRESH_RATE and will limit render rate to [0, max(PEAK, MIN)] 91 // in case physical refresh rate vote is discarded (due to other high priority votes), 92 // render rate vote can still apply 93 int PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE = 9; 94 95 // Restrict all displays to 60Hz when external display is connected. It votes [59Hz, 61Hz]. 96 int PRIORITY_SYNCHRONIZED_REFRESH_RATE = 10; 97 98 // Restrict displays max available resolution and refresh rates. It votes [0, LIMIT] 99 int PRIORITY_LIMIT_MODE = 11; 100 101 // To avoid delay in switching between 60HZ -> 90HZ when activating LHBM, set refresh 102 // rate to max value (same as for PRIORITY_UDFPS) on lock screen 103 int PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE = 12; 104 105 // For concurrent displays we want to limit refresh rate on all displays 106 int PRIORITY_LAYOUT_LIMITED_FRAME_RATE = 13; 107 108 // For internal application to limit display modes to specific ids 109 int PRIORITY_SYSTEM_REQUESTED_MODES = 14; 110 111 // PRIORITY_LOW_POWER_MODE_MODES limits display modes to specific refreshRate-vsync pairs if 112 // Settings.Global.LOW_POWER_MODE is on. 113 // Lower priority that PRIORITY_LOW_POWER_MODE_RENDER_RATE and if discarded (due to other 114 // higher priority votes), render rate limit can still apply 115 int PRIORITY_LOW_POWER_MODE_MODES = 15; 116 117 // PRIORITY_LOW_POWER_MODE_RENDER_RATE force the render frame rate to [0, 60HZ] if 118 // Settings.Global.LOW_POWER_MODE is on. 119 int PRIORITY_LOW_POWER_MODE_RENDER_RATE = 16; 120 121 // PRIORITY_FLICKER_REFRESH_RATE_SWITCH votes for disabling refresh rate switching. If the 122 // higher priority voters' result is a range, it will fix the rate to a single choice. 123 // It's used to avoid refresh rate switches in certain conditions which may result in the 124 // user seeing the display flickering when the switches occur. 125 int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 17; 126 127 // Force display to [0, 60HZ] if skin temperature is at or above CRITICAL. 128 int PRIORITY_SKIN_TEMPERATURE = 18; 129 130 // The proximity sensor needs the refresh rate to be locked in order to function, so this is 131 // set to a high priority. 132 int PRIORITY_PROXIMITY = 19; 133 134 // The Under-Display Fingerprint Sensor (UDFPS) needs the refresh rate to be locked in order 135 // to function, so this needs to be the highest priority of all votes. 136 int PRIORITY_UDFPS = 20; 137 138 @IntDef(prefix = { "PRIORITY_" }, value = { 139 PRIORITY_DEFAULT_RENDER_FRAME_RATE, 140 PRIORITY_FLICKER_REFRESH_RATE, 141 PRIORITY_HIGH_BRIGHTNESS_MODE, 142 PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE, 143 PRIORITY_USER_SETTING_DISPLAY_PREFERRED_SIZE, 144 PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE, 145 PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE, 146 PRIORITY_APP_REQUEST_SIZE, 147 PRIORITY_USER_SETTING_PEAK_REFRESH_RATE, 148 PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE, 149 PRIORITY_SYNCHRONIZED_REFRESH_RATE, 150 PRIORITY_LIMIT_MODE, 151 PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE, 152 PRIORITY_LAYOUT_LIMITED_FRAME_RATE, 153 PRIORITY_SYSTEM_REQUESTED_MODES, 154 PRIORITY_LOW_POWER_MODE_MODES, 155 PRIORITY_LOW_POWER_MODE_RENDER_RATE, 156 PRIORITY_FLICKER_REFRESH_RATE_SWITCH, 157 PRIORITY_SKIN_TEMPERATURE, 158 PRIORITY_PROXIMITY, 159 PRIORITY_UDFPS 160 }) 161 @Retention(RetentionPolicy.SOURCE) 162 @interface Priority {} 163 164 // Whenever a new priority is added, remember to update MIN_PRIORITY, MAX_PRIORITY, and 165 // APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF, as well as priorityToString. 166 @Priority int MIN_PRIORITY = PRIORITY_DEFAULT_RENDER_FRAME_RATE; 167 @Priority int MAX_PRIORITY = PRIORITY_UDFPS; 168 169 // The cutoff for the app request refresh rate range. Votes with priorities lower than this 170 // value will not be considered when constructing the app request refresh rate range. 171 @Priority int APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF = 172 PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE; 173 174 /** 175 * A value signifying an invalid width or height in a vote. 176 */ 177 int INVALID_SIZE = -1; 178 updateSummary(@onNull VoteSummary summary)179 void updateSummary(@NonNull VoteSummary summary); 180 forPhysicalRefreshRates(float minRefreshRate, float maxRefreshRate)181 static Vote forPhysicalRefreshRates(float minRefreshRate, float maxRefreshRate) { 182 return new CombinedVote( 183 List.of( 184 new RefreshRateVote.PhysicalVote(minRefreshRate, maxRefreshRate), 185 new DisableRefreshRateSwitchingVote(minRefreshRate == maxRefreshRate) 186 ) 187 ); 188 } 189 forRenderFrameRates(float minFrameRate, float maxFrameRate)190 static Vote forRenderFrameRates(float minFrameRate, float maxFrameRate) { 191 return new RefreshRateVote.RenderVote(minFrameRate, maxFrameRate); 192 } 193 forSize(int width, int height)194 static Vote forSize(int width, int height) { 195 return new SizeVote(width, height, width, height); 196 } 197 forSizeAndPhysicalRefreshRatesRange(int minWidth, int minHeight, int width, int height, float minRefreshRate, float maxRefreshRate)198 static Vote forSizeAndPhysicalRefreshRatesRange(int minWidth, int minHeight, 199 int width, int height, float minRefreshRate, float maxRefreshRate) { 200 return new CombinedVote( 201 List.of( 202 new SizeVote(width, height, minWidth, minHeight), 203 new RefreshRateVote.PhysicalVote(minRefreshRate, maxRefreshRate), 204 new DisableRefreshRateSwitchingVote(minRefreshRate == maxRefreshRate) 205 ) 206 ); 207 } 208 forDisableRefreshRateSwitching()209 static Vote forDisableRefreshRateSwitching() { 210 return new DisableRefreshRateSwitchingVote(true); 211 } 212 forBaseModeRefreshRate(float baseModeRefreshRate)213 static Vote forBaseModeRefreshRate(float baseModeRefreshRate) { 214 return new BaseModeRefreshRateVote(baseModeRefreshRate); 215 } 216 forRequestedRefreshRate(float refreshRate)217 static Vote forRequestedRefreshRate(float refreshRate) { 218 return new RequestedRefreshRateVote(refreshRate); 219 } 220 forSupportedRefreshRates(List<SupportedModeData> supportedModes)221 static Vote forSupportedRefreshRates(List<SupportedModeData> supportedModes) { 222 if (supportedModes.isEmpty()) { 223 return null; 224 } 225 List<SupportedRefreshRatesVote.RefreshRates> rates = new ArrayList<>(); 226 for (SupportedModeData data : supportedModes) { 227 rates.add(new SupportedRefreshRatesVote.RefreshRates(data.refreshRate, data.vsyncRate)); 228 } 229 return new SupportedRefreshRatesVote(rates); 230 } 231 forSupportedModes(List<Integer> modeIds)232 static Vote forSupportedModes(List<Integer> modeIds) { 233 return new SupportedModesVote(modeIds); 234 } 235 priorityToString(int priority)236 static String priorityToString(int priority) { 237 switch (priority) { 238 case PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE: 239 return "PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE"; 240 case PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE: 241 return "PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE"; 242 case PRIORITY_APP_REQUEST_SIZE: 243 return "PRIORITY_APP_REQUEST_SIZE"; 244 case PRIORITY_DEFAULT_RENDER_FRAME_RATE: 245 return "PRIORITY_DEFAULT_REFRESH_RATE"; 246 case PRIORITY_FLICKER_REFRESH_RATE: 247 return "PRIORITY_FLICKER_REFRESH_RATE"; 248 case PRIORITY_FLICKER_REFRESH_RATE_SWITCH: 249 return "PRIORITY_FLICKER_REFRESH_RATE_SWITCH"; 250 case PRIORITY_HIGH_BRIGHTNESS_MODE: 251 return "PRIORITY_HIGH_BRIGHTNESS_MODE"; 252 case PRIORITY_PROXIMITY: 253 return "PRIORITY_PROXIMITY"; 254 case PRIORITY_LOW_POWER_MODE_MODES: 255 return "PRIORITY_LOW_POWER_MODE_MODES"; 256 case PRIORITY_LOW_POWER_MODE_RENDER_RATE: 257 return "PRIORITY_LOW_POWER_MODE_RENDER_RATE"; 258 case PRIORITY_SKIN_TEMPERATURE: 259 return "PRIORITY_SKIN_TEMPERATURE"; 260 case PRIORITY_UDFPS: 261 return "PRIORITY_UDFPS"; 262 case PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE: 263 return "PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE"; 264 case PRIORITY_USER_SETTING_DISPLAY_PREFERRED_SIZE: 265 return "PRIORITY_USER_SETTING_DISPLAY_PREFERRED_SIZE"; 266 case PRIORITY_LIMIT_MODE: 267 return "PRIORITY_LIMIT_MODE"; 268 case PRIORITY_SYNCHRONIZED_REFRESH_RATE: 269 return "PRIORITY_SYNCHRONIZED_REFRESH_RATE"; 270 case PRIORITY_USER_SETTING_PEAK_REFRESH_RATE: 271 return "PRIORITY_USER_SETTING_PEAK_REFRESH_RATE"; 272 case PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE: 273 return "PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE"; 274 case PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE: 275 return "PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE"; 276 case PRIORITY_LAYOUT_LIMITED_FRAME_RATE: 277 return "PRIORITY_LAYOUT_LIMITED_FRAME_RATE"; 278 case PRIORITY_SYSTEM_REQUESTED_MODES: 279 return "PRIORITY_SYSTEM_REQUESTED_MODES"; 280 default: 281 return Integer.toString(priority); 282 } 283 } 284 } 285