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

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

Fix possible infinite loop when purging textures.

Change-Id: Ib05b398ae03e734da2dab0496df416fed4570b1c
parent 53389bdc
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -12,6 +12,8 @@

#include <jni.h>

#include <Caches.h>

#if 0
    #define TRACE_BITMAP(code)  code
#else
@@ -251,6 +253,9 @@ static jobject Bitmap_copy(JNIEnv* env, jobject, const SkBitmap* src,
}

static void Bitmap_destructor(JNIEnv* env, jobject, SkBitmap* bitmap) {
#ifdef USE_OPENGL_RENDERER
    android::uirenderer::Caches::getInstance().textureCache.remove(bitmap);
#endif
    delete bitmap;
}

+1 −5
Original line number Diff line number Diff line
@@ -143,11 +143,7 @@ void GenerationCache<K, V>::put(K key, V value) {
    }

    ssize_t index = mCache.indexOfKey(key);
    if (index >= 0) {
        sp<Entry<K, V> > entry = mCache.valueAt(index);
        detachFromCache(entry);
        addToCache(entry, key, value);
    } else {
    if (index < 0) {
        sp<Entry<K, V> > entry = new Entry<K, V>;
        addToCache(entry, key, value);
    }
+2 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
#ifndef ANDROID_UI_PATCH_CACHE_H
#define ANDROID_UI_PATCH_CACHE_H

#include <utils/ResourceTypes.h>

#include "Patch.h"
#include "GenerationCache.h"

+5 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ namespace uirenderer {
struct Texture {
    Texture() {
        cleanup = false;
        bitmapSize = 0;
    }

    /**
@@ -54,6 +55,10 @@ struct Texture {
     * Indicates whether this texture should be cleaned up after use.
     */
    bool cleanup;
    /**
     * Optional, size of the original bitmap.
     */
    uint32_t bitmapSize;
}; // struct Texture

class AutoTexture {
+16 −5
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@

#include <GLES2/gl2.h>

#include <utils/threads.h>

#include "TextureCache.h"
#include "Properties.h"

@@ -49,6 +51,7 @@ TextureCache::TextureCache(uint32_t maxByteSize):
}

TextureCache::~TextureCache() {
    Mutex::Autolock _l(mLock);
    mCache.clear();
}

@@ -64,14 +67,17 @@ void TextureCache::init() {
///////////////////////////////////////////////////////////////////////////////

uint32_t TextureCache::getSize() {
    Mutex::Autolock _l(mLock);
    return mSize;
}

uint32_t TextureCache::getMaxSize() {
    Mutex::Autolock _l(mLock);
    return mMaxSize;
}

void TextureCache::setMaxSize(uint32_t maxSize) {
    Mutex::Autolock _l(mLock);
    mMaxSize = maxSize;
    while (mSize > mMaxSize) {
        mCache.removeOldest();
@@ -83,12 +89,9 @@ void TextureCache::setMaxSize(uint32_t maxSize) {
///////////////////////////////////////////////////////////////////////////////

void TextureCache::operator()(SkBitmap*& bitmap, Texture*& texture) {
    if (bitmap) {
        const uint32_t size = bitmap->rowBytes() * bitmap->height();
        mSize -= size;
    }

    // This will be called already locked
    if (texture) {
        mSize -= texture->bitmapSize;
        glDeleteTextures(1, &texture->id);
        delete texture;
    }
@@ -99,6 +102,8 @@ void TextureCache::operator()(SkBitmap*& bitmap, Texture*& texture) {
///////////////////////////////////////////////////////////////////////////////

Texture* TextureCache::get(SkBitmap* bitmap) {
    Mutex::Autolock _l(mLock);

    Texture* texture = mCache.get(bitmap);
    if (!texture) {
        if (bitmap->width() > mMaxTextureSize || bitmap->height() > mMaxTextureSize) {
@@ -115,6 +120,7 @@ Texture* TextureCache::get(SkBitmap* bitmap) {
        }

        texture = new Texture;
        texture->bitmapSize = size;
        generateTexture(bitmap, texture, false);

        if (size < mMaxSize) {
@@ -131,15 +137,18 @@ Texture* TextureCache::get(SkBitmap* bitmap) {
}

void TextureCache::remove(SkBitmap* bitmap) {
    Mutex::Autolock _l(mLock);
    mCache.remove(bitmap);
}

void TextureCache::clear() {
    Mutex::Autolock _l(mLock);
    mCache.clear();
}

void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate) {
    SkAutoLockPixels alp(*bitmap);

    if (!bitmap->readyToDraw()) {
        LOGE("Cannot generate texture from bitmap");
        return;
@@ -159,6 +168,7 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege
    switch (bitmap->getConfig()) {
    case SkBitmap::kA8_Config:
        texture->blend = true;
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, bitmap->rowBytesAsPixels(), texture->height, 0,
                GL_ALPHA, GL_UNSIGNED_BYTE, bitmap->getPixels());
        break;
@@ -175,6 +185,7 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege
        texture->blend = !bitmap->isOpaque();
        break;
    default:
        LOGW("Unsupported bitmap config");
        break;
    }

Loading