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

Commit b92d8f79 authored by Chet Haase's avatar Chet Haase
Browse files

Optimize glyph cache texture uploads

Only upload the changed area of the glyph cache, not the entire
bitmap. Note that we can't do the full-on optimization here of copying a sub-rect
of the bitmap because of GL ES 2 limitations, but we can at least copy the
horizontal stripe containing the dirty rect, which can still be a big
savings over uploading the entire bitmap.

Issue #7158326 Bad framerates on MR1 (Mako, Manta, Prime)

Change-Id: Iab38d53202650f757ead4658cf4287bdad2b3cb9
parent 7b770b0e
Loading
Loading
Loading
Loading
+10 −7
Original line number Diff line number Diff line
@@ -331,10 +331,14 @@ void FontRenderer::checkTextureUpdate() {
    for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
        CacheTexture* cacheTexture = mCacheTextures[i];
        if (cacheTexture->isDirty() && cacheTexture->getTexture()) {
            uint32_t xOffset = 0;
            // Can't copy inner rect; glTexSubimage expects pointer to deal with entire buffer
            // of data. So expand the dirty rect to the encompassing horizontal stripe.
            const Rect* dirtyRect = cacheTexture->getDirtyRect();
            uint32_t x = 0;
            uint32_t y = dirtyRect->top;
            uint32_t width = cacheTexture->getWidth();
            uint32_t height = cacheTexture->getHeight();
            void* textureData = cacheTexture->getTexture();
            uint32_t height = dirtyRect->getHeight();
            void* textureData = cacheTexture->getTexture() + y * width;

            if (cacheTexture->getTextureId() != lastTextureId) {
                lastTextureId = cacheTexture->getTextureId();
@@ -342,12 +346,11 @@ void FontRenderer::checkTextureUpdate() {
                glBindTexture(GL_TEXTURE_2D, lastTextureId);
            }
#if DEBUG_FONT_RENDERER
            ALOGD("glTextSubimage for cacheTexture %d: xOff, width height = %d, %d, %d",
                    i, xOffset, width, height);
            ALOGD("glTexSubimage for cacheTexture %d: x, y, width height = %d, %d, %d, %d",
                    i, x, y, width, height);
#endif
            glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, 0, width, height,
            glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height,
                    GL_ALPHA, GL_UNSIGNED_BYTE, textureData);

            cacheTexture->setDirty(false);
        }
    }
+3 −0
Original line number Diff line number Diff line
@@ -171,6 +171,9 @@ bool CacheTexture::fitBitmap(const SkGlyph& glyph, uint32_t* retOriginX, uint32_
            }

            mDirty = true;
            const Rect r(*retOriginX - TEXTURE_BORDER_SIZE, *retOriginY - TEXTURE_BORDER_SIZE,
                    *retOriginX + glyphW, *retOriginY + glyphH);
            mDirtyRect.unionWith(r);
            mNumGlyphs++;

#if DEBUG_FONT_RENDERER
+9 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <utils/Log.h>

#include "FontUtil.h"
#include "Rect.h"

namespace android {
namespace uirenderer {
@@ -149,6 +150,10 @@ public:
        return mHeight;
    }

    inline const Rect* getDirtyRect() const {
        return &mDirtyRect;
    }

    inline uint8_t* getTexture() const {
        return mTexture;
    }
@@ -163,6 +168,9 @@ public:

    inline void setDirty(bool dirty) {
        mDirty = dirty;
        if (!dirty) {
            mDirtyRect.setEmpty();
        }
    }

    inline bool getLinearFiltering() const {
@@ -196,6 +204,7 @@ private:
    bool mDirty;
    uint16_t mNumGlyphs;
    CacheBlock* mCacheBlocks;
    Rect mDirtyRect;
};

}; // namespace uirenderer