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

Commit 2542cb07 authored by Peiyong Lin's avatar Peiyong Lin
Browse files

[RenderEngine] Refactor the generation of EOTF, OOTF and OETF.

Previously the generation of EOTF, OOTF and OETF are in fragment shader
generation function, this patch refactors them out as their own functions.

BUG: 73825729
Test: build, flash
Change-Id: I4701c04252fb35dfe1676570b775a94108610b9f
parent 79ab7215
Loading
Loading
Loading
Loading
+224 −215
Original line number Diff line number Diff line
@@ -168,72 +168,10 @@ ProgramCache::Key ProgramCache::computeKey(const Description& description) {
    return needs;
}

String8 ProgramCache::generateVertexShader(const Key& needs) {
    Formatter vs;
    if (needs.isTexturing()) {
        vs << "attribute vec4 texCoords;"
           << "varying vec2 outTexCoords;";
    }
    vs << "attribute vec4 position;"
       << "uniform mat4 projection;"
       << "uniform mat4 texture;"
       << "void main(void) {" << indent << "gl_Position = projection * position;";
    if (needs.isTexturing()) {
        vs << "outTexCoords = (texture * texCoords).st;";
    }
    vs << dedent << "}";
    return vs.getString();
}

String8 ProgramCache::generateFragmentShader(const Key& needs) {
    Formatter fs;
    if (needs.getTextureTarget() == Key::TEXTURE_EXT) {
        fs << "#extension GL_OES_EGL_image_external : require";
    }

    // default precision is required-ish in fragment shaders
    fs << "precision mediump float;";

    if (needs.getTextureTarget() == Key::TEXTURE_EXT) {
        fs << "uniform samplerExternalOES sampler;"
           << "varying vec2 outTexCoords;";
    } else if (needs.getTextureTarget() == Key::TEXTURE_2D) {
        fs << "uniform sampler2D sampler;"
           << "varying vec2 outTexCoords;";
    }

    if (needs.getTextureTarget() == Key::TEXTURE_OFF || needs.hasAlpha()) {
        fs << "uniform vec4 color;";
    }

    if (needs.isY410BT2020()) {
        fs << R"__SHADER__(
            vec3 convertY410BT2020(const vec3 color) {
                const vec3 offset = vec3(0.0625, 0.5, 0.5);
                const mat3 transform = mat3(
                    vec3(1.1678,  1.1678, 1.1678),
                    vec3(   0.0, -0.1878, 2.1481),
                    vec3(1.6836, -0.6523,   0.0));
                // Y is in G, U is in R, and V is in B
                return clamp(transform * (color.grb - offset), 0.0, 1.0);
            }
            )__SHADER__";
    }

    if (needs.hasColorMatrix()) {
        fs << "uniform mat4 colorMatrix;";

// Generate EOTF that converts signal values to relative display light,
// both normalized to [0, 1].
void ProgramCache::generateEOTF(Formatter& fs, const Key& needs) {
    switch (needs.getInputTF()) {
            case Key::INPUT_TF_LINEAR:
            default:
                fs << R"__SHADER__(
                    vec3 EOTF(const vec3 linear) {
                        return linear;
                    }
                )__SHADER__";
                break;
        case Key::INPUT_TF_SRGB:
            fs << R"__SHADER__(
                float EOTF_sRGB(float srgb) {
@@ -280,14 +218,23 @@ String8 ProgramCache::generateFragmentShader(const Key& needs) {
                }
            )__SHADER__";
            break;
        default:
            fs << R"__SHADER__(
                vec3 EOTF(const vec3 linear) {
                    return linear;
                }
            )__SHADER__";
            break;
    }
}

// Generate OOTF that modifies the relative scence light to relative display light.
void ProgramCache::generateOOTF(Formatter& fs, const Key& needs) {
    fs << R"__SHADER__(
        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;
            return color.r * 0.262700 + color.g * 0.677998 + color.b * 0.059302;
        }
    )__SHADER__";

@@ -377,19 +324,14 @@ String8 ProgramCache::generateFragmentShader(const Key& needs) {
                    return color;
                }
            )__SHADER__";
            break;
    }
}

// Generate OETF that converts relative display light to signal values,
// both normalized to [0, 1]
void ProgramCache::generateOETF(Formatter& fs, const Key& needs) {
    switch (needs.getOutputTF()) {
            case Key::OUTPUT_TF_LINEAR:
            default:
                fs << R"__SHADER__(
                    vec3 OETF(const vec3 linear) {
                        return linear;
                    }
                )__SHADER__";
                break;
        case Key::OUTPUT_TF_SRGB:
            fs << R"__SHADER__(
                float OETF_sRGB(const float linear) {
@@ -437,7 +379,74 @@ String8 ProgramCache::generateFragmentShader(const Key& needs) {
                }
            )__SHADER__";
            break;
        default:
            fs << R"__SHADER__(
                vec3 OETF(const vec3 linear) {
                    return linear;
                }
            )__SHADER__";
            break;
    }
}

String8 ProgramCache::generateVertexShader(const Key& needs) {
    Formatter vs;
    if (needs.isTexturing()) {
        vs << "attribute vec4 texCoords;"
           << "varying vec2 outTexCoords;";
    }
    vs << "attribute vec4 position;"
       << "uniform mat4 projection;"
       << "uniform mat4 texture;"
       << "void main(void) {" << indent << "gl_Position = projection * position;";
    if (needs.isTexturing()) {
        vs << "outTexCoords = (texture * texCoords).st;";
    }
    vs << dedent << "}";
    return vs.getString();
}

String8 ProgramCache::generateFragmentShader(const Key& needs) {
    Formatter fs;
    if (needs.getTextureTarget() == Key::TEXTURE_EXT) {
        fs << "#extension GL_OES_EGL_image_external : require";
    }

    // default precision is required-ish in fragment shaders
    fs << "precision mediump float;";

    if (needs.getTextureTarget() == Key::TEXTURE_EXT) {
        fs << "uniform samplerExternalOES sampler;"
           << "varying vec2 outTexCoords;";
    } else if (needs.getTextureTarget() == Key::TEXTURE_2D) {
        fs << "uniform sampler2D sampler;"
           << "varying vec2 outTexCoords;";
    }

    if (needs.getTextureTarget() == Key::TEXTURE_OFF || needs.hasAlpha()) {
        fs << "uniform vec4 color;";
    }

    if (needs.isY410BT2020()) {
        fs << R"__SHADER__(
            vec3 convertY410BT2020(const vec3 color) {
                const vec3 offset = vec3(0.0625, 0.5, 0.5);
                const mat3 transform = mat3(
                    vec3(1.1678,  1.1678, 1.1678),
                    vec3(   0.0, -0.1878, 2.1481),
                    vec3(1.6836, -0.6523,   0.0));
                // Y is in G, U is in R, and V is in B
                return clamp(transform * (color.grb - offset), 0.0, 1.0);
            }
            )__SHADER__";
    }

    if (needs.hasColorMatrix()) {
        fs << "uniform mat4 colorMatrix;";

        generateEOTF(fs, needs);
        generateOOTF(fs, needs);
        generateOETF(fs, needs);
    }

    fs << "void main(void) {" << indent;
+7 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
namespace android {

class Description;
class Formatter;
class Program;
class String8;

@@ -132,6 +133,12 @@ private:
    void primeCache();
    // compute a cache Key from a Description
    static Key computeKey(const Description& description);
    // Generate EOTF based from Key.
    static void generateEOTF(Formatter& fs, const Key& needs);
    // Generate OOTF based from Key.
    static void generateOOTF(Formatter& fs, const Key& needs);
    // Generate OETF based from Key.
    static void generateOETF(Formatter& fs, const Key& needs);
    // generates a program from the Key
    static Program* generateProgram(const Key& needs);
    // generates the vertex shader from the Key