blob: 1c93ea644ef41d8aa0d8248dfe3cc6fe4a37b202 [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 Dubroye4ac2d62010-12-01 11:23:13 -080063 SkPixelRef* pixref = bitmapResource->pixelRef();
64 if (pixref) pixref->globalRef();
65
Chet Haase5c13d892010-10-08 08:37:55 -070066 bitmapResource->getColorTable()->safeRef();
67 incrementRefcount((void*)bitmapResource, kBitmap);
68}
69
Chet Haase5c13d892010-10-08 08:37:55 -070070void ResourceCache::incrementRefcount(SkiaShader* shaderResource) {
71 shaderResource->getSkShader()->safeRef();
72 incrementRefcount((void*)shaderResource, kShader);
73}
74
Chet Haasead93c2b2010-10-22 16:17:12 -070075void ResourceCache::incrementRefcount(SkiaColorFilter* filterResource) {
76 filterResource->getSkColorFilter()->safeRef();
77 incrementRefcount((void*)filterResource, kColorFilter);
78}
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);
Chet Haase5c13d892010-10-08 08:37:55 -070082 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
83 if (ref == NULL) {
84 // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
85 return;
86 }
87 ref->refCount--;
88 if (ref->refCount == 0) {
89 deleteResourceReference(resource, ref);
90 }
91}
92
93void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
Patrick Dubroye4ac2d62010-12-01 11:23:13 -080094 SkPixelRef* pixref = bitmapResource->pixelRef();
95 if (pixref) pixref->globalUnref();
96
Chet Haase5c13d892010-10-08 08:37:55 -070097 bitmapResource->getColorTable()->safeUnref();
98 decrementRefcount((void*)bitmapResource);
99}
100
101void ResourceCache::decrementRefcount(SkiaShader* shaderResource) {
102 shaderResource->getSkShader()->safeUnref();
103 decrementRefcount((void*)shaderResource);
104}
105
Chet Haasead93c2b2010-10-22 16:17:12 -0700106void ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) {
107 filterResource->getSkColorFilter()->safeUnref();
108 decrementRefcount((void*)filterResource);
109}
110
Chet Haase5c13d892010-10-08 08:37:55 -0700111void ResourceCache::recycle(SkBitmap* resource) {
Chet Haasee7d22952010-11-11 16:30:16 -0800112 Mutex::Autolock _l(mLock);
Chet Haase5c13d892010-10-08 08:37:55 -0700113 if (mCache->indexOfKey(resource) < 0) {
114 // not tracking this resource; just recycle the pixel data
115 resource->setPixels(NULL, NULL);
116 return;
117 }
Chet Haase5c13d892010-10-08 08:37:55 -0700118 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
119 if (ref == NULL) {
120 // Should not get here - shouldn't get a call to recycle if we're not yet tracking it
121 return;
122 }
123 ref->recycled = true;
124 if (ref->refCount == 0) {
125 deleteResourceReference(resource, ref);
126 }
127}
128
129void ResourceCache::destructor(SkBitmap* resource) {
Chet Haasee7d22952010-11-11 16:30:16 -0800130 Mutex::Autolock _l(mLock);
Chet Haase5c13d892010-10-08 08:37:55 -0700131 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
132 if (ref == NULL) {
133 // If we're not tracking this resource, just delete it
134 if (Caches::hasInstance()) {
Romain Guyfe48f652010-11-11 15:36:56 -0800135 Caches::getInstance().textureCache.removeDeferred(resource);
Chet Haase5c13d892010-10-08 08:37:55 -0700136 }
137 delete resource;
138 return;
139 }
140 ref->destroyed = true;
141 if (ref->refCount == 0) {
142 deleteResourceReference(resource, ref);
143 return;
144 }
145}
146
Chet Haase5c13d892010-10-08 08:37:55 -0700147void ResourceCache::destructor(SkiaShader* 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().gradientCache.removeDeferred(resource->getSkShader());
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);
161 return;
162 }
163}
164
Chet Haasead93c2b2010-10-22 16:17:12 -0700165void ResourceCache::destructor(SkiaColorFilter* resource) {
Chet Haasee7d22952010-11-11 16:30:16 -0800166 Mutex::Autolock _l(mLock);
Chet Haasead93c2b2010-10-22 16:17:12 -0700167 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
168 if (ref == NULL) {
169 // If we're not tracking this resource, just delete it
170 delete resource;
171 return;
172 }
173 ref->destroyed = true;
174 if (ref->refCount == 0) {
175 deleteResourceReference(resource, ref);
176 return;
177 }
178}
179
Chet Haasee7d22952010-11-11 16:30:16 -0800180/**
181 * This method should only be called while the mLock mutex is held (that mutex is grabbed
182 * by the various destructor() and recycle() methods which call this method).
183 */
Chet Haase5c13d892010-10-08 08:37:55 -0700184void ResourceCache::deleteResourceReference(void* resource, ResourceReference* ref) {
185 if (ref->recycled && ref->resourceType == kBitmap) {
186 ((SkBitmap*) resource)->setPixels(NULL, NULL);
187 }
188 if (ref->destroyed) {
189 switch (ref->resourceType) {
190 case kBitmap:
191 {
192 SkBitmap* bitmap = (SkBitmap*)resource;
193 if (Caches::hasInstance()) {
Romain Guyfe48f652010-11-11 15:36:56 -0800194 Caches::getInstance().textureCache.removeDeferred(bitmap);
Chet Haase5c13d892010-10-08 08:37:55 -0700195 }
196 delete bitmap;
197 }
198 break;
Chet Haase5c13d892010-10-08 08:37:55 -0700199 case kShader:
Chet Haasead93c2b2010-10-22 16:17:12 -0700200 {
Chet Haase5c13d892010-10-08 08:37:55 -0700201 SkiaShader* shader = (SkiaShader*)resource;
202 if (Caches::hasInstance()) {
Romain Guyfe48f652010-11-11 15:36:56 -0800203 Caches::getInstance().gradientCache.removeDeferred(shader->getSkShader());
Chet Haase5c13d892010-10-08 08:37:55 -0700204 }
205 delete shader;
Chet Haasead93c2b2010-10-22 16:17:12 -0700206 }
207 break;
208 case kColorFilter:
209 {
210 SkiaColorFilter* filter = (SkiaColorFilter*)resource;
211 delete filter;
212 }
213 break;
Chet Haase5c13d892010-10-08 08:37:55 -0700214 }
215 }
216 mCache->removeItem(resource);
217 delete ref;
218}
219
220}; // namespace uirenderer
221}; // namespace android