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

Commit 8ffa54c2 authored by Oleg Petšjonkin's avatar Oleg Petšjonkin Committed by Android (Google) Code Review
Browse files

Merge "HdrClamper: properly handling hdr visible/invisible events" into main

parents b05b0b65 64395bf1
Loading
Loading
Loading
Loading
+20 −10
Original line number Diff line number Diff line
@@ -43,14 +43,16 @@ class BrightnessRangeController {

    BrightnessRangeController(HighBrightnessModeController hbmController,
            Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, Handler handler,
            DisplayManagerFlags flags) {
            DisplayManagerFlags flags, IBinder displayToken, DisplayDeviceInfo info) {
        this(hbmController, modeChangeCallback, displayDeviceConfig,
                new HdrClamper(modeChangeCallback::run, new Handler(handler.getLooper())), flags);
                new HdrClamper(modeChangeCallback::run, new Handler(handler.getLooper())), flags,
                displayToken, info);
    }

    BrightnessRangeController(HighBrightnessModeController hbmController,
            Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig,
            HdrClamper hdrClamper, DisplayManagerFlags flags) {
            HdrClamper hdrClamper, DisplayManagerFlags flags, IBinder displayToken,
            DisplayDeviceInfo info) {
        mHbmController = hbmController;
        mModeChangeCallback = modeChangeCallback;
        mHdrClamper = hdrClamper;
@@ -60,10 +62,7 @@ class BrightnessRangeController {
            mNormalBrightnessModeController.resetNbmData(
                    displayDeviceConfig.getLuxThrottlingData());
        }
        if (mUseHdrClamper) {
            mHdrClamper.resetHdrConfig(displayDeviceConfig.getHdrBrightnessData());
        }

        updateHdrClamper(info, displayToken, displayDeviceConfig);
    }

    void dump(PrintWriter pw) {
@@ -101,13 +100,12 @@ class BrightnessRangeController {
                            displayDeviceConfig::getHdrBrightnessFromSdr);
                }
        );
        if (mUseHdrClamper) {
            mHdrClamper.resetHdrConfig(displayDeviceConfig.getHdrBrightnessData());
        }
        updateHdrClamper(info, token, displayDeviceConfig);
    }

    void stop() {
        mHbmController.stop();
        mHdrClamper.stop();
    }

    void setAutoBrightnessEnabled(int state) {
@@ -151,6 +149,18 @@ class BrightnessRangeController {
        return mHbmController.getTransitionPoint();
    }

    private void updateHdrClamper(DisplayDeviceInfo info, IBinder token,
            DisplayDeviceConfig displayDeviceConfig) {
        if (mUseHdrClamper) {
            DisplayDeviceConfig.HighBrightnessModeData hbmData =
                    displayDeviceConfig.getHighBrightnessModeData();
            float minimumHdrPercentOfScreen =
                    hbmData == null ? -1f : hbmData.minimumHdrPercentOfScreen;
            mHdrClamper.resetHdrConfig(displayDeviceConfig.getHdrBrightnessData(), info.width,
                    info.height, minimumHdrPercentOfScreen, token);
        }
    }

    private void applyChanges(BooleanSupplier nbmChangesFunc, Runnable hbmChangesFunc) {
        if (mUseNbmController) {
            boolean nbmTransitionChanged = nbmChangesFunc.getAsBoolean();
+3 −1
Original line number Diff line number Diff line
@@ -687,7 +687,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        HighBrightnessModeController hbmController = createHbmControllerLocked(modeChangeCallback);

        mBrightnessRangeController = new BrightnessRangeController(hbmController,
                modeChangeCallback, mDisplayDeviceConfig, mHandler, flags);
                modeChangeCallback, mDisplayDeviceConfig, mHandler, flags,
                mDisplayDevice.getDisplayTokenLocked(),
                mDisplayDevice.getDisplayDeviceInfoLocked());

        mBrightnessThrottler = createBrightnessThrottlerLocked();

+9 −10
Original line number Diff line number Diff line
@@ -552,7 +552,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
        mBrightnessThrottler = createBrightnessThrottlerLocked();

        mBrightnessRangeController = mInjector.getBrightnessRangeController(hbmController,
                modeChangeCallback, mDisplayDeviceConfig, mHandler, flags);
                modeChangeCallback, mDisplayDeviceConfig, mHandler, flags,
                mDisplayDevice.getDisplayTokenLocked(),
                mDisplayDevice.getDisplayDeviceInfoLocked());

        mDisplayBrightnessController =
                new DisplayBrightnessController(context, null,
@@ -1896,15 +1898,12 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal

    private HighBrightnessModeController createHbmControllerLocked(
            HighBrightnessModeMetadata hbmMetadata, Runnable modeChangeCallback) {
        final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
        final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig();
        final IBinder displayToken =
                mLogicalDisplay.getPrimaryDisplayDeviceLocked().getDisplayTokenLocked();
        final String displayUniqueId =
                mLogicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
        final DisplayDeviceConfig ddConfig = mDisplayDevice.getDisplayDeviceConfig();
        final IBinder displayToken = mDisplayDevice.getDisplayTokenLocked();
        final String displayUniqueId = mDisplayDevice.getUniqueId();
        final DisplayDeviceConfig.HighBrightnessModeData hbmData =
                ddConfig != null ? ddConfig.getHighBrightnessModeData() : null;
        final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
        final DisplayDeviceInfo info = mDisplayDevice.getDisplayDeviceInfoLocked();
        return mInjector.getHighBrightnessModeController(mHandler, info.width, info.height,
                displayToken, displayUniqueId, PowerManager.BRIGHTNESS_MIN,
                PowerManager.BRIGHTNESS_MAX, hbmData, (sdrBrightness, maxDesiredHdrSdrRatio) ->
@@ -3050,9 +3049,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
        BrightnessRangeController getBrightnessRangeController(
                HighBrightnessModeController hbmController, Runnable modeChangeCallback,
                DisplayDeviceConfig displayDeviceConfig, Handler handler,
                DisplayManagerFlags flags) {
                DisplayManagerFlags flags, IBinder displayToken, DisplayDeviceInfo info) {
            return new BrightnessRangeController(hbmController,
                    modeChangeCallback, displayDeviceConfig, handler, flags);
                    modeChangeCallback, displayDeviceConfig, handler, flags, displayToken, info);
        }

        DisplayWhiteBalanceController getDisplayWhiteBalanceController(Handler handler,
+98 −7
Original line number Diff line number Diff line
@@ -17,9 +17,13 @@
package com.android.server.display.brightness.clamper;

import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
import android.view.SurfaceControlHdrLayerInfoListener;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.display.config.HdrBrightnessData;

import java.io.PrintWriter;
@@ -33,11 +37,18 @@ public class HdrClamper {

    private final Runnable mDebouncer;

    private final HdrLayerInfoListener mHdrListener;

    @Nullable
    private HdrBrightnessData mHdrBrightnessData = null;

    @Nullable
    private IBinder mRegisteredDisplayToken = null;

    private float mAmbientLux = Float.MAX_VALUE;

    private boolean mHdrVisible = false;

    private float mMaxBrightness = PowerManager.BRIGHTNESS_MAX;
    private float mDesiredMaxBrightness = PowerManager.BRIGHTNESS_MAX;

@@ -47,6 +58,12 @@ public class HdrClamper {

    public HdrClamper(BrightnessClamperController.ClamperChangeListener clamperChangeListener,
            Handler handler) {
        this(clamperChangeListener, handler, new Injector());
    }

    @VisibleForTesting
    public HdrClamper(BrightnessClamperController.ClamperChangeListener clamperChangeListener,
            Handler handler, Injector injector) {
        mClamperChangeListener = clamperChangeListener;
        mHandler = handler;
        mDebouncer = () -> {
@@ -54,6 +71,10 @@ public class HdrClamper {
            mMaxBrightness = mDesiredMaxBrightness;
            mClamperChangeListener.onChanged();
        };
        mHdrListener = injector.getHdrListener((visible) -> {
            mHdrVisible = visible;
            recalculateBrightnessCap(mHdrBrightnessData, mAmbientLux, mHdrVisible);
        }, handler);
    }

    // Called in same looper: mHandler.getLooper()
@@ -72,16 +93,37 @@ public class HdrClamper {
     */
    public void onAmbientLuxChange(float ambientLux) {
        mAmbientLux = ambientLux;
        recalculateBrightnessCap(mHdrBrightnessData, ambientLux);
        recalculateBrightnessCap(mHdrBrightnessData, ambientLux, mHdrVisible);
    }

    /**
     * Updates brightness cap config.
     * Called in same looper: mHandler.getLooper()
     */
    public void resetHdrConfig(HdrBrightnessData data) {
    @SuppressLint("AndroidFrameworkRequiresPermission")
    public void resetHdrConfig(HdrBrightnessData data, int width, int height,
            float minimumHdrPercentOfScreen, IBinder displayToken) {
        mHdrBrightnessData = data;
        recalculateBrightnessCap(data, mAmbientLux);
        mHdrListener.mHdrMinPixels = (float) (width * height) * minimumHdrPercentOfScreen;
        if (displayToken != mRegisteredDisplayToken) { // token changed, resubscribe
            if (mRegisteredDisplayToken != null) { // previous token not null, unsubscribe
                mHdrListener.unregister(mRegisteredDisplayToken);
                mHdrVisible = false;
            }
            if (displayToken != null) { // new token not null, subscribe
                mHdrListener.register(displayToken);
            }
            mRegisteredDisplayToken = displayToken;
        }
        recalculateBrightnessCap(data, mAmbientLux, mHdrVisible);
    }

    /** Clean up all resources */
    @SuppressLint("AndroidFrameworkRequiresPermission")
    public void stop() {
        if (mRegisteredDisplayToken != null) {
            mHdrListener.unregister(mRegisteredDisplayToken);
        }
    }

    /**
@@ -98,13 +140,28 @@ public class HdrClamper {
        pw.println("  mAmbientLux=" + mAmbientLux);
    }

    private void recalculateBrightnessCap(HdrBrightnessData data, float ambientLux) {
        if (data == null) {
    private void reset() {
        if (mMaxBrightness == PowerManager.BRIGHTNESS_MAX
                && mDesiredMaxBrightness == PowerManager.BRIGHTNESS_MAX && mTransitionRate == -1f
                && mDesiredTransitionRate == -1f) { // already done reset, do nothing
            return;
        }
        mHandler.removeCallbacks(mDebouncer);
        mMaxBrightness = PowerManager.BRIGHTNESS_MAX;
        mDesiredMaxBrightness = PowerManager.BRIGHTNESS_MAX;
        mDesiredTransitionRate = -1f;
        mTransitionRate = 1f;
        mClamperChangeListener.onChanged();
    }

    private void recalculateBrightnessCap(HdrBrightnessData data, float ambientLux,
            boolean hdrVisible) {
        if (data == null || !hdrVisible) {
            reset();
            return;
        }
        float expectedMaxBrightness = findBrightnessLimit(data, ambientLux);

        float expectedMaxBrightness = findBrightnessLimit(data, ambientLux);
        if (mMaxBrightness == expectedMaxBrightness) {
            mDesiredMaxBrightness = mMaxBrightness;
            mDesiredTransitionRate = -1f;
@@ -127,6 +184,8 @@ public class HdrClamper {
            mHandler.removeCallbacks(mDebouncer);
            mHandler.postDelayed(mDebouncer, debounceTime);
        }
        // do nothing if expectedMaxBrightness == mDesiredMaxBrightness
        // && expectedMaxBrightness != mMaxBrightness
    }

    private float findBrightnessLimit(HdrBrightnessData data, float ambientLux) {
@@ -143,4 +202,36 @@ public class HdrClamper {
        }
        return foundMaxBrightness;
    }

    @FunctionalInterface
    interface HdrListener {
        void onHdrVisible(boolean visible);
    }

    static class HdrLayerInfoListener extends SurfaceControlHdrLayerInfoListener {
        private final HdrListener mHdrListener;

        private final Handler mHandler;

        private float mHdrMinPixels = Float.MAX_VALUE;

        HdrLayerInfoListener(HdrListener hdrListener, Handler handler) {
            mHdrListener = hdrListener;
            mHandler = handler;
        }

        @Override
        public void onHdrInfoChanged(IBinder displayToken, int numberOfHdrLayers, int maxW,
                int maxH, int flags, float maxDesiredHdrSdrRatio) {
            mHandler.post(() ->
                    mHdrListener.onHdrVisible(
                            numberOfHdrLayers > 0 && (float) (maxW * maxH) >= mHdrMinPixels));
        }
    }

    static class Injector {
        HdrLayerInfoListener getHdrListener(HdrListener hdrListener, Handler handler) {
            return new HdrLayerInfoListener(hdrListener, handler);
        }
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -1851,9 +1851,9 @@ public final class DisplayPowerController2Test {
        BrightnessRangeController getBrightnessRangeController(
                HighBrightnessModeController hbmController, Runnable modeChangeCallback,
                DisplayDeviceConfig displayDeviceConfig, Handler handler,
                DisplayManagerFlags flags) {
                DisplayManagerFlags flags, IBinder displayToken, DisplayDeviceInfo info) {
            return new BrightnessRangeController(hbmController, modeChangeCallback,
                    displayDeviceConfig, mHdrClamper, mFlags);
                    displayDeviceConfig, mHdrClamper, mFlags, displayToken, info);
        }

        @Override
Loading