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

Commit 9cccc2b9 authored by Romain Guy's avatar Romain Guy
Browse files

Enforce maximum texture size.

When an app tries to render a bitmap or path larger than the GPU's maximum
texture size, the drawing command is ignored and a warning is logged. This
change also makes texture drawing more robust by catching potential errors
during texture creation.

This change also fixes a crash in the FontRenderer. The destructor would
sometimes try to free an uninitialized array.

Change-Id: I95ae0939c52192d97b340aa02417bf6d0c962c57
parent de0547c0
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -292,6 +292,9 @@ FontRenderer::FontRenderer() {
    mCurrentQuadIndex = 0;
    mTextureId = 0;

    mTextMeshPtr = NULL;
    mTextTexture = NULL;

    mIndexBufferID = 0;

    mCacheWidth = DEFAULT_TEXT_CACHE_WIDTH;
@@ -319,8 +322,10 @@ FontRenderer::~FontRenderer() {
    }
    mCacheLines.clear();

    if (mInitialized) {
        delete[] mTextMeshPtr;
        delete[] mTextTexture;
    }

    if (mTextureId) {
        glDeleteTextures(1, &mTextureId);
+1 −2
Original line number Diff line number Diff line
@@ -80,8 +80,7 @@ void GradientCache::operator()(SkShader*& shader, Texture*& texture) {
///////////////////////////////////////////////////////////////////////////////

Texture* GradientCache::get(SkShader* shader) {
    Texture* texture = mCache.get(shader);
    return texture;
    return mCache.get(shader);
}

void GradientCache::remove(SkShader* shader) {
+5 −0
Original line number Diff line number Diff line
@@ -436,6 +436,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, const S
    }

    const Texture* texture = mTextureCache.get(bitmap);
    if (!texture) return;
    const AutoTexture autoCleanup(texture);

    drawTextureRect(left, top, right, bottom, texture, paint);
@@ -451,6 +452,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const
    }

    const Texture* texture = mTextureCache.get(bitmap);
    if (!texture) return;
    const AutoTexture autoCleanup(texture);

    drawTextureRect(r.left, r.top, r.right, r.bottom, texture, paint);
@@ -465,6 +467,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
    }

    const Texture* texture = mTextureCache.get(bitmap);
    if (!texture) return;
    const AutoTexture autoCleanup(texture);

    const float width = texture->width;
@@ -489,6 +492,7 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
    }

    const Texture* texture = mTextureCache.get(bitmap);
    if (!texture) return;
    const AutoTexture autoCleanup(texture);

    int alpha;
@@ -617,6 +621,7 @@ void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
    glActiveTexture(gTextureUnits[textureUnit]);

    const PathTexture* texture = mPathCache.get(path, paint);
    if (!texture) return;
    const AutoTexture autoCleanup(texture);

    int alpha;
+15 −2
Original line number Diff line number Diff line
@@ -34,6 +34,10 @@ PathCache::PathCache(uint32_t maxByteSize):
        mCache(GenerationCache<PathCacheEntry, PathTexture*>::kUnlimitedCapacity),
        mSize(0), mMaxSize(maxByteSize) {
    mCache.setOnEntryRemovedListener(this);

    GLint maxTextureSize;
    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
    mMaxTextureSize = maxTextureSize;
}

PathCache::~PathCache() {
@@ -94,9 +98,18 @@ PathTexture* PathCache::get(SkPath* path, SkPaint* paint) {
PathTexture* PathCache::addTexture(const PathCacheEntry& entry,
        const SkPath *path, const SkPaint* paint) {
    const SkRect& bounds = path->getBounds();

    const float pathWidth = bounds.width();
    const float pathHeight = bounds.height();

    if (pathWidth > mMaxTextureSize || pathHeight > mMaxTextureSize) {
        LOGW("Path too large to be rendered into a texture");
        return NULL;
    }

    const float offset = entry.strokeWidth * 1.5f;
    const uint32_t width = uint32_t(bounds.width() + offset * 2.0 + 0.5);
    const uint32_t height = uint32_t(bounds.height() + offset * 2.0 + 0.5);
    const uint32_t width = uint32_t(pathWidth + offset * 2.0 + 0.5);
    const uint32_t height = uint32_t(pathHeight + offset * 2.0 + 0.5);

    const uint32_t size = width * height;
    // Don't even try to cache a bitmap that's bigger than the cache
+1 −0
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ private:

    uint32_t mSize;
    uint32_t mMaxSize;
    GLuint mMaxTextureSize;
}; // class PathCache

}; // namespace uirenderer
Loading