ResourceCache.cpp revision 5c13d89c1332fcc499379b9064b891187b75ca32
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() {
295c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    LOGD("ResourceCache: cacheReport:");
305c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    for (size_t i = 0; i < mCache->size(); ++i) {
315c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        ResourceReference* ref = mCache->valueAt(i);
325c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        LOGD("  ResourceCache: mCache(%d): resource, ref = 0x%p, 0x%p",
335c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                i, mCache->keyAt(i), mCache->valueAt(i));
345c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        LOGD("  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() {
405c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    mCache = new KeyedVector<void *, ResourceReference *>();
415c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
425c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
435c13d89c1332fcc499379b9064b891187b75ca32Chet HaaseResourceCache::~ResourceCache() {
445c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    delete mCache;
455c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
465c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
475c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) {
485c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    for (size_t i = 0; i < mCache->size(); ++i) {
495c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        void* ref = mCache->valueAt(i);
505c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
515c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
525c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref == NULL || mCache->size() == 0) {
535c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        ref = new ResourceReference(resourceType);
545c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        mCache->add(resource, ref);
555c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
565c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    ref->refCount++;
575c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
585c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
595c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::incrementRefcount(SkBitmap* bitmapResource) {
605c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    bitmapResource->pixelRef()->safeRef();
615c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    bitmapResource->getColorTable()->safeRef();
625c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    incrementRefcount((void*)bitmapResource, kBitmap);
635c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
645c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
655c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::incrementRefcount(SkMatrix* matrixResource) {
665c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    incrementRefcount((void*)matrixResource, kMatrix);
675c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
685c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
695c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::incrementRefcount(SkPaint* paintResource) {
705c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    incrementRefcount((void*)paintResource, kPaint);
715c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
725c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
735c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::incrementRefcount(SkiaShader* shaderResource) {
745c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    shaderResource->getSkShader()->safeRef();
755c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    incrementRefcount((void*)shaderResource, kShader);
765c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
775c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
785c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::decrementRefcount(void* resource) {
795c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
805c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref == NULL) {
815c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
825c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        return;
835c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
845c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    ref->refCount--;
855c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref->refCount == 0) {
865c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        deleteResourceReference(resource, ref);
875c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
885c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
895c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
905c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
915c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    bitmapResource->pixelRef()->safeUnref();
925c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    bitmapResource->getColorTable()->safeUnref();
935c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    decrementRefcount((void*)bitmapResource);
945c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
955c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
965c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::decrementRefcount(SkiaShader* shaderResource) {
975c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    shaderResource->getSkShader()->safeUnref();
985c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    decrementRefcount((void*)shaderResource);
995c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
1005c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
1015c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::recycle(SkBitmap* resource) {
1025c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (mCache->indexOfKey(resource) < 0) {
1035c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        // not tracking this resource; just recycle the pixel data
1045c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        resource->setPixels(NULL, NULL);
1055c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        return;
1065c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
1075c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    recycle((void*) resource);
1085c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
1095c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
1105c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::recycle(void* resource) {
1115c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
1125c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref == NULL) {
1135c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        // Should not get here - shouldn't get a call to recycle if we're not yet tracking it
1145c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        return;
1155c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
1165c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    ref->recycled = true;
1175c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref->refCount == 0) {
1185c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        deleteResourceReference(resource, ref);
1195c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
1205c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
1215c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
1225c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::destructor(SkBitmap* resource) {
1235c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
1245c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref == NULL) {
1255c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        // If we're not tracking this resource, just delete it
1265c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        if (Caches::hasInstance()) {
1275c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            Caches::getInstance().textureCache.remove(resource);
1285c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        }
1295c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        delete resource;
1305c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        return;
1315c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
1325c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    ref->destroyed = true;
1335c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref->refCount == 0) {
1345c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        deleteResourceReference(resource, ref);
1355c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        return;
1365c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
1375c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
1385c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
1395c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::destructor(SkMatrix* resource) {
1405c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
1415c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref == NULL) {
1425c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        // If we're not tracking this resource, just delete it
1435c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        delete resource;
1445c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        return;
1455c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
1465c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    ref->destroyed = true;
1475c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref->refCount == 0) {
1485c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        deleteResourceReference(resource, ref);
1495c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        return;
1505c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
1515c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
1525c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
1535c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::destructor(SkPaint* resource) {
1545c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
1555c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref == NULL) {
1565c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        // If we're not tracking this resource, just delete it
1575c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        delete resource;
1585c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        return;
1595c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
1605c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    ref->destroyed = true;
1615c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref->refCount == 0) {
1625c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        deleteResourceReference(resource, ref);
1635c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        return;
1645c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
1655c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
1665c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
1675c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::destructor(SkiaShader* resource) {
1685c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
1695c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref == NULL) {
1705c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        // If we're not tracking this resource, just delete it
1715c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        if (Caches::hasInstance()) {
1725c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            Caches::getInstance().gradientCache.remove(resource->getSkShader());
1735c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        }
1745c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        delete resource;
1755c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        return;
1765c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
1775c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    ref->destroyed = true;
1785c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref->refCount == 0) {
1795c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        deleteResourceReference(resource, ref);
1805c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        return;
1815c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
1825c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
1835c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
1845c13d89c1332fcc499379b9064b891187b75ca32Chet Haasevoid ResourceCache::deleteResourceReference(void* resource, ResourceReference* ref) {
1855c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref->recycled && ref->resourceType == kBitmap) {
1865c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        ((SkBitmap*) resource)->setPixels(NULL, NULL);
1875c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
1885c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    if (ref->destroyed) {
1895c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        switch (ref->resourceType) {
1905c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            case kBitmap:
1915c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            {
1925c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                SkBitmap* bitmap = (SkBitmap*)resource;
1935c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                if (Caches::hasInstance()) {
1945c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                    Caches::getInstance().textureCache.remove(bitmap);
1955c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                }
1965c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                delete bitmap;
1975c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            }
1985c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            break;
1995c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            case kMatrix:
2005c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                delete (SkMatrix*) resource;
2015c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                break;
2025c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            case kPaint:
2035c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                delete (SkPaint*) resource;
2045c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                break;
2055c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            case kShader:
2065c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                SkiaShader* shader = (SkiaShader*)resource;
2075c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                if (Caches::hasInstance()) {
2085c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                    Caches::getInstance().gradientCache.remove(shader->getSkShader());
2095c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                }
2105c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                delete shader;
2115c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                break;
2125c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        }
2135c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
2145c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    mCache->removeItem(resource);
2155c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    delete ref;
2165c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}
2175c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
2185c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}; // namespace uirenderer
2195c13d89c1332fcc499379b9064b891187b75ca32Chet Haase}; // namespace android
220