diff options
author | Danny Lin <danny@kdrag0n.dev> | 2021-07-08 18:40:18 -0700 |
---|---|---|
committer | alk3pInjection <webmaster@raspii.tech> | 2022-01-26 11:42:56 +0800 |
commit | 20936b79d8cd392880b6d61aed4ad2aff0de99da (patch) | |
tree | 9917dbc92683230a7ac13402425da21b30e0267c | |
parent | 31604c494c73e4dd4b31ed9a450ee941dc7a5829 (diff) |
display: ColorBalance: Add support for non-linear native color spaces
On some devices and/or color modes, color transforms are applied in an
"unmanaged" native color space, so apply a linear sRGB transformation
matrix is wrong.
It's not technically possible to implement accurate color balance in
such cases, but attempt to accommodate it by assuming non-linear sRGB
and applying the sRGB transfer function on the matrix.
Change-Id: Ia786bf2468f29d729607ecc3f4a26305440717de
-rw-r--r-- | services/core/java/com/android/server/display/color/ColorBalanceTintController.java | 28 | ||||
-rw-r--r-- | services/core/java/com/android/server/display/color/ColorDisplayService.java | 5 |
2 files changed, 30 insertions, 3 deletions
diff --git a/services/core/java/com/android/server/display/color/ColorBalanceTintController.java b/services/core/java/com/android/server/display/color/ColorBalanceTintController.java index 0c2db0cb4780..5b5ef7ffb619 100644 --- a/services/core/java/com/android/server/display/color/ColorBalanceTintController.java +++ b/services/core/java/com/android/server/display/color/ColorBalanceTintController.java @@ -30,9 +30,11 @@ import java.util.Arrays; final class ColorBalanceTintController extends TintController { private final float[] mMatrix = new float[16]; + private boolean mNeedsLinear; @Override public void setUp(Context context, boolean needsLinear) { + mNeedsLinear = needsLinear; } @Override @@ -43,9 +45,21 @@ final class ColorBalanceTintController extends TintController { @Override public void setMatrix(int rgb) { Matrix.setIdentityM(mMatrix, 0); - mMatrix[0] = ((float) Color.red(rgb)) / 255.0f; - mMatrix[5] = ((float) Color.green(rgb)) / 255.0f; - mMatrix[10] = ((float) Color.blue(rgb)) / 255.0f; + + float red = ((float) Color.red(rgb)) / 255.0f; + float green = ((float) Color.green(rgb)) / 255.0f; + float blue = ((float) Color.blue(rgb)) / 255.0f; + + if (!mNeedsLinear) { + // Convert to non-linear sRGB as the assumed native color space + red = linearToSrgb(red); + green = linearToSrgb(green); + blue = linearToSrgb(blue); + } + + mMatrix[0] = red; + mMatrix[5] = green; + mMatrix[10] = blue; } @Override @@ -82,4 +96,12 @@ final class ColorBalanceTintController extends TintController { throw new IllegalArgumentException("Unknown channel: " + channel); } } + + private static float linearToSrgb(float x) { + if (x >= 0.0031308) { + return (1.055f) * ((float) Math.pow(x, 1.0f / 2.4f)) - 0.055f; + } else { + return 12.92f * x; + } + } } diff --git a/services/core/java/com/android/server/display/color/ColorDisplayService.java b/services/core/java/com/android/server/display/color/ColorDisplayService.java index eb67227ebb6f..c188d182daea 100644 --- a/services/core/java/com/android/server/display/color/ColorDisplayService.java +++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java @@ -575,6 +575,11 @@ public final class ColorDisplayService extends SystemService { if (mDisplayWhiteBalanceTintController.isAvailable(getContext())) { updateDisplayWhiteBalanceStatus(); } + + if (mColorBalanceTintController.isAvailable(getContext())) { + mColorBalanceTintController.setUp(getContext(), + DisplayTransformManager.needsLinearColorMatrix(mode)); + } } private void onAccessibilityActivated() { |