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

Commit 0929c55b authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Merge cherrypicks of [4027269] into pi-release

Change-Id: Ic0f7b0ea1b9c8b99e19860e1ca04399c3fc39c79
parents 73070601 ee2cdf67
Loading
Loading
Loading
Loading
+78 −152
Original line number Diff line number Diff line
@@ -233,73 +233,31 @@ void ProgramCache::generateEOTF(Formatter& fs, const Key& needs) {
}

// Generate OOTF that modifies the relative scence light to relative display light.
void ProgramCache::generateOOTF(Formatter& fs, const ProgramCache::Key& needs) {
    // When HDR and non-HDR contents are mixed, or different types of HDR contents are
    // mixed, we will do a transcoding process to transcode the input content to output
    // content. Currently, the following conversions handled, they are:
    // * SDR -> HLG
    // * SDR -> PQ
    // * HLG -> PQ

    // Convert relative light to absolute light.
    switch (needs.getInputTF()) {
        case Key::INPUT_TF_ST2084:
void ProgramCache::generateOOTF(Formatter& fs, const Key& needs) {
    fs << R"__SHADER__(
                highp vec3 ScaleLuminance(color) {
                    return color * 10000.0;
                }
            )__SHADER__";
            break;
        case Key::INPUT_TF_HLG:
            fs << R"__SHADER__(
                highp vec3 ScaleLuminance(color) {
                    // The formula is:
                    // alpha * pow(Y, gamma - 1.0) * color + beta;
                    // where alpha is 1000.0, gamma is 1.2, beta is 0.0.
                    return color * 1000.0 * pow(color.y, 0.2);
        highp float CalculateY(const highp vec3 color) {
            // BT2020 standard uses the unadjusted KR = 0.2627,
            // KB = 0.0593 luminance interpretation for RGB conversion.
            return color.r * 0.262700 + color.g * 0.677998 + color.b * 0.059302;
        }
    )__SHADER__";
            break;
        default:
            fs << R"__SHADER__(
                highp vec3 ScaleLuminance(color) {
                    return color * displayMaxLuminance;
                }
            )__SHADER__";
            break;
    }

    // Tone map absolute light to display luminance range.
    // Generate OOTF that modifies the relative display light.
    switch(needs.getInputTF()) {
        case Key::INPUT_TF_ST2084:
        case Key::INPUT_TF_HLG:
            switch (needs.getOutputTF()) {
                case Key::OUTPUT_TF_HLG:
                    // Right now when mixed PQ and HLG contents are presented,
                    // HLG content will always be converted to PQ. However, for
                    // completeness, we simply clamp the value to [0.0, 1000.0].
                    fs << R"__SHADER__(
                        highp vec3 ToneMap(color) {
                            return clamp(color, 0.0, 1000.0);
                        }
                    )__SHADER__";
                    break;
                case Key::OUTPUT_TF_ST2084:
                    fs << R"__SHADER__(
                        highp vec3 ToneMap(color) {
                            return color;
                        }
                    )__SHADER__";
                    break;
                default:
            fs << R"__SHADER__(
                        highp vec3 ToneMap(color) {
                highp vec3 OOTF(const highp vec3 color) {
                    const float maxLumi = 10000.0;
                    const float maxMasteringLumi = 1000.0;
                    const float maxContentLumi = 1000.0;
                    const float maxInLumi = min(maxMasteringLumi, maxContentLumi);
                    float maxOutLumi = displayMaxLuminance;

                            float nits = color.y;
                    // Calculate Y value in XYZ color space.
                    float colorY = CalculateY(color);

                    // convert to nits first
                    float nits = colorY * maxLumi;

                    // clamp to max input luminance
                    nits = clamp(nits, 0.0, maxInLumi);
@@ -317,12 +275,12 @@ void ProgramCache::generateOOTF(Formatter& fs, const ProgramCache::Key& needs) {
                        float y2 = y1 + (maxOutLumi - y1) * 0.75;

                        // horizontal distances between the last three control points
                                const float h12 = x2 - x1;
                                const float h23 = maxInLumi - x2;
                        float h12 = x2 - x1;
                        float h23 = maxInLumi - x2;
                        // tangents at the last three control points
                                const float m1 = (y2 - y1) / h12;
                                const float m3 = (maxOutLumi - y2) / h23;
                                const float m2 = (m1 + m3) / 2.0;
                        float m1 = (y2 - y1) / h12;
                        float m3 = (maxOutLumi - y2) / h23;
                        float m2 = (m1 + m3) / 2.0;

                        if (nits < x0) {
                            // scale [0.0, x0] to [0.0, y0] linearly
@@ -330,7 +288,7 @@ void ProgramCache::generateOOTF(Formatter& fs, const ProgramCache::Key& needs) {
                            nits *= slope;
                        } else if (nits < x1) {
                            // scale [x0, x1] to [y0, y1] linearly
                                    const float slope = (y1 - y0) / (x1 - x0);
                            float slope = (y1 - y0) / (x1 - x0);
                            nits = y0 + (nits - x0) * slope;
                        } else if (nits < x2) {
                            // scale [x1, x2] to [y1, y2] using Hermite interp
@@ -345,64 +303,32 @@ void ProgramCache::generateOOTF(Formatter& fs, const ProgramCache::Key& needs) {
                        }
                    }

                            return color * (nits / max(1e-6, color.y));
                    // convert back to [0.0, 1.0]
                    float targetY = nits / maxOutLumi;
                    return color * (targetY / max(1e-6, colorY));
                }
            )__SHADER__";
            break;
            }
            break;
        default:
            // TODO(73825729) We need to revert the tone mapping in
            // hardware composer properly.
            fs << R"__SHADER__(
                highp vec3 ToneMap(color) {
                    return color;
                }
            )__SHADER__";
            break;
    }

    // convert absolute light to relative light.
    switch (needs.getOutputTF()) {
        case Key::OUTPUT_TF_ST2084:
            fs << R"__SHADER__(
                highp vec3 NormalizeLuminance(color) {
                    return color / 10000.0;
                }
            )__SHADER__";
            break;
        case Key::OUTPUT_TF_HLG:
        case Key::INPUT_TF_HLG:
            fs << R"__SHADER__(
                highp vec3 NormalizeLuminance(color) {
                    return color / 1000.0 * pow(color.y / 1000.0, -0.2 / 1.2);
                highp vec3 OOTF(const highp vec3 color) {
                    const float maxOutLumi = 500.0;
                    const float gamma = 1.2 + 0.42 * log(maxOutLumi / 1000.0) / log(10.0);
                    // The formula is:
                    // alpha * pow(Y, gamma - 1.0) * color + beta;
                    // where alpha is 1.0, beta is 0.0 as recommended in
                    // Rec. ITU-R BT.2100-1 TABLE 5.
                    return pow(CalculateY(color), gamma - 1.0) * color;
                }
            )__SHADER__";
            break;
        default:
            fs << R"__SHADER__(
                highp vec3 NormalizeLuminance(color) {
                    return color / displayMaxLuminance;
                }
            )__SHADER__";
            break;
    }

    if (needs.getInputTF() == needs.getOutputTF() ||
        (needs.getInputTF() == Key::INPUT_TF_LINEAR &&
         needs.getOutputTF() == Key::OUTPUT_TF_SRGB) ||
        (needs.getInputTF() == Key::INPUT_TF_SRGB &&
         needs.getOutputTF() == Key::OUTPUT_TF_LINEAR)) {
            fs << R"__SHADER__(
                highp vec3 OOTF(const highp vec3 color) {
                    return color;
                }
            )__SHADER__";
    } else {
        fs << R"__SHADER__(
            highp vec3 OOTF(const highp vec3 color) {
                return NormalizeLuminance(ToneMap(ScaleLuminance(color)));
            }
        )__SHADER__";
            break;
    }
}