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

Commit e3c26851 authored by Romain Guy's avatar Romain Guy
Browse files

Improve rendering performance on some GPUs

This change sets textures filtering to GL_NEAREST by default. GL_LINEAR
filtering is only used when textures are transformed with a scale or
a rotation. This helps save a couple of fps on some GPUs.

Change-Id: I1efaa452c2c79905f00238e54d886a37203a2ac1
parent 29d23ecf
Loading
Loading
Loading
Loading
+2 −5
Original line number Diff line number Diff line
@@ -181,11 +181,8 @@ void GradientCache::generateTexture(SkBitmap* bitmap, Texture* texture) {
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap->rowBytesAsPixels(), texture->height, 0,
            GL_RGBA, GL_UNSIGNED_BYTE, bitmap->getPixels());

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    texture->setFilter(GL_LINEAR, GL_LINEAR);
    texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
}

}; // namespace uirenderer
+2 −22
Original line number Diff line number Diff line
@@ -51,8 +51,6 @@ struct Layer {
        texture.width = layerWidth;
        texture.height = layerHeight;
        colorFilter = NULL;
        firstFilter = true;
        firstWrap = true;
    }

    ~Layer() {
@@ -150,27 +148,11 @@ struct Layer {
    }

    void setWrap(GLenum wrapS, GLenum wrapT, bool bindTexture = false, bool force = false) {
        if (firstWrap || force || wrapS != texture.wrapS || wrapT != texture.wrapT) {
            firstWrap = true;
            texture.setWrap(wrapS, wrapT);
            if (bindTexture) {
                glBindTexture(renderTarget, texture.id);
            }
            glTexParameteri(renderTarget, GL_TEXTURE_WRAP_S, wrapS);
            glTexParameteri(renderTarget, GL_TEXTURE_WRAP_T, wrapT);
        }
        texture.setWrap(wrapS, wrapT, bindTexture, force, renderTarget);
    }

    void setFilter(GLenum min, GLenum mag, bool bindTexture = false, bool force = false) {
        if (firstFilter || force || min != texture.minFilter || mag != texture.magFilter) {
            firstFilter = false;
            texture.setFilter(min, mag);
            if (bindTexture) {
                glBindTexture(renderTarget, texture.id);
            }
            glTexParameteri(renderTarget, GL_TEXTURE_MIN_FILTER, min);
            glTexParameteri(renderTarget, GL_TEXTURE_MAG_FILTER, mag);
        }
        texture.setFilter(min, mag,bindTexture, force, renderTarget);
    }

    inline bool isCacheable() {
@@ -296,8 +278,6 @@ private:
     */
    mat4 texTransform;

    bool firstFilter;
    bool firstWrap;
}; // struct Layer

}; // namespace uirenderer
+1 −1
Original line number Diff line number Diff line
@@ -107,7 +107,7 @@ Layer* LayerCache::get(const uint32_t width, const uint32_t height) {
        layer->generateTexture();
        layer->bindTexture();
        layer->setFilter(GL_NEAREST, GL_NEAREST);
        layer->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
        layer->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, false);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

#if DEBUG_LAYERS
+17 −23
Original line number Diff line number Diff line
@@ -1293,16 +1293,16 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, Sk
    SkXfermode::Mode mode;
    getAlphaAndMode(paint, &alpha, &mode);

    setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);

    float x = left;
    float y = top;

    GLenum filter = GL_LINEAR;
    bool ignoreTransform = false;
    if (mSnapshot->transform->isPureTranslate()) {
        x = (int) floorf(left + mSnapshot->transform->getTranslateX() + 0.5f);
        y = (int) floorf(top + mSnapshot->transform->getTranslateY() + 0.5f);
        ignoreTransform = true;
        filter = GL_NEAREST;
    }

    setupDraw();
@@ -1315,7 +1315,11 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, Sk
    setupDrawBlending(true, mode);
    setupDrawProgram();
    setupDrawModelView(x, y, x + texture->width, y + texture->height, ignoreTransform);

    setupDrawTexture(texture->id);
    texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
    texture->setFilter(filter, filter);

    setupDrawPureColorUniforms();
    setupDrawColorFilterUniforms();
    setupDrawShaderUniforms();
@@ -1379,7 +1383,9 @@ void OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHei
    Texture* texture = mCaches.textureCache.get(bitmap);
    if (!texture) return;
    const AutoTexture autoCleanup(texture);
    setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);

    texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, true);
    texture->setFilter(GL_LINEAR, GL_LINEAR, true);

    int alpha;
    SkXfermode::Mode mode;
@@ -1462,7 +1468,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
    Texture* texture = mCaches.textureCache.get(bitmap);
    if (!texture) return;
    const AutoTexture autoCleanup(texture);
    setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
    texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, true);

    const float width = texture->width;
    const float height = texture->height;
@@ -1483,11 +1489,13 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
        const float x = (int) floorf(dstLeft + mSnapshot->transform->getTranslateX() + 0.5f);
        const float y = (int) floorf(dstTop + mSnapshot->transform->getTranslateY() + 0.5f);

        texture->setFilter(GL_NEAREST, GL_NEAREST, true);
        drawTextureMesh(x, y, x + (dstRight - dstLeft), y + (dstBottom - dstTop),
                texture->id, alpha / 255.0f, mode, texture->blend,
                &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
                GL_TRIANGLE_STRIP, gMeshCount, false, true);
    } else {
        texture->setFilter(GL_LINEAR, GL_LINEAR, true);
        drawTextureMesh(dstLeft, dstTop, dstRight, dstBottom, texture->id, alpha / 255.0f,
                mode, texture->blend, &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
                GL_TRIANGLE_STRIP, gMeshCount);
@@ -1507,7 +1515,8 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int
    Texture* texture = mCaches.textureCache.get(bitmap);
    if (!texture) return;
    const AutoTexture autoCleanup(texture);
    setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
    texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, true);
    texture->setFilter(GL_LINEAR, GL_LINEAR, true);

    int alpha;
    SkXfermode::Mode mode;
@@ -2411,16 +2420,18 @@ void OpenGLRenderer::drawTextureRect(float left, float top, float right, float b
    SkXfermode::Mode mode;
    getAlphaAndMode(paint, &alpha, &mode);

    setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
    texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, true);

    if (mSnapshot->transform->isPureTranslate()) {
        const float x = (int) floorf(left + mSnapshot->transform->getTranslateX() + 0.5f);
        const float y = (int) floorf(top + mSnapshot->transform->getTranslateY() + 0.5f);

        texture->setFilter(GL_NEAREST, GL_NEAREST, true);
        drawTextureMesh(x, y, x + texture->width, y + texture->height, texture->id,
                alpha / 255.0f, mode, texture->blend, (GLvoid*) NULL,
                (GLvoid*) gMeshTextureOffset, GL_TRIANGLE_STRIP, gMeshCount, false, true);
    } else {
        texture->setFilter(GL_LINEAR, GL_LINEAR, true);
        drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, mode,
                texture->blend, (GLvoid*) NULL, (GLvoid*) gMeshTextureOffset,
                GL_TRIANGLE_STRIP, gMeshCount);
@@ -2550,22 +2561,5 @@ SkXfermode::Mode OpenGLRenderer::getXfermode(SkXfermode* mode) {
    return resultMode;
}

void OpenGLRenderer::setTextureWrapModes(Texture* texture, GLenum wrapS, GLenum wrapT) {
    bool bound = false;
    if (wrapS != texture->wrapS) {
        glBindTexture(GL_TEXTURE_2D, texture->id);
        bound = true;
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
        texture->wrapS = wrapS;
    }
    if (wrapT != texture->wrapT) {
        if (!bound) {
            glBindTexture(GL_TEXTURE_2D, texture->id);
        }
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
        texture->wrapT = wrapT;
    }
}

}; // namespace uirenderer
}; // namespace android
+0 −6
Original line number Diff line number Diff line
@@ -463,12 +463,6 @@ private:
        glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
    }

    /**
     * Sets the wrap modes for the specified texture. The wrap modes are modified
     * only when needed.
     */
    inline void setTextureWrapModes(Texture* texture, GLenum wrapS, GLenum wrapT);

    /**
     * Enable or disable blending as necessary. This function sets the appropriate
     * blend function based on the specified xfermode.
Loading