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