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