| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 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 |  | 
 | 21 | namespace android { | 
 | 22 | namespace uirenderer { | 
 | 23 |  | 
 | 24 | /////////////////////////////////////////////////////////////////////////////// | 
 | 25 | // Resource cache | 
 | 26 | /////////////////////////////////////////////////////////////////////////////// | 
 | 27 |  | 
 | 28 | void 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 |  | 
 | 39 | ResourceCache::ResourceCache() { | 
| Chet Haase | e7d2295 | 2010-11-11 16:30:16 -0800 | [diff] [blame] | 40 |     Mutex::Autolock _l(mLock); | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 41 |     mCache = new KeyedVector<void *, ResourceReference *>(); | 
 | 42 | } | 
 | 43 |  | 
 | 44 | ResourceCache::~ResourceCache() { | 
| Chet Haase | e7d2295 | 2010-11-11 16:30:16 -0800 | [diff] [blame] | 45 |     Mutex::Autolock _l(mLock); | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 46 |     delete mCache; | 
 | 47 | } | 
 | 48 |  | 
 | 49 | void ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) { | 
| Chet Haase | e7d2295 | 2010-11-11 16:30:16 -0800 | [diff] [blame] | 50 |     Mutex::Autolock _l(mLock); | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 51 |     for (size_t i = 0; i < mCache->size(); ++i) { | 
 | 52 |         void* ref = mCache->valueAt(i); | 
 | 53 |     } | 
 | 54 |     ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; | 
 | 55 |     if (ref == NULL || mCache->size() == 0) { | 
 | 56 |         ref = new ResourceReference(resourceType); | 
 | 57 |         mCache->add(resource, ref); | 
 | 58 |     } | 
 | 59 |     ref->refCount++; | 
 | 60 | } | 
 | 61 |  | 
 | 62 | void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) { | 
| Derek Sollenberger | 6062c59 | 2011-02-22 13:55:04 -0500 | [diff] [blame] | 63 |     SkSafeRef(bitmapResource->pixelRef()); | 
 | 64 |     SkSafeRef(bitmapResource->getColorTable()); | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 65 |     incrementRefcount((void*)bitmapResource, kBitmap); | 
 | 66 | } | 
 | 67 |  | 
| Chet Haase | 5a7e828 | 2011-02-04 12:50:55 -0800 | [diff] [blame] | 68 | void ResourceCache::incrementRefcount(SkPath* pathResource) { | 
 | 69 |     incrementRefcount((void*)pathResource, kPath); | 
 | 70 | } | 
 | 71 |  | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 72 | void ResourceCache::incrementRefcount(SkiaShader* shaderResource) { | 
| Derek Sollenberger | 6062c59 | 2011-02-22 13:55:04 -0500 | [diff] [blame] | 73 |     SkSafeRef(shaderResource->getSkShader()); | 
| Romain Guy | 43ccf46 | 2011-01-14 18:51:01 -0800 | [diff] [blame] | 74 |     incrementRefcount((void*) shaderResource, kShader); | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 75 | } | 
 | 76 |  | 
| Chet Haase | ad93c2b | 2010-10-22 16:17:12 -0700 | [diff] [blame] | 77 | void ResourceCache::incrementRefcount(SkiaColorFilter* filterResource) { | 
| Derek Sollenberger | 6062c59 | 2011-02-22 13:55:04 -0500 | [diff] [blame] | 78 |     SkSafeRef(filterResource->getSkColorFilter()); | 
| Romain Guy | 43ccf46 | 2011-01-14 18:51:01 -0800 | [diff] [blame] | 79 |     incrementRefcount((void*) filterResource, kColorFilter); | 
| Chet Haase | ad93c2b | 2010-10-22 16:17:12 -0700 | [diff] [blame] | 80 | } | 
 | 81 |  | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 82 | void ResourceCache::decrementRefcount(void* resource) { | 
| Chet Haase | e7d2295 | 2010-11-11 16:30:16 -0800 | [diff] [blame] | 83 |     Mutex::Autolock _l(mLock); | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 84 |     ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; | 
 | 85 |     if (ref == NULL) { | 
 | 86 |         // Should not get here - shouldn't get a call to decrement if we're not yet tracking it | 
 | 87 |         return; | 
 | 88 |     } | 
 | 89 |     ref->refCount--; | 
 | 90 |     if (ref->refCount == 0) { | 
 | 91 |         deleteResourceReference(resource, ref); | 
 | 92 |     } | 
 | 93 | } | 
 | 94 |  | 
 | 95 | void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) { | 
| Derek Sollenberger | 6062c59 | 2011-02-22 13:55:04 -0500 | [diff] [blame] | 96 |     SkSafeUnref(bitmapResource->pixelRef()); | 
 | 97 |     SkSafeUnref(bitmapResource->getColorTable()); | 
| Romain Guy | 43ccf46 | 2011-01-14 18:51:01 -0800 | [diff] [blame] | 98 |     decrementRefcount((void*) bitmapResource); | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 99 | } | 
 | 100 |  | 
| Chet Haase | 5a7e828 | 2011-02-04 12:50:55 -0800 | [diff] [blame] | 101 | void ResourceCache::decrementRefcount(SkPath* pathResource) { | 
 | 102 |     decrementRefcount((void*) pathResource); | 
 | 103 | } | 
 | 104 |  | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 105 | void ResourceCache::decrementRefcount(SkiaShader* shaderResource) { | 
| Derek Sollenberger | 6062c59 | 2011-02-22 13:55:04 -0500 | [diff] [blame] | 106 |     SkSafeUnref(shaderResource->getSkShader()); | 
| Romain Guy | 43ccf46 | 2011-01-14 18:51:01 -0800 | [diff] [blame] | 107 |     decrementRefcount((void*) shaderResource); | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 108 | } | 
 | 109 |  | 
| Chet Haase | ad93c2b | 2010-10-22 16:17:12 -0700 | [diff] [blame] | 110 | void ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) { | 
| Derek Sollenberger | 6062c59 | 2011-02-22 13:55:04 -0500 | [diff] [blame] | 111 |     SkSafeUnref(filterResource->getSkColorFilter()); | 
| Romain Guy | 43ccf46 | 2011-01-14 18:51:01 -0800 | [diff] [blame] | 112 |     decrementRefcount((void*) filterResource); | 
| Chet Haase | ad93c2b | 2010-10-22 16:17:12 -0700 | [diff] [blame] | 113 | } | 
 | 114 |  | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 115 | void ResourceCache::recycle(SkBitmap* resource) { | 
| Chet Haase | e7d2295 | 2010-11-11 16:30:16 -0800 | [diff] [blame] | 116 |     Mutex::Autolock _l(mLock); | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 117 |     if (mCache->indexOfKey(resource) < 0) { | 
 | 118 |         // not tracking this resource; just recycle the pixel data | 
 | 119 |         resource->setPixels(NULL, NULL); | 
 | 120 |         return; | 
 | 121 |     } | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 122 |     ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; | 
 | 123 |     if (ref == NULL) { | 
 | 124 |         // Should not get here - shouldn't get a call to recycle if we're not yet tracking it | 
 | 125 |         return; | 
 | 126 |     } | 
 | 127 |     ref->recycled = true; | 
 | 128 |     if (ref->refCount == 0) { | 
 | 129 |         deleteResourceReference(resource, ref); | 
 | 130 |     } | 
 | 131 | } | 
 | 132 |  | 
| Chet Haase | 5a7e828 | 2011-02-04 12:50:55 -0800 | [diff] [blame] | 133 | void ResourceCache::destructor(SkPath* resource) { | 
 | 134 |     Mutex::Autolock _l(mLock); | 
 | 135 |     ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; | 
 | 136 |     if (ref == NULL) { | 
 | 137 |         // If we're not tracking this resource, just delete it | 
 | 138 |         if (Caches::hasInstance()) { | 
 | 139 |             Caches::getInstance().pathCache.removeDeferred(resource); | 
 | 140 |         } | 
 | 141 |         delete resource; | 
 | 142 |         return; | 
 | 143 |     } | 
 | 144 |     ref->destroyed = true; | 
 | 145 |     if (ref->refCount == 0) { | 
 | 146 |         deleteResourceReference(resource, ref); | 
 | 147 |         return; | 
 | 148 |     } | 
 | 149 | } | 
 | 150 |  | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 151 | void ResourceCache::destructor(SkBitmap* resource) { | 
| Chet Haase | e7d2295 | 2010-11-11 16:30:16 -0800 | [diff] [blame] | 152 |     Mutex::Autolock _l(mLock); | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 153 |     ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; | 
 | 154 |     if (ref == NULL) { | 
 | 155 |         // If we're not tracking this resource, just delete it | 
 | 156 |         if (Caches::hasInstance()) { | 
| Romain Guy | fe48f65 | 2010-11-11 15:36:56 -0800 | [diff] [blame] | 157 |             Caches::getInstance().textureCache.removeDeferred(resource); | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 158 |         } | 
 | 159 |         delete resource; | 
 | 160 |         return; | 
 | 161 |     } | 
 | 162 |     ref->destroyed = true; | 
 | 163 |     if (ref->refCount == 0) { | 
 | 164 |         deleteResourceReference(resource, ref); | 
 | 165 |         return; | 
 | 166 |     } | 
 | 167 | } | 
 | 168 |  | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 169 | void ResourceCache::destructor(SkiaShader* resource) { | 
| Chet Haase | e7d2295 | 2010-11-11 16:30:16 -0800 | [diff] [blame] | 170 |     Mutex::Autolock _l(mLock); | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 171 |     ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; | 
 | 172 |     if (ref == NULL) { | 
 | 173 |         // If we're not tracking this resource, just delete it | 
 | 174 |         if (Caches::hasInstance()) { | 
| Romain Guy | fe48f65 | 2010-11-11 15:36:56 -0800 | [diff] [blame] | 175 |             Caches::getInstance().gradientCache.removeDeferred(resource->getSkShader()); | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 176 |         } | 
 | 177 |         delete resource; | 
 | 178 |         return; | 
 | 179 |     } | 
 | 180 |     ref->destroyed = true; | 
 | 181 |     if (ref->refCount == 0) { | 
 | 182 |         deleteResourceReference(resource, ref); | 
 | 183 |         return; | 
 | 184 |     } | 
 | 185 | } | 
 | 186 |  | 
| Chet Haase | ad93c2b | 2010-10-22 16:17:12 -0700 | [diff] [blame] | 187 | void ResourceCache::destructor(SkiaColorFilter* resource) { | 
| Chet Haase | e7d2295 | 2010-11-11 16:30:16 -0800 | [diff] [blame] | 188 |     Mutex::Autolock _l(mLock); | 
| Chet Haase | ad93c2b | 2010-10-22 16:17:12 -0700 | [diff] [blame] | 189 |     ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; | 
 | 190 |     if (ref == NULL) { | 
 | 191 |         // If we're not tracking this resource, just delete it | 
 | 192 |         delete resource; | 
 | 193 |         return; | 
 | 194 |     } | 
 | 195 |     ref->destroyed = true; | 
 | 196 |     if (ref->refCount == 0) { | 
 | 197 |         deleteResourceReference(resource, ref); | 
 | 198 |         return; | 
 | 199 |     } | 
 | 200 | } | 
 | 201 |  | 
| Chet Haase | e7d2295 | 2010-11-11 16:30:16 -0800 | [diff] [blame] | 202 | /** | 
 | 203 |  * This method should only be called while the mLock mutex is held (that mutex is grabbed | 
 | 204 |  * by the various destructor() and recycle() methods which call this method). | 
 | 205 |  */ | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 206 | void ResourceCache::deleteResourceReference(void* resource, ResourceReference* ref) { | 
 | 207 |     if (ref->recycled && ref->resourceType == kBitmap) { | 
 | 208 |         ((SkBitmap*) resource)->setPixels(NULL, NULL); | 
 | 209 |     } | 
 | 210 |     if (ref->destroyed) { | 
 | 211 |         switch (ref->resourceType) { | 
 | 212 |             case kBitmap: | 
 | 213 |             { | 
 | 214 |                 SkBitmap* bitmap = (SkBitmap*)resource; | 
 | 215 |                 if (Caches::hasInstance()) { | 
| Romain Guy | fe48f65 | 2010-11-11 15:36:56 -0800 | [diff] [blame] | 216 |                     Caches::getInstance().textureCache.removeDeferred(bitmap); | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 217 |                 } | 
 | 218 |                 delete bitmap; | 
 | 219 |             } | 
 | 220 |             break; | 
| Chet Haase | 5a7e828 | 2011-02-04 12:50:55 -0800 | [diff] [blame] | 221 |             case kPath: | 
 | 222 |             { | 
 | 223 |                 SkPath* path = (SkPath*)resource; | 
 | 224 |                 if (Caches::hasInstance()) { | 
 | 225 |                     Caches::getInstance().pathCache.removeDeferred(path); | 
 | 226 |                 } | 
 | 227 |                 delete path; | 
 | 228 |             } | 
 | 229 |             break; | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 230 |             case kShader: | 
| Chet Haase | ad93c2b | 2010-10-22 16:17:12 -0700 | [diff] [blame] | 231 |             { | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 232 |                 SkiaShader* shader = (SkiaShader*)resource; | 
 | 233 |                 if (Caches::hasInstance()) { | 
| Romain Guy | fe48f65 | 2010-11-11 15:36:56 -0800 | [diff] [blame] | 234 |                     Caches::getInstance().gradientCache.removeDeferred(shader->getSkShader()); | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 235 |                 } | 
 | 236 |                 delete shader; | 
| Chet Haase | ad93c2b | 2010-10-22 16:17:12 -0700 | [diff] [blame] | 237 |             } | 
 | 238 |             break; | 
 | 239 |             case kColorFilter: | 
 | 240 |             { | 
 | 241 |                 SkiaColorFilter* filter = (SkiaColorFilter*)resource; | 
 | 242 |                 delete filter; | 
 | 243 |             } | 
 | 244 |             break; | 
| Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 245 |         } | 
 | 246 |     } | 
 | 247 |     mCache->removeItem(resource); | 
 | 248 |     delete ref; | 
 | 249 | } | 
 | 250 |  | 
 | 251 | }; // namespace uirenderer | 
 | 252 | }; // namespace android |