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

Commit ede3ded5 authored by Santos Cordon's avatar Santos Cordon
Browse files

Add HDR-HBM support into framework.

Add a listener to know when HDR layers are present on displays
which support HBM.

Pass both HDR and SDR brightness requests from DPC to
SurfaceFlinger. Lots and lots of scaffolding for this.

Bug: 175321409
Bug: 175821789
Test: atest com.android.server.display
Test: Manually verify that brightness levels are correct when in high
      lux and HDR, low lux and HDR, and various luxes without HDR.
Change-Id: I530299455a7745fd57d44b1e8b20477674894e21
parent 3ec44592
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -33,7 +33,8 @@ public final class BrightnessInfo implements Parcelable {

    @IntDef(prefix = {"HIGH_BRIGHTNESS_MODE_"}, value = {
            HIGH_BRIGHTNESS_MODE_OFF,
            HIGH_BRIGHTNESS_MODE_SUNLIGHT
            HIGH_BRIGHTNESS_MODE_SUNLIGHT,
            HIGH_BRIGHTNESS_MODE_HDR
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface HighBrightnessMode {}
@@ -50,6 +51,12 @@ public final class BrightnessInfo implements Parcelable {
     */
    public static final int HIGH_BRIGHTNESS_MODE_SUNLIGHT = 1;

    /**
     * High brightness mode is ON due to high ambient light (sunlight). The high brightness range is
     * currently accessible to the user.
     */
    public static final int HIGH_BRIGHTNESS_MODE_HDR = 2;

    /** Brightness */
    public final float brightness;

@@ -73,6 +80,21 @@ public final class BrightnessInfo implements Parcelable {
        this.highBrightnessMode = highBrightnessMode;
    }

    /**
     * @return User-friendly string for specified {@link HighBrightnessMode} parameter.
     */
    public static String hbmToString(@HighBrightnessMode int highBrightnessMode) {
        switch (highBrightnessMode) {
            case HIGH_BRIGHTNESS_MODE_OFF:
                return "off";
            case HIGH_BRIGHTNESS_MODE_HDR:
                return "hdr";
            case HIGH_BRIGHTNESS_MODE_SUNLIGHT:
                return "sunlight";
        }
        return "invalid";
    }

    @Override
    public int describeContents() {
        return 0;
+7 −1
Original line number Diff line number Diff line
@@ -738,13 +738,19 @@ class AutomaticBrightnessController {
        float value = mBrightnessMapper.getBrightness(mAmbientLux, mForegroundAppPackageName,
                mForegroundAppCategory);
        float newScreenAutoBrightness = clampScreenBrightness(value);

        // The min/max range can change for brightness due to HBM. See if the current brightness
        // value still falls within the current range (which could have changed).
        final boolean currentBrightnessWithinAllowedRange = BrightnessSynchronizer.floatEquals(
                mScreenAutoBrightness, clampScreenBrightness(mScreenAutoBrightness));
        // If screenAutoBrightness is set, we should have screen{Brightening,Darkening}Threshold,
        // in which case we ignore the new screen brightness if it doesn't differ enough from the
        // previous one.
        if (!Float.isNaN(mScreenAutoBrightness)
                && !isManuallySet
                && newScreenAutoBrightness > mScreenDarkeningThreshold
                && newScreenAutoBrightness < mScreenBrighteningThreshold) {
                && newScreenAutoBrightness < mScreenBrighteningThreshold
                && currentBrightnessWithinAllowedRange) {
            if (mLoggingEnabled) {
                Slog.d(TAG, "ignoring newScreenAutoBrightness: "
                        + mScreenDarkeningThreshold + " < " + newScreenAutoBrightness
+4 −1
Original line number Diff line number Diff line
@@ -20,5 +20,8 @@ package com.android.server.display;
 * Interface used to update the actual display state.
 */
public interface DisplayBlanker {
    void requestDisplayState(int displayId, int state, float brightness);
    /**
     * Requests the specified display state and brightness levels for the specified displayId.
     */
    void requestDisplayState(int displayId, int state, float brightness, float sdrBrightness);
}
+3 −1
Original line number Diff line number Diff line
@@ -156,10 +156,12 @@ abstract class DisplayDevice {
     *
     * @param state The new display state.
     * @param brightnessState The new display brightnessState.
     * @param sdrBrightnessState The new display brightnessState for SDR layers.
     * @return A runnable containing work to be deferred until after we have
     * exited the critical section, or null if none.
     */
    public Runnable requestDisplayStateLocked(int state, float brightnessState) {
    public Runnable requestDisplayStateLocked(int state, float brightnessState,
            float sdrBrightnessState) {
        return null;
    }

+23 −0
Original line number Diff line number Diff line
@@ -104,6 +104,7 @@ public class DisplayDeviceConfig {
    private float mBrightnessRampSlowIncrease = Float.NaN;
    private Spline mBrightnessToBacklightSpline;
    private Spline mBacklightToBrightnessSpline;
    private Spline mBacklightToNitsSpline;
    private List<String> mQuirks;
    private boolean mIsHighBrightnessModeEnabled = false;
    private HighBrightnessModeData mHbmData;
@@ -218,6 +219,20 @@ public class DisplayDeviceConfig {
        return mBrightnessToBacklightSpline.interpolate(brightness);
    }

    /**
     * Calculates the nits value for the specified backlight value if a mapping exists.
     *
     * @return The mapped nits or 0 if no mapping exits.
     */
    public float getNitsFromBacklight(float backlight) {
        if (mBacklightToNitsSpline == null) {
            Slog.wtf(TAG, "requesting nits when no mapping exists.");
            return -1;
        }
        backlight = Math.max(backlight, mBacklightMinimum);
        return mBacklightToNitsSpline.interpolate(backlight);
    }

    /**
     * Return an array of equal length to backlight and nits, that covers the entire system
     * brightness range of 0.0-1.0.
@@ -257,6 +272,13 @@ public class DisplayDeviceConfig {
        return mAmbientLightSensor;
    }

    /**
     * @return true if a nits to backlight mapping is defined in this config, false otherwise.
     */
    public boolean hasNitsMapping() {
        return mBacklightToNitsSpline != null;
    }

    /**
     * @param quirkValue The quirk to test.
     * @return {@code true} if the specified quirk is present in this configuration,
@@ -584,6 +606,7 @@ public class DisplayDeviceConfig {
        }
        mBrightnessToBacklightSpline = Spline.createSpline(mBrightness, mBacklight);
        mBacklightToBrightnessSpline = Spline.createSpline(mBacklight, mBrightness);
        mBacklightToNitsSpline = Spline.createSpline(mBacklight, mNits);
    }

    private void loadQuirks(DisplayConfiguration config) {
Loading