From 6183c97e5f317ad52ad16fe50e40129e2c7b2150 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Thu, 16 Mar 2017 12:24:55 -0700 Subject: 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 --- libs/hwui/ProgramCache.cpp | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'libs/hwui/ProgramCache.cpp') diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp index 3f842e0b5679..38c23e4babe8 100644 --- a/libs/hwui/ProgramCache.cpp +++ b/libs/hwui/ProgramCache.cpp @@ -202,23 +202,26 @@ const char* gFS_Gradient_Functions = R"__SHADER__( )__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 @@ const char* gFS_Main_FetchGradient[6] = { // 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"; -- cgit v1.2.3-59-g8ed1b