From 9fe7e16399aa9739b63ce9add1d04fd8ef00678f Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Fri, 3 Feb 2017 16:16:07 -0800 Subject: Gradients are now an absurd Chimera As of O, gradients are interpolated in linear space. This unfortunately affects applications that were expecting a certain behavior for the alpha ramp. This change attempts to get the best of both world: better color interpolation (in linear space) and the old alpha interpolation (in gamma space). This is achieved by applying the electro-optical transfer function to the alpha channel; an idea so wrong it would make any graphics programmer worth his salt weep in disgust. As abhorrent this idea might be to me, it also acts as a faint beacon of hope admist the unfathomable darkness that is Android's color management. And if you allow me another misguided metaphor, this change represents the flotsam I can cling onto in the hope to one day reach the bountiful shores of linear blending and accurate color management. Would this change not fix the distress caused by its predecessors, I will have no choice but bow my head in shame until the day I can finally devise an infallible plan. Bug: 33010587 Test: CtsUiRenderingTestCases Change-Id: I5397fefd7944413f2c820e613a5cba50579d4dd5 --- libs/hwui/GradientCache.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'libs/hwui/GradientCache.cpp') diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp index 1dad58fd64b9..71bee93fc4c7 100644 --- a/libs/hwui/GradientCache.cpp +++ b/libs/hwui/GradientCache.cpp @@ -205,6 +205,10 @@ void GradientCache::mixFloats(const FloatColor& start, const FloatColor& end, *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); -- cgit v1.2.3-59-g8ed1b