blob: 87fdfb5212a1314a778a1ba87db4d14771f46396 [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() {
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() {
Chet Haasee7d22952010-11-11 16:30:16 -080040 Mutex::Autolock _l(mLock);
Chet Haase5c13d892010-10-08 08:37:55 -070041 mCache = new KeyedVector<void *, ResourceReference *>();
42}
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
49void ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) {
Chet Haasee7d22952010-11-11 16:30:16 -080050 Mutex::Autolock _l(mLock);
Chet Haase5c13d892010-10-08 08:37:55 -070051 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
62void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) {
Patrick Dubroyf890fab2010-12-19 16:47:17 -080063 bitmapResource->pixelRef()->safeRef();
Chet Haase5c13d892010-10-08 08:37:55 -070064 bitmapResource->getColorTable()->safeRef();
65 incrementRefcount((void*)bitmapResource, kBitmap);
66}
67
Chet Haase5a7e8282011-02-04 12:50:55 -080068void ResourceCache::incrementRefcount(SkPath* pathResource) {
69 incrementRefcount((void*)pathResource, kPath);
70}
71
Chet Haase5c13d892010-10-08 08:37:55 -070072void ResourceCache::incrementRefcount(SkiaShader* shaderResource) {
73 shaderResource->getSkShader()->safeRef();
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) {
78 filterResource->getSkColorFilter()->safeRef();
Romain Guy43ccf462011-01-14 18:51:01 -080079 incrementRefcount((void*) filterResource, kColorFilter);
Chet Haasead93c2b2010-10-22 16:17:12 -070080}
81
Chet Haase5c13d892010-10-08 08:37:55 -070082void ResourceCache::decrementRefcount(void* resource) {
Chet Haasee7d22952010-11-11 16:30:16 -080083 Mutex::Autolock _l(mLock);
Chet Haase5c13d892010-10-08 08:37:55 -070084 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
95void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
Patrick Dubroyf890fab2010-12-19 16:47:17 -080096 bitmapResource->pixelRef()->safeUnref();
Chet Haase5c13d892010-10-08 08:37:55 -070097 bitmapResource->getColorTable()->safeUnref();
Romain Guy43ccf462011-01-14 18:51:01 -080098 decrementRefcount((void*) bitmapResource);
Chet Haase5c13d892010-10-08 08:37:55 -070099}
100
Chet Haase5a7e8282011-02-04 12:50:55 -0800101void ResourceCache::decrementRefcount(SkPath* pathResource) {
102 decrementRefcount((void*) pathResource);
103}
104
Chet Haase5c13d892010-10-08 08:37:55 -0700105void ResourceCache::decrementRefcount(SkiaShader* shaderResource) {
106 shaderResource->getSkShader()->safeUnref();
Romain Guy43ccf462011-01-14 18:51:01 -0800107 decrementRefcount((void*) shaderResource);
Chet Haase5c13d892010-10-08 08:37:55 -0700108}
109
Chet Haasead93c2b2010-10-22 16:17:12 -0700110void ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) {
111 filterResource->getSkColorFilter()->safeUnref();
Romain Guy43ccf462011-01-14 18:51:01 -0800112 decrementRefcount((void*) filterResource);
Chet Haasead93c2b2010-10-22 16:17:12 -0700113}
114
Chet Haase5c13d892010-10-08 08:37:55 -0700115void ResourceCache::recycle(SkBitmap* resource) {
Chet Haasee7d22952010-11-11 16:30:16 -0800116 Mutex::Autolock _l(mLock);
Chet Haase5c13d892010-10-08 08:37:55 -0700117 if (mCache->indexOfKey(resource) < 0) {
118 // not tracking this resource; just recycle the pixel data
119 resource->setPixels(NULL, NULL);
120 return;
121 }
Chet Haase5c13d892010-10-08 08:37:55 -0700122 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 Haase5a7e8282011-02-04 12:50:55 -0800133void 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 Haase5c13d892010-10-08 08:37:55 -0700151void ResourceCache::destructor(SkBitmap* resource) {
Chet Haasee7d22952010-11-11 16:30:16 -0800152 Mutex::Autolock _l(mLock);
Chet Haase5c13d892010-10-08 08:37:55 -0700153 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 Guyfe48f652010-11-11 15:36:56 -0800157 Caches::getInstance().textureCache.removeDeferred(resource);
Chet Haase5c13d892010-10-08 08:37:55 -0700158 }
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 Haase5c13d892010-10-08 08:37:55 -0700169void ResourceCache::destructor(SkiaShader* resource) {
Chet Haasee7d22952010-11-11 16:30:16 -0800170 Mutex::Autolock _l(mLock);
Chet Haase5c13d892010-10-08 08:37:55 -0700171 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 Guyfe48f652010-11-11 15:36:56 -0800175 Caches::getInstance().gradientCache.removeDeferred(resource->getSkShader());
Chet Haase5c13d892010-10-08 08:37:55 -0700176 }
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 Haasead93c2b2010-10-22 16:17:12 -0700187void ResourceCache::destructor(SkiaColorFilter* resource) {
Chet Haasee7d22952010-11-11 16:30:16 -0800188 Mutex::Autolock _l(mLock);
Chet Haasead93c2b2010-10-22 16:17:12 -0700189 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 Haasee7d22952010-11-11 16:30:16 -0800202/**
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 Haase5c13d892010-10-08 08:37:55 -0700206void 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 Guyfe48f652010-11-11 15:36:56 -0800216 Caches::getInstance().textureCache.removeDeferred(bitmap);
Chet Haase5c13d892010-10-08 08:37:55 -0700217 }
218 delete bitmap;
219 }
220 break;
Chet Haase5a7e8282011-02-04 12:50:55 -0800221 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 Haase5c13d892010-10-08 08:37:55 -0700230 case kShader:
Chet Haasead93c2b2010-10-22 16:17:12 -0700231 {
Chet Haase5c13d892010-10-08 08:37:55 -0700232 SkiaShader* shader = (SkiaShader*)resource;
233 if (Caches::hasInstance()) {
Romain Guyfe48f652010-11-11 15:36:56 -0800234 Caches::getInstance().gradientCache.removeDeferred(shader->getSkShader());
Chet Haase5c13d892010-10-08 08:37:55 -0700235 }
236 delete shader;
Chet Haasead93c2b2010-10-22 16:17:12 -0700237 }
238 break;
239 case kColorFilter:
240 {
241 SkiaColorFilter* filter = (SkiaColorFilter*)resource;
242 delete filter;
243 }
244 break;
Chet Haase5c13d892010-10-08 08:37:55 -0700245 }
246 }
247 mCache->removeItem(resource);
248 delete ref;
249}
250
251}; // namespace uirenderer
252}; // namespace android