Merge "Bowing my head in shame, going back to gamma interpolated gradients"
diff --git a/libs/hwui/FloatColor.h b/libs/hwui/FloatColor.h
index d8afa35..a738ba4 100644
--- a/libs/hwui/FloatColor.h
+++ b/libs/hwui/FloatColor.h
@@ -38,13 +38,14 @@
}
// "color" is a gamma-encoded sRGB color
- // After calling this method, the color is stored as a linear color. The color
- // is not pre-multiplied.
- void setUnPreMultipliedSRGB(uint32_t color) {
+ // After calling this method, the color is stored as a un-premultiplied linear color
+ // if linear blending is enabled. Otherwise, the color is stored as a un-premultiplied
+ // gamma-encoded sRGB color
+ void setUnPreMultiplied(uint32_t color) {
a = ((color >> 24) & 0xff) / 255.0f;
- r = EOCF_sRGB(((color >> 16) & 0xff) / 255.0f);
- g = EOCF_sRGB(((color >> 8) & 0xff) / 255.0f);
- b = EOCF_sRGB(((color ) & 0xff) / 255.0f);
+ r = EOCF(((color >> 16) & 0xff) / 255.0f);
+ g = EOCF(((color >> 8) & 0xff) / 255.0f);
+ b = EOCF(((color ) & 0xff) / 255.0f);
}
bool isNotBlack() {
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index 18bfcc2..dceb285 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -189,9 +189,9 @@
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 @@
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 @@
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 @@
currentPos++;
- end.setUnPreMultipliedSRGB(colors[currentPos]);
+ end.setUnPreMultiplied(colors[currentPos]);
distance = positions[currentPos] - startPos;
}
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 3f842e0..38c23e4 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -202,23 +202,26 @@
)__SHADER__";
const char* gFS_Gradient_Preamble[2] = {
// Linear framebuffer
- "\nvec4 dither(const vec4 color) {\n"
- " return color + (triangleNoise(gl_FragCoord.xy * screenSize.xy) / 255.0);\n"
- "}\n"
- "\nvec4 gammaMix(const vec4 a, const vec4 b, float v) {\n"
- " vec4 c = mix(a, b, v);\n"
- " c.a = EOTF_sRGB(c.a);\n" // This is technically incorrect but preserves compatibility
- " return vec4(OETF_sRGB(c.rgb) * c.a, c.a);\n"
- "}\n",
+ R"__SHADER__(
+ vec4 dither(const vec4 color) {
+ return color + (triangleNoise(gl_FragCoord.xy * screenSize.xy) / 255.0);
+ }
+ vec4 gradientMix(const vec4 a, const vec4 b, float v) {
+ vec4 c = mix(a, b, v);
+ return vec4(c.rgb * c.a, c.a);
+ }
+ )__SHADER__",
// sRGB framebuffer
- "\nvec4 dither(const vec4 color) {\n"
- " vec3 dithered = sqrt(color.rgb) + (triangleNoise(gl_FragCoord.xy * screenSize.xy) / 255.0);\n"
- " return vec4(dithered * dithered, color.a);\n"
- "}\n"
- "\nvec4 gammaMix(const vec4 a, const vec4 b, float v) {\n"
- " vec4 c = mix(a, b, v);\n"
- " return vec4(c.rgb * c.a, c.a);\n"
- "}\n"
+ R"__SHADER__(
+ vec4 dither(const vec4 color) {
+ vec3 dithered = sqrt(color.rgb) + (triangleNoise(gl_FragCoord.xy * screenSize.xy) / 255.0);
+ return vec4(dithered * dithered, color.a);
+ }
+ vec4 gradientMixMix(const vec4 a, const vec4 b, float v) {
+ vec4 c = mix(a, b, v);
+ return vec4(c.rgb * c.a, c.a);
+ }
+ )__SHADER__",
};
// Uses luminance coefficients from Rec.709 to choose the appropriate gamma
@@ -272,19 +275,19 @@
// Linear
" vec4 gradientColor = texture2D(gradientSampler, linear);\n",
- " vec4 gradientColor = gammaMix(startColor, endColor, clamp(linear, 0.0, 1.0));\n",
+ " vec4 gradientColor = gradientMix(startColor, endColor, clamp(linear, 0.0, 1.0));\n",
// Circular
" vec4 gradientColor = texture2D(gradientSampler, vec2(length(circular), 0.5));\n",
- " vec4 gradientColor = gammaMix(startColor, endColor, clamp(length(circular), 0.0, 1.0));\n",
+ " vec4 gradientColor = gradientMix(startColor, endColor, clamp(length(circular), 0.0, 1.0));\n",
// Sweep
" highp float index = atan(sweep.y, sweep.x) * 0.15915494309; // inv(2 * PI)\n"
" vec4 gradientColor = texture2D(gradientSampler, vec2(index - floor(index), 0.5));\n",
" highp float index = atan(sweep.y, sweep.x) * 0.15915494309; // inv(2 * PI)\n"
- " vec4 gradientColor = gammaMix(startColor, endColor, clamp(index - floor(index), 0.0, 1.0));\n"
+ " vec4 gradientColor = gradientMix(startColor, endColor, clamp(index - floor(index), 0.0, 1.0));\n"
};
const char* gFS_Main_FetchBitmap =
" vec4 bitmapColor = OETF(texture2D(bitmapSampler, outBitmapTexCoords));\n";
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 760c10c..4f7f9d7 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -173,8 +173,8 @@
outData->gradientSampler = 0;
outData->gradientTexture = nullptr;
- outData->startColor.setUnPreMultipliedSRGB(gradInfo.fColors[0]);
- outData->endColor.setUnPreMultipliedSRGB(gradInfo.fColors[1]);
+ outData->startColor.setUnPreMultiplied(gradInfo.fColors[0]);
+ outData->endColor.setUnPreMultiplied(gradInfo.fColors[1]);
}
return true;