blob: 20b8d6ce5b83166820d08b2e135f03aceda88efd [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
65void ResourceCache::incrementRefcount(SkMatrix* matrixResource) {
66 incrementRefcount((void*)matrixResource, kMatrix);
67}
68
69void ResourceCache::incrementRefcount(SkPaint* paintResource) {
70 incrementRefcount((void*)paintResource, kPaint);
71}
72
73void ResourceCache::incrementRefcount(SkiaShader* shaderResource) {
74 shaderResource->getSkShader()->safeRef();
75 incrementRefcount((void*)shaderResource, kShader);
76}
77
78void ResourceCache::decrementRefcount(void* resource) {
79 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
80 if (ref == NULL) {
81 // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
82 return;
83 }
84 ref->refCount--;
85 if (ref->refCount == 0) {
86 deleteResourceReference(resource, ref);
87 }
88}
89
90void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
91 bitmapResource->pixelRef()->safeUnref();
92 bitmapResource->getColorTable()->safeUnref();
93 decrementRefcount((void*)bitmapResource);
94}
95
96void ResourceCache::decrementRefcount(SkiaShader* shaderResource) {
97 shaderResource->getSkShader()->safeUnref();
98 decrementRefcount((void*)shaderResource);
99}
100
101void ResourceCache::recycle(SkBitmap* resource) {
102 if (mCache->indexOfKey(resource) < 0) {
103 // not tracking this resource; just recycle the pixel data
104 resource->setPixels(NULL, NULL);
105 return;
106 }
107 recycle((void*) resource);
108}
109
110void ResourceCache::recycle(void* resource) {
111 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
112 if (ref == NULL) {
113 // Should not get here - shouldn't get a call to recycle if we're not yet tracking it
114 return;
115 }
116 ref->recycled = true;
117 if (ref->refCount == 0) {
118 deleteResourceReference(resource, ref);
119 }
120}
121
122void ResourceCache::destructor(SkBitmap* resource) {
123 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
124 if (ref == NULL) {
125 // If we're not tracking this resource, just delete it
126 if (Caches::hasInstance()) {
127 Caches::getInstance().textureCache.remove(resource);
128 }
129 delete resource;
130 return;
131 }
132 ref->destroyed = true;
133 if (ref->refCount == 0) {
134 deleteResourceReference(resource, ref);
135 return;
136 }
137}
138
139void ResourceCache::destructor(SkMatrix* resource) {
140 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
141 if (ref == NULL) {
142 // If we're not tracking this resource, just delete it
143 delete resource;
144 return;
145 }
146 ref->destroyed = true;
147 if (ref->refCount == 0) {
148 deleteResourceReference(resource, ref);
149 return;
150 }
151}
152
153void ResourceCache::destructor(SkPaint* resource) {
154 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
155 if (ref == NULL) {
156 // If we're not tracking this resource, just delete it
157 delete resource;
158 return;
159 }
160 ref->destroyed = true;
161 if (ref->refCount == 0) {
162 deleteResourceReference(resource, ref);
163 return;
164 }
165}
166
167void ResourceCache::destructor(SkiaShader* resource) {
168 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
169 if (ref == NULL) {
170 // If we're not tracking this resource, just delete it
171 if (Caches::hasInstance()) {
172 Caches::getInstance().gradientCache.remove(resource->getSkShader());
173 }
174 delete resource;
175 return;
176 }
177 ref->destroyed = true;
178 if (ref->refCount == 0) {
179 deleteResourceReference(resource, ref);
180 return;
181 }
182}
183
184void 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()) {
194 Caches::getInstance().textureCache.remove(bitmap);
195 }
196 delete bitmap;
197 }
198 break;
199 case kMatrix:
200 delete (SkMatrix*) resource;
201 break;
202 case kPaint:
203 delete (SkPaint*) resource;
204 break;
205 case kShader:
206 SkiaShader* shader = (SkiaShader*)resource;
207 if (Caches::hasInstance()) {
208 Caches::getInstance().gradientCache.remove(shader->getSkShader());
209 }
210 delete shader;
211 break;
212 }
213 }
214 mCache->removeItem(resource);
215 delete ref;
216}
217
218}; // namespace uirenderer
219}; // namespace android