Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f596ba93 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Bowing my head in shame, going back to gamma interpolated gradients"

parents 2257285a 6183c97e
Loading
Loading
Loading
Loading
+7 −6
Original line number Original line Diff line number Diff line
@@ -38,13 +38,14 @@ struct FloatColor {
    }
    }


    // "color" is a gamma-encoded sRGB color
    // "color" is a gamma-encoded sRGB color
    // After calling this method, the color is stored as a linear color. The color
    // After calling this method, the color is stored as a un-premultiplied linear color
    // is not pre-multiplied.
    // if linear blending is enabled. Otherwise, the color is stored as a un-premultiplied
    void setUnPreMultipliedSRGB(uint32_t color) {
    // gamma-encoded sRGB color
    void setUnPreMultiplied(uint32_t color) {
        a = ((color >> 24) & 0xff) / 255.0f;
        a = ((color >> 24) & 0xff) / 255.0f;
        r = EOCF_sRGB(((color >> 16) & 0xff) / 255.0f);
        r = EOCF(((color >> 16) & 0xff) / 255.0f);
        g = EOCF_sRGB(((color >>  8) & 0xff) / 255.0f);
        g = EOCF(((color >>  8) & 0xff) / 255.0f);
        b = EOCF_sRGB(((color      ) & 0xff) / 255.0f);
        b = EOCF(((color      ) & 0xff) / 255.0f);
    }
    }


    bool isNotBlack() {
    bool isNotBlack() {
+10 −13
Original line number Original line Diff line number Diff line
@@ -189,9 +189,9 @@ void GradientCache::mixBytes(const FloatColor& start, const FloatColor& end,
        float amount, uint8_t*& dst) const {
        float amount, uint8_t*& dst) const {
    float oppAmount = 1.0f - amount;
    float oppAmount = 1.0f - amount;
    float a = start.a * oppAmount + end.a * 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(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(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.b * oppAmount + end.b * amount) * 255.0f);
    *dst++ = uint8_t(a * 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 a = start.a * oppAmount + end.a * amount;
    float* d = (float*) dst;
    float* d = (float*) dst;
#ifdef ANDROID_ENABLE_LINEAR_BLENDING
#ifdef ANDROID_ENABLE_LINEAR_BLENDING
    // We want to stay linear
    *d++ = a * (start.r * oppAmount + end.r * amount);
    *d++ = a * (start.r * oppAmount + end.r * amount);
    *d++ = a * (start.g * oppAmount + end.g * amount);
    *d++ = a * (start.g * oppAmount + end.g * amount);
    *d++ = a * (start.b * oppAmount + end.b * amount);
    *d++ = a * (start.b * oppAmount + end.b * amount);
#else
#else
    // What we're doing to the alpha channel here is technically incorrect
    *d++ = a * OECF(start.r * oppAmount + end.r * amount);
    // but reproduces Android's old behavior when the alpha was pre-multiplied
    *d++ = a * OECF(start.g * oppAmount + end.g * amount);
    // with gamma-encoded colors
    *d++ = a * OECF(start.b * oppAmount + end.b * amount);
    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);
#endif
#endif
    *d++ = a;
    *d++ = a;
    dst += 4 * sizeof(float);
    dst += 4 * sizeof(float);
@@ -232,10 +229,10 @@ void GradientCache::generateTexture(uint32_t* colors, float* positions,
    ChannelMixer mix = gMixers[mUseFloatTexture];
    ChannelMixer mix = gMixers[mUseFloatTexture];


    FloatColor start;
    FloatColor start;
    start.setUnPreMultipliedSRGB(colors[0]);
    start.setUnPreMultiplied(colors[0]);


    FloatColor end;
    FloatColor end;
    end.setUnPreMultipliedSRGB(colors[1]);
    end.setUnPreMultiplied(colors[1]);


    int currentPos = 1;
    int currentPos = 1;
    float startPos = positions[0];
    float startPos = positions[0];
@@ -250,7 +247,7 @@ void GradientCache::generateTexture(uint32_t* colors, float* positions,


            currentPos++;
            currentPos++;


            end.setUnPreMultipliedSRGB(colors[currentPos]);
            end.setUnPreMultiplied(colors[currentPos]);
            distance = positions[currentPos] - startPos;
            distance = positions[currentPos] - startPos;
        }
        }


+22 −19
Original line number Original line Diff line number Diff line
@@ -202,23 +202,26 @@ const char* gFS_Gradient_Functions = R"__SHADER__(
)__SHADER__";
)__SHADER__";
const char* gFS_Gradient_Preamble[2] = {
const char* gFS_Gradient_Preamble[2] = {
        // Linear framebuffer
        // Linear framebuffer
        "\nvec4 dither(const vec4 color) {\n"
        R"__SHADER__(
        "    return color + (triangleNoise(gl_FragCoord.xy * screenSize.xy) / 255.0);\n"
        vec4 dither(const vec4 color) {
        "}\n"
            return color + (triangleNoise(gl_FragCoord.xy * screenSize.xy) / 255.0);
        "\nvec4 gammaMix(const vec4 a, const vec4 b, float v) {\n"
        }
        "    vec4 c = mix(a, b, v);\n"
        vec4 gradientMix(const vec4 a, const vec4 b, float v) {
        "    c.a = EOTF_sRGB(c.a);\n" // This is technically incorrect but preserves compatibility
            vec4 c = mix(a, b, v);
        "    return vec4(OETF_sRGB(c.rgb) * c.a, c.a);\n"
            return vec4(c.rgb * c.a, c.a);
        "}\n",
        }
        )__SHADER__",
        // sRGB framebuffer
        // sRGB framebuffer
        "\nvec4 dither(const vec4 color) {\n"
        R"__SHADER__(
        "    vec3 dithered = sqrt(color.rgb) + (triangleNoise(gl_FragCoord.xy * screenSize.xy) / 255.0);\n"
        vec4 dither(const vec4 color) {
        "    return vec4(dithered * dithered, color.a);\n"
            vec3 dithered = sqrt(color.rgb) + (triangleNoise(gl_FragCoord.xy * screenSize.xy) / 255.0);
        "}\n"
            return vec4(dithered * dithered, color.a);
        "\nvec4 gammaMix(const vec4 a, const vec4 b, float v) {\n"
        }
        "    vec4 c = mix(a, b, v);\n"
        vec4 gradientMixMix(const vec4 a, const vec4 b, float v) {
        "    return vec4(c.rgb * c.a, c.a);\n"
            vec4 c = mix(a, b, v);
        "}\n"
            return vec4(c.rgb * c.a, c.a);
        }
        )__SHADER__",
};
};


// Uses luminance coefficients from Rec.709 to choose the appropriate gamma
// Uses luminance coefficients from Rec.709 to choose the appropriate gamma
@@ -272,19 +275,19 @@ const char* gFS_Main_FetchGradient[6] = {
        // Linear
        // Linear
        "    vec4 gradientColor = texture2D(gradientSampler, linear);\n",
        "    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
        // Circular
        "    vec4 gradientColor = texture2D(gradientSampler, vec2(length(circular), 0.5));\n",
        "    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
        // Sweep
        "    highp float index = atan(sweep.y, sweep.x) * 0.15915494309; // inv(2 * PI)\n"
        "    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",
        "    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"
        "    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 =
const char* gFS_Main_FetchBitmap =
        "    vec4 bitmapColor = OETF(texture2D(bitmapSampler, outBitmapTexCoords));\n";
        "    vec4 bitmapColor = OETF(texture2D(bitmapSampler, outBitmapTexCoords));\n";
+2 −2
Original line number Original line Diff line number Diff line
@@ -173,8 +173,8 @@ bool tryStoreGradient(Caches& caches, const SkShader& shader, const Matrix4 mode
        outData->gradientSampler = 0;
        outData->gradientSampler = 0;
        outData->gradientTexture = nullptr;
        outData->gradientTexture = nullptr;


        outData->startColor.setUnPreMultipliedSRGB(gradInfo.fColors[0]);
        outData->startColor.setUnPreMultiplied(gradInfo.fColors[0]);
        outData->endColor.setUnPreMultipliedSRGB(gradInfo.fColors[1]);
        outData->endColor.setUnPreMultiplied(gradInfo.fColors[1]);
    }
    }


    return true;
    return true;