summaryrefslogtreecommitdiff
path: root/libs/hwui/GradientCache.cpp
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2017-03-16 12:24:55 -0700
committerRomain Guy <romainguy@google.com>2017-03-16 12:29:03 -0700
commit6183c97e5f317ad52ad16fe50e40129e2c7b2150 (patch)
tree3b0d5ed72a57fa5d10567aff1ecb5174b7b4340b /libs/hwui/GradientCache.cpp
parent0d86d7ebc2b83f0bdd28bb99e57289215947f2e0 (diff)
Bowing my head in shame, going back to gamma interpolated gradients
Frankengradients (linearly interpolated RGB, gamma interpolated alpha) look fantastic but unfortunately create sligh compatibility issues. For instance, a gradient from 0xffea1030 to 0x00ea1030 (opaque to alpha, with a single color) blended on top of 0xff101010 would not look the same as a single opaque gradient from 0xffea1030 to 0xff101010. The difference is hardly noticeable on simple gradients but it could cause confusion amongst app developers. Their life is hard enough as it is, let's be good to them. My crusade against the gamma world is not over and one day I shall be the victor. I am patience. Bug: 35485208 Test: UiRendering.ShaderTests, UiRendering.GradientTests, manual testing Change-Id: I8204e60cdf0a6b12dfe22638d30ca9622687000e
Diffstat (limited to 'libs/hwui/GradientCache.cpp')
-rw-r--r--libs/hwui/GradientCache.cpp23
1 files changed, 10 insertions, 13 deletions
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index 18bfcc2bbddf..dceb28518db3 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -189,9 +189,9 @@ void GradientCache::mixBytes(const FloatColor& start, const FloatColor& end,
float amount, uint8_t*& dst) const {
float oppAmount = 1.0f - amount;
float a = start.a * oppAmount + end.a * amount;
- *dst++ = uint8_t(a * OECF_sRGB((start.r * oppAmount + end.r * amount)) * 255.0f);
- *dst++ = uint8_t(a * OECF_sRGB((start.g * oppAmount + end.g * amount)) * 255.0f);
- *dst++ = uint8_t(a * OECF_sRGB((start.b * oppAmount + end.b * amount)) * 255.0f);
+ *dst++ = uint8_t(a * OECF(start.r * oppAmount + end.r * amount) * 255.0f);
+ *dst++ = uint8_t(a * OECF(start.g * oppAmount + end.g * amount) * 255.0f);
+ *dst++ = uint8_t(a * OECF(start.b * oppAmount + end.b * amount) * 255.0f);
*dst++ = uint8_t(a * 255.0f);
}
@@ -201,17 +201,14 @@ void GradientCache::mixFloats(const FloatColor& start, const FloatColor& end,
float a = start.a * oppAmount + end.a * amount;
float* d = (float*) dst;
#ifdef ANDROID_ENABLE_LINEAR_BLENDING
+ // We want to stay linear
*d++ = a * (start.r * oppAmount + end.r * amount);
*d++ = a * (start.g * oppAmount + end.g * amount);
*d++ = a * (start.b * oppAmount + end.b * amount);
#else
- // What we're doing to the alpha channel here is technically incorrect
- // but reproduces Android's old behavior when the alpha was pre-multiplied
- // with gamma-encoded colors
- a = EOCF_sRGB(a);
- *d++ = a * OECF_sRGB(start.r * oppAmount + end.r * amount);
- *d++ = a * OECF_sRGB(start.g * oppAmount + end.g * amount);
- *d++ = a * OECF_sRGB(start.b * oppAmount + end.b * amount);
+ *d++ = a * OECF(start.r * oppAmount + end.r * amount);
+ *d++ = a * OECF(start.g * oppAmount + end.g * amount);
+ *d++ = a * OECF(start.b * oppAmount + end.b * amount);
#endif
*d++ = a;
dst += 4 * sizeof(float);
@@ -232,10 +229,10 @@ void GradientCache::generateTexture(uint32_t* colors, float* positions,
ChannelMixer mix = gMixers[mUseFloatTexture];
FloatColor start;
- start.setUnPreMultipliedSRGB(colors[0]);
+ start.setUnPreMultiplied(colors[0]);
FloatColor end;
- end.setUnPreMultipliedSRGB(colors[1]);
+ end.setUnPreMultiplied(colors[1]);
int currentPos = 1;
float startPos = positions[0];
@@ -250,7 +247,7 @@ void GradientCache::generateTexture(uint32_t* colors, float* positions,
currentPos++;
- end.setUnPreMultipliedSRGB(colors[currentPos]);
+ end.setUnPreMultiplied(colors[currentPos]);
distance = positions[currentPos] - startPos;
}