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

Commit bb68e3d7 authored by Sally Qi's avatar Sally Qi Committed by Android (Google) Code Review
Browse files

Merge "[Lut shader] Fix the issue if using HLG/PQ transfer function." into main

parents b6520d23 999f99f4
Loading
Loading
Loading
Loading
+23 −8
Original line number Diff line number Diff line
@@ -39,10 +39,13 @@ static const SkString kShader = SkString(R"(
    uniform int key;
    uniform int dimension;
    uniform vec3 luminanceCoefficients; // for CIE_Y
    // for hlg/pq transfer function, we need normalize it to [0.0, 1.0]
    // we use `normalizeScalar` to do so
    uniform float normalizeScalar;

    vec4 main(vec2 xy) {
        float4 rgba = image.eval(xy);
        float3 linear = toLinearSrgb(rgba.rgb);
        float3 linear = toLinearSrgb(rgba.rgb) * normalizeScalar;
        if (dimension == 1) {
            // RGB
            if (key == 0) {
@@ -52,19 +55,19 @@ static const SkString kShader = SkString(R"(
                float gainR = lut.eval(vec2(indexR, 0.0) + 0.5).r;
                float gainG = lut.eval(vec2(indexG, 0.0) + 0.5).r;
                float gainB = lut.eval(vec2(indexB, 0.0) + 0.5).r;
                return float4(linear.r * gainR, linear.g * gainG, linear.b * gainB, rgba.a);
                linear = float3(linear.r * gainR, linear.g * gainG, linear.b * gainB);
            // MAX_RGB
            } else if (key == 1) {
                float maxRGB = max(linear.r, max(linear.g, linear.b));
                float index = maxRGB * float(size - 1);
                float gain = lut.eval(vec2(index, 0.0) + 0.5).r;
                return float4(linear * gain, rgba.a);
                linear = linear * gain;
            // CIE_Y
            } else if (key == 2) {
                float y = dot(linear, luminanceCoefficients) / 3.0;
                float index = y * float(size - 1);
                float gain = lut.eval(vec2(index, 0.0) + 0.5).r;
                return float4(linear * gain, rgba.a);
                linear = linear * gain;
            }
        } else if (dimension == 3) {
            if (key == 0) {
@@ -110,12 +113,10 @@ static const SkString kShader = SkString(R"(
                float3 c0 = mix(c00, c10, linear.g);
                float3 c1 = mix(c01, c11, linear.g);

                float3 val = mix(c0, c1, linear.b);

                return float4(val, rgba.a);
                linear = mix(c0, c1, linear.b);
            }
        }
        return rgba;
        return float4(linear, rgba.a);
    })");

// same as shader::toColorSpace function
@@ -197,9 +198,22 @@ sk_sp<SkShader> LutShader::generateLutShader(sk_sp<SkShader> input,
                                            ? SkSamplingOptions(SkFilterMode::kLinear)
                                            : SkSamplingOptions());

    float normalizeScalar = 1.0;
    switch (srcDataspace & HAL_DATASPACE_TRANSFER_MASK) {
        case HAL_DATASPACE_TRANSFER_HLG:
            normalizeScalar = 0.203;
            break;
        case HAL_DATASPACE_TRANSFER_ST2084:
            normalizeScalar = 0.0203;
            break;
        default:
            normalizeScalar = 1.0;
    }
    const int uSize = static_cast<int>(size);
    const int uKey = static_cast<int>(samplingKey);
    const int uDimension = static_cast<int>(dimension);
    const float uNormalizeScalar = static_cast<float>(normalizeScalar);

    if (static_cast<LutProperties::SamplingKey>(samplingKey) == LutProperties::SamplingKey::CIE_Y) {
        // Use predefined colorspaces of input dataspace so that we can get D65 illuminant
        mat3 toXYZMatrix(toColorSpace(srcDataspace).getRGBtoXYZ());
@@ -211,6 +225,7 @@ sk_sp<SkShader> LutShader::generateLutShader(sk_sp<SkShader> input,
    mBuilder->uniform("size") = uSize;
    mBuilder->uniform("key") = uKey;
    mBuilder->uniform("dimension") = uDimension;
    mBuilder->uniform("normalizeScalar") = uNormalizeScalar;
    return mBuilder->makeShader();
}