blob: 2153a8bb89add455c8d59df39923f78a3fabbcda [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);
Romain Guy8dcfd5e2012-07-20 11:36:03 -070051 ssize_t index = mCache->indexOfKey(resource);
52 ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
Chet Haase5c13d892010-10-08 08:37:55 -070053 if (ref == NULL || mCache->size() == 0) {
54 ref = new ResourceReference(resourceType);
55 mCache->add(resource, ref);
56 }
57 ref->refCount++;
58}
59
60void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) {
Derek Sollenberger6062c592011-02-22 13:55:04 -050061 SkSafeRef(bitmapResource->pixelRef());
62 SkSafeRef(bitmapResource->getColorTable());
Romain Guy49c5fc02012-05-15 11:10:01 -070063 incrementRefcount((void*) bitmapResource, kBitmap);
Chet Haase5c13d892010-10-08 08:37:55 -070064}
65
Chet Haase5a7e8282011-02-04 12:50:55 -080066void ResourceCache::incrementRefcount(SkPath* pathResource) {
Romain Guy49c5fc02012-05-15 11:10:01 -070067 incrementRefcount((void*) pathResource, kPath);
Chet Haase5a7e8282011-02-04 12:50:55 -080068}
69
Chet Haase5c13d892010-10-08 08:37:55 -070070void ResourceCache::incrementRefcount(SkiaShader* shaderResource) {
Derek Sollenberger6062c592011-02-22 13:55:04 -050071 SkSafeRef(shaderResource->getSkShader());
Romain Guy43ccf462011-01-14 18:51:01 -080072 incrementRefcount((void*) shaderResource, kShader);
Chet Haase5c13d892010-10-08 08:37:55 -070073}
74
Chet Haasead93c2b2010-10-22 16:17:12 -070075void ResourceCache::incrementRefcount(SkiaColorFilter* filterResource) {
Derek Sollenberger6062c592011-02-22 13:55:04 -050076 SkSafeRef(filterResource->getSkColorFilter());
Romain Guy43ccf462011-01-14 18:51:01 -080077 incrementRefcount((void*) filterResource, kColorFilter);
Chet Haasead93c2b2010-10-22 16:17:12 -070078}
79
Chet Haase5c13d892010-10-08 08:37:55 -070080void ResourceCache::decrementRefcount(void* resource) {
Chet Haasee7d22952010-11-11 16:30:16 -080081 Mutex::Autolock _l(mLock);
Romain Guy8dcfd5e2012-07-20 11:36:03 -070082 ssize_t index = mCache->indexOfKey(resource);
83 ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
Chet Haase5c13d892010-10-08 08:37:55 -070084 if (ref == NULL) {
85 // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
86 return;
87 }
88 ref->refCount--;
89 if (ref->refCount == 0) {
90 deleteResourceReference(resource, ref);
91 }
92}
93
94void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
Derek Sollenberger6062c592011-02-22 13:55:04 -050095 SkSafeUnref(bitmapResource->pixelRef());
96 SkSafeUnref(bitmapResource->getColorTable());
Romain Guy43ccf462011-01-14 18:51:01 -080097 decrementRefcount((void*) bitmapResource);
Chet Haase5c13d892010-10-08 08:37:55 -070098}
99
Chet Haase5a7e8282011-02-04 12:50:55 -0800100void ResourceCache::decrementRefcount(SkPath* pathResource) {
101 decrementRefcount((void*) pathResource);
102}
103
Chet Haase5c13d892010-10-08 08:37:55 -0700104void ResourceCache::decrementRefcount(SkiaShader* shaderResource) {
Derek Sollenberger6062c592011-02-22 13:55:04 -0500105 SkSafeUnref(shaderResource->getSkShader());
Romain Guy43ccf462011-01-14 18:51:01 -0800106 decrementRefcount((void*) shaderResource);
Chet Haase5c13d892010-10-08 08:37:55 -0700107}
108
Chet Haasead93c2b2010-10-22 16:17:12 -0700109void ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) {
Derek Sollenberger6062c592011-02-22 13:55:04 -0500110 SkSafeUnref(filterResource->getSkColorFilter());
Romain Guy43ccf462011-01-14 18:51:01 -0800111 decrementRefcount((void*) filterResource);
Chet Haasead93c2b2010-10-22 16:17:12 -0700112}
113
Chet Haase5c13d892010-10-08 08:37:55 -0700114void ResourceCache::recycle(SkBitmap* resource) {
Chet Haasee7d22952010-11-11 16:30:16 -0800115 Mutex::Autolock _l(mLock);
Romain Guy8dcfd5e2012-07-20 11:36:03 -0700116 ssize_t index = mCache->indexOfKey(resource);
117 if (index < 0) {
Chet Haase5c13d892010-10-08 08:37:55 -0700118 // not tracking this resource; just recycle the pixel data
119 resource->setPixels(NULL, NULL);
120 return;
121 }
Romain Guy8dcfd5e2012-07-20 11:36:03 -0700122 ResourceReference* ref = mCache->valueAt(index);
Chet Haase5c13d892010-10-08 08:37:55 -0700123 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);
Romain Guy8dcfd5e2012-07-20 11:36:03 -0700135 ssize_t index = mCache->indexOfKey(resource);
136 ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
Chet Haase5a7e8282011-02-04 12:50:55 -0800137 if (ref == NULL) {
138 // If we're not tracking this resource, just delete it
139 if (Caches::hasInstance()) {
140 Caches::getInstance().pathCache.removeDeferred(resource);
141 }
142 delete resource;
143 return;
144 }
145 ref->destroyed = true;
146 if (ref->refCount == 0) {
147 deleteResourceReference(resource, ref);
Chet Haase5a7e8282011-02-04 12:50:55 -0800148 }
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);
Romain Guy8dcfd5e2012-07-20 11:36:03 -0700153 ssize_t index = mCache->indexOfKey(resource);
154 ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
Chet Haase5c13d892010-10-08 08:37:55 -0700155 if (ref == NULL) {
156 // If we're not tracking this resource, just delete it
157 if (Caches::hasInstance()) {
Romain Guyfe48f652010-11-11 15:36:56 -0800158 Caches::getInstance().textureCache.removeDeferred(resource);
Chet Haase5c13d892010-10-08 08:37:55 -0700159 }
160 delete resource;
161 return;
162 }
163 ref->destroyed = true;
164 if (ref->refCount == 0) {
165 deleteResourceReference(resource, ref);
Chet Haase5c13d892010-10-08 08:37:55 -0700166 }
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);
Romain Guy8dcfd5e2012-07-20 11:36:03 -0700171 ssize_t index = mCache->indexOfKey(resource);
172 ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
Chet Haase5c13d892010-10-08 08:37:55 -0700173 if (ref == NULL) {
174 // If we're not tracking this resource, just delete it
Chet Haase5c13d892010-10-08 08:37:55 -0700175 delete resource;
176 return;
177 }
178 ref->destroyed = true;
179 if (ref->refCount == 0) {
180 deleteResourceReference(resource, ref);
Chet Haase5c13d892010-10-08 08:37:55 -0700181 }
182}
183
Chet Haasead93c2b2010-10-22 16:17:12 -0700184void ResourceCache::destructor(SkiaColorFilter* resource) {
Chet Haasee7d22952010-11-11 16:30:16 -0800185 Mutex::Autolock _l(mLock);
Romain Guy8dcfd5e2012-07-20 11:36:03 -0700186 ssize_t index = mCache->indexOfKey(resource);
187 ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
Chet Haasead93c2b2010-10-22 16:17:12 -0700188 if (ref == NULL) {
189 // If we're not tracking this resource, just delete it
190 delete resource;
191 return;
192 }
193 ref->destroyed = true;
194 if (ref->refCount == 0) {
195 deleteResourceReference(resource, ref);
Chet Haasead93c2b2010-10-22 16:17:12 -0700196 }
197}
198
Chet Haasee7d22952010-11-11 16:30:16 -0800199/**
200 * This method should only be called while the mLock mutex is held (that mutex is grabbed
201 * by the various destructor() and recycle() methods which call this method).
202 */
Chet Haase5c13d892010-10-08 08:37:55 -0700203void ResourceCache::deleteResourceReference(void* resource, ResourceReference* ref) {
204 if (ref->recycled && ref->resourceType == kBitmap) {
205 ((SkBitmap*) resource)->setPixels(NULL, NULL);
206 }
207 if (ref->destroyed) {
208 switch (ref->resourceType) {
Romain Guyd586ad92011-06-22 16:14:36 -0700209 case kBitmap: {
210 SkBitmap* bitmap = (SkBitmap*) resource;
Chet Haase5c13d892010-10-08 08:37:55 -0700211 if (Caches::hasInstance()) {
Romain Guyfe48f652010-11-11 15:36:56 -0800212 Caches::getInstance().textureCache.removeDeferred(bitmap);
Chet Haase5c13d892010-10-08 08:37:55 -0700213 }
214 delete bitmap;
215 }
216 break;
Romain Guyd586ad92011-06-22 16:14:36 -0700217 case kPath: {
218 SkPath* path = (SkPath*) resource;
Chet Haase5a7e8282011-02-04 12:50:55 -0800219 if (Caches::hasInstance()) {
220 Caches::getInstance().pathCache.removeDeferred(path);
221 }
222 delete path;
223 }
224 break;
Romain Guyd586ad92011-06-22 16:14:36 -0700225 case kShader: {
226 SkiaShader* shader = (SkiaShader*) resource;
Chet Haase5c13d892010-10-08 08:37:55 -0700227 delete shader;
Chet Haasead93c2b2010-10-22 16:17:12 -0700228 }
229 break;
Romain Guyd586ad92011-06-22 16:14:36 -0700230 case kColorFilter: {
231 SkiaColorFilter* filter = (SkiaColorFilter*) resource;
Chet Haasead93c2b2010-10-22 16:17:12 -0700232 delete filter;
233 }
234 break;
Chet Haase5c13d892010-10-08 08:37:55 -0700235 }
236 }
237 mCache->removeItem(resource);
238 delete ref;
239}
240
241}; // namespace uirenderer
242}; // namespace android