ResourceCache.cpp revision a35778c799e8073a42b9e22191bde9d838327ab7
15c13d89c1332fcc499379b9064b891187b75ca32Chet Haase/*
25c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * Copyright (C) 2010 The Android Open Source Project
35c13d89c1332fcc499379b9064b891187b75ca32Chet Haase *
45c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * Licensed under the Apache License, Version 2.0 (the "License");
55c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * you may not use this file except in compliance with the License.
65c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * You may obtain a copy of the License at
75c13d89c1332fcc499379b9064b891187b75ca32Chet Haase *
85c13d89c1332fcc499379b9064b891187b75ca32Chet Haase *      http://www.apache.org/licenses/LICENSE-2.0
95c13d89c1332fcc499379b9064b891187b75ca32Chet Haase *
105c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * Unless required by applicable law or agreed to in writing, software
115c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * distributed under the License is distributed on an "AS IS" BASIS,
125c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * See the License for the specific language governing permissions and
145c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * limitations under the License.
155c13d89c1332fcc499379b9064b891187b75ca32Chet Haase */
165c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
17e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy#define LOG_TAG "OpenGLRenderer"
18e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
195c13d89c1332fcc499379b9064b891187b75ca32Chet Haase#include <SkPixelRef.h>
205c13d89c1332fcc499379b9064b891187b75ca32Chet Haase#include "ResourceCache.h"
215c13d89c1332fcc499379b9064b891187b75ca32Chet Haase#include "Caches.h"
225c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
235c13d89c1332fcc499379b9064b891187b75ca32Chet Haasenamespace android {
24a35778c799e8073a42b9e22191bde9d838327ab7John Reck
25a35778c799e8073a42b9e22191bde9d838327ab7John Reck#ifdef USE_OPENGL_RENDERER
26a35778c799e8073a42b9e22191bde9d838327ab7John Reckusing namespace uirenderer;
27a35778c799e8073a42b9e22191bde9d838327ab7John ReckANDROID_SINGLETON_STATIC_INSTANCE(ResourceCache);
28a35778c799e8073a42b9e22191bde9d838327ab7John Reck#endif
29a35778c799e8073a42b9e22191bde9d838327ab7John Reck
305c13d89c1332fcc499379b9064b891187b75ca32Chet Haasenamespace uirenderer {
315c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
325c13d89c1332fcc499379b9064b891187b75ca32Chet Haase///////////////////////////////////////////////////////////////////////////////
335c13d89c1332fcc499379b9064b891187b75ca32Chet Haase// Resource cache
345c13d89c1332fcc499379b9064b891187b75ca32Chet Haase///////////////////////////////////////////////////////////////////////////////
355c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
365c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::logCache() {
375baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("ResourceCache: cacheReport:");
385c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    for (size_t i = 0; i < mCache->size(); ++i) {
395c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        ResourceReference* ref = mCache->valueAt(i);
40f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat        ALOGD("  ResourceCache: mCache(%zu): resource, ref = 0x%p, 0x%p",
415c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                i, mCache->keyAt(i), mCache->valueAt(i));
42f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat        ALOGD("  ResourceCache: mCache(%zu): refCount, recycled, destroyed, type = %d, %d, %d, %d",
435c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                i, ref->refCount, ref->recycled, ref->destroyed, ref->resourceType);
445c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
455c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
465c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
475c13d89c1332fcc499379b9064b891187b75ca32Chet HaaseResourceCache::ResourceCache() {
48e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase    Mutex::Autolock _l(mLock);
49d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik    mCache = new KeyedVector<const void*, ResourceReference*>();
505c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
515c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
525c13d89c1332fcc499379b9064b891187b75ca32Chet HaaseResourceCache::~ResourceCache() {
53e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase    Mutex::Autolock _l(mLock);
545c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    delete mCache;
555c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
565c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
5758ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::lock() {
5858ecc204fbcacef34806290492384677a330d4d4Romain Guy    mLock.lock();
5958ecc204fbcacef34806290492384677a330d4d4Romain Guy}
6058ecc204fbcacef34806290492384677a330d4d4Romain Guy
6158ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::unlock() {
6258ecc204fbcacef34806290492384677a330d4d4Romain Guy    mLock.unlock();
6358ecc204fbcacef34806290492384677a330d4d4Romain Guy}
6458ecc204fbcacef34806290492384677a330d4d4Romain Guy
655c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) {
66e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase    Mutex::Autolock _l(mLock);
6758ecc204fbcacef34806290492384677a330d4d4Romain Guy    incrementRefcountLocked(resource, resourceType);
685c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
695c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
70d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikvoid ResourceCache::incrementRefcount(const SkBitmap* bitmapResource) {
710c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik    bitmapResource->pixelRef()->globalRef();
726062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger    SkSafeRef(bitmapResource->getColorTable());
7349c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy    incrementRefcount((void*) bitmapResource, kBitmap);
745c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
755c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
76d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikvoid ResourceCache::incrementRefcount(const SkPath* pathResource) {
7749c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy    incrementRefcount((void*) pathResource, kPath);
785a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase}
795a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase
80d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikvoid ResourceCache::incrementRefcount(const Res_png_9patch* patchResource) {
81e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    incrementRefcount((void*) patchResource, kNinePatch);
82e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy}
83e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
8458ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::incrementRefcountLocked(void* resource, ResourceType resourceType) {
858dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ssize_t index = mCache->indexOfKey(resource);
868dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
8758ecc204fbcacef34806290492384677a330d4d4Romain Guy    if (ref == NULL || mCache->size() == 0) {
8858ecc204fbcacef34806290492384677a330d4d4Romain Guy        ref = new ResourceReference(resourceType);
8958ecc204fbcacef34806290492384677a330d4d4Romain Guy        mCache->add(resource, ref);
905c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
9158ecc204fbcacef34806290492384677a330d4d4Romain Guy    ref->refCount++;
9258ecc204fbcacef34806290492384677a330d4d4Romain Guy}
9358ecc204fbcacef34806290492384677a330d4d4Romain Guy
94d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikvoid ResourceCache::incrementRefcountLocked(const SkBitmap* bitmapResource) {
950c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik    bitmapResource->pixelRef()->globalRef();
9658ecc204fbcacef34806290492384677a330d4d4Romain Guy    SkSafeRef(bitmapResource->getColorTable());
9758ecc204fbcacef34806290492384677a330d4d4Romain Guy    incrementRefcountLocked((void*) bitmapResource, kBitmap);
9858ecc204fbcacef34806290492384677a330d4d4Romain Guy}
9958ecc204fbcacef34806290492384677a330d4d4Romain Guy
100d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikvoid ResourceCache::incrementRefcountLocked(const SkPath* pathResource) {
10158ecc204fbcacef34806290492384677a330d4d4Romain Guy    incrementRefcountLocked((void*) pathResource, kPath);
10258ecc204fbcacef34806290492384677a330d4d4Romain Guy}
10358ecc204fbcacef34806290492384677a330d4d4Romain Guy
104d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikvoid ResourceCache::incrementRefcountLocked(const Res_png_9patch* patchResource) {
105e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    incrementRefcountLocked((void*) patchResource, kNinePatch);
106e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy}
107e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
10858ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::decrementRefcount(void* resource) {
10958ecc204fbcacef34806290492384677a330d4d4Romain Guy    Mutex::Autolock _l(mLock);
11058ecc204fbcacef34806290492384677a330d4d4Romain Guy    decrementRefcountLocked(resource);
1115c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
1125c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
113d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikvoid ResourceCache::decrementRefcount(const SkBitmap* bitmapResource) {
1140c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik    bitmapResource->pixelRef()->globalUnref();
1156062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger    SkSafeUnref(bitmapResource->getColorTable());
11643ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guy    decrementRefcount((void*) bitmapResource);
1175c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
1185c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
119d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikvoid ResourceCache::decrementRefcount(const SkPath* pathResource) {
1205a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    decrementRefcount((void*) pathResource);
1215a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase}
1225a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase
123d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikvoid ResourceCache::decrementRefcount(const Res_png_9patch* patchResource) {
124e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    decrementRefcount((void*) patchResource);
125e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy}
126e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
12758ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::decrementRefcountLocked(void* resource) {
1288dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ssize_t index = mCache->indexOfKey(resource);
12958ecc204fbcacef34806290492384677a330d4d4Romain Guy    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
1305c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref == NULL) {
13158ecc204fbcacef34806290492384677a330d4d4Romain Guy        // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
1325c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        return;
1335c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
13458ecc204fbcacef34806290492384677a330d4d4Romain Guy    ref->refCount--;
1355c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref->refCount == 0) {
13697dc9172b0e58979c63de0dedbab656399a62281Romain Guy        deleteResourceReferenceLocked(resource, ref);
1375c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
1385c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
1395c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
140d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikvoid ResourceCache::decrementRefcountLocked(const SkBitmap* bitmapResource) {
1410c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik    bitmapResource->pixelRef()->globalUnref();
14258ecc204fbcacef34806290492384677a330d4d4Romain Guy    SkSafeUnref(bitmapResource->getColorTable());
14358ecc204fbcacef34806290492384677a330d4d4Romain Guy    decrementRefcountLocked((void*) bitmapResource);
14458ecc204fbcacef34806290492384677a330d4d4Romain Guy}
14558ecc204fbcacef34806290492384677a330d4d4Romain Guy
146d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikvoid ResourceCache::decrementRefcountLocked(const SkPath* pathResource) {
14758ecc204fbcacef34806290492384677a330d4d4Romain Guy    decrementRefcountLocked((void*) pathResource);
14858ecc204fbcacef34806290492384677a330d4d4Romain Guy}
14958ecc204fbcacef34806290492384677a330d4d4Romain Guy
150d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikvoid ResourceCache::decrementRefcountLocked(const Res_png_9patch* patchResource) {
151e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    decrementRefcountLocked((void*) patchResource);
152e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy}
153e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
1545a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haasevoid ResourceCache::destructor(SkPath* resource) {
1555a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    Mutex::Autolock _l(mLock);
15658ecc204fbcacef34806290492384677a330d4d4Romain Guy    destructorLocked(resource);
15758ecc204fbcacef34806290492384677a330d4d4Romain Guy}
15858ecc204fbcacef34806290492384677a330d4d4Romain Guy
15958ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::destructorLocked(SkPath* resource) {
1608dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ssize_t index = mCache->indexOfKey(resource);
1618dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
1625a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    if (ref == NULL) {
1635a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase        // If we're not tracking this resource, just delete it
1645a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase        if (Caches::hasInstance()) {
1655a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase            Caches::getInstance().pathCache.removeDeferred(resource);
16636fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee        } else {
16736fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee            delete resource;
1685a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase        }
1695a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase        return;
1705a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    }
1715a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    ref->destroyed = true;
1725a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    if (ref->refCount == 0) {
17397dc9172b0e58979c63de0dedbab656399a62281Romain Guy        deleteResourceReferenceLocked(resource, ref);
1745a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    }
1755a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase}
1765a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase
177d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikvoid ResourceCache::destructor(const SkBitmap* resource) {
178e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase    Mutex::Autolock _l(mLock);
17958ecc204fbcacef34806290492384677a330d4d4Romain Guy    destructorLocked(resource);
18058ecc204fbcacef34806290492384677a330d4d4Romain Guy}
18158ecc204fbcacef34806290492384677a330d4d4Romain Guy
182d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikvoid ResourceCache::destructorLocked(const SkBitmap* resource) {
1838dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ssize_t index = mCache->indexOfKey(resource);
1848dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
1855c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref == NULL) {
1865c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        // If we're not tracking this resource, just delete it
1875c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        if (Caches::hasInstance()) {
188fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy            Caches::getInstance().textureCache.removeDeferred(resource);
18936fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee        } else {
19036fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee            delete resource;
1915c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        }
1925c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        return;
1935c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
1945c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    ref->destroyed = true;
1955c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref->refCount == 0) {
19697dc9172b0e58979c63de0dedbab656399a62281Romain Guy        deleteResourceReferenceLocked(resource, ref);
1975c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
1985c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
1995c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
200e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guyvoid ResourceCache::destructor(Res_png_9patch* resource) {
201e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    Mutex::Autolock _l(mLock);
202e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    destructorLocked(resource);
203e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy}
204e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
205e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guyvoid ResourceCache::destructorLocked(Res_png_9patch* resource) {
206e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    ssize_t index = mCache->indexOfKey(resource);
207e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
208e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    if (ref == NULL) {
20936fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee        // If we're not tracking this resource, just delete it
210e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy        if (Caches::hasInstance()) {
211e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy            Caches::getInstance().patchCache.removeDeferred(resource);
21236fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee        } else {
21336fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee            // A Res_png_9patch is actually an array of byte that's larger
21436fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee            // than sizeof(Res_png_9patch). It must be freed as an array.
21536fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee            delete[] (int8_t*) resource;
216e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy        }
217e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy        return;
218e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    }
219e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    ref->destroyed = true;
220e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    if (ref->refCount == 0) {
221e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy        deleteResourceReferenceLocked(resource, ref);
222e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    }
223e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy}
224e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
225547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase/**
226547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase * Return value indicates whether resource was actually recycled, which happens when RefCnt
227547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase * reaches 0.
228547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase */
229547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haasebool ResourceCache::recycle(SkBitmap* resource) {
23058ecc204fbcacef34806290492384677a330d4d4Romain Guy    Mutex::Autolock _l(mLock);
231547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase    return recycleLocked(resource);
23258ecc204fbcacef34806290492384677a330d4d4Romain Guy}
23358ecc204fbcacef34806290492384677a330d4d4Romain Guy
234547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase/**
235547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase * Return value indicates whether resource was actually recycled, which happens when RefCnt
236547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase * reaches 0.
237547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase */
238547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haasebool ResourceCache::recycleLocked(SkBitmap* resource) {
23958ecc204fbcacef34806290492384677a330d4d4Romain Guy    ssize_t index = mCache->indexOfKey(resource);
24058ecc204fbcacef34806290492384677a330d4d4Romain Guy    if (index < 0) {
24158ecc204fbcacef34806290492384677a330d4d4Romain Guy        // not tracking this resource; just recycle the pixel data
24258ecc204fbcacef34806290492384677a330d4d4Romain Guy        resource->setPixels(NULL, NULL);
243547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase        return true;
24458ecc204fbcacef34806290492384677a330d4d4Romain Guy    }
24558ecc204fbcacef34806290492384677a330d4d4Romain Guy    ResourceReference* ref = mCache->valueAt(index);
24658ecc204fbcacef34806290492384677a330d4d4Romain Guy    if (ref == NULL) {
24758ecc204fbcacef34806290492384677a330d4d4Romain Guy        // Should not get here - shouldn't get a call to recycle if we're not yet tracking it
248547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase        return true;
24958ecc204fbcacef34806290492384677a330d4d4Romain Guy    }
25058ecc204fbcacef34806290492384677a330d4d4Romain Guy    ref->recycled = true;
25158ecc204fbcacef34806290492384677a330d4d4Romain Guy    if (ref->refCount == 0) {
25297dc9172b0e58979c63de0dedbab656399a62281Romain Guy        deleteResourceReferenceLocked(resource, ref);
253547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase        return true;
25458ecc204fbcacef34806290492384677a330d4d4Romain Guy    }
255547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase    // Still referring to resource, don't recycle yet
256547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase    return false;
25758ecc204fbcacef34806290492384677a330d4d4Romain Guy}
25858ecc204fbcacef34806290492384677a330d4d4Romain Guy
259e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase/**
260e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase * This method should only be called while the mLock mutex is held (that mutex is grabbed
261e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase * by the various destructor() and recycle() methods which call this method).
262e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase */
263d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikvoid ResourceCache::deleteResourceReferenceLocked(const void* resource, ResourceReference* ref) {
2645c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref->recycled && ref->resourceType == kBitmap) {
2655c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        ((SkBitmap*) resource)->setPixels(NULL, NULL);
2665c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
2670e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck    if (ref->destroyed) {
2685c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        switch (ref->resourceType) {
269d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy            case kBitmap: {
270d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy                SkBitmap* bitmap = (SkBitmap*) resource;
2715c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                if (Caches::hasInstance()) {
272fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy                    Caches::getInstance().textureCache.removeDeferred(bitmap);
27336fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee                } else {
27436fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee                    delete bitmap;
2755c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                }
2765c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            }
2775c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            break;
278d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy            case kPath: {
279d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy                SkPath* path = (SkPath*) resource;
2805a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase                if (Caches::hasInstance()) {
2815a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase                    Caches::getInstance().pathCache.removeDeferred(path);
28236fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee                } else {
28336fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee                    delete path;
2845a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase                }
2855a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase            }
2865a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase            break;
287e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy            case kNinePatch: {
288e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy                if (Caches::hasInstance()) {
289e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy                    Caches::getInstance().patchCache.removeDeferred((Res_png_9patch*) resource);
29036fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee                } else {
29136fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee                    // A Res_png_9patch is actually an array of byte that's larger
29236fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee                    // than sizeof(Res_png_9patch). It must be freed as an array.
29336fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee                    int8_t* patch = (int8_t*) resource;
29436fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee                    delete[] patch;
295e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy                }
296e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy            }
297e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy            break;
2985c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        }
2995c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
3005c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    mCache->removeItem(resource);
3015c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    delete ref;
3025c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
3035c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
3045c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}; // namespace uirenderer
3055c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}; // namespace android
306