summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanny Lin <danny@kdrag0n.dev>2021-07-08 18:40:18 -0700
committeralk3pInjection <webmaster@raspii.tech>2022-01-26 11:42:56 +0800
commit20936b79d8cd392880b6d61aed4ad2aff0de99da (patch)
tree9917dbc92683230a7ac13402425da21b30e0267c
parent31604c494c73e4dd4b31ed9a450ee941dc7a5829 (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.java28
-rw-r--r--services/core/java/com/android/server/display/color/ColorDisplayService.java5
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() {