Loading services/core/java/com/android/server/display/config/RefreshRateData.java +20 −5 Original line number Diff line number Diff line Loading @@ -20,6 +20,10 @@ import android.annotation.Nullable; import android.content.res.Resources; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import java.util.Collections; import java.util.List; /** * RefreshRates config for display Loading Loading @@ -58,12 +62,17 @@ public class RefreshRateData { */ public final int defaultRefreshRateInHbmSunlight; public final List<SupportedModeData> lowPowerSupportedModes; @VisibleForTesting public RefreshRateData(int defaultRefreshRate, int defaultPeakRefreshRate, int defaultRefreshRateInHbmHdr, int defaultRefreshRateInHbmSunlight) { int defaultRefreshRateInHbmHdr, int defaultRefreshRateInHbmSunlight, List<SupportedModeData> lowPowerSupportedModes) { this.defaultRefreshRate = defaultRefreshRate; this.defaultPeakRefreshRate = defaultPeakRefreshRate; this.defaultRefreshRateInHbmHdr = defaultRefreshRateInHbmHdr; this.defaultRefreshRateInHbmSunlight = defaultRefreshRateInHbmSunlight; this.lowPowerSupportedModes = Collections.unmodifiableList(lowPowerSupportedModes); } Loading @@ -71,9 +80,10 @@ public class RefreshRateData { public String toString() { return "RefreshRateData {" + "defaultRefreshRate: " + defaultRefreshRate + "defaultPeakRefreshRate: " + defaultPeakRefreshRate + "defaultRefreshRateInHbmHdr: " + defaultRefreshRateInHbmHdr + "defaultRefreshRateInHbmSunlight: " + defaultRefreshRateInHbmSunlight + ", defaultPeakRefreshRate: " + defaultPeakRefreshRate + ", defaultRefreshRateInHbmHdr: " + defaultRefreshRateInHbmHdr + ", defaultRefreshRateInHbmSunlight: " + defaultRefreshRateInHbmSunlight + ", lowPowerSupportedModes=" + lowPowerSupportedModes + "} "; } Loading @@ -90,8 +100,13 @@ public class RefreshRateData { int defaultRefreshRateInHbmSunlight = loadDefaultRefreshRateInHbmSunlight( refreshRateConfigs, resources); NonNegativeFloatToFloatMap modes = refreshRateConfigs == null ? null : refreshRateConfigs.getLowPowerSupportedModes(); List<SupportedModeData> lowPowerSupportedModes = SupportedModeData.load(modes); return new RefreshRateData(defaultRefreshRate, defaultPeakRefreshRate, defaultRefreshRateInHbmHdr, defaultRefreshRateInHbmSunlight); defaultRefreshRateInHbmHdr, defaultRefreshRateInHbmSunlight, lowPowerSupportedModes); } private static int loadDefaultRefreshRate( Loading services/core/java/com/android/server/display/config/SensorData.java +4 −20 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import android.text.TextUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.server.display.feature.DisplayManagerFlags; import java.util.ArrayList; import java.util.Collections; import java.util.List; Loading @@ -42,7 +41,7 @@ public class SensorData { public final String name; public final float minRefreshRate; public final float maxRefreshRate; public final List<SupportedMode> supportedModes; public final List<SupportedModeData> supportedModes; @VisibleForTesting public SensorData() { Loading @@ -61,7 +60,7 @@ public class SensorData { @VisibleForTesting public SensorData(String type, String name, float minRefreshRate, float maxRefreshRate, List<SupportedMode> supportedModes) { List<SupportedModeData> supportedModes) { this.type = type; this.name = name; this.minRefreshRate = minRefreshRate; Loading Loading @@ -214,26 +213,11 @@ public class SensorData { minRefreshRate = rr.getMinimum().floatValue(); maxRefreshRate = rr.getMaximum().floatValue(); } ArrayList<SupportedMode> supportedModes = new ArrayList<>(); NonNegativeFloatToFloatMap configSupportedModes = sensorDetails.getSupportedModes(); if (configSupportedModes != null) { for (NonNegativeFloatToFloatPoint supportedMode : configSupportedModes.getPoint()) { supportedModes.add(new SupportedMode(supportedMode.getFirst().floatValue(), supportedMode.getSecond().floatValue())); } } List<SupportedModeData> supportedModes = SupportedModeData.load( sensorDetails.getSupportedModes()); return new SensorData(sensorDetails.getType(), sensorDetails.getName(), minRefreshRate, maxRefreshRate, supportedModes); } public static class SupportedMode { public final float refreshRate; public final float vsyncRate; public SupportedMode(float refreshRate, float vsyncRate) { this.refreshRate = refreshRate; this.vsyncRate = vsyncRate; } } } services/core/java/com/android/server/display/config/SupportedModeData.java 0 → 100644 +54 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.display.config; import android.annotation.Nullable; import java.util.ArrayList; import java.util.List; /** * Supported display mode data. Display mode is uniquely identified by refreshRate-vsync pair */ public class SupportedModeData { public final float refreshRate; public final float vsyncRate; public SupportedModeData(float refreshRate, float vsyncRate) { this.refreshRate = refreshRate; this.vsyncRate = vsyncRate; } @Override public String toString() { return "SupportedModeData{" + "refreshRate= " + refreshRate + ", vsyncRate= " + vsyncRate + '}'; } static List<SupportedModeData> load(@Nullable NonNegativeFloatToFloatMap configMap) { ArrayList<SupportedModeData> supportedModes = new ArrayList<>(); if (configMap != null) { for (NonNegativeFloatToFloatPoint supportedMode : configMap.getPoint()) { supportedModes.add(new SupportedModeData(supportedMode.getFirst().floatValue(), supportedMode.getSecond().floatValue())); } } return supportedModes; } } services/core/java/com/android/server/display/mode/DisplayModeDirector.java +55 −22 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ import com.android.server.LocalServices; import com.android.server.display.DisplayDeviceConfig; import com.android.server.display.config.IdleScreenRefreshRateTimeoutLuxThresholdPoint; import com.android.server.display.config.RefreshRateData; import com.android.server.display.config.SupportedModeData; import com.android.server.display.feature.DeviceConfigParameterProvider; import com.android.server.display.feature.DisplayManagerFlags; import com.android.server.display.utils.AmbientFilter; Loading Loading @@ -451,15 +452,6 @@ public class DisplayModeDirector { return config != null && config.isVrrSupportEnabled(); } private boolean isVrrSupportedByAnyDisplayLocked() { for (int i = 0; i < mDisplayDeviceConfigByDisplay.size(); i++) { if (mDisplayDeviceConfigByDisplay.valueAt(i).isVrrSupportEnabled()) { return true; } } return false; } /** * Sets the desiredDisplayModeSpecsListener for changes to display mode and refresh rate ranges. */ Loading Loading @@ -939,18 +931,44 @@ public class DisplayModeDirector { private final Uri mMatchContentFrameRateSetting = Settings.Secure.getUriFor(Settings.Secure.MATCH_CONTENT_FRAME_RATE); private final boolean mVsynLowPowerVoteEnabled; private final boolean mVsyncLowPowerVoteEnabled; private final boolean mPeakRefreshRatePhysicalLimitEnabled; private final Context mContext; private final Handler mHandler; private float mDefaultPeakRefreshRate; private float mDefaultRefreshRate; private boolean mIsLowPower = false; private final DisplayManager.DisplayListener mDisplayListener = new DisplayManager.DisplayListener() { @Override public void onDisplayAdded(int displayId) { synchronized (mLock) { updateLowPowerModeAllowedModesLocked(); } } @Override public void onDisplayRemoved(int displayId) { mVotesStorage.updateVote(displayId, Vote.PRIORITY_LOW_POWER_MODE_MODES, null); } @Override public void onDisplayChanged(int displayId) { synchronized (mLock) { updateLowPowerModeAllowedModesLocked(); } } }; SettingsObserver(@NonNull Context context, @NonNull Handler handler, DisplayManagerFlags flags) { super(handler); mContext = context; mVsynLowPowerVoteEnabled = flags.isVsyncLowPowerVoteEnabled(); mHandler = handler; mVsyncLowPowerVoteEnabled = flags.isVsyncLowPowerVoteEnabled(); mPeakRefreshRatePhysicalLimitEnabled = flags.isPeakRefreshRatePhysicalLimitEnabled(); // We don't want to load from the DeviceConfig while constructing since this leads to // a spike in the latency of DisplayManagerService startup. This happens because Loading Loading @@ -983,6 +1001,7 @@ public class DisplayModeDirector { UserHandle.USER_SYSTEM); cr.registerContentObserver(mMatchContentFrameRateSetting, false /*notifyDescendants*/, this); mInjector.registerDisplayListener(mDisplayListener, mHandler); float deviceConfigDefaultPeakRefresh = mConfigParameterProvider.getPeakRefreshRateDefault(); Loading @@ -995,6 +1014,7 @@ public class DisplayModeDirector { updateLowPowerModeSettingLocked(); updateModeSwitchingTypeSettingLocked(); } } public void setDefaultRefreshRate(float refreshRate) { Loading Loading @@ -1061,23 +1081,36 @@ public class DisplayModeDirector { } private void updateLowPowerModeSettingLocked() { boolean inLowPowerMode = Settings.Global.getInt(mContext.getContentResolver(), mIsLowPower = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.LOW_POWER_MODE, 0 /*default*/) != 0; final Vote vote; if (inLowPowerMode && mVsynLowPowerVoteEnabled && isVrrSupportedByAnyDisplayLocked()) { vote = Vote.forSupportedRefreshRates(List.of( new SupportedRefreshRatesVote.RefreshRates(/* peakRefreshRate= */ 60f, /* vsyncRate= */ 240f), new SupportedRefreshRatesVote.RefreshRates(/* peakRefreshRate= */ 60f, /* vsyncRate= */ 60f) )); } else if (inLowPowerMode) { if (mIsLowPower) { vote = Vote.forRenderFrameRates(0f, 60f); } else { vote = null; } mVotesStorage.updateGlobalVote(Vote.PRIORITY_LOW_POWER_MODE, vote); mBrightnessObserver.onLowPowerModeEnabledLocked(inLowPowerMode); mVotesStorage.updateGlobalVote(Vote.PRIORITY_LOW_POWER_MODE_RENDER_RATE, vote); mBrightnessObserver.onLowPowerModeEnabledLocked(mIsLowPower); updateLowPowerModeAllowedModesLocked(); } private void updateLowPowerModeAllowedModesLocked() { if (!mVsyncLowPowerVoteEnabled) { return; } if (mIsLowPower) { for (int i = 0; i < mDisplayDeviceConfigByDisplay.size(); i++) { DisplayDeviceConfig config = mDisplayDeviceConfigByDisplay.valueAt(i); List<SupportedModeData> supportedModes = config .getRefreshRateData().lowPowerSupportedModes; mVotesStorage.updateVote( mDisplayDeviceConfigByDisplay.keyAt(i), Vote.PRIORITY_LOW_POWER_MODE_MODES, Vote.forSupportedRefreshRates(supportedModes)); } } else { mVotesStorage.removeAllVotesForPriority(Vote.PRIORITY_LOW_POWER_MODE_MODES); } } /** Loading services/core/java/com/android/server/display/mode/Vote.java +27 −10 Original line number Diff line number Diff line Loading @@ -18,6 +18,9 @@ package com.android.server.display.mode; import android.annotation.NonNull; import com.android.server.display.config.SupportedModeData; import java.util.ArrayList; import java.util.List; interface Vote { Loading Loading @@ -102,9 +105,15 @@ interface Vote { // For internal application to limit display modes to specific ids int PRIORITY_SYSTEM_REQUESTED_MODES = 14; // LOW_POWER_MODE force the render frame rate to [0, 60HZ] if // PRIORITY_LOW_POWER_MODE_MODES limits display modes to specific refreshRate-vsync pairs if // Settings.Global.LOW_POWER_MODE is on. // Lower priority that PRIORITY_LOW_POWER_MODE_RENDER_RATE and if discarded (due to other // higher priority votes), render rate limit can still apply int PRIORITY_LOW_POWER_MODE_MODES = 14; // PRIORITY_LOW_POWER_MODE_RENDER_RATE force the render frame rate to [0, 60HZ] if // Settings.Global.LOW_POWER_MODE is on. int PRIORITY_LOW_POWER_MODE = 15; int PRIORITY_LOW_POWER_MODE_RENDER_RATE = 15; // PRIORITY_FLICKER_REFRESH_RATE_SWITCH votes for disabling refresh rate switching. If the // higher priority voters' result is a range, it will fix the rate to a single choice. Loading Loading @@ -177,22 +186,26 @@ interface Vote { return new BaseModeRefreshRateVote(baseModeRefreshRate); } static Vote forSupportedRefreshRates( List<SupportedRefreshRatesVote.RefreshRates> refreshRates) { return new SupportedRefreshRatesVote(refreshRates); static Vote forSupportedRefreshRates(List<SupportedModeData> supportedModes) { if (supportedModes.isEmpty()) { return null; } List<SupportedRefreshRatesVote.RefreshRates> rates = new ArrayList<>(); for (SupportedModeData data : supportedModes) { rates.add(new SupportedRefreshRatesVote.RefreshRates(data.refreshRate, data.vsyncRate)); } return new SupportedRefreshRatesVote(rates); } static Vote forSupportedModes(List<Integer> modeIds) { return new SupportedModesVote(modeIds); } static Vote forSupportedRefreshRatesAndDisableSwitching( List<SupportedRefreshRatesVote.RefreshRates> supportedRefreshRates) { return new CombinedVote( List.of(forDisableRefreshRateSwitching(), forSupportedRefreshRates(supportedRefreshRates))); new SupportedRefreshRatesVote(supportedRefreshRates))); } static String priorityToString(int priority) { Loading @@ -213,8 +226,10 @@ interface Vote { return "PRIORITY_HIGH_BRIGHTNESS_MODE"; case PRIORITY_PROXIMITY: return "PRIORITY_PROXIMITY"; case PRIORITY_LOW_POWER_MODE: return "PRIORITY_LOW_POWER_MODE"; case PRIORITY_LOW_POWER_MODE_MODES: return "PRIORITY_LOW_POWER_MODE_MODES"; case PRIORITY_LOW_POWER_MODE_RENDER_RATE: return "PRIORITY_LOW_POWER_MODE_RENDER_RATE"; case PRIORITY_SKIN_TEMPERATURE: return "PRIORITY_SKIN_TEMPERATURE"; case PRIORITY_UDFPS: Loading @@ -227,6 +242,8 @@ interface Vote { return "PRIORITY_LIMIT_MODE"; case PRIORITY_SYNCHRONIZED_REFRESH_RATE: return "PRIORITY_SYNCHRONIZED_REFRESH_RATE"; case PRIORITY_USER_SETTING_PEAK_REFRESH_RATE: return "PRIORITY_USER_SETTING_PEAK_REFRESH_RATE"; case PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE: return "PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE"; case PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE: Loading Loading
services/core/java/com/android/server/display/config/RefreshRateData.java +20 −5 Original line number Diff line number Diff line Loading @@ -20,6 +20,10 @@ import android.annotation.Nullable; import android.content.res.Resources; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import java.util.Collections; import java.util.List; /** * RefreshRates config for display Loading Loading @@ -58,12 +62,17 @@ public class RefreshRateData { */ public final int defaultRefreshRateInHbmSunlight; public final List<SupportedModeData> lowPowerSupportedModes; @VisibleForTesting public RefreshRateData(int defaultRefreshRate, int defaultPeakRefreshRate, int defaultRefreshRateInHbmHdr, int defaultRefreshRateInHbmSunlight) { int defaultRefreshRateInHbmHdr, int defaultRefreshRateInHbmSunlight, List<SupportedModeData> lowPowerSupportedModes) { this.defaultRefreshRate = defaultRefreshRate; this.defaultPeakRefreshRate = defaultPeakRefreshRate; this.defaultRefreshRateInHbmHdr = defaultRefreshRateInHbmHdr; this.defaultRefreshRateInHbmSunlight = defaultRefreshRateInHbmSunlight; this.lowPowerSupportedModes = Collections.unmodifiableList(lowPowerSupportedModes); } Loading @@ -71,9 +80,10 @@ public class RefreshRateData { public String toString() { return "RefreshRateData {" + "defaultRefreshRate: " + defaultRefreshRate + "defaultPeakRefreshRate: " + defaultPeakRefreshRate + "defaultRefreshRateInHbmHdr: " + defaultRefreshRateInHbmHdr + "defaultRefreshRateInHbmSunlight: " + defaultRefreshRateInHbmSunlight + ", defaultPeakRefreshRate: " + defaultPeakRefreshRate + ", defaultRefreshRateInHbmHdr: " + defaultRefreshRateInHbmHdr + ", defaultRefreshRateInHbmSunlight: " + defaultRefreshRateInHbmSunlight + ", lowPowerSupportedModes=" + lowPowerSupportedModes + "} "; } Loading @@ -90,8 +100,13 @@ public class RefreshRateData { int defaultRefreshRateInHbmSunlight = loadDefaultRefreshRateInHbmSunlight( refreshRateConfigs, resources); NonNegativeFloatToFloatMap modes = refreshRateConfigs == null ? null : refreshRateConfigs.getLowPowerSupportedModes(); List<SupportedModeData> lowPowerSupportedModes = SupportedModeData.load(modes); return new RefreshRateData(defaultRefreshRate, defaultPeakRefreshRate, defaultRefreshRateInHbmHdr, defaultRefreshRateInHbmSunlight); defaultRefreshRateInHbmHdr, defaultRefreshRateInHbmSunlight, lowPowerSupportedModes); } private static int loadDefaultRefreshRate( Loading
services/core/java/com/android/server/display/config/SensorData.java +4 −20 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import android.text.TextUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.server.display.feature.DisplayManagerFlags; import java.util.ArrayList; import java.util.Collections; import java.util.List; Loading @@ -42,7 +41,7 @@ public class SensorData { public final String name; public final float minRefreshRate; public final float maxRefreshRate; public final List<SupportedMode> supportedModes; public final List<SupportedModeData> supportedModes; @VisibleForTesting public SensorData() { Loading @@ -61,7 +60,7 @@ public class SensorData { @VisibleForTesting public SensorData(String type, String name, float minRefreshRate, float maxRefreshRate, List<SupportedMode> supportedModes) { List<SupportedModeData> supportedModes) { this.type = type; this.name = name; this.minRefreshRate = minRefreshRate; Loading Loading @@ -214,26 +213,11 @@ public class SensorData { minRefreshRate = rr.getMinimum().floatValue(); maxRefreshRate = rr.getMaximum().floatValue(); } ArrayList<SupportedMode> supportedModes = new ArrayList<>(); NonNegativeFloatToFloatMap configSupportedModes = sensorDetails.getSupportedModes(); if (configSupportedModes != null) { for (NonNegativeFloatToFloatPoint supportedMode : configSupportedModes.getPoint()) { supportedModes.add(new SupportedMode(supportedMode.getFirst().floatValue(), supportedMode.getSecond().floatValue())); } } List<SupportedModeData> supportedModes = SupportedModeData.load( sensorDetails.getSupportedModes()); return new SensorData(sensorDetails.getType(), sensorDetails.getName(), minRefreshRate, maxRefreshRate, supportedModes); } public static class SupportedMode { public final float refreshRate; public final float vsyncRate; public SupportedMode(float refreshRate, float vsyncRate) { this.refreshRate = refreshRate; this.vsyncRate = vsyncRate; } } }
services/core/java/com/android/server/display/config/SupportedModeData.java 0 → 100644 +54 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.display.config; import android.annotation.Nullable; import java.util.ArrayList; import java.util.List; /** * Supported display mode data. Display mode is uniquely identified by refreshRate-vsync pair */ public class SupportedModeData { public final float refreshRate; public final float vsyncRate; public SupportedModeData(float refreshRate, float vsyncRate) { this.refreshRate = refreshRate; this.vsyncRate = vsyncRate; } @Override public String toString() { return "SupportedModeData{" + "refreshRate= " + refreshRate + ", vsyncRate= " + vsyncRate + '}'; } static List<SupportedModeData> load(@Nullable NonNegativeFloatToFloatMap configMap) { ArrayList<SupportedModeData> supportedModes = new ArrayList<>(); if (configMap != null) { for (NonNegativeFloatToFloatPoint supportedMode : configMap.getPoint()) { supportedModes.add(new SupportedModeData(supportedMode.getFirst().floatValue(), supportedMode.getSecond().floatValue())); } } return supportedModes; } }
services/core/java/com/android/server/display/mode/DisplayModeDirector.java +55 −22 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ import com.android.server.LocalServices; import com.android.server.display.DisplayDeviceConfig; import com.android.server.display.config.IdleScreenRefreshRateTimeoutLuxThresholdPoint; import com.android.server.display.config.RefreshRateData; import com.android.server.display.config.SupportedModeData; import com.android.server.display.feature.DeviceConfigParameterProvider; import com.android.server.display.feature.DisplayManagerFlags; import com.android.server.display.utils.AmbientFilter; Loading Loading @@ -451,15 +452,6 @@ public class DisplayModeDirector { return config != null && config.isVrrSupportEnabled(); } private boolean isVrrSupportedByAnyDisplayLocked() { for (int i = 0; i < mDisplayDeviceConfigByDisplay.size(); i++) { if (mDisplayDeviceConfigByDisplay.valueAt(i).isVrrSupportEnabled()) { return true; } } return false; } /** * Sets the desiredDisplayModeSpecsListener for changes to display mode and refresh rate ranges. */ Loading Loading @@ -939,18 +931,44 @@ public class DisplayModeDirector { private final Uri mMatchContentFrameRateSetting = Settings.Secure.getUriFor(Settings.Secure.MATCH_CONTENT_FRAME_RATE); private final boolean mVsynLowPowerVoteEnabled; private final boolean mVsyncLowPowerVoteEnabled; private final boolean mPeakRefreshRatePhysicalLimitEnabled; private final Context mContext; private final Handler mHandler; private float mDefaultPeakRefreshRate; private float mDefaultRefreshRate; private boolean mIsLowPower = false; private final DisplayManager.DisplayListener mDisplayListener = new DisplayManager.DisplayListener() { @Override public void onDisplayAdded(int displayId) { synchronized (mLock) { updateLowPowerModeAllowedModesLocked(); } } @Override public void onDisplayRemoved(int displayId) { mVotesStorage.updateVote(displayId, Vote.PRIORITY_LOW_POWER_MODE_MODES, null); } @Override public void onDisplayChanged(int displayId) { synchronized (mLock) { updateLowPowerModeAllowedModesLocked(); } } }; SettingsObserver(@NonNull Context context, @NonNull Handler handler, DisplayManagerFlags flags) { super(handler); mContext = context; mVsynLowPowerVoteEnabled = flags.isVsyncLowPowerVoteEnabled(); mHandler = handler; mVsyncLowPowerVoteEnabled = flags.isVsyncLowPowerVoteEnabled(); mPeakRefreshRatePhysicalLimitEnabled = flags.isPeakRefreshRatePhysicalLimitEnabled(); // We don't want to load from the DeviceConfig while constructing since this leads to // a spike in the latency of DisplayManagerService startup. This happens because Loading Loading @@ -983,6 +1001,7 @@ public class DisplayModeDirector { UserHandle.USER_SYSTEM); cr.registerContentObserver(mMatchContentFrameRateSetting, false /*notifyDescendants*/, this); mInjector.registerDisplayListener(mDisplayListener, mHandler); float deviceConfigDefaultPeakRefresh = mConfigParameterProvider.getPeakRefreshRateDefault(); Loading @@ -995,6 +1014,7 @@ public class DisplayModeDirector { updateLowPowerModeSettingLocked(); updateModeSwitchingTypeSettingLocked(); } } public void setDefaultRefreshRate(float refreshRate) { Loading Loading @@ -1061,23 +1081,36 @@ public class DisplayModeDirector { } private void updateLowPowerModeSettingLocked() { boolean inLowPowerMode = Settings.Global.getInt(mContext.getContentResolver(), mIsLowPower = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.LOW_POWER_MODE, 0 /*default*/) != 0; final Vote vote; if (inLowPowerMode && mVsynLowPowerVoteEnabled && isVrrSupportedByAnyDisplayLocked()) { vote = Vote.forSupportedRefreshRates(List.of( new SupportedRefreshRatesVote.RefreshRates(/* peakRefreshRate= */ 60f, /* vsyncRate= */ 240f), new SupportedRefreshRatesVote.RefreshRates(/* peakRefreshRate= */ 60f, /* vsyncRate= */ 60f) )); } else if (inLowPowerMode) { if (mIsLowPower) { vote = Vote.forRenderFrameRates(0f, 60f); } else { vote = null; } mVotesStorage.updateGlobalVote(Vote.PRIORITY_LOW_POWER_MODE, vote); mBrightnessObserver.onLowPowerModeEnabledLocked(inLowPowerMode); mVotesStorage.updateGlobalVote(Vote.PRIORITY_LOW_POWER_MODE_RENDER_RATE, vote); mBrightnessObserver.onLowPowerModeEnabledLocked(mIsLowPower); updateLowPowerModeAllowedModesLocked(); } private void updateLowPowerModeAllowedModesLocked() { if (!mVsyncLowPowerVoteEnabled) { return; } if (mIsLowPower) { for (int i = 0; i < mDisplayDeviceConfigByDisplay.size(); i++) { DisplayDeviceConfig config = mDisplayDeviceConfigByDisplay.valueAt(i); List<SupportedModeData> supportedModes = config .getRefreshRateData().lowPowerSupportedModes; mVotesStorage.updateVote( mDisplayDeviceConfigByDisplay.keyAt(i), Vote.PRIORITY_LOW_POWER_MODE_MODES, Vote.forSupportedRefreshRates(supportedModes)); } } else { mVotesStorage.removeAllVotesForPriority(Vote.PRIORITY_LOW_POWER_MODE_MODES); } } /** Loading
services/core/java/com/android/server/display/mode/Vote.java +27 −10 Original line number Diff line number Diff line Loading @@ -18,6 +18,9 @@ package com.android.server.display.mode; import android.annotation.NonNull; import com.android.server.display.config.SupportedModeData; import java.util.ArrayList; import java.util.List; interface Vote { Loading Loading @@ -102,9 +105,15 @@ interface Vote { // For internal application to limit display modes to specific ids int PRIORITY_SYSTEM_REQUESTED_MODES = 14; // LOW_POWER_MODE force the render frame rate to [0, 60HZ] if // PRIORITY_LOW_POWER_MODE_MODES limits display modes to specific refreshRate-vsync pairs if // Settings.Global.LOW_POWER_MODE is on. // Lower priority that PRIORITY_LOW_POWER_MODE_RENDER_RATE and if discarded (due to other // higher priority votes), render rate limit can still apply int PRIORITY_LOW_POWER_MODE_MODES = 14; // PRIORITY_LOW_POWER_MODE_RENDER_RATE force the render frame rate to [0, 60HZ] if // Settings.Global.LOW_POWER_MODE is on. int PRIORITY_LOW_POWER_MODE = 15; int PRIORITY_LOW_POWER_MODE_RENDER_RATE = 15; // PRIORITY_FLICKER_REFRESH_RATE_SWITCH votes for disabling refresh rate switching. If the // higher priority voters' result is a range, it will fix the rate to a single choice. Loading Loading @@ -177,22 +186,26 @@ interface Vote { return new BaseModeRefreshRateVote(baseModeRefreshRate); } static Vote forSupportedRefreshRates( List<SupportedRefreshRatesVote.RefreshRates> refreshRates) { return new SupportedRefreshRatesVote(refreshRates); static Vote forSupportedRefreshRates(List<SupportedModeData> supportedModes) { if (supportedModes.isEmpty()) { return null; } List<SupportedRefreshRatesVote.RefreshRates> rates = new ArrayList<>(); for (SupportedModeData data : supportedModes) { rates.add(new SupportedRefreshRatesVote.RefreshRates(data.refreshRate, data.vsyncRate)); } return new SupportedRefreshRatesVote(rates); } static Vote forSupportedModes(List<Integer> modeIds) { return new SupportedModesVote(modeIds); } static Vote forSupportedRefreshRatesAndDisableSwitching( List<SupportedRefreshRatesVote.RefreshRates> supportedRefreshRates) { return new CombinedVote( List.of(forDisableRefreshRateSwitching(), forSupportedRefreshRates(supportedRefreshRates))); new SupportedRefreshRatesVote(supportedRefreshRates))); } static String priorityToString(int priority) { Loading @@ -213,8 +226,10 @@ interface Vote { return "PRIORITY_HIGH_BRIGHTNESS_MODE"; case PRIORITY_PROXIMITY: return "PRIORITY_PROXIMITY"; case PRIORITY_LOW_POWER_MODE: return "PRIORITY_LOW_POWER_MODE"; case PRIORITY_LOW_POWER_MODE_MODES: return "PRIORITY_LOW_POWER_MODE_MODES"; case PRIORITY_LOW_POWER_MODE_RENDER_RATE: return "PRIORITY_LOW_POWER_MODE_RENDER_RATE"; case PRIORITY_SKIN_TEMPERATURE: return "PRIORITY_SKIN_TEMPERATURE"; case PRIORITY_UDFPS: Loading @@ -227,6 +242,8 @@ interface Vote { return "PRIORITY_LIMIT_MODE"; case PRIORITY_SYNCHRONIZED_REFRESH_RATE: return "PRIORITY_SYNCHRONIZED_REFRESH_RATE"; case PRIORITY_USER_SETTING_PEAK_REFRESH_RATE: return "PRIORITY_USER_SETTING_PEAK_REFRESH_RATE"; case PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE: return "PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE"; case PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE: Loading