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

Commit 707b2f78 authored by Romain Guy's avatar Romain Guy
Browse files

Optimize GLSL shaders.

Change-Id: I9a5e01bced63d8da0c61330a543a2b805388a59d
parent 7537f856
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.SparseBooleanArray;
@@ -2980,7 +2979,6 @@ public class ListView extends AbsListView {
            if (!mStackFromBottom) {
                int bottom;
                
                final int scrollY = mScrollY;
                for (int i = 0; i < count; i++) {
                    if ((headerDividers || first + i >= headerCount) &&
                            (footerDividers || first + i < footerLimit)) {
+11 −3
Original line number Diff line number Diff line
@@ -985,6 +985,7 @@ void OpenGLRenderer::setupTextureAlpha8(GLuint texture, uint32_t width, uint32_t
     ProgramDescription description;
     description.hasTexture = true;
     description.hasAlpha8Texture = true;
     const bool setColor = description.setAlpha8Color(r, g, b, a);

     if (applyFilters) {
         if (mShader) {
@@ -1021,7 +1022,9 @@ void OpenGLRenderer::setupTextureAlpha8(GLuint texture, uint32_t width, uint32_t
         mModelView.loadIdentity();
     }
     mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
     glUniform4f(mCaches.currentProgram->color, r, g, b, a);
     if (setColor) {
         mCaches.currentProgram->setColor(r, g, b, a);
     }

     textureUnit++;
     if (applyFilters) {
@@ -1126,6 +1129,8 @@ void OpenGLRenderer::setupColorRect(float left, float top, float right, float bo

    // Describe the required shaders
    ProgramDescription description;
    const bool setColor = description.setColor(r, g, b, a);

    if (mShader) {
        mShader->describe(description, mExtensions);
    }
@@ -1152,7 +1157,7 @@ void OpenGLRenderer::setupColorRect(float left, float top, float right, float bo
        mat4 identity;
        mCaches.currentProgram->set(mOrthoMatrix, mModelView, identity);
    }
    glUniform4f(mCaches.currentProgram->color, r, g, b, a);
    mCaches.currentProgram->setColor(r, g, b, a);

    // Setup attributes and uniforms required by the shaders
    if (mShader) {
@@ -1189,6 +1194,7 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b

    ProgramDescription description;
    description.hasTexture = true;
    const bool setColor = description.setColor(alpha, alpha, alpha, alpha);
    if (mColorFilter) {
        mColorFilter->describe(description, mExtensions);
    }
@@ -1211,7 +1217,9 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b
    glUniform1i(mCaches.currentProgram->getUniform("sampler"), 0);

    // Always premultiplied
    glUniform4f(mCaches.currentProgram->color, alpha, alpha, alpha, alpha);
    if (setColor) {
        mCaches.currentProgram->setColor(alpha, alpha, alpha, alpha);
    }

    // Mesh
    int texCoordsSlot = mCaches.currentProgram->getAttrib("texCoords");
+4 −1
Original line number Diff line number Diff line
@@ -58,7 +58,6 @@ Program::Program(const char* vertex, const char* fragment) {
    mUse = false;

    position = addAttrib("position");
    color = addUniform("color");
    transform = addUniform("transform");
}

@@ -124,6 +123,10 @@ void Program::set(const mat4& projectionMatrix, const mat4& modelViewMatrix,
    glUniformMatrix4fv(transform, 1, GL_FALSE, &t.data[0]);
}

void Program::setColor(const float r, const float g, const float b, const float a) {
    glUniform4f(getUniform("color"), r, g, b, a);
}

void Program::use() {
    glUseProgram(id);
    mUse = true;
+4 −4
Original line number Diff line number Diff line
@@ -77,14 +77,14 @@ public:
             const mat4& transformMatrix);

    /**
     * Name of the position attribute.
     * Sets the color associated with this shader.
     */
    int position;
    void setColor(const float r, const float g, const float b, const float a);

    /**
     * Name of the color uniform.
     * Name of the position attribute.
     */
    int color;
    int position;

    /**
     * Name of the transform uniform.
+150 −21
Original line number Diff line number Diff line
@@ -23,6 +23,14 @@
namespace android {
namespace uirenderer {

///////////////////////////////////////////////////////////////////////////////
// Defines
///////////////////////////////////////////////////////////////////////////////

#define MODULATE_OP_NO_MODULATE 0
#define MODULATE_OP_MODULATE 1
#define MODULATE_OP_MODULATE_A8 2

///////////////////////////////////////////////////////////////////////////////
// Vertex shaders snippets
///////////////////////////////////////////////////////////////////////////////
@@ -69,8 +77,7 @@ const char* gVS_Main_OutGradient[3] = {
        "    sweep = (screenSpace * position).xy;\n"
};
const char* gVS_Main_OutBitmapTexCoords =
        "    vec4 bitmapCoords = textureTransform * position;\n"
        "    outBitmapTexCoords = bitmapCoords.xy * textureDimension;\n";
        "    outBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n";
const char* gVS_Main_Position =
        "    gl_Position = transform * position;\n";
const char* gVS_Footer =
@@ -113,12 +120,52 @@ const char* gFS_Uniforms_ColorOp[4] = {
const char* gFS_Main =
        "\nvoid main(void) {\n"
        "    lowp vec4 fragColor;\n";

// Fast cases
const char* gFS_Fast_SingleColor =
        "\nvoid main(void) {\n"
        "    gl_FragColor = color;\n"
        "}\n\n";
const char* gFS_Fast_SingleTexture =
        "\nvoid main(void) {\n"
        "    gl_FragColor = texture2D(sampler, outTexCoords);\n"
        "}\n\n";
const char* gFS_Fast_SingleModulateTexture =
        "\nvoid main(void) {\n"
        "    gl_FragColor = color.a * texture2D(sampler, outTexCoords);\n"
        "}\n\n";
const char* gFS_Fast_SingleA8Texture =
        "\nvoid main(void) {\n"
        "    gl_FragColor = vec4(0.0, 0.0, 0.0, texture2D(sampler, outTexCoords).a);\n"
        "}\n\n";
const char* gFS_Fast_SingleModulateA8Texture =
        "\nvoid main(void) {\n"
        "    gl_FragColor = color * texture2D(sampler, outTexCoords).a;\n"
        "}\n\n";
const char* gFS_Fast_SingleGradient =
        "\nvoid main(void) {\n"
        "    gl_FragColor = texture2D(gradientSampler, linear);\n"
        "}\n\n";
const char* gFS_Fast_SingleModulateGradient =
        "\nvoid main(void) {\n"
        "    gl_FragColor = color.a * texture2D(gradientSampler, linear);\n"
        "}\n\n";

// General case
const char* gFS_Main_FetchColor =
        "    fragColor = color;\n";
const char* gFS_Main_FetchTexture =
        "    fragColor = color * texture2D(sampler, outTexCoords);\n";
const char* gFS_Main_FetchA8Texture =
        "    fragColor = color * texture2D(sampler, outTexCoords).a;\n";
const char* gFS_Main_FetchTexture[2] = {
        // Don't modulate
        "    fragColor = texture2D(sampler, outTexCoords);\n",
        // Modulate
        "    fragColor = color * texture2D(sampler, outTexCoords);\n"
};
const char* gFS_Main_FetchA8Texture[2] = {
        // Don't modulate
        "    fragColor = vec4(0.0, 0.0, 0.0, texture2D(sampler, outTexCoords).a);\n",
        // Modulate
        "    fragColor = color * texture2D(sampler, outTexCoords).a;\n"
};
const char* gFS_Main_FetchGradient[3] = {
        // Linear
        "    vec4 gradientColor = texture2D(gradientSampler, linear);\n",
@@ -137,12 +184,30 @@ const char* gFS_Main_BlendShadersBG =
        "    fragColor = blendShaders(gradientColor, bitmapColor)";
const char* gFS_Main_BlendShadersGB =
        "    fragColor = blendShaders(bitmapColor, gradientColor)";
const char* gFS_Main_BlendShaders_Modulate =
        " * fragColor.a;\n";
const char* gFS_Main_GradientShader_Modulate =
        "    fragColor = gradientColor * fragColor.a;\n";
const char* gFS_Main_BitmapShader_Modulate =
        "    fragColor = bitmapColor * fragColor.a;\n";
const char* gFS_Main_BlendShaders_Modulate[3] = {
        // Don't modulate
        ";\n",
        // Modulate
        " * fragColor.a;\n",
        // Modulate with alpha 8 texture
        " * texture2D(sampler, outTexCoords).a;\n"
};
const char* gFS_Main_GradientShader_Modulate[3] = {
        // Don't modulate
        "    fragColor = gradientColor;\n",
        // Modulate
        "    fragColor = gradientColor * fragColor.a;\n",
        // Modulate with alpha 8 texture
        "    fragColor = gradientColor * texture2D(sampler, outTexCoords).a;\n"
    };
const char* gFS_Main_BitmapShader_Modulate[3] = {
        // Don't modulate
        "    fragColor = bitmapColor;\n",
        // Modulate
        "    fragColor = bitmapColor * fragColor.a;\n",
        // Modulate with alpha 8 texture
        "    fragColor = bitmapColor * texture2D(sampler, outTexCoords).a;\n"
    };
const char* gFS_Main_FragColor =
        "    gl_FragColor = fragColor;\n";
const char* gFS_Main_FragColor_Blend =
@@ -317,7 +382,7 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
    // Set the default precision
    String8 shader;

    bool blendFramebuffer = description.framebufferMode >= SkXfermode::kPlus_Mode;
    const bool blendFramebuffer = description.framebufferMode >= SkXfermode::kPlus_Mode;
    if (blendFramebuffer) {
        shader.append(gFS_Header_Extension_FramebufferFetch);
    }
@@ -335,15 +400,72 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
        shader.append(gVS_Header_Varyings_HasBitmap);
    }


    // Uniforms
    int modulateOp = MODULATE_OP_NO_MODULATE;
    const bool singleColor = !description.hasTexture &&
            !description.hasGradient && !description.hasBitmap;

    if (description.modulate || singleColor) {
        shader.append(gFS_Uniforms_Color);
        if (!singleColor) modulateOp = MODULATE_OP_MODULATE;
    }
    if (description.hasTexture) {
        shader.append(gFS_Uniforms_TextureSampler);
    }
    if (description.hasGradient) {
        shader.append(gFS_Uniforms_GradientSampler[description.gradientType]);
    }

    // Optimization for common cases
    if (!blendFramebuffer) {
        bool fast = false;

        const bool noShader = !description.hasGradient && !description.hasBitmap;
        const bool singleTexture = description.hasTexture &&
                !description.hasAlpha8Texture && noShader;
        const bool singleA8Texture = description.hasTexture &&
                description.hasAlpha8Texture && noShader;
        const bool singleGradient = !description.hasTexture &&
                description.hasGradient && !description.hasBitmap &&
                description.gradientType == ProgramDescription::kGradientLinear;

        if (singleColor) {
            shader.append(gFS_Fast_SingleColor);
            fast = true;
        } else if (singleTexture) {
            if (!description.modulate) {
                shader.append(gFS_Fast_SingleTexture);
            } else {
                shader.append(gFS_Fast_SingleModulateTexture);
            }
            fast = true;
        } else if (singleA8Texture) {
            if (!description.modulate) {
                shader.append(gFS_Fast_SingleA8Texture);
            } else {
                shader.append(gFS_Fast_SingleModulateA8Texture);
            }
            fast = true;
        } else if (singleGradient) {
            if (!description.modulate) {
                shader.append(gFS_Fast_SingleGradient);
            } else {
                shader.append(gFS_Fast_SingleModulateGradient);
            }
            fast = true;
        }

        if (fast) {
            if (DEBUG_PROGRAM_CACHE) {
                PROGRAM_LOGD("*** Fast case:\n");
                PROGRAM_LOGD("*** Generated fragment shader:\n\n");
                printLongString(shader);
            }

            return shader;
        }
    }

    if (description.hasBitmap) {
        shader.append(gFS_Uniforms_BitmapSampler);
    }
@@ -368,13 +490,17 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
        // Stores the result in fragColor directly
        if (description.hasTexture) {
            if (description.hasAlpha8Texture) {
                shader.append(gFS_Main_FetchA8Texture);
                if (!description.hasGradient && !description.hasBitmap) {
                    shader.append(gFS_Main_FetchA8Texture[modulateOp]);
                }
            } else {
                shader.append(gFS_Main_FetchTexture);
                shader.append(gFS_Main_FetchTexture[modulateOp]);
            }
        } else {
            if ((!description.hasGradient && !description.hasBitmap) || description.modulate) {
                shader.append(gFS_Main_FetchColor);
            }
        }
        if (description.hasGradient) {
            shader.append(gFS_Main_FetchGradient[description.gradientType]);
        }
@@ -387,17 +513,20 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
        }
        // Case when we have two shaders set
        if (description.hasGradient && description.hasBitmap) {
            int op = description.hasAlpha8Texture ? MODULATE_OP_MODULATE_A8 : modulateOp;
            if (description.isBitmapFirst) {
                shader.append(gFS_Main_BlendShadersBG);
            } else {
                shader.append(gFS_Main_BlendShadersGB);
            }
            shader.append(gFS_Main_BlendShaders_Modulate);
            shader.append(gFS_Main_BlendShaders_Modulate[op]);
        } else {
            if (description.hasGradient) {
                shader.append(gFS_Main_GradientShader_Modulate);
                int op = description.hasAlpha8Texture ? MODULATE_OP_MODULATE_A8 : modulateOp;
                shader.append(gFS_Main_GradientShader_Modulate[op]);
            } else if (description.hasBitmap) {
                shader.append(gFS_Main_BitmapShader_Modulate);
                int op = description.hasAlpha8Texture ? MODULATE_OP_MODULATE_A8 : modulateOp;
                shader.append(gFS_Main_BitmapShader_Modulate[op]);
            }
        }
        // Apply the color op if needed
Loading