From ed5a8fe9b70afe6ef1f4ccf686ccd1ef09612dc0 Mon Sep 17 00:00:00 2001 From: Santos Cordon Date: Wed, 13 May 2020 18:25:21 +0100 Subject: [PATCH] Adjust float-to-int brightness conversion to be purely in float. By converting to int and back as part of the final steps in sending the brightness to the HAL, we undo the whole benefit of having floating point brightness. This change alters the conversion to an int-range without using the int-primitives. This helps maintain the existing precision. Bug: 155875691 Test: Manually verify with logs that the float value isn't altered before going to the HAL (it previously was). Test: atest CtsDisplayTestCases Test: atest DisplayManagerServiceTests Change-Id: Ibf2f8d00c575d440c3fe437b32c0613bcd471c2a Change-Id: Ie9569efb7b951c15ffcf2306ff9f864f858df8b1 --- .../internal/BrightnessSynchronizer.java | 65 +++++++++++-------- .../server/display/LocalDisplayAdapter.java | 12 ++-- 2 files changed, 42 insertions(+), 35 deletions(-) diff --git a/core/java/com/android/internal/BrightnessSynchronizer.java b/core/java/com/android/internal/BrightnessSynchronizer.java index aa23251b9b856..42724bede4813 100644 --- a/core/java/com/android/internal/BrightnessSynchronizer.java +++ b/core/java/com/android/internal/BrightnessSynchronizer.java @@ -84,17 +84,17 @@ public class BrightnessSynchronizer{ * Converts between the int brightness system and the float brightness system. */ public static float brightnessIntToFloat(Context context, int brightnessInt) { - PowerManager pm = context.getSystemService(PowerManager.class); - float pmMinBrightness = pm.getBrightnessConstraint( + final PowerManager pm = context.getSystemService(PowerManager.class); + final float pmMinBrightness = pm.getBrightnessConstraint( PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM); - float pmMaxBrightness = pm.getBrightnessConstraint( + final float pmMaxBrightness = pm.getBrightnessConstraint( PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM); - int minBrightnessInt = brightnessFloatToInt(pmMinBrightness, PowerManager.BRIGHTNESS_MIN, - PowerManager.BRIGHTNESS_MAX, PowerManager.BRIGHTNESS_OFF + 1, - PowerManager.BRIGHTNESS_ON); - int maxBrightnessInt = brightnessFloatToInt(pmMaxBrightness, PowerManager.BRIGHTNESS_MIN, - PowerManager.BRIGHTNESS_MAX, PowerManager.BRIGHTNESS_OFF + 1, - PowerManager.BRIGHTNESS_ON); + final int minBrightnessInt = Math.round(brightnessFloatToIntRange(pmMinBrightness, + PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, + PowerManager.BRIGHTNESS_OFF + 1, PowerManager.BRIGHTNESS_ON)); + final int maxBrightnessInt = Math.round(brightnessFloatToIntRange(pmMaxBrightness, + PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, + PowerManager.BRIGHTNESS_OFF + 1, PowerManager.BRIGHTNESS_ON)); return brightnessIntToFloat(brightnessInt, minBrightnessInt, maxBrightnessInt, pmMinBrightness, pmMaxBrightness); @@ -119,34 +119,43 @@ public class BrightnessSynchronizer{ * Converts between the float brightness system and the int brightness system. */ public static int brightnessFloatToInt(Context context, float brightnessFloat) { - PowerManager pm = context.getSystemService(PowerManager.class); - float pmMinBrightness = pm.getBrightnessConstraint( - PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM); - float pmMaxBrightness = pm.getBrightnessConstraint( - PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM); - int minBrightnessInt = brightnessFloatToInt(pmMinBrightness, PowerManager.BRIGHTNESS_MIN, - PowerManager.BRIGHTNESS_MAX, PowerManager.BRIGHTNESS_OFF + 1, - PowerManager.BRIGHTNESS_ON); - int maxBrightnessInt = brightnessFloatToInt(pmMaxBrightness, PowerManager.BRIGHTNESS_MIN, - PowerManager.BRIGHTNESS_MAX, PowerManager.BRIGHTNESS_OFF + 1, - PowerManager.BRIGHTNESS_ON); - - return brightnessFloatToInt(brightnessFloat, pmMinBrightness, pmMaxBrightness, - minBrightnessInt, maxBrightnessInt); + return Math.round(brightnessFloatToIntRange(context, brightnessFloat)); } /** - * Converts between the float brightness system and the int brightness system. + * Converts between the float brightness system and the int brightness system, but returns + * the converted value as a float within the int-system's range. This method helps with + * conversions from one system to the other without losing the floating-point precision. */ - public static int brightnessFloatToInt(float brightnessFloat, float minFloat, float maxFloat, - int minInt, int maxInt) { + public static float brightnessFloatToIntRange(Context context, float brightnessFloat) { + final PowerManager pm = context.getSystemService(PowerManager.class); + final float minFloat = pm.getBrightnessConstraint( + PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM); + final float maxFloat = pm.getBrightnessConstraint( + PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM); + final float minInt = brightnessFloatToIntRange(minFloat, + PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, + PowerManager.BRIGHTNESS_OFF + 1, PowerManager.BRIGHTNESS_ON); + final float maxInt = brightnessFloatToIntRange(maxFloat, + PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, + PowerManager.BRIGHTNESS_OFF + 1, PowerManager.BRIGHTNESS_ON); + return brightnessFloatToIntRange(brightnessFloat, minFloat, maxFloat, minInt, maxInt); + } + + /** + * Translates specified value from the float brightness system to the int brightness system, + * given the min/max of each range. Accounts for special values such as OFF and invalid values. + * Value returned as a float privimite (to preserve precision), but is a value within the + * int-system range. + */ + private static float brightnessFloatToIntRange(float brightnessFloat, float minFloat, + float maxFloat, float minInt, float maxInt) { if (floatEquals(brightnessFloat, PowerManager.BRIGHTNESS_OFF_FLOAT)) { return PowerManager.BRIGHTNESS_OFF; } else if (Float.isNaN(brightnessFloat)) { return PowerManager.BRIGHTNESS_INVALID; } else { - return Math.round(MathUtils.constrainedMap((float) minInt, (float) maxInt, minFloat, - maxFloat, brightnessFloat)); + return MathUtils.constrainedMap(minInt, maxInt, minFloat, maxFloat, brightnessFloat); } } diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index 4f5a02ad22fac..2a65b33461cf9 100644 --- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java @@ -201,7 +201,6 @@ final class LocalDisplayAdapter extends DisplayAdapter { private SurfaceControl.DisplayConfig[] mDisplayConfigs; private Spline mSystemBrightnessToNits; private Spline mNitsToHalBrightness; - private boolean mHalBrightnessSupport; private DisplayDeviceConfig mDisplayDeviceConfig; @@ -225,7 +224,6 @@ final class LocalDisplayAdapter extends DisplayAdapter { } mAllmSupported = SurfaceControl.getAutoLowLatencyModeSupport(displayToken); mGameContentTypeSupported = SurfaceControl.getGameContentTypeSupport(displayToken); - mHalBrightnessSupport = SurfaceControl.getDisplayBrightnessSupport(displayToken); mDisplayDeviceConfig = null; // Defer configuration file loading BackgroundThread.getHandler().sendMessage(PooledLambda.obtainMessage( @@ -717,11 +715,10 @@ final class LocalDisplayAdapter extends DisplayAdapter { Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness(" + "id=" + physicalDisplayId + ", brightness=" + brightness + ")"); try { - // TODO: make it float if (isHalBrightnessRangeSpecified()) { brightness = displayBrightnessToHalBrightness( - BrightnessSynchronizer.brightnessFloatToInt(getContext(), - brightness)); + BrightnessSynchronizer.brightnessFloatToIntRange( + getContext(), brightness)); } if (mBacklight != null) { mBacklight.setBrightness(brightness); @@ -744,12 +741,13 @@ final class LocalDisplayAdapter extends DisplayAdapter { * Hal brightness space if the HAL brightness space has been provided via * a display device configuration file. */ - private float displayBrightnessToHalBrightness(int brightness) { + private float displayBrightnessToHalBrightness(float brightness) { if (!isHalBrightnessRangeSpecified()) { return PowerManager.BRIGHTNESS_INVALID_FLOAT; } - if (brightness == 0) { + if (BrightnessSynchronizer.floatEquals( + brightness, PowerManager.BRIGHTNESS_OFF)) { return PowerManager.BRIGHTNESS_OFF_FLOAT; }