ResourceCache.cpp revision 36fad8f6fcfbc2087b910600ed5a6f9741177d00
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 {
245c13d89c1332fcc499379b9064b891187b75ca32Chet Haasenamespace uirenderer {
255c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
265c13d89c1332fcc499379b9064b891187b75ca32Chet Haase///////////////////////////////////////////////////////////////////////////////
275c13d89c1332fcc499379b9064b891187b75ca32Chet Haase// Resource cache
285c13d89c1332fcc499379b9064b891187b75ca32Chet Haase///////////////////////////////////////////////////////////////////////////////
295c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
305c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::logCache() {
315baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("ResourceCache: cacheReport:");
325c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    for (size_t i = 0; i < mCache->size(); ++i) {
335c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        ResourceReference* ref = mCache->valueAt(i);
345baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("  ResourceCache: mCache(%d): resource, ref = 0x%p, 0x%p",
355c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                i, mCache->keyAt(i), mCache->valueAt(i));
365baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("  ResourceCache: mCache(%d): refCount, recycled, destroyed, type = %d, %d, %d, %d",
375c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                i, ref->refCount, ref->recycled, ref->destroyed, ref->resourceType);
385c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
395c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
405c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
415c13d89c1332fcc499379b9064b891187b75ca32Chet HaaseResourceCache::ResourceCache() {
42e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase    Mutex::Autolock _l(mLock);
4358ecc204fbcacef34806290492384677a330d4d4Romain Guy    mCache = new KeyedVector<void*, ResourceReference*>();
445c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
455c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
465c13d89c1332fcc499379b9064b891187b75ca32Chet HaaseResourceCache::~ResourceCache() {
47e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase    Mutex::Autolock _l(mLock);
485c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    delete mCache;
495c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
505c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
5158ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::lock() {
5258ecc204fbcacef34806290492384677a330d4d4Romain Guy    mLock.lock();
5358ecc204fbcacef34806290492384677a330d4d4Romain Guy}
5458ecc204fbcacef34806290492384677a330d4d4Romain Guy
5558ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::unlock() {
5658ecc204fbcacef34806290492384677a330d4d4Romain Guy    mLock.unlock();
5758ecc204fbcacef34806290492384677a330d4d4Romain Guy}
5858ecc204fbcacef34806290492384677a330d4d4Romain Guy
595c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) {
60e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase    Mutex::Autolock _l(mLock);
6158ecc204fbcacef34806290492384677a330d4d4Romain Guy    incrementRefcountLocked(resource, resourceType);
625c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
635c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
645c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::incrementRefcount(SkBitmap* bitmapResource) {
650c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik    bitmapResource->pixelRef()->globalRef();
666062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger    SkSafeRef(bitmapResource->getColorTable());
6749c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy    incrementRefcount((void*) bitmapResource, kBitmap);
685c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
695c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
705a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haasevoid ResourceCache::incrementRefcount(SkPath* pathResource) {
7149c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy    incrementRefcount((void*) pathResource, kPath);
725a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase}
735a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase
745c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::incrementRefcount(SkiaShader* shaderResource) {
756062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger    SkSafeRef(shaderResource->getSkShader());
7643ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guy    incrementRefcount((void*) shaderResource, kShader);
775c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
785c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
79ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haasevoid ResourceCache::incrementRefcount(SkiaColorFilter* filterResource) {
806062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger    SkSafeRef(filterResource->getSkColorFilter());
8143ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guy    incrementRefcount((void*) filterResource, kColorFilter);
82ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase}
83ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase
84e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guyvoid ResourceCache::incrementRefcount(Res_png_9patch* patchResource) {
85e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    incrementRefcount((void*) patchResource, kNinePatch);
86e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy}
87e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
88603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haasevoid ResourceCache::incrementRefcount(Layer* layerResource) {
89603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase    incrementRefcount((void*) layerResource, kLayer);
90603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase}
91603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase
9258ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::incrementRefcountLocked(void* resource, ResourceType resourceType) {
938dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ssize_t index = mCache->indexOfKey(resource);
948dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
9558ecc204fbcacef34806290492384677a330d4d4Romain Guy    if (ref == NULL || mCache->size() == 0) {
9658ecc204fbcacef34806290492384677a330d4d4Romain Guy        ref = new ResourceReference(resourceType);
9758ecc204fbcacef34806290492384677a330d4d4Romain Guy        mCache->add(resource, ref);
985c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
9958ecc204fbcacef34806290492384677a330d4d4Romain Guy    ref->refCount++;
10058ecc204fbcacef34806290492384677a330d4d4Romain Guy}
10158ecc204fbcacef34806290492384677a330d4d4Romain Guy
10258ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::incrementRefcountLocked(SkBitmap* bitmapResource) {
1030c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik    bitmapResource->pixelRef()->globalRef();
10458ecc204fbcacef34806290492384677a330d4d4Romain Guy    SkSafeRef(bitmapResource->getColorTable());
10558ecc204fbcacef34806290492384677a330d4d4Romain Guy    incrementRefcountLocked((void*) bitmapResource, kBitmap);
10658ecc204fbcacef34806290492384677a330d4d4Romain Guy}
10758ecc204fbcacef34806290492384677a330d4d4Romain Guy
10858ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::incrementRefcountLocked(SkPath* pathResource) {
10958ecc204fbcacef34806290492384677a330d4d4Romain Guy    incrementRefcountLocked((void*) pathResource, kPath);
11058ecc204fbcacef34806290492384677a330d4d4Romain Guy}
11158ecc204fbcacef34806290492384677a330d4d4Romain Guy
11258ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::incrementRefcountLocked(SkiaShader* shaderResource) {
11358ecc204fbcacef34806290492384677a330d4d4Romain Guy    SkSafeRef(shaderResource->getSkShader());
11458ecc204fbcacef34806290492384677a330d4d4Romain Guy    incrementRefcountLocked((void*) shaderResource, kShader);
11558ecc204fbcacef34806290492384677a330d4d4Romain Guy}
11658ecc204fbcacef34806290492384677a330d4d4Romain Guy
11758ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::incrementRefcountLocked(SkiaColorFilter* filterResource) {
11858ecc204fbcacef34806290492384677a330d4d4Romain Guy    SkSafeRef(filterResource->getSkColorFilter());
11958ecc204fbcacef34806290492384677a330d4d4Romain Guy    incrementRefcountLocked((void*) filterResource, kColorFilter);
12058ecc204fbcacef34806290492384677a330d4d4Romain Guy}
12158ecc204fbcacef34806290492384677a330d4d4Romain Guy
122e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guyvoid ResourceCache::incrementRefcountLocked(Res_png_9patch* patchResource) {
123e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    incrementRefcountLocked((void*) patchResource, kNinePatch);
124e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy}
125e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
126603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haasevoid ResourceCache::incrementRefcountLocked(Layer* layerResource) {
127603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase    incrementRefcountLocked((void*) layerResource, kLayer);
128603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase}
129603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase
13058ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::decrementRefcount(void* resource) {
13158ecc204fbcacef34806290492384677a330d4d4Romain Guy    Mutex::Autolock _l(mLock);
13258ecc204fbcacef34806290492384677a330d4d4Romain Guy    decrementRefcountLocked(resource);
1335c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
1345c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
1355c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
1360c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik    bitmapResource->pixelRef()->globalUnref();
1376062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger    SkSafeUnref(bitmapResource->getColorTable());
13843ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guy    decrementRefcount((void*) bitmapResource);
1395c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
1405c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
1415a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haasevoid ResourceCache::decrementRefcount(SkPath* pathResource) {
1425a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    decrementRefcount((void*) pathResource);
1435a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase}
1445a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase
1455c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::decrementRefcount(SkiaShader* shaderResource) {
1466062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger    SkSafeUnref(shaderResource->getSkShader());
14743ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guy    decrementRefcount((void*) shaderResource);
1485c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
1495c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
150ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haasevoid ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) {
1516062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger    SkSafeUnref(filterResource->getSkColorFilter());
15243ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guy    decrementRefcount((void*) filterResource);
153ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase}
154ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase
155e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guyvoid ResourceCache::decrementRefcount(Res_png_9patch* patchResource) {
156e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    decrementRefcount((void*) patchResource);
157e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy}
158e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
159603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haasevoid ResourceCache::decrementRefcount(Layer* layerResource) {
160603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase    decrementRefcount((void*) layerResource);
161603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase}
162603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase
16358ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::decrementRefcountLocked(void* resource) {
1648dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ssize_t index = mCache->indexOfKey(resource);
16558ecc204fbcacef34806290492384677a330d4d4Romain Guy    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
1665c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref == NULL) {
16758ecc204fbcacef34806290492384677a330d4d4Romain Guy        // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
1685c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        return;
1695c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
17058ecc204fbcacef34806290492384677a330d4d4Romain Guy    ref->refCount--;
1715c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref->refCount == 0) {
17297dc9172b0e58979c63de0dedbab656399a62281Romain Guy        deleteResourceReferenceLocked(resource, ref);
1735c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
1745c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
1755c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
17658ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::decrementRefcountLocked(SkBitmap* bitmapResource) {
1770c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik    bitmapResource->pixelRef()->globalUnref();
17858ecc204fbcacef34806290492384677a330d4d4Romain Guy    SkSafeUnref(bitmapResource->getColorTable());
17958ecc204fbcacef34806290492384677a330d4d4Romain Guy    decrementRefcountLocked((void*) bitmapResource);
18058ecc204fbcacef34806290492384677a330d4d4Romain Guy}
18158ecc204fbcacef34806290492384677a330d4d4Romain Guy
18258ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::decrementRefcountLocked(SkPath* pathResource) {
18358ecc204fbcacef34806290492384677a330d4d4Romain Guy    decrementRefcountLocked((void*) pathResource);
18458ecc204fbcacef34806290492384677a330d4d4Romain Guy}
18558ecc204fbcacef34806290492384677a330d4d4Romain Guy
18658ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::decrementRefcountLocked(SkiaShader* shaderResource) {
18758ecc204fbcacef34806290492384677a330d4d4Romain Guy    SkSafeUnref(shaderResource->getSkShader());
18858ecc204fbcacef34806290492384677a330d4d4Romain Guy    decrementRefcountLocked((void*) shaderResource);
18958ecc204fbcacef34806290492384677a330d4d4Romain Guy}
19058ecc204fbcacef34806290492384677a330d4d4Romain Guy
19158ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::decrementRefcountLocked(SkiaColorFilter* filterResource) {
19258ecc204fbcacef34806290492384677a330d4d4Romain Guy    SkSafeUnref(filterResource->getSkColorFilter());
19358ecc204fbcacef34806290492384677a330d4d4Romain Guy    decrementRefcountLocked((void*) filterResource);
19458ecc204fbcacef34806290492384677a330d4d4Romain Guy}
19558ecc204fbcacef34806290492384677a330d4d4Romain Guy
196e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guyvoid ResourceCache::decrementRefcountLocked(Res_png_9patch* patchResource) {
197e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    decrementRefcountLocked((void*) patchResource);
198e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy}
199e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
200603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haasevoid ResourceCache::decrementRefcountLocked(Layer* layerResource) {
201603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase    decrementRefcountLocked((void*) layerResource);
202603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase}
203603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase
2045a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haasevoid ResourceCache::destructor(SkPath* resource) {
2055a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    Mutex::Autolock _l(mLock);
20658ecc204fbcacef34806290492384677a330d4d4Romain Guy    destructorLocked(resource);
20758ecc204fbcacef34806290492384677a330d4d4Romain Guy}
20858ecc204fbcacef34806290492384677a330d4d4Romain Guy
20958ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::destructorLocked(SkPath* resource) {
2108dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ssize_t index = mCache->indexOfKey(resource);
2118dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
2125a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    if (ref == NULL) {
2135a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase        // If we're not tracking this resource, just delete it
2145a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase        if (Caches::hasInstance()) {
2155a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase            Caches::getInstance().pathCache.removeDeferred(resource);
21636fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee        } else {
21736fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee            delete resource;
2185a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase        }
2195a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase        return;
2205a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    }
2215a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    ref->destroyed = true;
2225a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    if (ref->refCount == 0) {
22397dc9172b0e58979c63de0dedbab656399a62281Romain Guy        deleteResourceReferenceLocked(resource, ref);
2245a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    }
2255a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase}
2265a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase
2275c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::destructor(SkBitmap* resource) {
228e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase    Mutex::Autolock _l(mLock);
22958ecc204fbcacef34806290492384677a330d4d4Romain Guy    destructorLocked(resource);
23058ecc204fbcacef34806290492384677a330d4d4Romain Guy}
23158ecc204fbcacef34806290492384677a330d4d4Romain Guy
23258ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::destructorLocked(SkBitmap* resource) {
2338dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ssize_t index = mCache->indexOfKey(resource);
2348dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
2355c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref == NULL) {
2365c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        // If we're not tracking this resource, just delete it
2375c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        if (Caches::hasInstance()) {
238fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy            Caches::getInstance().textureCache.removeDeferred(resource);
23936fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee        } else {
24036fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee            delete resource;
2415c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        }
2425c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        return;
2435c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
2445c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    ref->destroyed = true;
2455c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref->refCount == 0) {
24697dc9172b0e58979c63de0dedbab656399a62281Romain Guy        deleteResourceReferenceLocked(resource, ref);
2475c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
2485c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
2495c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
2505c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::destructor(SkiaShader* resource) {
251e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase    Mutex::Autolock _l(mLock);
25258ecc204fbcacef34806290492384677a330d4d4Romain Guy    destructorLocked(resource);
25358ecc204fbcacef34806290492384677a330d4d4Romain Guy}
25458ecc204fbcacef34806290492384677a330d4d4Romain Guy
25558ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::destructorLocked(SkiaShader* resource) {
2568dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ssize_t index = mCache->indexOfKey(resource);
2578dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
2585c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref == NULL) {
2595c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        // If we're not tracking this resource, just delete it
2605c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        delete resource;
2615c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        return;
2625c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
2635c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    ref->destroyed = true;
2645c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref->refCount == 0) {
26597dc9172b0e58979c63de0dedbab656399a62281Romain Guy        deleteResourceReferenceLocked(resource, ref);
2665c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
2675c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
2685c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
269ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haasevoid ResourceCache::destructor(SkiaColorFilter* resource) {
270e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase    Mutex::Autolock _l(mLock);
27158ecc204fbcacef34806290492384677a330d4d4Romain Guy    destructorLocked(resource);
27258ecc204fbcacef34806290492384677a330d4d4Romain Guy}
27358ecc204fbcacef34806290492384677a330d4d4Romain Guy
27458ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::destructorLocked(SkiaColorFilter* resource) {
2758dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ssize_t index = mCache->indexOfKey(resource);
2768dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
277ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase    if (ref == NULL) {
278ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase        // If we're not tracking this resource, just delete it
279ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase        delete resource;
280ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase        return;
281ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase    }
282ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase    ref->destroyed = true;
283ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase    if (ref->refCount == 0) {
28497dc9172b0e58979c63de0dedbab656399a62281Romain Guy        deleteResourceReferenceLocked(resource, ref);
285ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase    }
286ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase}
287ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase
288e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guyvoid ResourceCache::destructor(Res_png_9patch* resource) {
289e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    Mutex::Autolock _l(mLock);
290e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    destructorLocked(resource);
291e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy}
292e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
293e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guyvoid ResourceCache::destructorLocked(Res_png_9patch* resource) {
294e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    ssize_t index = mCache->indexOfKey(resource);
295e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
296e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    if (ref == NULL) {
29736fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee        // If we're not tracking this resource, just delete it
298e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy        if (Caches::hasInstance()) {
299e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy            Caches::getInstance().patchCache.removeDeferred(resource);
30036fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee        } else {
30136fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee            // A Res_png_9patch is actually an array of byte that's larger
30236fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee            // than sizeof(Res_png_9patch). It must be freed as an array.
30336fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee            delete[] (int8_t*) resource;
304e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy        }
305e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy        return;
306e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    }
307e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    ref->destroyed = true;
308e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    if (ref->refCount == 0) {
309e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy        deleteResourceReferenceLocked(resource, ref);
310e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    }
311e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy}
312e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
313547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase/**
314547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase * Return value indicates whether resource was actually recycled, which happens when RefCnt
315547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase * reaches 0.
316547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase */
317547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haasebool ResourceCache::recycle(SkBitmap* resource) {
31858ecc204fbcacef34806290492384677a330d4d4Romain Guy    Mutex::Autolock _l(mLock);
319547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase    return recycleLocked(resource);
32058ecc204fbcacef34806290492384677a330d4d4Romain Guy}
32158ecc204fbcacef34806290492384677a330d4d4Romain Guy
322547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase/**
323547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase * Return value indicates whether resource was actually recycled, which happens when RefCnt
324547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase * reaches 0.
325547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase */
326547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haasebool ResourceCache::recycleLocked(SkBitmap* resource) {
32758ecc204fbcacef34806290492384677a330d4d4Romain Guy    ssize_t index = mCache->indexOfKey(resource);
32858ecc204fbcacef34806290492384677a330d4d4Romain Guy    if (index < 0) {
32958ecc204fbcacef34806290492384677a330d4d4Romain Guy        // not tracking this resource; just recycle the pixel data
33058ecc204fbcacef34806290492384677a330d4d4Romain Guy        resource->setPixels(NULL, NULL);
331547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase        return true;
33258ecc204fbcacef34806290492384677a330d4d4Romain Guy    }
33358ecc204fbcacef34806290492384677a330d4d4Romain Guy    ResourceReference* ref = mCache->valueAt(index);
33458ecc204fbcacef34806290492384677a330d4d4Romain Guy    if (ref == NULL) {
33558ecc204fbcacef34806290492384677a330d4d4Romain Guy        // Should not get here - shouldn't get a call to recycle if we're not yet tracking it
336547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase        return true;
33758ecc204fbcacef34806290492384677a330d4d4Romain Guy    }
33858ecc204fbcacef34806290492384677a330d4d4Romain Guy    ref->recycled = true;
33958ecc204fbcacef34806290492384677a330d4d4Romain Guy    if (ref->refCount == 0) {
34097dc9172b0e58979c63de0dedbab656399a62281Romain Guy        deleteResourceReferenceLocked(resource, ref);
341547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase        return true;
34258ecc204fbcacef34806290492384677a330d4d4Romain Guy    }
343547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase    // Still referring to resource, don't recycle yet
344547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase    return false;
34558ecc204fbcacef34806290492384677a330d4d4Romain Guy}
34658ecc204fbcacef34806290492384677a330d4d4Romain Guy
347e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase/**
348e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase * This method should only be called while the mLock mutex is held (that mutex is grabbed
349e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase * by the various destructor() and recycle() methods which call this method).
350e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase */
35197dc9172b0e58979c63de0dedbab656399a62281Romain Guyvoid ResourceCache::deleteResourceReferenceLocked(void* resource, ResourceReference* ref) {
3525c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref->recycled && ref->resourceType == kBitmap) {
3535c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        ((SkBitmap*) resource)->setPixels(NULL, NULL);
3545c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
355603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase    if (ref->destroyed || ref->resourceType == kLayer) {
3565c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        switch (ref->resourceType) {
357d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy            case kBitmap: {
358d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy                SkBitmap* bitmap = (SkBitmap*) resource;
3595c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                if (Caches::hasInstance()) {
360fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy                    Caches::getInstance().textureCache.removeDeferred(bitmap);
36136fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee                } else {
36236fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee                    delete bitmap;
3635c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                }
3645c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            }
3655c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            break;
366d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy            case kPath: {
367d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy                SkPath* path = (SkPath*) resource;
3685a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase                if (Caches::hasInstance()) {
3695a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase                    Caches::getInstance().pathCache.removeDeferred(path);
37036fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee                } else {
37136fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee                    delete path;
3725a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase                }
3735a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase            }
3745a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase            break;
375d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy            case kShader: {
376d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy                SkiaShader* shader = (SkiaShader*) resource;
3775c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                delete shader;
378ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase            }
379ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase            break;
380d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy            case kColorFilter: {
381d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy                SkiaColorFilter* filter = (SkiaColorFilter*) resource;
382ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase                delete filter;
383ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase            }
384ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase            break;
385e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy            case kNinePatch: {
386e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy                if (Caches::hasInstance()) {
387e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy                    Caches::getInstance().patchCache.removeDeferred((Res_png_9patch*) resource);
38836fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee                } else {
38936fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee                    // A Res_png_9patch is actually an array of byte that's larger
39036fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee                    // than sizeof(Res_png_9patch). It must be freed as an array.
39136fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee                    int8_t* patch = (int8_t*) resource;
39236fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee                    delete[] patch;
393e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy                }
394e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy            }
395e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy            break;
396603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase            case kLayer: {
39756257aff8a55c847be72be9924c392033fd8151dDave Burke                Layer* layer = (Layer*) resource;
39854643d72f86d0ee0b23e3643ac9257d52ddfae6bMathias Agopian                Caches::getInstance().deleteLayerDeferred(layer);
399603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase            }
400603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase            break;
4015c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        }
4025c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
4035c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    mCache->removeItem(resource);
4045c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    delete ref;
4055c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
4065c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
4075c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}; // namespace uirenderer
4085c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}; // namespace android
409