blob: 47c5d489b3e8b27c231d094cd30a3e53f5b80574 [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() {
40 mCache = new KeyedVector<void *, ResourceReference *>();
41}
42
43ResourceCache::~ResourceCache() {
44 delete mCache;
45}
46
47void ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) {
48 for (size_t i = 0; i < mCache->size(); ++i) {
49 void* ref = mCache->valueAt(i);
50 }
51 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) {
60 bitmapResource->pixelRef()->safeRef();
61 bitmapResource->getColorTable()->safeRef();
62 incrementRefcount((void*)bitmapResource, kBitmap);
63}
64
Chet Haase5c13d892010-10-08 08:37:55 -070065void ResourceCache::incrementRefcount(SkiaShader* shaderResource) {
66 shaderResource->getSkShader()->safeRef();
67 incrementRefcount((void*)shaderResource, kShader);
68}
69
Chet Haasead93c2b2010-10-22 16:17:12 -070070void ResourceCache::incrementRefcount(SkiaColorFilter* filterResource) {
71 filterResource->getSkColorFilter()->safeRef();
72 incrementRefcount((void*)filterResource, kColorFilter);
73}
74
Chet Haase5c13d892010-10-08 08:37:55 -070075void ResourceCache::decrementRefcount(void* resource) {
76 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
77 if (ref == NULL) {
78 // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
79 return;
80 }
81 ref->refCount--;
82 if (ref->refCount == 0) {
83 deleteResourceReference(resource, ref);
84 }
85}
86
87void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
88 bitmapResource->pixelRef()->safeUnref();
89 bitmapResource->getColorTable()->safeUnref();
90 decrementRefcount((void*)bitmapResource);
91}
92
93void ResourceCache::decrementRefcount(SkiaShader* shaderResource) {
94 shaderResource->getSkShader()->safeUnref();
95 decrementRefcount((void*)shaderResource);
96}
97
Chet Haasead93c2b2010-10-22 16:17:12 -070098void ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) {
99 filterResource->getSkColorFilter()->safeUnref();
100 decrementRefcount((void*)filterResource);
101}
102
Chet Haase5c13d892010-10-08 08:37:55 -0700103void ResourceCache::recycle(SkBitmap* resource) {
104 if (mCache->indexOfKey(resource) < 0) {
105 // not tracking this resource; just recycle the pixel data
106 resource->setPixels(NULL, NULL);
107 return;
108 }
109 recycle((void*) resource);
110}
111
112void ResourceCache::recycle(void* resource) {
113 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
114 if (ref == NULL) {
115 // Should not get here - shouldn't get a call to recycle if we're not yet tracking it
116 return;
117 }
118 ref->recycled = true;
119 if (ref->refCount == 0) {
120 deleteResourceReference(resource, ref);
121 }
122}
123
124void ResourceCache::destructor(SkBitmap* resource) {
125 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
126 if (ref == NULL) {
127 // If we're not tracking this resource, just delete it
128 if (Caches::hasInstance()) {
129 Caches::getInstance().textureCache.remove(resource);
130 }
131 delete resource;
132 return;
133 }
134 ref->destroyed = true;
135 if (ref->refCount == 0) {
136 deleteResourceReference(resource, ref);
137 return;
138 }
139}
140
Chet Haase5c13d892010-10-08 08:37:55 -0700141void ResourceCache::destructor(SkiaShader* resource) {
142 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
143 if (ref == NULL) {
144 // If we're not tracking this resource, just delete it
145 if (Caches::hasInstance()) {
146 Caches::getInstance().gradientCache.remove(resource->getSkShader());
147 }
148 delete resource;
149 return;
150 }
151 ref->destroyed = true;
152 if (ref->refCount == 0) {
153 deleteResourceReference(resource, ref);
154 return;
155 }
156}
157
Chet Haasead93c2b2010-10-22 16:17:12 -0700158void ResourceCache::destructor(SkiaColorFilter* resource) {
159 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
160 if (ref == NULL) {
161 // If we're not tracking this resource, just delete it
162 delete resource;
163 return;
164 }
165 ref->destroyed = true;
166 if (ref->refCount == 0) {
167 deleteResourceReference(resource, ref);
168 return;
169 }
170}
171
Chet Haase5c13d892010-10-08 08:37:55 -0700172void ResourceCache::deleteResourceReference(void* resource, ResourceReference* ref) {
173 if (ref->recycled && ref->resourceType == kBitmap) {
174 ((SkBitmap*) resource)->setPixels(NULL, NULL);
175 }
176 if (ref->destroyed) {
177 switch (ref->resourceType) {
178 case kBitmap:
179 {
180 SkBitmap* bitmap = (SkBitmap*)resource;
181 if (Caches::hasInstance()) {
182 Caches::getInstance().textureCache.remove(bitmap);
183 }
184 delete bitmap;
185 }
186 break;
Chet Haase5c13d892010-10-08 08:37:55 -0700187 case kShader:
Chet Haasead93c2b2010-10-22 16:17:12 -0700188 {
Chet Haase5c13d892010-10-08 08:37:55 -0700189 SkiaShader* shader = (SkiaShader*)resource;
190 if (Caches::hasInstance()) {
191 Caches::getInstance().gradientCache.remove(shader->getSkShader());
192 }
193 delete shader;
Chet Haasead93c2b2010-10-22 16:17:12 -0700194 }
195 break;
196 case kColorFilter:
197 {
198 SkiaColorFilter* filter = (SkiaColorFilter*)resource;
199 delete filter;
200 }
201 break;
Chet Haase5c13d892010-10-08 08:37:55 -0700202 }
203 }
204 mCache->removeItem(resource);
205 delete ref;
206}
207
208}; // namespace uirenderer
209}; // namespace android