Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ddc1da92 authored by Piotr Wilczyński's avatar Piotr Wilczyński
Browse files

Use concurrent displays brightness throttling map if needed

- add a property to display layout config
- add a property to LogicalDisplay
- pick the appropriate throttling map in DPC

Bug: 241308595
Test: atest com.android.server.display
Test: adb shell dumpsys display | grep LogicalDisplay
Test: adb shell dumpsys display | grep BrightnessThrottler
Change-Id: I172860016961696b15e3e308e8594920640afc28
parent 32338521
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -122,7 +122,8 @@ class DeviceStateToLayoutMap {
                            DisplayAddress.fromPhysicalDisplayId(d.getAddress().longValue()),
                            d.isDefaultDisplay(),
                            d.isEnabled(),
                            mIdProducer);
                            mIdProducer,
                            d.getBrightnessThrottlingMapId());

                    if (FRONT_STRING.equals(d.getPosition())) {
                        display.setPosition(POSITION_FRONT);
+37 −81
Original line number Diff line number Diff line
@@ -74,8 +74,10 @@ import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.xml.datatype.DatatypeConfigurationException;

@@ -411,6 +413,8 @@ public class DisplayDeviceConfig {

    public static final String QUIRK_CAN_SET_BRIGHTNESS_VIA_HWC = "canSetBrightnessViaHwc";

    static final String DEFAULT_BRIGHTNESS_THROTTLING_DATA_ID = "default";

    private static final float BRIGHTNESS_DEFAULT = 0.5f;
    private static final String ETC_DIR = "etc";
    private static final String DISPLAY_CONFIG_DIR = "displayconfig";
@@ -627,13 +631,7 @@ public class DisplayDeviceConfig {
    private int[] mHighDisplayBrightnessThresholds = DEFAULT_BRIGHTNESS_THRESHOLDS;
    private int[] mHighAmbientBrightnessThresholds = DEFAULT_BRIGHTNESS_THRESHOLDS;

    // Brightness Throttling data may be updated via the DeviceConfig. Here we store the original
    // data, which comes from the ddc, and the current one, which may be the DeviceConfig
    // overwritten value.
    private BrightnessThrottlingData mBrightnessThrottlingData;
    private BrightnessThrottlingData mOriginalBrightnessThrottlingData;
    // The concurrent displays mode might need a stricter throttling policy
    private BrightnessThrottlingData mConcurrentDisplaysBrightnessThrottlingData;
    private Map<String, BrightnessThrottlingData> mBrightnessThrottlingDataMap = new HashMap();

    @Nullable
    private HostUsiVersion mHostUsiVersion;
@@ -779,10 +777,6 @@ public class DisplayDeviceConfig {
        return config;
    }

    void setBrightnessThrottlingData(BrightnessThrottlingData brightnessThrottlingData) {
        mBrightnessThrottlingData = brightnessThrottlingData;
    }

    /**
     * Return the brightness mapping nits array.
     *
@@ -1282,18 +1276,11 @@ public class DisplayDeviceConfig {
    }

    /**
     * @param id The ID of the throttling data
     * @return brightness throttling configuration data for the display.
     */
    public BrightnessThrottlingData getBrightnessThrottlingData() {
        return BrightnessThrottlingData.create(mBrightnessThrottlingData);
    }

    /**
     * @return brightness throttling configuration data for the display for the concurrent
     * displays mode.
     */
    public BrightnessThrottlingData getConcurrentDisplaysBrightnessThrottlingData() {
        return BrightnessThrottlingData.create(mConcurrentDisplaysBrightnessThrottlingData);
    public BrightnessThrottlingData getBrightnessThrottlingData(String id) {
        return BrightnessThrottlingData.create(mBrightnessThrottlingDataMap.get(id));
    }

    /**
@@ -1411,8 +1398,7 @@ public class DisplayDeviceConfig {
                + ", isHbmEnabled=" + mIsHighBrightnessModeEnabled
                + ", mHbmData=" + mHbmData
                + ", mSdrToHdrRatioSpline=" + mSdrToHdrRatioSpline
                + ", mBrightnessThrottlingData=" + mBrightnessThrottlingData
                + ", mOriginalBrightnessThrottlingData=" + mOriginalBrightnessThrottlingData
                + ", mBrightnessThrottlingData=" + mBrightnessThrottlingDataMap
                + "\n"
                + ", mBrightnessRampFastDecrease=" + mBrightnessRampFastDecrease
                + ", mBrightnessRampFastIncrease=" + mBrightnessRampFastIncrease
@@ -1545,8 +1531,7 @@ public class DisplayDeviceConfig {
                loadBrightnessDefaultFromDdcXml(config);
                loadBrightnessConstraintsFromConfigXml();
                loadBrightnessMap(config);
                loadBrightnessThrottlingMap(config);
                loadConcurrentDisplaysBrightnessThrottlingMap(config);
                loadBrightnessThrottlingMaps(config);
                loadHighBrightnessModeData(config);
                loadQuirks(config);
                loadBrightnessRamps(config);
@@ -1756,19 +1741,20 @@ public class DisplayDeviceConfig {
        return Spline.createSpline(nits, ratios);
    }

    private void loadBrightnessThrottlingMap(DisplayConfiguration config) {
    private void loadBrightnessThrottlingMaps(DisplayConfiguration config) {
        final ThermalThrottling throttlingConfig = config.getThermalThrottling();
        if (throttlingConfig == null) {
            Slog.i(TAG, "No thermal throttling config found");
            return;
        }

        final BrightnessThrottlingMap map = throttlingConfig.getBrightnessThrottlingMap();
        if (map == null) {
        final List<BrightnessThrottlingMap> maps = throttlingConfig.getBrightnessThrottlingMap();
        if (maps == null || maps.isEmpty()) {
            Slog.i(TAG, "No brightness throttling map found");
            return;
        }

        for (BrightnessThrottlingMap map : maps) {
            final List<BrightnessThrottlingPoint> points = map.getBrightnessThrottlingPoint();
            // At least 1 point is guaranteed by the display device config schema
            List<BrightnessThrottlingData.ThrottlingLevel> throttlingLevels =
@@ -1787,45 +1773,15 @@ public class DisplayDeviceConfig {
            }

            if (!badConfig) {
            mBrightnessThrottlingData = BrightnessThrottlingData.create(throttlingLevels);
            mOriginalBrightnessThrottlingData = mBrightnessThrottlingData;
        }
    }

    private void loadConcurrentDisplaysBrightnessThrottlingMap(DisplayConfiguration config) {
        final ThermalThrottling throttlingConfig = config.getThermalThrottling();
        if (throttlingConfig == null) {
            Slog.i(TAG, "No concurrent displays thermal throttling config found");
            return;
        }

        final BrightnessThrottlingMap map =
                throttlingConfig.getConcurrentDisplaysBrightnessThrottlingMap();
        if (map == null) {
            Slog.i(TAG, "No concurrent displays brightness throttling map found");
            return;
                String id = map.getId() == null ? DEFAULT_BRIGHTNESS_THROTTLING_DATA_ID
                        : map.getId();
                if (mBrightnessThrottlingDataMap.containsKey(id)) {
                    throw new RuntimeException("Brightness throttling data with ID " + id
                            + " already exists");
                }

        final List<BrightnessThrottlingPoint> points = map.getBrightnessThrottlingPoint();
        // At least 1 point is guaranteed by the display device config schema
        List<BrightnessThrottlingData.ThrottlingLevel> throttlingLevels =
                new ArrayList<>(points.size());

        boolean badConfig = false;
        for (BrightnessThrottlingPoint point : points) {
            ThermalStatus status = point.getThermalStatus();
            if (!thermalStatusIsValid(status)) {
                badConfig = true;
                break;
                mBrightnessThrottlingDataMap.put(id,
                        BrightnessThrottlingData.create(throttlingLevels));
            }

            throttlingLevels.add(new BrightnessThrottlingData.ThrottlingLevel(
                    convertThermalStatus(status), point.getBrightness().floatValue()));
        }

        if (!badConfig) {
            mConcurrentDisplaysBrightnessThrottlingData =
                    BrightnessThrottlingData.create(throttlingLevels);
        }
    }

+17 −12
Original line number Diff line number Diff line
@@ -504,6 +504,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    private boolean mIsEnabled;
    private boolean mIsInTransition;

    private String mBrightnessThrottlingDataId;

    // DPCs following the brightness of this DPC. This is used in concurrent displays mode - there
    // is one lead display, the additional displays follow the brightness value of the lead display.
    @GuardedBy("mLock")
@@ -539,6 +541,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        mHandler = new DisplayControllerHandler(handler.getLooper());
        mLastBrightnessEvent = new BrightnessEvent(mDisplayId);
        mTempBrightnessEvent = new BrightnessEvent(mDisplayId);
        mBrightnessThrottlingDataId = logicalDisplay.getBrightnessThrottlingDataIdLocked();

        if (mDisplayId == Display.DEFAULT_DISPLAY) {
            mBatteryStats = BatteryStatsService.getService();
@@ -860,6 +863,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
        final boolean isEnabled = mLogicalDisplay.isEnabledLocked();
        final boolean isInTransition = mLogicalDisplay.isInTransitionLocked();
        final String brightnessThrottlingDataId =
                mLogicalDisplay.getBrightnessThrottlingDataIdLocked();
        mHandler.post(() -> {
            boolean changed = false;
            if (mDisplayDevice != device) {
@@ -868,12 +873,19 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                mUniqueDisplayId = uniqueId;
                mDisplayStatsId = mUniqueDisplayId.hashCode();
                mDisplayDeviceConfig = config;
                mBrightnessThrottlingDataId = brightnessThrottlingDataId;
                loadFromDisplayDeviceConfig(token, info, hbmMetadata);

                /// Since the underlying display-device changed, we really don't know the
                // last command that was sent to change it's state. Lets assume it is unknown so
                // that we trigger a change immediately.
                mPowerState.resetScreenState();
            } else if (!mBrightnessThrottlingDataId.equals(brightnessThrottlingDataId)) {
                changed = true;
                mBrightnessThrottlingDataId = brightnessThrottlingDataId;
                mBrightnessThrottler.resetThrottlingData(
                        config.getBrightnessThrottlingData(mBrightnessThrottlingDataId),
                        mUniqueDisplayId);
            }
            if (mIsEnabled != isEnabled || mIsInTransition != isInTransition) {
                changed = true;
@@ -885,9 +897,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                updatePowerState();
            }
        });

        // TODO (b/265793751): Re-create BrightnessTracker if we're enetering/exiting concurrent
        // displays mode
    }

    /**
@@ -946,10 +955,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                        return mDisplayDeviceConfig.getHdrBrightnessFromSdr(sdrBrightness);
                    }
                });
        // TODO (b/265793751): Use the appropriate throttling data if we're in concurrent displays
        // mode
        mBrightnessThrottler.resetThrottlingData(
                mDisplayDeviceConfig.getBrightnessThrottlingData(), mUniqueDisplayId);
                mDisplayDeviceConfig.getBrightnessThrottlingData(mBrightnessThrottlingDataId),
                mUniqueDisplayId);
    }

    private void sendUpdatePowerState() {
@@ -2053,11 +2061,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    private BrightnessThrottler createBrightnessThrottlerLocked() {
        final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
        final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig();
        // TODO (b/265793751): Use the appropriate throttling data if we're in concurrent displays
        // mode
        final DisplayDeviceConfig.BrightnessThrottlingData data =
                ddConfig != null ? ddConfig.getBrightnessThrottlingData() : null;
        return new BrightnessThrottler(mHandler, data,
        return new BrightnessThrottler(mHandler,
                ddConfig.getBrightnessThrottlingData(mBrightnessThrottlingDataId),
                () -> {
                    sendUpdatePowerState();
                    postBrightnessChangeRunnable();
+17 −12
Original line number Diff line number Diff line
@@ -411,6 +411,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
    private boolean mIsEnabled;
    private boolean mIsInTransition;

    private String mBrightnessThrottlingDataId;

    // DPCs following the brightness of this DPC. This is used in concurrent displays mode - there
    // is one lead display, the additional displays follow the brightness value of the lead display.
    @GuardedBy("mLock")
@@ -443,6 +445,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
        mHighBrightnessModeMetadata = hbmMetadata;
        mDisplayStateController = new DisplayStateController(mDisplayPowerProximityStateController);
        mTag = "DisplayPowerController2[" + mDisplayId + "]";
        mBrightnessThrottlingDataId = logicalDisplay.getBrightnessThrottlingDataIdLocked();

        mDisplayDevice = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
        mUniqueDisplayId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
@@ -705,6 +708,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
        final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
        final boolean isEnabled = mLogicalDisplay.isEnabledLocked();
        final boolean isInTransition = mLogicalDisplay.isInTransitionLocked();
        final String brightnessThrottlingDataId =
                mLogicalDisplay.getBrightnessThrottlingDataIdLocked();

        mHandler.post(() -> {
            boolean changed = false;
@@ -714,6 +719,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
                mUniqueDisplayId = uniqueId;
                mDisplayStatsId = mUniqueDisplayId.hashCode();
                mDisplayDeviceConfig = config;
                mBrightnessThrottlingDataId = brightnessThrottlingDataId;
                loadFromDisplayDeviceConfig(token, info, hbmMetadata);
                mDisplayPowerProximityStateController.notifyDisplayDeviceChanged(config);

@@ -721,6 +727,12 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
                // last command that was sent to change it's state. Lets assume it is unknown so
                // that we trigger a change immediately.
                mPowerState.resetScreenState();
            } else if (!mBrightnessThrottlingDataId.equals(brightnessThrottlingDataId)) {
                changed = true;
                mBrightnessThrottlingDataId = brightnessThrottlingDataId;
                mBrightnessThrottler.resetThrottlingData(
                        config.getBrightnessThrottlingData(mBrightnessThrottlingDataId),
                        mUniqueDisplayId);
            }
            if (mIsEnabled != isEnabled || mIsInTransition != isInTransition) {
                changed = true;
@@ -732,9 +744,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
                updatePowerState();
            }
        });

        // TODO (b/265793751): Re-create BrightnessTracker if we're enetering/exiting concurrent
        // displays mode
    }

    /**
@@ -786,10 +795,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
                        return mDisplayDeviceConfig.getHdrBrightnessFromSdr(sdrBrightness);
                    }
                });
        // TODO (b/265793751): Use the appropriate throttling data if we're in concurrent displays
        // mode
        mBrightnessThrottler.resetThrottlingData(
                mDisplayDeviceConfig.getBrightnessThrottlingData(), mUniqueDisplayId);
                mDisplayDeviceConfig.getBrightnessThrottlingData(mBrightnessThrottlingDataId),
                mUniqueDisplayId);
    }

    private void sendUpdatePowerState() {
@@ -1760,11 +1768,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
    private BrightnessThrottler createBrightnessThrottlerLocked() {
        final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
        final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig();
        // TODO (b/265793751): Use the appropriate throttling data if we're in concurrent displays
        // mode
        final DisplayDeviceConfig.BrightnessThrottlingData data =
                ddConfig != null ? ddConfig.getBrightnessThrottlingData() : null;
        return new BrightnessThrottler(mHandler, data,
        return new BrightnessThrottler(mHandler,
                ddConfig.getBrightnessThrottlingData(mBrightnessThrottlingDataId),
                () -> {
                    sendUpdatePowerState();
                    postBrightnessChangeRunnable();
+26 −1
Original line number Diff line number Diff line
@@ -152,6 +152,13 @@ final class LogicalDisplay {
    // the {@link mIsEnabled} is changing, or the underlying mPrimiaryDisplayDevice is changing.
    private boolean mIsInTransition;

    /**
     * The ID of the brightness throttling data that should be used. This can change e.g. in
     * concurrent displays mode in which a stricter brightness throttling policy might need to be
     * used.
     */
    private String mBrightnessThrottlingDataId;

    public LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice) {
        mDisplayId = displayId;
        mLayerStack = layerStack;
@@ -160,6 +167,7 @@ final class LogicalDisplay {
        mTempFrameRateOverride = new SparseArray<>();
        mIsEnabled = true;
        mIsInTransition = false;
        mBrightnessThrottlingDataId = DisplayDeviceConfig.DEFAULT_BRIGHTNESS_THROTTLING_DATA_ID;
    }

    /**
@@ -762,7 +770,7 @@ final class LogicalDisplay {
    /**
     * Sets the display as enabled.
     *
     * @param enable True if enabled, false otherwise.
     * @param enabled True if enabled, false otherwise.
     */
    public void setEnabledLocked(boolean enabled) {
        mIsEnabled = enabled;
@@ -785,6 +793,22 @@ final class LogicalDisplay {
        mIsInTransition = isInTransition;
    }

    /**
     * @return The ID of the brightness throttling data that this display should use.
     */
    public String getBrightnessThrottlingDataIdLocked() {
        return mBrightnessThrottlingDataId;
    }

    /**
     * @param brightnessThrottlingDataId The ID of the brightness throttling data that this
     *                                  display should use.
     */
    public void setBrightnessThrottlingDataIdLocked(String brightnessThrottlingDataId) {
        mBrightnessThrottlingDataId =
                brightnessThrottlingDataId;
    }

    public void dumpLocked(PrintWriter pw) {
        pw.println("mDisplayId=" + mDisplayId);
        pw.println("mIsEnabled=" + mIsEnabled);
@@ -802,6 +826,7 @@ final class LogicalDisplay {
        pw.println("mRequestedMinimalPostProcessing=" + mRequestedMinimalPostProcessing);
        pw.println("mFrameRateOverrides=" + Arrays.toString(mFrameRateOverrides));
        pw.println("mPendingFrameRateOverrideUids=" + mPendingFrameRateOverrideUids);
        pw.println("mBrightnessThrottlingDataId=" + mBrightnessThrottlingDataId);
    }

    @Override
Loading