blob: b0fbe65339bbe8839c47ba992e659718745e32e8 [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
70void ResourceCache::decrementRefcount(void* resource) {
71 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
72 if (ref == NULL) {
73 // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
74 return;
75 }
76 ref->refCount--;
77 if (ref->refCount == 0) {
78 deleteResourceReference(resource, ref);
79 }
80}
81
82void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
83 bitmapResource->pixelRef()->safeUnref();
84 bitmapResource->getColorTable()->safeUnref();
85 decrementRefcount((void*)bitmapResource);
86}
87
88void ResourceCache::decrementRefcount(SkiaShader* shaderResource) {
89 shaderResource->getSkShader()->safeUnref();
90 decrementRefcount((void*)shaderResource);
91}
92
93void ResourceCache::recycle(SkBitmap* resource) {
94 if (mCache->indexOfKey(resource) < 0) {
95 // not tracking this resource; just recycle the pixel data
96 resource->setPixels(NULL, NULL);
97 return;
98 }
99 recycle((void*) resource);
100}
101
102void ResourceCache::recycle(void* resource) {
103 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
104 if (ref == NULL) {
105 // Should not get here - shouldn't get a call to recycle if we're not yet tracking it
106 return;
107 }
108 ref->recycled = true;
109 if (ref->refCount == 0) {
110 deleteResourceReference(resource, ref);
111 }
112}
113
114void ResourceCache::destructor(SkBitmap* resource) {
115 ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
116 if (ref == NULL) {
117 // If we're not tracking this resource, just delete it
118 if (Caches::hasInstance()) {
119 Caches::getInstance().textureCache.remove(resource);
120 }
121 delete resource;
122 return;
123 }
124 ref->destroyed = true;
125 if (ref->refCount == 0) {
126 deleteResourceReference(resource, ref);
127 return;
128 }
129}
130
Chet Haase5c13d892010-10-08 08:37:55 -0700131void ResourceCache::destructor(SkiaShader* resource) {
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().gradientCache.remove(resource->getSkShader());
137 }
138 delete resource;
139 return;
140 }
141 ref->destroyed = true;
142 if (ref->refCount == 0) {
143 deleteResourceReference(resource, ref);
144 return;
145 }
146}
147
148void ResourceCache::deleteResourceReference(void* resource, ResourceReference* ref) {
149 if (ref->recycled && ref->resourceType == kBitmap) {
150 ((SkBitmap*) resource)->setPixels(NULL, NULL);
151 }
152 if (ref->destroyed) {
153 switch (ref->resourceType) {
154 case kBitmap:
155 {
156 SkBitmap* bitmap = (SkBitmap*)resource;
157 if (Caches::hasInstance()) {
158 Caches::getInstance().textureCache.remove(bitmap);
159 }
160 delete bitmap;
161 }
162 break;
Chet Haase5c13d892010-10-08 08:37:55 -0700163 case kShader:
164 SkiaShader* shader = (SkiaShader*)resource;
165 if (Caches::hasInstance()) {
166 Caches::getInstance().gradientCache.remove(shader->getSkShader());
167 }
168 delete shader;
169 break;
170 }
171 }
172 mCache->removeItem(resource);
173 delete ref;
174}
175
176}; // namespace uirenderer
177}; // namespace android