1 /*
2  * Copyright (C) 2024 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.config;
18 
19 import android.annotation.Nullable;
20 import android.content.res.Resources;
21 
22 import com.android.internal.R;
23 import com.android.internal.annotations.VisibleForTesting;
24 
25 import java.util.Collections;
26 import java.util.List;
27 
28 /**
29  * RefreshRates config for display
30  */
31 public class RefreshRateData {
32     public static RefreshRateData DEFAULT_REFRESH_RATE_DATA = loadRefreshRateData(null, null);
33 
34     private static final int DEFAULT_REFRESH_RATE = 60;
35     private static final int DEFAULT_PEAK_REFRESH_RATE = 0;
36     private static final int DEFAULT_REFRESH_RATE_IN_HBM = 0;
37 
38     /**
39      * The default refresh rate for a given device. This value sets the higher default
40      * refresh rate. If the hardware composer on the device supports display modes with
41      * a higher refresh rate than the default value specified here, the framework may use those
42      * higher refresh rate modes if an app chooses one by setting preferredDisplayModeId or calling
43      * setFrameRate(). We have historically allowed fallback to mDefaultPeakRefreshRate if
44      * defaultRefreshRate is set to 0, but this is not supported anymore.
45      */
46     public final int defaultRefreshRate;
47 
48     /**
49      * The default peak refresh rate for a given device. This value prevents the framework from
50      * using higher refresh rates, even if display modes with higher refresh rates are available
51      * from hardware composer. Only has an effect if the value is non-zero.
52      */
53     public final int defaultPeakRefreshRate;
54 
55     /**
56      * Default refresh rate while the device has high brightness mode enabled for HDR.
57      */
58     public final int defaultRefreshRateInHbmHdr;
59 
60     /**
61      * Default refresh rate while the device has high brightness mode enabled for Sunlight.
62      */
63     public final int defaultRefreshRateInHbmSunlight;
64 
65     public final List<SupportedModeData> lowPowerSupportedModes;
66 
67     public final List<SupportedModeData> lowLightBlockingZoneSupportedModes;
68 
69     @VisibleForTesting
RefreshRateData(int defaultRefreshRate, int defaultPeakRefreshRate, int defaultRefreshRateInHbmHdr, int defaultRefreshRateInHbmSunlight, List<SupportedModeData> lowPowerSupportedModes, List<SupportedModeData> lowLightBlockingZoneSupportedModes)70     public RefreshRateData(int defaultRefreshRate, int defaultPeakRefreshRate,
71             int defaultRefreshRateInHbmHdr, int defaultRefreshRateInHbmSunlight,
72             List<SupportedModeData> lowPowerSupportedModes,
73             List<SupportedModeData> lowLightBlockingZoneSupportedModes) {
74         this.defaultRefreshRate = defaultRefreshRate;
75         this.defaultPeakRefreshRate = defaultPeakRefreshRate;
76         this.defaultRefreshRateInHbmHdr = defaultRefreshRateInHbmHdr;
77         this.defaultRefreshRateInHbmSunlight = defaultRefreshRateInHbmSunlight;
78         this.lowPowerSupportedModes = Collections.unmodifiableList(lowPowerSupportedModes);
79         this.lowLightBlockingZoneSupportedModes =
80                 Collections.unmodifiableList(lowLightBlockingZoneSupportedModes);
81     }
82 
83     @Override
toString()84     public String toString() {
85         return "RefreshRateData {"
86                 + "defaultRefreshRate: " + defaultRefreshRate
87                 + ", defaultPeakRefreshRate: " + defaultPeakRefreshRate
88                 + ", defaultRefreshRateInHbmHdr: " + defaultRefreshRateInHbmHdr
89                 + ", defaultRefreshRateInHbmSunlight: " + defaultRefreshRateInHbmSunlight
90                 + ", lowPowerSupportedModes=" + lowPowerSupportedModes
91                 + ", lowLightBlockingZoneSupportedModes=" + lowLightBlockingZoneSupportedModes
92                 + "} ";
93     }
94 
95     /**
96      * Loads RefreshRateData from DisplayConfiguration and Resources
97      */
loadRefreshRateData( @ullable DisplayConfiguration config, @Nullable Resources resources)98     public static RefreshRateData loadRefreshRateData(
99             @Nullable DisplayConfiguration config, @Nullable Resources resources) {
100         RefreshRateConfigs refreshRateConfigs = config == null ? null : config.getRefreshRate();
101 
102         int defaultRefreshRate = loadDefaultRefreshRate(refreshRateConfigs, resources);
103         int defaultPeakRefreshRate = loadDefaultPeakRefreshRate(refreshRateConfigs, resources);
104         int defaultRefreshRateInHbmHdr = loadDefaultRefreshRateInHbm(refreshRateConfigs, resources);
105         int defaultRefreshRateInHbmSunlight = loadDefaultRefreshRateInHbmSunlight(
106                 refreshRateConfigs, resources);
107 
108         NonNegativeFloatToFloatMap lowPowerModes =
109                 refreshRateConfigs == null ? null : refreshRateConfigs.getLowPowerSupportedModes();
110         List<SupportedModeData> lowPowerSupportedModes = SupportedModeData.load(lowPowerModes);
111 
112         BlockingZoneConfig lowerZoneConfig = refreshRateConfigs == null ? null
113                 : refreshRateConfigs.getLowerBlockingZoneConfigs();
114         NonNegativeFloatToFloatMap lowerZoneModes =
115                 lowerZoneConfig == null ? null : lowerZoneConfig.getSupportedModes();
116         List<SupportedModeData> lowLightSupportedModes = SupportedModeData.load(lowerZoneModes);
117 
118         return new RefreshRateData(defaultRefreshRate, defaultPeakRefreshRate,
119                 defaultRefreshRateInHbmHdr, defaultRefreshRateInHbmSunlight,
120                 lowPowerSupportedModes, lowLightSupportedModes);
121     }
122 
loadDefaultRefreshRate( @ullable RefreshRateConfigs refreshRateConfigs, @Nullable Resources resources)123     private static int loadDefaultRefreshRate(
124             @Nullable RefreshRateConfigs refreshRateConfigs, @Nullable Resources resources) {
125         if (refreshRateConfigs != null && refreshRateConfigs.getDefaultRefreshRate() != null) {
126             return refreshRateConfigs.getDefaultRefreshRate().intValue();
127         } else if (resources != null) {
128             return resources.getInteger(R.integer.config_defaultRefreshRate);
129         }
130         return DEFAULT_REFRESH_RATE;
131     }
132 
loadDefaultPeakRefreshRate( @ullable RefreshRateConfigs refreshRateConfigs, @Nullable Resources resources)133     private static int loadDefaultPeakRefreshRate(
134             @Nullable RefreshRateConfigs refreshRateConfigs, @Nullable Resources resources) {
135         if (refreshRateConfigs != null && refreshRateConfigs.getDefaultPeakRefreshRate() != null) {
136             return refreshRateConfigs.getDefaultPeakRefreshRate().intValue();
137         } else if (resources != null) {
138             return resources.getInteger(R.integer.config_defaultPeakRefreshRate);
139         }
140         return DEFAULT_PEAK_REFRESH_RATE;
141     }
142 
loadDefaultRefreshRateInHbm( @ullable RefreshRateConfigs refreshRateConfigs, @Nullable Resources resources)143     private static int loadDefaultRefreshRateInHbm(
144             @Nullable RefreshRateConfigs refreshRateConfigs, @Nullable Resources resources) {
145         if (refreshRateConfigs != null
146                 && refreshRateConfigs.getDefaultRefreshRateInHbmHdr() != null) {
147             return refreshRateConfigs.getDefaultRefreshRateInHbmHdr().intValue();
148         } else if (resources != null) {
149             return resources.getInteger(R.integer.config_defaultRefreshRateInHbmHdr);
150         }
151         return DEFAULT_REFRESH_RATE_IN_HBM;
152     }
153 
loadDefaultRefreshRateInHbmSunlight( @ullable RefreshRateConfigs refreshRateConfigs, @Nullable Resources resources)154     private static int loadDefaultRefreshRateInHbmSunlight(
155             @Nullable RefreshRateConfigs refreshRateConfigs, @Nullable Resources resources) {
156         if (refreshRateConfigs != null
157                 && refreshRateConfigs.getDefaultRefreshRateInHbmSunlight() != null) {
158             return refreshRateConfigs.getDefaultRefreshRateInHbmSunlight().intValue();
159         } else if (resources != null) {
160             return resources.getInteger(R.integer.config_defaultRefreshRateInHbmSunlight);
161         }
162         return DEFAULT_REFRESH_RATE_IN_HBM;
163     }
164 }
165