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

Commit 2a47c14e authored by Chet Haase's avatar Chet Haase
Browse files

Fix issues from recent glyph caching change

There were 2 issues remaining after a recent change to support
glyph caching from multiple textures:
- memory in the GPU for all textures was being allocated automatically.
This is now lazy, being allocated only when those textures are first
needed.
- filtering (applied when a rendered object is transformed) was ignoring
the new multiple-texture structure. Filtering should be applied correctly
whenever we change textures.

Change-Id: I5c8eb8d46c73cd01782a353fc79b11cacc2146ab
parent dd73df35
Loading
Loading
Loading
Loading
+31 −19
Original line number Diff line number Diff line
@@ -348,6 +348,8 @@ FontRenderer::FontRenderer() {
    mCacheTexture256 = NULL;
    mCacheTexture512 = NULL;

    mLinearFiltering = false;

    mIndexBufferID = 0;

    mSmallCacheWidth = DEFAULT_TEXT_CACHE_WIDTH;
@@ -412,11 +414,23 @@ void FontRenderer::flushAllAndInvalidate() {
    }
}

uint8_t* FontRenderer::allocateTextureMemory(int width, int height) {
    uint8_t* textureMemory = new uint8_t[width * height];
    memset(textureMemory, 0, width * height * sizeof(uint8_t));
void FontRenderer::allocateTextureMemory(CacheTexture *cacheTexture) {
    int width = cacheTexture->mWidth;
    int height = cacheTexture->mHeight;
    cacheTexture->mTexture = new uint8_t[width * height];
    memset(cacheTexture->mTexture, 0, width * height * sizeof(uint8_t));
    glBindTexture(GL_TEXTURE_2D, cacheTexture->mTextureId);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    // Initialize texture dimensions
    glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0,
            GL_ALPHA, GL_UNSIGNED_BYTE, 0);

    const GLenum filtering = cacheTexture->mLinearFiltering ? GL_LINEAR : GL_NEAREST;
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);

    return textureMemory;
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}

void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
@@ -475,7 +489,7 @@ void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyp
    CacheTexture *cacheTexture = cacheLine->mCacheTexture;
    if (cacheTexture->mTexture == NULL) {
        // Large-glyph texture memory is allocated only as needed
        cacheTexture->mTexture = allocateTextureMemory(cacheTexture->mWidth, cacheTexture->mHeight);
        allocateTextureMemory(cacheTexture);
    }
    uint8_t* cacheBuffer = cacheTexture->mTexture;
    uint8_t* bitmapBuffer = (uint8_t*) glyph.fImage;
@@ -492,23 +506,15 @@ void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyp
}

CacheTexture* FontRenderer::createCacheTexture(int width, int height, bool allocate) {
    uint8_t* textureMemory = allocate ? allocateTextureMemory(width, height) : NULL;
    GLuint textureId;
    glGenTextures(1, &textureId);
    glBindTexture(GL_TEXTURE_2D, textureId);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    // Initialize texture dimensions
    glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0,
            GL_ALPHA, GL_UNSIGNED_BYTE, 0);

    mLinearFiltering = false;
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    uint8_t* textureMemory = NULL;

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    return new CacheTexture(textureMemory, textureId, width, height);
    CacheTexture* cacheTexture = new CacheTexture(textureMemory, textureId, width, height);
    if (allocate) {
        allocateTextureMemory(cacheTexture);
    }
    return cacheTexture;
}

void FontRenderer::initTextTexture() {
@@ -641,6 +647,12 @@ void FontRenderer::checkTextureUpdate() {
    }

    glBindTexture(GL_TEXTURE_2D, mCurrentCacheTexture->mTextureId);
    if (mLinearFiltering != mCurrentCacheTexture->mLinearFiltering) {
        const GLenum filtering = mLinearFiltering ? GL_LINEAR : GL_NEAREST;
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
        mCurrentCacheTexture->mLinearFiltering = mLinearFiltering;
    }
    mLastCacheTexture = mCurrentCacheTexture;

    mUploadTexture = false;
+6 −4
Original line number Diff line number Diff line
@@ -59,7 +59,8 @@ class CacheTexture {
public:
    CacheTexture(){}
    CacheTexture(uint8_t* texture, GLuint textureId, uint16_t width, uint16_t height) :
        mTexture(texture), mTextureId(textureId), mWidth(width), mHeight(height) {}
        mTexture(texture), mTextureId(textureId), mWidth(width), mHeight(height),
        mLinearFiltering(false) {}
    ~CacheTexture() {
        if (mTexture != NULL) {
            delete[] mTexture;
@@ -73,6 +74,7 @@ public:
    GLuint mTextureId;
    uint16_t mWidth;
    uint16_t mHeight;
    bool mLinearFiltering;
};

class CacheTextureLine {
@@ -249,7 +251,8 @@ public:

    GLuint getTexture(bool linearFiltering = false) {
        checkInit();
        if (linearFiltering != mLinearFiltering) {
        if (linearFiltering != mCurrentCacheTexture->mLinearFiltering) {
            mCurrentCacheTexture->mLinearFiltering = linearFiltering;
            mLinearFiltering = linearFiltering;
            const GLenum filtering = linearFiltering ? GL_LINEAR : GL_NEAREST;

@@ -282,7 +285,7 @@ protected:

    const uint8_t* mGammaTable;

    uint8_t* allocateTextureMemory(int width, int height);
    void allocateTextureMemory(CacheTexture* cacheTexture);
    void initTextTexture();
    CacheTexture *createCacheTexture(int width, int height, bool allocate);
    void cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
@@ -318,7 +321,6 @@ protected:
    CacheTexture* mCacheTexture256;
    CacheTexture* mCacheTexture512;


    void checkTextureUpdate();
    bool mUploadTexture;