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

Commit 9e5368a5 authored by Peiyong Lin's avatar Peiyong Lin Committed by android-build-merger
Browse files

Merge "[RenderEngine] Refactor the generation of EOTF, OOTF and OETF." into pi-dev am: 26a76f59

am: 56bf8970

Change-Id: I1db82d47f15a6af36ed77622d730648273337a82
parents 60b63143 56bf8970
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