ResourceCache.cpp revision 5c13d89c1332fcc499379b9064b891187b75ca32
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <SkPixelRef.h> 18#include "ResourceCache.h" 19#include "Caches.h" 20 21namespace android { 22namespace uirenderer { 23 24/////////////////////////////////////////////////////////////////////////////// 25// Resource cache 26/////////////////////////////////////////////////////////////////////////////// 27 28void ResourceCache::logCache() { 29 LOGD("ResourceCache: cacheReport:"); 30 for (size_t i = 0; i < mCache->size(); ++i) { 31 ResourceReference* ref = mCache->valueAt(i); 32 LOGD(" ResourceCache: mCache(%d): resource, ref = 0x%p, 0x%p", 33 i, mCache->keyAt(i), mCache->valueAt(i)); 34 LOGD(" ResourceCache: mCache(%d): refCount, recycled, destroyed, type = %d, %d, %d, %d", 35 i, ref->refCount, ref->recycled, ref->destroyed, ref->resourceType); 36 } 37} 38 39ResourceCache::ResourceCache() { 40 mCache = new KeyedVector<void *, ResourceReference *>(); 41} 42 43ResourceCache::~ResourceCache() { 44 delete mCache; 45} 46 47void ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) { 48 for (size_t i = 0; i < mCache->size(); ++i) { 49 void* ref = mCache->valueAt(i); 50 } 51 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; 52 if (ref == NULL || mCache->size() == 0) { 53 ref = new ResourceReference(resourceType); 54 mCache->add(resource, ref); 55 } 56 ref->refCount++; 57} 58 59void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) { 60 bitmapResource->pixelRef()->safeRef(); 61 bitmapResource->getColorTable()->safeRef(); 62 incrementRefcount((void*)bitmapResource, kBitmap); 63} 64 65void ResourceCache::incrementRefcount(SkMatrix* matrixResource) { 66 incrementRefcount((void*)matrixResource, kMatrix); 67} 68 69void ResourceCache::incrementRefcount(SkPaint* paintResource) { 70 incrementRefcount((void*)paintResource, kPaint); 71} 72 73void ResourceCache::incrementRefcount(SkiaShader* shaderResource) { 74 shaderResource->getSkShader()->safeRef(); 75 incrementRefcount((void*)shaderResource, kShader); 76} 77 78void ResourceCache::decrementRefcount(void* resource) { 79 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; 80 if (ref == NULL) { 81 // Should not get here - shouldn't get a call to decrement if we're not yet tracking it 82 return; 83 } 84 ref->refCount--; 85 if (ref->refCount == 0) { 86 deleteResourceReference(resource, ref); 87 } 88} 89 90void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) { 91 bitmapResource->pixelRef()->safeUnref(); 92 bitmapResource->getColorTable()->safeUnref(); 93 decrementRefcount((void*)bitmapResource); 94} 95 96void ResourceCache::decrementRefcount(SkiaShader* shaderResource) { 97 shaderResource->getSkShader()->safeUnref(); 98 decrementRefcount((void*)shaderResource); 99} 100 101void ResourceCache::recycle(SkBitmap* resource) { 102 if (mCache->indexOfKey(resource) < 0) { 103 // not tracking this resource; just recycle the pixel data 104 resource->setPixels(NULL, NULL); 105 return; 106 } 107 recycle((void*) resource); 108} 109 110void ResourceCache::recycle(void* resource) { 111 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; 112 if (ref == NULL) { 113 // Should not get here - shouldn't get a call to recycle if we're not yet tracking it 114 return; 115 } 116 ref->recycled = true; 117 if (ref->refCount == 0) { 118 deleteResourceReference(resource, ref); 119 } 120} 121 122void ResourceCache::destructor(SkBitmap* resource) { 123 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; 124 if (ref == NULL) { 125 // If we're not tracking this resource, just delete it 126 if (Caches::hasInstance()) { 127 Caches::getInstance().textureCache.remove(resource); 128 } 129 delete resource; 130 return; 131 } 132 ref->destroyed = true; 133 if (ref->refCount == 0) { 134 deleteResourceReference(resource, ref); 135 return; 136 } 137} 138 139void ResourceCache::destructor(SkMatrix* resource) { 140 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; 141 if (ref == NULL) { 142 // If we're not tracking this resource, just delete it 143 delete resource; 144 return; 145 } 146 ref->destroyed = true; 147 if (ref->refCount == 0) { 148 deleteResourceReference(resource, ref); 149 return; 150 } 151} 152 153void ResourceCache::destructor(SkPaint* resource) { 154 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; 155 if (ref == NULL) { 156 // If we're not tracking this resource, just delete it 157 delete resource; 158 return; 159 } 160 ref->destroyed = true; 161 if (ref->refCount == 0) { 162 deleteResourceReference(resource, ref); 163 return; 164 } 165} 166 167void ResourceCache::destructor(SkiaShader* resource) { 168 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; 169 if (ref == NULL) { 170 // If we're not tracking this resource, just delete it 171 if (Caches::hasInstance()) { 172 Caches::getInstance().gradientCache.remove(resource->getSkShader()); 173 } 174 delete resource; 175 return; 176 } 177 ref->destroyed = true; 178 if (ref->refCount == 0) { 179 deleteResourceReference(resource, ref); 180 return; 181 } 182} 183 184void ResourceCache::deleteResourceReference(void* resource, ResourceReference* ref) { 185 if (ref->recycled && ref->resourceType == kBitmap) { 186 ((SkBitmap*) resource)->setPixels(NULL, NULL); 187 } 188 if (ref->destroyed) { 189 switch (ref->resourceType) { 190 case kBitmap: 191 { 192 SkBitmap* bitmap = (SkBitmap*)resource; 193 if (Caches::hasInstance()) { 194 Caches::getInstance().textureCache.remove(bitmap); 195 } 196 delete bitmap; 197 } 198 break; 199 case kMatrix: 200 delete (SkMatrix*) resource; 201 break; 202 case kPaint: 203 delete (SkPaint*) resource; 204 break; 205 case kShader: 206 SkiaShader* shader = (SkiaShader*)resource; 207 if (Caches::hasInstance()) { 208 Caches::getInstance().gradientCache.remove(shader->getSkShader()); 209 } 210 delete shader; 211 break; 212 } 213 } 214 mCache->removeItem(resource); 215 delete ref; 216} 217 218}; // namespace uirenderer 219}; // namespace android 220