ResourceCache.cpp revision 547e66531d521eb1eadac87edb0f79f8c2f1bbe0
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
175c13d89c1332fcc499379b9064b891187b75ca32Chet Haase#include <SkPixelRef.h>
185c13d89c1332fcc499379b9064b891187b75ca32Chet Haase#include "ResourceCache.h"
195c13d89c1332fcc499379b9064b891187b75ca32Chet Haase#include "Caches.h"
205c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
215c13d89c1332fcc499379b9064b891187b75ca32Chet Haasenamespace android {
225c13d89c1332fcc499379b9064b891187b75ca32Chet Haasenamespace uirenderer {
235c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
245c13d89c1332fcc499379b9064b891187b75ca32Chet Haase///////////////////////////////////////////////////////////////////////////////
255c13d89c1332fcc499379b9064b891187b75ca32Chet Haase// Resource cache
265c13d89c1332fcc499379b9064b891187b75ca32Chet Haase///////////////////////////////////////////////////////////////////////////////
275c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
285c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::logCache() {
295baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("ResourceCache: cacheReport:");
305c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    for (size_t i = 0; i < mCache->size(); ++i) {
315c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        ResourceReference* ref = mCache->valueAt(i);
325baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("  ResourceCache: mCache(%d): resource, ref = 0x%p, 0x%p",
335c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                i, mCache->keyAt(i), mCache->valueAt(i));
345baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("  ResourceCache: mCache(%d): refCount, recycled, destroyed, type = %d, %d, %d, %d",
355c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                i, ref->refCount, ref->recycled, ref->destroyed, ref->resourceType);
365c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
375c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
385c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
395c13d89c1332fcc499379b9064b891187b75ca32Chet HaaseResourceCache::ResourceCache() {
40e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase    Mutex::Autolock _l(mLock);
4158ecc204fbcacef34806290492384677a330d4d4Romain Guy    mCache = new KeyedVector<void*, ResourceReference*>();
425c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
435c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
445c13d89c1332fcc499379b9064b891187b75ca32Chet HaaseResourceCache::~ResourceCache() {
45e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase    Mutex::Autolock _l(mLock);
465c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    delete mCache;
475c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
485c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
4958ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::lock() {
5058ecc204fbcacef34806290492384677a330d4d4Romain Guy    mLock.lock();
5158ecc204fbcacef34806290492384677a330d4d4Romain Guy}
5258ecc204fbcacef34806290492384677a330d4d4Romain Guy
5358ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::unlock() {
5458ecc204fbcacef34806290492384677a330d4d4Romain Guy    mLock.unlock();
5558ecc204fbcacef34806290492384677a330d4d4Romain Guy}
5658ecc204fbcacef34806290492384677a330d4d4Romain Guy
575c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) {
58e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase    Mutex::Autolock _l(mLock);
5958ecc204fbcacef34806290492384677a330d4d4Romain Guy    incrementRefcountLocked(resource, resourceType);
605c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
615c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
625c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::incrementRefcount(SkBitmap* bitmapResource) {
636062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger    SkSafeRef(bitmapResource->pixelRef());
646062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger    SkSafeRef(bitmapResource->getColorTable());
6549c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy    incrementRefcount((void*) bitmapResource, kBitmap);
665c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
675c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
685a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haasevoid ResourceCache::incrementRefcount(SkPath* pathResource) {
6949c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy    incrementRefcount((void*) pathResource, kPath);
705a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase}
715a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase
725c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::incrementRefcount(SkiaShader* shaderResource) {
736062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger    SkSafeRef(shaderResource->getSkShader());
7443ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guy    incrementRefcount((void*) shaderResource, kShader);
755c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
765c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
77ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haasevoid ResourceCache::incrementRefcount(SkiaColorFilter* filterResource) {
786062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger    SkSafeRef(filterResource->getSkColorFilter());
7943ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guy    incrementRefcount((void*) filterResource, kColorFilter);
80ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase}
81ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase
82603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haasevoid ResourceCache::incrementRefcount(Layer* layerResource) {
83603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase    incrementRefcount((void*) layerResource, kLayer);
84603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase}
85603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase
8658ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::incrementRefcountLocked(void* resource, ResourceType resourceType) {
878dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ssize_t index = mCache->indexOfKey(resource);
888dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
8958ecc204fbcacef34806290492384677a330d4d4Romain Guy    if (ref == NULL || mCache->size() == 0) {
9058ecc204fbcacef34806290492384677a330d4d4Romain Guy        ref = new ResourceReference(resourceType);
9158ecc204fbcacef34806290492384677a330d4d4Romain Guy        mCache->add(resource, ref);
925c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
9358ecc204fbcacef34806290492384677a330d4d4Romain Guy    ref->refCount++;
9458ecc204fbcacef34806290492384677a330d4d4Romain Guy}
9558ecc204fbcacef34806290492384677a330d4d4Romain Guy
9658ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::incrementRefcountLocked(SkBitmap* bitmapResource) {
9758ecc204fbcacef34806290492384677a330d4d4Romain Guy    SkSafeRef(bitmapResource->pixelRef());
9858ecc204fbcacef34806290492384677a330d4d4Romain Guy    SkSafeRef(bitmapResource->getColorTable());
9958ecc204fbcacef34806290492384677a330d4d4Romain Guy    incrementRefcountLocked((void*) bitmapResource, kBitmap);
10058ecc204fbcacef34806290492384677a330d4d4Romain Guy}
10158ecc204fbcacef34806290492384677a330d4d4Romain Guy
10258ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::incrementRefcountLocked(SkPath* pathResource) {
10358ecc204fbcacef34806290492384677a330d4d4Romain Guy    incrementRefcountLocked((void*) pathResource, kPath);
10458ecc204fbcacef34806290492384677a330d4d4Romain Guy}
10558ecc204fbcacef34806290492384677a330d4d4Romain Guy
10658ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::incrementRefcountLocked(SkiaShader* shaderResource) {
10758ecc204fbcacef34806290492384677a330d4d4Romain Guy    SkSafeRef(shaderResource->getSkShader());
10858ecc204fbcacef34806290492384677a330d4d4Romain Guy    incrementRefcountLocked((void*) shaderResource, kShader);
10958ecc204fbcacef34806290492384677a330d4d4Romain Guy}
11058ecc204fbcacef34806290492384677a330d4d4Romain Guy
11158ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::incrementRefcountLocked(SkiaColorFilter* filterResource) {
11258ecc204fbcacef34806290492384677a330d4d4Romain Guy    SkSafeRef(filterResource->getSkColorFilter());
11358ecc204fbcacef34806290492384677a330d4d4Romain Guy    incrementRefcountLocked((void*) filterResource, kColorFilter);
11458ecc204fbcacef34806290492384677a330d4d4Romain Guy}
11558ecc204fbcacef34806290492384677a330d4d4Romain Guy
116603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haasevoid ResourceCache::incrementRefcountLocked(Layer* layerResource) {
117603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase    incrementRefcountLocked((void*) layerResource, kLayer);
118603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase}
119603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase
12058ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::decrementRefcount(void* resource) {
12158ecc204fbcacef34806290492384677a330d4d4Romain Guy    Mutex::Autolock _l(mLock);
12258ecc204fbcacef34806290492384677a330d4d4Romain Guy    decrementRefcountLocked(resource);
1235c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
1245c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
1255c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
1266062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger    SkSafeUnref(bitmapResource->pixelRef());
1276062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger    SkSafeUnref(bitmapResource->getColorTable());
12843ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guy    decrementRefcount((void*) bitmapResource);
1295c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
1305c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
1315a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haasevoid ResourceCache::decrementRefcount(SkPath* pathResource) {
1325a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    decrementRefcount((void*) pathResource);
1335a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase}
1345a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase
1355c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::decrementRefcount(SkiaShader* shaderResource) {
1366062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger    SkSafeUnref(shaderResource->getSkShader());
13743ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guy    decrementRefcount((void*) shaderResource);
1385c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
1395c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
140ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haasevoid ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) {
1416062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger    SkSafeUnref(filterResource->getSkColorFilter());
14243ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guy    decrementRefcount((void*) filterResource);
143ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase}
144ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase
145603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haasevoid ResourceCache::decrementRefcount(Layer* layerResource) {
146603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase    decrementRefcount((void*) layerResource);
147603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase}
148603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase
14958ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::decrementRefcountLocked(void* resource) {
1508dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ssize_t index = mCache->indexOfKey(resource);
15158ecc204fbcacef34806290492384677a330d4d4Romain Guy    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
1525c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref == NULL) {
15358ecc204fbcacef34806290492384677a330d4d4Romain Guy        // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
1545c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        return;
1555c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
15658ecc204fbcacef34806290492384677a330d4d4Romain Guy    ref->refCount--;
1575c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref->refCount == 0) {
15897dc9172b0e58979c63de0dedbab656399a62281Romain Guy        deleteResourceReferenceLocked(resource, ref);
1595c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
1605c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
1615c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
16258ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::decrementRefcountLocked(SkBitmap* bitmapResource) {
16358ecc204fbcacef34806290492384677a330d4d4Romain Guy    SkSafeUnref(bitmapResource->pixelRef());
16458ecc204fbcacef34806290492384677a330d4d4Romain Guy    SkSafeUnref(bitmapResource->getColorTable());
16558ecc204fbcacef34806290492384677a330d4d4Romain Guy    decrementRefcountLocked((void*) bitmapResource);
16658ecc204fbcacef34806290492384677a330d4d4Romain Guy}
16758ecc204fbcacef34806290492384677a330d4d4Romain Guy
16858ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::decrementRefcountLocked(SkPath* pathResource) {
16958ecc204fbcacef34806290492384677a330d4d4Romain Guy    decrementRefcountLocked((void*) pathResource);
17058ecc204fbcacef34806290492384677a330d4d4Romain Guy}
17158ecc204fbcacef34806290492384677a330d4d4Romain Guy
17258ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::decrementRefcountLocked(SkiaShader* shaderResource) {
17358ecc204fbcacef34806290492384677a330d4d4Romain Guy    SkSafeUnref(shaderResource->getSkShader());
17458ecc204fbcacef34806290492384677a330d4d4Romain Guy    decrementRefcountLocked((void*) shaderResource);
17558ecc204fbcacef34806290492384677a330d4d4Romain Guy}
17658ecc204fbcacef34806290492384677a330d4d4Romain Guy
17758ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::decrementRefcountLocked(SkiaColorFilter* filterResource) {
17858ecc204fbcacef34806290492384677a330d4d4Romain Guy    SkSafeUnref(filterResource->getSkColorFilter());
17958ecc204fbcacef34806290492384677a330d4d4Romain Guy    decrementRefcountLocked((void*) filterResource);
18058ecc204fbcacef34806290492384677a330d4d4Romain Guy}
18158ecc204fbcacef34806290492384677a330d4d4Romain Guy
182603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haasevoid ResourceCache::decrementRefcountLocked(Layer* layerResource) {
183603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase    decrementRefcountLocked((void*) layerResource);
184603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase}
185603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase
1865a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haasevoid ResourceCache::destructor(SkPath* resource) {
1875a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    Mutex::Autolock _l(mLock);
18858ecc204fbcacef34806290492384677a330d4d4Romain Guy    destructorLocked(resource);
18958ecc204fbcacef34806290492384677a330d4d4Romain Guy}
19058ecc204fbcacef34806290492384677a330d4d4Romain Guy
19158ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::destructorLocked(SkPath* resource) {
1928dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ssize_t index = mCache->indexOfKey(resource);
1938dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
1945a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    if (ref == NULL) {
1955a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase        // If we're not tracking this resource, just delete it
1965a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase        if (Caches::hasInstance()) {
1975a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase            Caches::getInstance().pathCache.removeDeferred(resource);
1985a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase        }
1995a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase        delete resource;
2005a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase        return;
2015a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    }
2025a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    ref->destroyed = true;
2035a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    if (ref->refCount == 0) {
20497dc9172b0e58979c63de0dedbab656399a62281Romain Guy        deleteResourceReferenceLocked(resource, ref);
2055a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase    }
2065a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase}
2075a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase
2085c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::destructor(SkBitmap* resource) {
209e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase    Mutex::Autolock _l(mLock);
21058ecc204fbcacef34806290492384677a330d4d4Romain Guy    destructorLocked(resource);
21158ecc204fbcacef34806290492384677a330d4d4Romain Guy}
21258ecc204fbcacef34806290492384677a330d4d4Romain Guy
21358ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::destructorLocked(SkBitmap* resource) {
2148dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ssize_t index = mCache->indexOfKey(resource);
2158dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
2165c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref == NULL) {
2175c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        // If we're not tracking this resource, just delete it
2185c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        if (Caches::hasInstance()) {
219fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy            Caches::getInstance().textureCache.removeDeferred(resource);
2205c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        }
2215c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        delete resource;
2225c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        return;
2235c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
2245c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    ref->destroyed = true;
2255c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref->refCount == 0) {
22697dc9172b0e58979c63de0dedbab656399a62281Romain Guy        deleteResourceReferenceLocked(resource, ref);
2275c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
2285c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
2295c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
2305c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::destructor(SkiaShader* resource) {
231e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase    Mutex::Autolock _l(mLock);
23258ecc204fbcacef34806290492384677a330d4d4Romain Guy    destructorLocked(resource);
23358ecc204fbcacef34806290492384677a330d4d4Romain Guy}
23458ecc204fbcacef34806290492384677a330d4d4Romain Guy
23558ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::destructorLocked(SkiaShader* resource) {
2368dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ssize_t index = mCache->indexOfKey(resource);
2378dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
2385c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref == NULL) {
2395c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        // If we're not tracking this resource, just delete it
2405c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        delete resource;
2415c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        return;
2425c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
2435c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    ref->destroyed = true;
2445c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref->refCount == 0) {
24597dc9172b0e58979c63de0dedbab656399a62281Romain Guy        deleteResourceReferenceLocked(resource, ref);
2465c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
2475c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
2485c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
249ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haasevoid ResourceCache::destructor(SkiaColorFilter* resource) {
250e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase    Mutex::Autolock _l(mLock);
25158ecc204fbcacef34806290492384677a330d4d4Romain Guy    destructorLocked(resource);
25258ecc204fbcacef34806290492384677a330d4d4Romain Guy}
25358ecc204fbcacef34806290492384677a330d4d4Romain Guy
25458ecc204fbcacef34806290492384677a330d4d4Romain Guyvoid ResourceCache::destructorLocked(SkiaColorFilter* resource) {
2558dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ssize_t index = mCache->indexOfKey(resource);
2568dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
257ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase    if (ref == NULL) {
258ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase        // If we're not tracking this resource, just delete it
259ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase        delete resource;
260ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase        return;
261ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase    }
262ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase    ref->destroyed = true;
263ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase    if (ref->refCount == 0) {
26497dc9172b0e58979c63de0dedbab656399a62281Romain Guy        deleteResourceReferenceLocked(resource, ref);
265ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase    }
266ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase}
267ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase
268547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase/**
269547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase * Return value indicates whether resource was actually recycled, which happens when RefCnt
270547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase * reaches 0.
271547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase */
272547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haasebool ResourceCache::recycle(SkBitmap* resource) {
27358ecc204fbcacef34806290492384677a330d4d4Romain Guy    Mutex::Autolock _l(mLock);
274547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase    return recycleLocked(resource);
27558ecc204fbcacef34806290492384677a330d4d4Romain Guy}
27658ecc204fbcacef34806290492384677a330d4d4Romain Guy
277547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase/**
278547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase * Return value indicates whether resource was actually recycled, which happens when RefCnt
279547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase * reaches 0.
280547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase */
281547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haasebool ResourceCache::recycleLocked(SkBitmap* resource) {
28258ecc204fbcacef34806290492384677a330d4d4Romain Guy    ssize_t index = mCache->indexOfKey(resource);
28358ecc204fbcacef34806290492384677a330d4d4Romain Guy    if (index < 0) {
28458ecc204fbcacef34806290492384677a330d4d4Romain Guy        // not tracking this resource; just recycle the pixel data
28558ecc204fbcacef34806290492384677a330d4d4Romain Guy        resource->setPixels(NULL, NULL);
286547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase        return true;
28758ecc204fbcacef34806290492384677a330d4d4Romain Guy    }
28858ecc204fbcacef34806290492384677a330d4d4Romain Guy    ResourceReference* ref = mCache->valueAt(index);
28958ecc204fbcacef34806290492384677a330d4d4Romain Guy    if (ref == NULL) {
29058ecc204fbcacef34806290492384677a330d4d4Romain Guy        // Should not get here - shouldn't get a call to recycle if we're not yet tracking it
291547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase        return true;
29258ecc204fbcacef34806290492384677a330d4d4Romain Guy    }
29358ecc204fbcacef34806290492384677a330d4d4Romain Guy    ref->recycled = true;
29458ecc204fbcacef34806290492384677a330d4d4Romain Guy    if (ref->refCount == 0) {
29597dc9172b0e58979c63de0dedbab656399a62281Romain Guy        deleteResourceReferenceLocked(resource, ref);
296547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase        return true;
29758ecc204fbcacef34806290492384677a330d4d4Romain Guy    }
298547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase    // Still referring to resource, don't recycle yet
299547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase    return false;
30058ecc204fbcacef34806290492384677a330d4d4Romain Guy}
30158ecc204fbcacef34806290492384677a330d4d4Romain Guy
302e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase/**
303e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase * This method should only be called while the mLock mutex is held (that mutex is grabbed
304e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase * by the various destructor() and recycle() methods which call this method).
305e7d2295c06ef9b9df6336cbff23007a13fb3f6e4Chet Haase */
30697dc9172b0e58979c63de0dedbab656399a62281Romain Guyvoid ResourceCache::deleteResourceReferenceLocked(void* resource, ResourceReference* ref) {
3075c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref->recycled && ref->resourceType == kBitmap) {
3085c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        ((SkBitmap*) resource)->setPixels(NULL, NULL);
3095c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
310603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase    if (ref->destroyed || ref->resourceType == kLayer) {
3115c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        switch (ref->resourceType) {
312d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy            case kBitmap: {
313d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy                SkBitmap* bitmap = (SkBitmap*) resource;
3145c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                if (Caches::hasInstance()) {
315fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy                    Caches::getInstance().textureCache.removeDeferred(bitmap);
3165c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                }
3175c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                delete bitmap;
3185c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            }
3195c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            break;
320d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy            case kPath: {
321d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy                SkPath* path = (SkPath*) resource;
3225a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase                if (Caches::hasInstance()) {
3235a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase                    Caches::getInstance().pathCache.removeDeferred(path);
3245a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase                }
3255a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase                delete path;
3265a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase            }
3275a7e828842c26f64bb6e0ef3e0019e1949b245eeChet Haase            break;
328d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy            case kShader: {
329d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy                SkiaShader* shader = (SkiaShader*) resource;
3305c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                delete shader;
331ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase            }
332ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase            break;
333d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy            case kColorFilter: {
334d586ad9c9fec80aa1d24d6b53cd2c8d5b47fe868Romain Guy                SkiaColorFilter* filter = (SkiaColorFilter*) resource;
335ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase                delete filter;
336ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase            }
337ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase            break;
338603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase            case kLayer: {
33956257aff8a55c847be72be9924c392033fd8151dDave Burke                Layer* layer = (Layer*) resource;
34054643d72f86d0ee0b23e3643ac9257d52ddfae6bMathias Agopian                Caches::getInstance().deleteLayerDeferred(layer);
341603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase            }
342603f6de35f21d74ae242d52d501f4f5c25ff4f4cChet Haase            break;
3435c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        }
3445c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
3455c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    mCache->removeItem(resource);
3465c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    delete ref;
3475c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
3485c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
3495c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}; // namespace uirenderer
3505c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}; // namespace android
351