ResourceCache.cpp revision fe48f65922d4a3cc4aefe058cee5acec51504a20
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(SkiaShader* shaderResource) { 66 shaderResource->getSkShader()->safeRef(); 67 incrementRefcount((void*)shaderResource, kShader); 68} 69 70void ResourceCache::incrementRefcount(SkiaColorFilter* filterResource) { 71 filterResource->getSkColorFilter()->safeRef(); 72 incrementRefcount((void*)filterResource, kColorFilter); 73} 74 75void ResourceCache::decrementRefcount(void* resource) { 76 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; 77 if (ref == NULL) { 78 // Should not get here - shouldn't get a call to decrement if we're not yet tracking it 79 return; 80 } 81 ref->refCount--; 82 if (ref->refCount == 0) { 83 deleteResourceReference(resource, ref); 84 } 85} 86 87void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) { 88 bitmapResource->pixelRef()->safeUnref(); 89 bitmapResource->getColorTable()->safeUnref(); 90 decrementRefcount((void*)bitmapResource); 91} 92 93void ResourceCache::decrementRefcount(SkiaShader* shaderResource) { 94 shaderResource->getSkShader()->safeUnref(); 95 decrementRefcount((void*)shaderResource); 96} 97 98void ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) { 99 filterResource->getSkColorFilter()->safeUnref(); 100 decrementRefcount((void*)filterResource); 101} 102 103void ResourceCache::recycle(SkBitmap* resource) { 104 if (mCache->indexOfKey(resource) < 0) { 105 // not tracking this resource; just recycle the pixel data 106 resource->setPixels(NULL, NULL); 107 return; 108 } 109 recycle((void*) resource); 110} 111 112void ResourceCache::recycle(void* resource) { 113 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; 114 if (ref == NULL) { 115 // Should not get here - shouldn't get a call to recycle if we're not yet tracking it 116 return; 117 } 118 ref->recycled = true; 119 if (ref->refCount == 0) { 120 deleteResourceReference(resource, ref); 121 } 122} 123 124void ResourceCache::destructor(SkBitmap* resource) { 125 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; 126 if (ref == NULL) { 127 // If we're not tracking this resource, just delete it 128 if (Caches::hasInstance()) { 129 Caches::getInstance().textureCache.removeDeferred(resource); 130 } 131 delete resource; 132 return; 133 } 134 ref->destroyed = true; 135 if (ref->refCount == 0) { 136 deleteResourceReference(resource, ref); 137 return; 138 } 139} 140 141void ResourceCache::destructor(SkiaShader* resource) { 142 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; 143 if (ref == NULL) { 144 // If we're not tracking this resource, just delete it 145 if (Caches::hasInstance()) { 146 Caches::getInstance().gradientCache.removeDeferred(resource->getSkShader()); 147 } 148 delete resource; 149 return; 150 } 151 ref->destroyed = true; 152 if (ref->refCount == 0) { 153 deleteResourceReference(resource, ref); 154 return; 155 } 156} 157 158void ResourceCache::destructor(SkiaColorFilter* resource) { 159 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; 160 if (ref == NULL) { 161 // If we're not tracking this resource, just delete it 162 delete resource; 163 return; 164 } 165 ref->destroyed = true; 166 if (ref->refCount == 0) { 167 deleteResourceReference(resource, ref); 168 return; 169 } 170} 171 172void ResourceCache::deleteResourceReference(void* resource, ResourceReference* ref) { 173 if (ref->recycled && ref->resourceType == kBitmap) { 174 ((SkBitmap*) resource)->setPixels(NULL, NULL); 175 } 176 if (ref->destroyed) { 177 switch (ref->resourceType) { 178 case kBitmap: 179 { 180 SkBitmap* bitmap = (SkBitmap*)resource; 181 if (Caches::hasInstance()) { 182 Caches::getInstance().textureCache.removeDeferred(bitmap); 183 } 184 delete bitmap; 185 } 186 break; 187 case kShader: 188 { 189 SkiaShader* shader = (SkiaShader*)resource; 190 if (Caches::hasInstance()) { 191 Caches::getInstance().gradientCache.removeDeferred(shader->getSkShader()); 192 } 193 delete shader; 194 } 195 break; 196 case kColorFilter: 197 { 198 SkiaColorFilter* filter = (SkiaColorFilter*)resource; 199 delete filter; 200 } 201 break; 202 } 203 } 204 mCache->removeItem(resource); 205 delete ref; 206} 207 208}; // namespace uirenderer 209}; // namespace android 210