blob: 9ffad8839c785a1cd323026020af1f5ead7ffe40 [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);
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 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) {
Derek Sollenberger6062c592011-02-22 13:55:04 -050060 SkSafeRef(bitmapResource->pixelRef());
61 SkSafeRef(bitmapResource->getColorTable());
Chet Haase5c13d892010-10-08 08:37:55 -070062 incrementRefcount((void*)bitmapResource, kBitmap);
63}
64
Chet Haase5a7e8282011-02-04 12:50:55 -080065void ResourceCache::incrementRefcount(SkPath* pathResource) {
66 incrementRefcount((void*)pathResource, kPath);
67}
68
Chet Haase5c13d892010-10-08 08:37:55 -070069void ResourceCache::incrementRefcount(SkiaShader* shaderResource) {
Derek Sollenberger6062c592011-02-22 13:55:04 -050070 SkSafeRef(shaderResource->getSkShader());
Romain Guy43ccf462011-01-14 18:51:01 -080071 incrementRefcount((void*) shaderResource, kShader);
Chet Haase5c13d892010-10-08 08:37:55 -070072}
73
Chet Haasead93c2b2010-10-22 16:17:12 -070074void ResourceCache::incrementRefcount(SkiaColorFilter* filterResource) {
Derek Sollenberger6062c592011-02-22 13:55:04 -050075 SkSafeRef(filterResource->getSkColorFilter());
Romain Guy43ccf462011-01-14 18:51:01 -080076 incrementRefcount((void*) filterResource, kColorFilter);
Chet Haasead93c2b2010-10-22 16:17:12 -070077}
78
Chet Haase5c13d892010-10-08 08:37:55 -070079void ResourceCache::decrementRefcount(void* resource) {
Chet Haasee7d22952010-11-11 16:30:16 -080080 Mutex::Autolock _l(mLock);
Chet Haase5c13d892010-10-08 08:37:55 -070081 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
82 if (ref == NULL) {
83 // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
84 return;
85 }
86 ref->refCount--;
87 if (ref->refCount == 0) {
88 deleteResourceReference(resource, ref);
89 }
90}
91
92void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
Derek Sollenberger6062c592011-02-22 13:55:04 -050093 SkSafeUnref(bitmapResource->pixelRef());
94 SkSafeUnref(bitmapResource->getColorTable());
Romain Guy43ccf462011-01-14 18:51:01 -080095 decrementRefcount((void*) bitmapResource);
Chet Haase5c13d892010-10-08 08:37:55 -070096}
97
Chet Haase5a7e8282011-02-04 12:50:55 -080098void ResourceCache::decrementRefcount(SkPath* pathResource) {
99 decrementRefcount((void*) pathResource);
100}
101
Chet Haase5c13d892010-10-08 08:37:55 -0700102void ResourceCache::decrementRefcount(SkiaShader* shaderResource) {
Derek Sollenberger6062c592011-02-22 13:55:04 -0500103 SkSafeUnref(shaderResource->getSkShader());
Romain Guy43ccf462011-01-14 18:51:01 -0800104 decrementRefcount((void*) shaderResource);
Chet Haase5c13d892010-10-08 08:37:55 -0700105}
106
Chet Haasead93c2b2010-10-22 16:17:12 -0700107void ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) {
Derek Sollenberger6062c592011-02-22 13:55:04 -0500108 SkSafeUnref(filterResource->getSkColorFilter());
Romain Guy43ccf462011-01-14 18:51:01 -0800109 decrementRefcount((void*) filterResource);
Chet Haasead93c2b2010-10-22 16:17:12 -0700110}
111
Chet Haase5c13d892010-10-08 08:37:55 -0700112void ResourceCache::recycle(SkBitmap* resource) {
Chet Haasee7d22952010-11-11 16:30:16 -0800113 Mutex::Autolock _l(mLock);
Chet Haase5c13d892010-10-08 08:37:55 -0700114 if (mCache->indexOfKey(resource) < 0) {
115 // not tracking this resource; just recycle the pixel data
116 resource->setPixels(NULL, NULL);
117 return;
118 }
Chet Haase5c13d892010-10-08 08:37:55 -0700119 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
120 if (ref == NULL) {
121 // Should not get here - shouldn't get a call to recycle if we're not yet tracking it
122 return;
123 }
124 ref->recycled = true;
125 if (ref->refCount == 0) {
126 deleteResourceReference(resource, ref);
127 }
128}
129
Chet Haase5a7e8282011-02-04 12:50:55 -0800130void ResourceCache::destructor(SkPath* resource) {
131 Mutex::Autolock _l(mLock);
132 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
133 if (ref == NULL) {
134 // If we're not tracking this resource, just delete it
135 if (Caches::hasInstance()) {
136 Caches::getInstance().pathCache.removeDeferred(resource);
137 }
138 delete resource;
139 return;
140 }
141 ref->destroyed = true;
142 if (ref->refCount == 0) {
143 deleteResourceReference(resource, ref);
Chet Haase5a7e8282011-02-04 12:50:55 -0800144 }
145}
146
Chet Haase5c13d892010-10-08 08:37:55 -0700147void ResourceCache::destructor(SkBitmap* resource) {
Chet Haasee7d22952010-11-11 16:30:16 -0800148 Mutex::Autolock _l(mLock);
Chet Haase5c13d892010-10-08 08:37:55 -0700149 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
150 if (ref == NULL) {
151 // If we're not tracking this resource, just delete it
152 if (Caches::hasInstance()) {
Romain Guyfe48f652010-11-11 15:36:56 -0800153 Caches::getInstance().textureCache.removeDeferred(resource);
Chet Haase5c13d892010-10-08 08:37:55 -0700154 }
155 delete resource;
156 return;
157 }
158 ref->destroyed = true;
159 if (ref->refCount == 0) {
160 deleteResourceReference(resource, ref);
Chet Haase5c13d892010-10-08 08:37:55 -0700161 }
162}
163
Chet Haase5c13d892010-10-08 08:37:55 -0700164void ResourceCache::destructor(SkiaShader* resource) {
Chet Haasee7d22952010-11-11 16:30:16 -0800165 Mutex::Autolock _l(mLock);
Chet Haase5c13d892010-10-08 08:37:55 -0700166 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
167 if (ref == NULL) {
168 // If we're not tracking this resource, just delete it
Chet Haase5c13d892010-10-08 08:37:55 -0700169 delete resource;
170 return;
171 }
172 ref->destroyed = true;
173 if (ref->refCount == 0) {
174 deleteResourceReference(resource, ref);
Chet Haase5c13d892010-10-08 08:37:55 -0700175 }
176}
177
Chet Haasead93c2b2010-10-22 16:17:12 -0700178void ResourceCache::destructor(SkiaColorFilter* resource) {
Chet Haasee7d22952010-11-11 16:30:16 -0800179 Mutex::Autolock _l(mLock);
Chet Haasead93c2b2010-10-22 16:17:12 -0700180 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
181 if (ref == NULL) {
182 // If we're not tracking this resource, just delete it
183 delete resource;
184 return;
185 }
186 ref->destroyed = true;
187 if (ref->refCount == 0) {
188 deleteResourceReference(resource, ref);
Chet Haasead93c2b2010-10-22 16:17:12 -0700189 }
190}
191
Chet Haasee7d22952010-11-11 16:30:16 -0800192/**
193 * This method should only be called while the mLock mutex is held (that mutex is grabbed
194 * by the various destructor() and recycle() methods which call this method).
195 */
Chet Haase5c13d892010-10-08 08:37:55 -0700196void ResourceCache::deleteResourceReference(void* resource, ResourceReference* ref) {
197 if (ref->recycled && ref->resourceType == kBitmap) {
198 ((SkBitmap*) resource)->setPixels(NULL, NULL);
199 }
200 if (ref->destroyed) {
201 switch (ref->resourceType) {
Romain Guyd586ad92011-06-22 16:14:36 -0700202 case kBitmap: {
203 SkBitmap* bitmap = (SkBitmap*) resource;
Chet Haase5c13d892010-10-08 08:37:55 -0700204 if (Caches::hasInstance()) {
Romain Guyfe48f652010-11-11 15:36:56 -0800205 Caches::getInstance().textureCache.removeDeferred(bitmap);
Chet Haase5c13d892010-10-08 08:37:55 -0700206 }
207 delete bitmap;
208 }
209 break;
Romain Guyd586ad92011-06-22 16:14:36 -0700210 case kPath: {
211 SkPath* path = (SkPath*) resource;
Chet Haase5a7e8282011-02-04 12:50:55 -0800212 if (Caches::hasInstance()) {
213 Caches::getInstance().pathCache.removeDeferred(path);
214 }
215 delete path;
216 }
217 break;
Romain Guyd586ad92011-06-22 16:14:36 -0700218 case kShader: {
219 SkiaShader* shader = (SkiaShader*) resource;
Chet Haase5c13d892010-10-08 08:37:55 -0700220 delete shader;
Chet Haasead93c2b2010-10-22 16:17:12 -0700221 }
222 break;
Romain Guyd586ad92011-06-22 16:14:36 -0700223 case kColorFilter: {
224 SkiaColorFilter* filter = (SkiaColorFilter*) resource;
Chet Haasead93c2b2010-10-22 16:17:12 -0700225 delete filter;
226 }
227 break;
Chet Haase5c13d892010-10-08 08:37:55 -0700228 }
229 }
230 mCache->removeItem(resource);
231 delete ref;
232}
233
234}; // namespace uirenderer
235}; // namespace android