• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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