blob: 81f7b94b31eea76aa25b44289f84e67786f4a8a8 [file] [log] [blame]
Chet Haase5c13d892010-10-08 08:37:55 -07001/*
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() {
Steve Block5baa3a62011-12-20 16:23:08 +000029 ALOGD("ResourceCache: cacheReport:");
Chet Haase5c13d892010-10-08 08:37:55 -070030 for (size_t i = 0; i < mCache->size(); ++i) {
31 ResourceReference* ref = mCache->valueAt(i);
Steve Block5baa3a62011-12-20 16:23:08 +000032 ALOGD(" ResourceCache: mCache(%d): resource, ref = 0x%p, 0x%p",
Chet Haase5c13d892010-10-08 08:37:55 -070033 i, mCache->keyAt(i), mCache->valueAt(i));
Steve Block5baa3a62011-12-20 16:23:08 +000034 ALOGD(" ResourceCache: mCache(%d): refCount, recycled, destroyed, type = %d, %d, %d, %d",
Chet Haase5c13d892010-10-08 08:37:55 -070035 i, ref->refCount, ref->recycled, ref->destroyed, ref->resourceType);
36 }
37}
38
39ResourceCache::ResourceCache() {
Chet Haasee7d22952010-11-11 16:30:16 -080040 Mutex::Autolock _l(mLock);
Romain Guy58ecc202012-09-07 11:58:36 -070041 mCache = new KeyedVector<void*, ResourceReference*>();
Chet Haase5c13d892010-10-08 08:37:55 -070042}
43
44ResourceCache::~ResourceCache() {
Chet Haasee7d22952010-11-11 16:30:16 -080045 Mutex::Autolock _l(mLock);
Chet Haase5c13d892010-10-08 08:37:55 -070046 delete mCache;
47}
48
Romain Guy58ecc202012-09-07 11:58:36 -070049void ResourceCache::lock() {
50 mLock.lock();
51}
52
53void ResourceCache::unlock() {
54 mLock.unlock();
55}
56
Chet Haase5c13d892010-10-08 08:37:55 -070057void ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) {
Chet Haasee7d22952010-11-11 16:30:16 -080058 Mutex::Autolock _l(mLock);
Romain Guy58ecc202012-09-07 11:58:36 -070059 incrementRefcountLocked(resource, resourceType);
Chet Haase5c13d892010-10-08 08:37:55 -070060}
61
62void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) {
Derek Sollenberger6062c592011-02-22 13:55:04 -050063 SkSafeRef(bitmapResource->pixelRef());
64 SkSafeRef(bitmapResource->getColorTable());
Romain Guy49c5fc02012-05-15 11:10:01 -070065 incrementRefcount((void*) bitmapResource, kBitmap);
Chet Haase5c13d892010-10-08 08:37:55 -070066}
67
Chet Haase5a7e8282011-02-04 12:50:55 -080068void ResourceCache::incrementRefcount(SkPath* pathResource) {
Romain Guy49c5fc02012-05-15 11:10:01 -070069 incrementRefcount((void*) pathResource, kPath);
Chet Haase5a7e8282011-02-04 12:50:55 -080070}
71
Chet Haase5c13d892010-10-08 08:37:55 -070072void ResourceCache::incrementRefcount(SkiaShader* shaderResource) {
Derek Sollenberger6062c592011-02-22 13:55:04 -050073 SkSafeRef(shaderResource->getSkShader());
Romain Guy43ccf462011-01-14 18:51:01 -080074 incrementRefcount((void*) shaderResource, kShader);
Chet Haase5c13d892010-10-08 08:37:55 -070075}
76
Chet Haasead93c2b2010-10-22 16:17:12 -070077void ResourceCache::incrementRefcount(SkiaColorFilter* filterResource) {
Derek Sollenberger6062c592011-02-22 13:55:04 -050078 SkSafeRef(filterResource->getSkColorFilter());
Romain Guy43ccf462011-01-14 18:51:01 -080079 incrementRefcount((void*) filterResource, kColorFilter);
Chet Haasead93c2b2010-10-22 16:17:12 -070080}
81
Chet Haase603f6de2012-09-14 15:31:25 -070082void ResourceCache::incrementRefcount(Layer* layerResource) {
83 incrementRefcount((void*) layerResource, kLayer);
84}
85
Romain Guy58ecc202012-09-07 11:58:36 -070086void ResourceCache::incrementRefcountLocked(void* resource, ResourceType resourceType) {
Romain Guy8dcfd5e2012-07-20 11:36:03 -070087 ssize_t index = mCache->indexOfKey(resource);
88 ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
Romain Guy58ecc202012-09-07 11:58:36 -070089 if (ref == NULL || mCache->size() == 0) {
90 ref = new ResourceReference(resourceType);
91 mCache->add(resource, ref);
Chet Haase5c13d892010-10-08 08:37:55 -070092 }
Romain Guy58ecc202012-09-07 11:58:36 -070093 ref->refCount++;
94}
95
96void ResourceCache::incrementRefcountLocked(SkBitmap* bitmapResource) {
97 SkSafeRef(bitmapResource->pixelRef());
98 SkSafeRef(bitmapResource->getColorTable());
99 incrementRefcountLocked((void*) bitmapResource, kBitmap);
100}
101
102void ResourceCache::incrementRefcountLocked(SkPath* pathResource) {
103 incrementRefcountLocked((void*) pathResource, kPath);
104}
105
106void ResourceCache::incrementRefcountLocked(SkiaShader* shaderResource) {
107 SkSafeRef(shaderResource->getSkShader());
108 incrementRefcountLocked((void*) shaderResource, kShader);
109}
110
111void ResourceCache::incrementRefcountLocked(SkiaColorFilter* filterResource) {
112 SkSafeRef(filterResource->getSkColorFilter());
113 incrementRefcountLocked((void*) filterResource, kColorFilter);
114}
115
Chet Haase603f6de2012-09-14 15:31:25 -0700116void ResourceCache::incrementRefcountLocked(Layer* layerResource) {
117 incrementRefcountLocked((void*) layerResource, kLayer);
118}
119
Romain Guy58ecc202012-09-07 11:58:36 -0700120void ResourceCache::decrementRefcount(void* resource) {
121 Mutex::Autolock _l(mLock);
122 decrementRefcountLocked(resource);
Chet Haase5c13d892010-10-08 08:37:55 -0700123}
124
125void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
Derek Sollenberger6062c592011-02-22 13:55:04 -0500126 SkSafeUnref(bitmapResource->pixelRef());
127 SkSafeUnref(bitmapResource->getColorTable());
Romain Guy43ccf462011-01-14 18:51:01 -0800128 decrementRefcount((void*) bitmapResource);
Chet Haase5c13d892010-10-08 08:37:55 -0700129}
130
Chet Haase5a7e8282011-02-04 12:50:55 -0800131void ResourceCache::decrementRefcount(SkPath* pathResource) {
132 decrementRefcount((void*) pathResource);
133}
134
Chet Haase5c13d892010-10-08 08:37:55 -0700135void ResourceCache::decrementRefcount(SkiaShader* shaderResource) {
Derek Sollenberger6062c592011-02-22 13:55:04 -0500136 SkSafeUnref(shaderResource->getSkShader());
Romain Guy43ccf462011-01-14 18:51:01 -0800137 decrementRefcount((void*) shaderResource);
Chet Haase5c13d892010-10-08 08:37:55 -0700138}
139
Chet Haasead93c2b2010-10-22 16:17:12 -0700140void ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) {
Derek Sollenberger6062c592011-02-22 13:55:04 -0500141 SkSafeUnref(filterResource->getSkColorFilter());
Romain Guy43ccf462011-01-14 18:51:01 -0800142 decrementRefcount((void*) filterResource);
Chet Haasead93c2b2010-10-22 16:17:12 -0700143}
144
Chet Haase603f6de2012-09-14 15:31:25 -0700145void ResourceCache::decrementRefcount(Layer* layerResource) {
146 decrementRefcount((void*) layerResource);
147}
148
Romain Guy58ecc202012-09-07 11:58:36 -0700149void ResourceCache::decrementRefcountLocked(void* resource) {
Romain Guy8dcfd5e2012-07-20 11:36:03 -0700150 ssize_t index = mCache->indexOfKey(resource);
Romain Guy58ecc202012-09-07 11:58:36 -0700151 ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
Chet Haase5c13d892010-10-08 08:37:55 -0700152 if (ref == NULL) {
Romain Guy58ecc202012-09-07 11:58:36 -0700153 // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
Chet Haase5c13d892010-10-08 08:37:55 -0700154 return;
155 }
Romain Guy58ecc202012-09-07 11:58:36 -0700156 ref->refCount--;
Chet Haase5c13d892010-10-08 08:37:55 -0700157 if (ref->refCount == 0) {
Romain Guy97dc9172012-09-23 17:46:45 -0700158 deleteResourceReferenceLocked(resource, ref);
Chet Haase5c13d892010-10-08 08:37:55 -0700159 }
160}
161
Romain Guy58ecc202012-09-07 11:58:36 -0700162void ResourceCache::decrementRefcountLocked(SkBitmap* bitmapResource) {
163 SkSafeUnref(bitmapResource->pixelRef());
164 SkSafeUnref(bitmapResource->getColorTable());
165 decrementRefcountLocked((void*) bitmapResource);
166}
167
168void ResourceCache::decrementRefcountLocked(SkPath* pathResource) {
169 decrementRefcountLocked((void*) pathResource);
170}
171
172void ResourceCache::decrementRefcountLocked(SkiaShader* shaderResource) {
173 SkSafeUnref(shaderResource->getSkShader());
174 decrementRefcountLocked((void*) shaderResource);
175}
176
177void ResourceCache::decrementRefcountLocked(SkiaColorFilter* filterResource) {
178 SkSafeUnref(filterResource->getSkColorFilter());
179 decrementRefcountLocked((void*) filterResource);
180}
181
Chet Haase603f6de2012-09-14 15:31:25 -0700182void ResourceCache::decrementRefcountLocked(Layer* layerResource) {
183 decrementRefcountLocked((void*) layerResource);
184}
185
Chet Haase5a7e8282011-02-04 12:50:55 -0800186void ResourceCache::destructor(SkPath* resource) {
187 Mutex::Autolock _l(mLock);
Romain Guy58ecc202012-09-07 11:58:36 -0700188 destructorLocked(resource);
189}
190
191void ResourceCache::destructorLocked(SkPath* resource) {
Romain Guy8dcfd5e2012-07-20 11:36:03 -0700192 ssize_t index = mCache->indexOfKey(resource);
193 ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
Chet Haase5a7e8282011-02-04 12:50:55 -0800194 if (ref == NULL) {
195 // If we're not tracking this resource, just delete it
196 if (Caches::hasInstance()) {
197 Caches::getInstance().pathCache.removeDeferred(resource);
198 }
199 delete resource;
200 return;
201 }
202 ref->destroyed = true;
203 if (ref->refCount == 0) {
Romain Guy97dc9172012-09-23 17:46:45 -0700204 deleteResourceReferenceLocked(resource, ref);
Chet Haase5a7e8282011-02-04 12:50:55 -0800205 }
206}
207
Chet Haase5c13d892010-10-08 08:37:55 -0700208void ResourceCache::destructor(SkBitmap* resource) {
Chet Haasee7d22952010-11-11 16:30:16 -0800209 Mutex::Autolock _l(mLock);
Romain Guy58ecc202012-09-07 11:58:36 -0700210 destructorLocked(resource);
211}
212
213void ResourceCache::destructorLocked(SkBitmap* resource) {
Romain Guy8dcfd5e2012-07-20 11:36:03 -0700214 ssize_t index = mCache->indexOfKey(resource);
215 ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
Chet Haase5c13d892010-10-08 08:37:55 -0700216 if (ref == NULL) {
217 // If we're not tracking this resource, just delete it
218 if (Caches::hasInstance()) {
Romain Guyfe48f652010-11-11 15:36:56 -0800219 Caches::getInstance().textureCache.removeDeferred(resource);
Chet Haase5c13d892010-10-08 08:37:55 -0700220 }
221 delete resource;
222 return;
223 }
224 ref->destroyed = true;
225 if (ref->refCount == 0) {
Romain Guy97dc9172012-09-23 17:46:45 -0700226 deleteResourceReferenceLocked(resource, ref);
Chet Haase5c13d892010-10-08 08:37:55 -0700227 }
228}
229
Chet Haase5c13d892010-10-08 08:37:55 -0700230void ResourceCache::destructor(SkiaShader* resource) {
Chet Haasee7d22952010-11-11 16:30:16 -0800231 Mutex::Autolock _l(mLock);
Romain Guy58ecc202012-09-07 11:58:36 -0700232 destructorLocked(resource);
233}
234
235void ResourceCache::destructorLocked(SkiaShader* resource) {
Romain Guy8dcfd5e2012-07-20 11:36:03 -0700236 ssize_t index = mCache->indexOfKey(resource);
237 ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
Chet Haase5c13d892010-10-08 08:37:55 -0700238 if (ref == NULL) {
239 // If we're not tracking this resource, just delete it
Chet Haase5c13d892010-10-08 08:37:55 -0700240 delete resource;
241 return;
242 }
243 ref->destroyed = true;
244 if (ref->refCount == 0) {
Romain Guy97dc9172012-09-23 17:46:45 -0700245 deleteResourceReferenceLocked(resource, ref);
Chet Haase5c13d892010-10-08 08:37:55 -0700246 }
247}
248
Chet Haasead93c2b2010-10-22 16:17:12 -0700249void ResourceCache::destructor(SkiaColorFilter* resource) {
Chet Haasee7d22952010-11-11 16:30:16 -0800250 Mutex::Autolock _l(mLock);
Romain Guy58ecc202012-09-07 11:58:36 -0700251 destructorLocked(resource);
252}
253
254void ResourceCache::destructorLocked(SkiaColorFilter* resource) {
Romain Guy8dcfd5e2012-07-20 11:36:03 -0700255 ssize_t index = mCache->indexOfKey(resource);
256 ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
Chet Haasead93c2b2010-10-22 16:17:12 -0700257 if (ref == NULL) {
258 // If we're not tracking this resource, just delete it
259 delete resource;
260 return;
261 }
262 ref->destroyed = true;
263 if (ref->refCount == 0) {
Romain Guy97dc9172012-09-23 17:46:45 -0700264 deleteResourceReferenceLocked(resource, ref);
Chet Haasead93c2b2010-10-22 16:17:12 -0700265 }
266}
267
Romain Guy58ecc202012-09-07 11:58:36 -0700268void ResourceCache::recycle(SkBitmap* resource) {
269 Mutex::Autolock _l(mLock);
270 recycleLocked(resource);
271}
272
273void ResourceCache::recycleLocked(SkBitmap* resource) {
274 ssize_t index = mCache->indexOfKey(resource);
275 if (index < 0) {
276 // not tracking this resource; just recycle the pixel data
277 resource->setPixels(NULL, NULL);
278 return;
279 }
280 ResourceReference* ref = mCache->valueAt(index);
281 if (ref == NULL) {
282 // Should not get here - shouldn't get a call to recycle if we're not yet tracking it
283 return;
284 }
285 ref->recycled = true;
286 if (ref->refCount == 0) {
Romain Guy97dc9172012-09-23 17:46:45 -0700287 deleteResourceReferenceLocked(resource, ref);
Romain Guy58ecc202012-09-07 11:58:36 -0700288 }
289}
290
Chet Haasee7d22952010-11-11 16:30:16 -0800291/**
292 * This method should only be called while the mLock mutex is held (that mutex is grabbed
293 * by the various destructor() and recycle() methods which call this method).
294 */
Romain Guy97dc9172012-09-23 17:46:45 -0700295void ResourceCache::deleteResourceReferenceLocked(void* resource, ResourceReference* ref) {
Chet Haase5c13d892010-10-08 08:37:55 -0700296 if (ref->recycled && ref->resourceType == kBitmap) {
297 ((SkBitmap*) resource)->setPixels(NULL, NULL);
298 }
Chet Haase603f6de2012-09-14 15:31:25 -0700299 if (ref->destroyed || ref->resourceType == kLayer) {
Chet Haase5c13d892010-10-08 08:37:55 -0700300 switch (ref->resourceType) {
Romain Guyd586ad92011-06-22 16:14:36 -0700301 case kBitmap: {
302 SkBitmap* bitmap = (SkBitmap*) resource;
Chet Haase5c13d892010-10-08 08:37:55 -0700303 if (Caches::hasInstance()) {
Romain Guyfe48f652010-11-11 15:36:56 -0800304 Caches::getInstance().textureCache.removeDeferred(bitmap);
Chet Haase5c13d892010-10-08 08:37:55 -0700305 }
306 delete bitmap;
307 }
308 break;
Romain Guyd586ad92011-06-22 16:14:36 -0700309 case kPath: {
310 SkPath* path = (SkPath*) resource;
Chet Haase5a7e8282011-02-04 12:50:55 -0800311 if (Caches::hasInstance()) {
312 Caches::getInstance().pathCache.removeDeferred(path);
313 }
314 delete path;
315 }
316 break;
Romain Guyd586ad92011-06-22 16:14:36 -0700317 case kShader: {
318 SkiaShader* shader = (SkiaShader*) resource;
Chet Haase5c13d892010-10-08 08:37:55 -0700319 delete shader;
Chet Haasead93c2b2010-10-22 16:17:12 -0700320 }
321 break;
Romain Guyd586ad92011-06-22 16:14:36 -0700322 case kColorFilter: {
323 SkiaColorFilter* filter = (SkiaColorFilter*) resource;
Chet Haasead93c2b2010-10-22 16:17:12 -0700324 delete filter;
325 }
326 break;
Chet Haase603f6de2012-09-14 15:31:25 -0700327 case kLayer: {
Dave Burke56257af2012-09-25 20:30:09 -0700328 Layer* layer = (Layer*) resource;
Mathias Agopian54643d72012-09-25 21:30:22 -0700329 Caches::getInstance().deleteLayerDeferred(layer);
Chet Haase603f6de2012-09-14 15:31:25 -0700330 }
331 break;
Chet Haase5c13d892010-10-08 08:37:55 -0700332 }
333 }
334 mCache->removeItem(resource);
335 delete ref;
336}
337
338}; // namespace uirenderer
339}; // namespace android