Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: src/gpu/GrResourceCache.cpp

Issue 705413002: Remove GrResourceKey from GrResourceCache (Closed) Base URL: https://skia.googlesource.com/skia.git@content
Patch Set: update Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2010 Google Inc. 3 * Copyright 2010 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "GrResourceCache.h" 9 #include "GrResourceCache.h"
10 #include "GrGpuResource.h" 10 #include "GrGpuResource.h"
(...skipping 17 matching lines...) Expand all
28 int32_t type = sk_atomic_inc(&gNextType); 28 int32_t type = sk_atomic_inc(&gNextType);
29 if (type >= (1 << 8 * sizeof(ResourceType))) { 29 if (type >= (1 << 8 * sizeof(ResourceType))) {
30 SkFAIL("Too many Resource Types"); 30 SkFAIL("Too many Resource Types");
31 } 31 }
32 32
33 return static_cast<ResourceType>(type); 33 return static_cast<ResourceType>(type);
34 } 34 }
35 35
36 /////////////////////////////////////////////////////////////////////////////// 36 ///////////////////////////////////////////////////////////////////////////////
37 37
38 GrResourceCacheEntry::GrResourceCacheEntry(GrResourceCache* resourceCache, 38 GrResourceCacheEntry::GrResourceCacheEntry(GrResourceCache* resourceCache, GrGpu Resource* resource)
39 const GrResourceKey& key,
40 GrGpuResource* resource)
41 : fResourceCache(resourceCache), 39 : fResourceCache(resourceCache),
42 fKey(key),
43 fResource(resource), 40 fResource(resource),
44 fCachedSize(resource->gpuMemorySize()), 41 fCachedSize(resource->gpuMemorySize()) {
45 fIsExclusive(false) {
46 // we assume ownership of the resource, and will unref it when we die 42 // we assume ownership of the resource, and will unref it when we die
47 SkASSERT(resource); 43 SkASSERT(resource);
48 resource->ref(); 44 resource->ref();
49 } 45 }
50 46
51 GrResourceCacheEntry::~GrResourceCacheEntry() { 47 GrResourceCacheEntry::~GrResourceCacheEntry() {
52 // We're relying on having the cache entry to remove this from GrResourceCac he2's content hash. 48 // We're relying on having the cache entry to remove this from GrResourceCac he2's content hash.
53 // fResource->setCacheEntry(NULL); 49 // fResource->setCacheEntry(NULL);
54 fResource->unref(); 50 fResource->unref();
55 } 51 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 92
97 GrResourceCache::~GrResourceCache() { 93 GrResourceCache::~GrResourceCache() {
98 GrAutoResourceCacheValidate atcv(this); 94 GrAutoResourceCacheValidate atcv(this);
99 95
100 EntryList::Iter iter; 96 EntryList::Iter iter;
101 97
102 // Unlike the removeAll, here we really remove everything, including locked resources. 98 // Unlike the removeAll, here we really remove everything, including locked resources.
103 while (GrResourceCacheEntry* entry = fList.head()) { 99 while (GrResourceCacheEntry* entry = fList.head()) {
104 GrAutoResourceCacheValidate atcv(this); 100 GrAutoResourceCacheValidate atcv(this);
105 101
106 // remove from our cache
107 fCache.remove(entry->fKey, entry);
108
109 // remove from our llist 102 // remove from our llist
110 this->internalDetach(entry); 103 this->internalDetach(entry);
111 104
112 delete entry; 105 delete entry;
113 } 106 }
114 } 107 }
115 108
116 void GrResourceCache::getLimits(int* maxResources, size_t* maxResourceBytes) con st{ 109 void GrResourceCache::getLimits(int* maxResources, size_t* maxResourceBytes) con st{
117 if (maxResources) { 110 if (maxResources) {
118 *maxResources = fMaxCount; 111 *maxResources = fMaxCount;
(...skipping 29 matching lines...) Expand all
148 #if GR_CACHE_STATS 141 #if GR_CACHE_STATS
149 if (fHighWaterEntryCount < fEntryCount) { 142 if (fHighWaterEntryCount < fEntryCount) {
150 fHighWaterEntryCount = fEntryCount; 143 fHighWaterEntryCount = fEntryCount;
151 } 144 }
152 if (fHighWaterEntryBytes < fEntryBytes) { 145 if (fHighWaterEntryBytes < fEntryBytes) {
153 fHighWaterEntryBytes = fEntryBytes; 146 fHighWaterEntryBytes = fEntryBytes;
154 } 147 }
155 #endif 148 #endif
156 } 149 }
157 150
158 // This functor just searches for an entry with only a single ref (from
159 // the texture cache itself). Presumably in this situation no one else
160 // is relying on the texture.
161 class GrTFindUnreffedFunctor {
162 public:
163 bool operator()(const GrResourceCacheEntry* entry) const {
164 return entry->resource()->isPurgable();
165 }
166 };
167
168 151
169 void GrResourceCache::makeResourceMRU(GrGpuResource* resource) { 152 void GrResourceCache::makeResourceMRU(GrGpuResource* resource) {
170 GrResourceCacheEntry* entry = resource->getCacheEntry(); 153 GrResourceCacheEntry* entry = resource->getCacheEntry();
171 if (entry) { 154 if (entry) {
172 this->internalDetach(entry); 155 this->internalDetach(entry);
173 this->attachToHead(entry); 156 this->attachToHead(entry);
174 } 157 }
175 } 158 }
176 159
177 void GrResourceCache::notifyPurgable(const GrGpuResource* resource) { 160 void GrResourceCache::notifyPurgable(const GrGpuResource* resource) {
178 // Remove scratch textures from the cache the moment they become purgeable i f 161 // Remove scratch textures from the cache the moment they become purgeable i f
179 // scratch texture reuse is turned off. 162 // scratch texture reuse is turned off.
180 SkASSERT(resource->getCacheEntry()); 163 SkASSERT(resource->getCacheEntry());
181 if (resource->getCacheEntry()->key().getResourceType() == GrTexturePriv::Res ourceType() && 164 if (resource->isScratch()) {
182 resource->getCacheEntry()->key().isScratch() && 165 const GrResourceKey& key = resource->getScratchKey();
183 !fCaps->reuseScratchTextures() && 166 if (key.getResourceType() == GrTexturePriv::ResourceType() &&
184 !(static_cast<const GrSurface*>(resource)->desc().fFlags & kRenderTarget _GrSurfaceFlag)) { 167 !fCaps->reuseScratchTextures() &&
185 this->deleteResource(resource->getCacheEntry()); 168 !(static_cast<const GrSurface*>(resource)->desc().fFlags & kRenderTa rget_GrSurfaceFlag)) {
169 this->deleteResource(resource->getCacheEntry());
170 }
186 } 171 }
187 } 172 }
188 173
189 bool GrResourceCache::addResource(const GrResourceKey& key, GrGpuResource* resou rce) { 174 bool GrResourceCache::addResource(const GrResourceKey& key, GrGpuResource* resou rce) {
190 if (NULL != resource->getCacheEntry()) { 175 if (NULL != resource->getCacheEntry()) {
191 return false; 176 return false;
192 } 177 }
178
179 if (key.isScratch()) {
180 SkASSERT(resource->isScratch() && key == resource->getScratchKey());
181 } else {
182 if (!resource->setContentKey(key)) {
183 return false;
184 }
185 }
193 186
194 // we don't expect to create new resources during a purge. In theory 187 // we don't expect to create new resources during a purge. In theory
195 // this could cause purgeAsNeeded() into an infinite loop (e.g. 188 // this could cause purgeAsNeeded() into an infinite loop (e.g.
196 // each resource destroyed creates and locks 2 resources and 189 // each resource destroyed creates and locks 2 resources and
197 // unlocks 1 thereby causing a new purge). 190 // unlocks 1 thereby causing a new purge).
198 SkASSERT(!fPurging); 191 SkASSERT(!fPurging);
199 GrAutoResourceCacheValidate atcv(this); 192 GrAutoResourceCacheValidate atcv(this);
200 193
201 GrResourceCacheEntry* entry = SkNEW_ARGS(GrResourceCacheEntry, (this, key, r esource)); 194 GrResourceCacheEntry* entry = SkNEW_ARGS(GrResourceCacheEntry, (this, resour ce));
202 if (!resource->setCacheEntry(entry)) { 195 resource->setCacheEntry(entry);
203 SkDELETE(entry);
204 this->purgeAsNeeded();
205 return false;
206 }
207 196
208 this->attachToHead(entry); 197 this->attachToHead(entry);
209 fCache.insert(key, entry);
210 this->purgeAsNeeded(); 198 this->purgeAsNeeded();
211 return true; 199 return true;
212 } 200 }
213 201
214 void GrResourceCache::didIncreaseResourceSize(const GrResourceCacheEntry* entry, size_t amountInc) { 202 void GrResourceCache::didIncreaseResourceSize(const GrResourceCacheEntry* entry, size_t amountInc) {
215 fEntryBytes += amountInc; 203 fEntryBytes += amountInc;
216 this->purgeAsNeeded(); 204 this->purgeAsNeeded();
217 } 205 }
218 206
219 void GrResourceCache::didDecreaseResourceSize(const GrResourceCacheEntry* entry, size_t amountDec) { 207 void GrResourceCache::didDecreaseResourceSize(const GrResourceCacheEntry* entry, size_t amountDec) {
(...skipping 17 matching lines...) Expand all
237 * for incoming resources (e.g., GrContext is about to add 10MB split between 225 * for incoming resources (e.g., GrContext is about to add 10MB split between
238 * 10 textures). 226 * 10 textures).
239 */ 227 */
240 void GrResourceCache::purgeAsNeeded(int extraCount, size_t extraBytes) { 228 void GrResourceCache::purgeAsNeeded(int extraCount, size_t extraBytes) {
241 if (fPurging) { 229 if (fPurging) {
242 return; 230 return;
243 } 231 }
244 232
245 fPurging = true; 233 fPurging = true;
246 234
247 this->purgeInvalidated();
248
249 this->internalPurge(extraCount, extraBytes); 235 this->internalPurge(extraCount, extraBytes);
250 if (((fEntryCount+extraCount) > fMaxCount || 236 if (((fEntryCount+extraCount) > fMaxCount ||
251 (fEntryBytes+extraBytes) > fMaxBytes) && 237 (fEntryBytes+extraBytes) > fMaxBytes) &&
252 fOverbudgetCB) { 238 fOverbudgetCB) {
253 // Despite the purge we're still over budget. See if Ganesh can 239 // Despite the purge we're still over budget. See if Ganesh can
254 // release some resources and purge again. 240 // release some resources and purge again.
255 if ((*fOverbudgetCB)(fOverbudgetData)) { 241 if ((*fOverbudgetCB)(fOverbudgetData)) {
256 this->internalPurge(extraCount, extraBytes); 242 this->internalPurge(extraCount, extraBytes);
257 } 243 }
258 } 244 }
259 245
260 fPurging = false; 246 fPurging = false;
261 } 247 }
262 248
263 void GrResourceCache::purgeInvalidated() { 249 void GrResourceCache::purgeInvalidated() {
264 SkTDArray<GrResourceInvalidatedMessage> invalidated; 250 // TODO: Implement this in GrResourceCache2.
bsalomon 2014/11/10 18:38:51 I won't land this until there is a follow up CL re
265 fInvalidationInbox.poll(&invalidated);
266
267 for (int i = 0; i < invalidated.count(); i++) {
268 while (GrResourceCacheEntry* entry = fCache.find(invalidated[i].key, GrT FindUnreffedFunctor())) {
269 this->deleteResource(entry);
270 }
271 }
272 } 251 }
273 252
274 void GrResourceCache::deleteResource(GrResourceCacheEntry* entry) { 253 void GrResourceCache::deleteResource(GrResourceCacheEntry* entry) {
275 SkASSERT(entry->fResource->isPurgable()); 254 SkASSERT(entry->fResource->isPurgable());
276
277 // remove from our cache
278 fCache.remove(entry->key(), entry);
279
280 // remove from our llist 255 // remove from our llist
281 this->internalDetach(entry); 256 this->internalDetach(entry);
282 delete entry; 257 delete entry;
283 } 258 }
284 259
285 void GrResourceCache::internalPurge(int extraCount, size_t extraBytes) { 260 void GrResourceCache::internalPurge(int extraCount, size_t extraBytes) {
286 SkASSERT(fPurging); 261 SkASSERT(fPurging);
287 262
288 bool withinBudget = false; 263 bool withinBudget = false;
289 bool changed = false; 264 bool changed = false;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 // we can have one GrCacheable holding a lock on another 301 // we can have one GrCacheable holding a lock on another
327 // so we don't want to just do a simple loop kicking each 302 // so we don't want to just do a simple loop kicking each
328 // entry out. Instead change the budget and purge. 303 // entry out. Instead change the budget and purge.
329 304
330 size_t savedMaxBytes = fMaxBytes; 305 size_t savedMaxBytes = fMaxBytes;
331 int savedMaxCount = fMaxCount; 306 int savedMaxCount = fMaxCount;
332 fMaxBytes = (size_t) -1; 307 fMaxBytes = (size_t) -1;
333 fMaxCount = 0; 308 fMaxCount = 0;
334 this->purgeAsNeeded(); 309 this->purgeAsNeeded();
335 310
336 #ifdef SK_DEBUG
337 if (!fCache.count()) {
338 SkASSERT(fList.isEmpty());
339 }
340 #endif
341
342 fMaxBytes = savedMaxBytes; 311 fMaxBytes = savedMaxBytes;
343 fMaxCount = savedMaxCount; 312 fMaxCount = savedMaxCount;
344 } 313 }
345 314
346 /////////////////////////////////////////////////////////////////////////////// 315 ///////////////////////////////////////////////////////////////////////////////
347 316
348 #ifdef SK_DEBUG 317 #ifdef SK_DEBUG
349 size_t GrResourceCache::countBytes(const EntryList& list) { 318 size_t GrResourceCache::countBytes(const EntryList& list) {
350 size_t bytes = 0; 319 size_t bytes = 0;
351 320
352 EntryList::Iter iter; 321 EntryList::Iter iter;
353 322
354 const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(list), 323 const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(list),
355 EntryList::Iter::kTail_IterSta rt); 324 EntryList::Iter::kTail_IterSta rt);
356 325
357 for ( ; entry; entry = iter.prev()) { 326 for ( ; entry; entry = iter.prev()) {
358 bytes += entry->resource()->gpuMemorySize(); 327 bytes += entry->resource()->gpuMemorySize();
359 } 328 }
360 return bytes; 329 return bytes;
361 } 330 }
362 331
363 static bool both_zero_or_nonzero(int count, size_t bytes) { 332 static bool both_zero_or_nonzero(int count, size_t bytes) {
364 return (count == 0 && bytes == 0) || (count > 0 && bytes > 0); 333 return (count == 0 && bytes == 0) || (count > 0 && bytes > 0);
365 } 334 }
366 335
367 void GrResourceCache::validate() const { 336 void GrResourceCache::validate() const {
368 fList.validate(); 337 fList.validate();
369 SkASSERT(both_zero_or_nonzero(fEntryCount, fEntryBytes)); 338 SkASSERT(both_zero_or_nonzero(fEntryCount, fEntryBytes));
370 SkASSERT(fEntryCount == fCache.count());
371 339
372 EntryList::Iter iter; 340 EntryList::Iter iter;
373 341
374 // check that the shareable entries are okay 342 // check that the shareable entries are okay
375 const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(fList), 343 const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(fList),
376 EntryList::Iter::kHead_IterSta rt); 344 EntryList::Iter::kHead_IterSta rt);
377 345
378 int count = 0; 346 int count = 0;
379 for ( ; entry; entry = iter.next()) { 347 for ( ; entry; entry = iter.next()) {
380 entry->validate(); 348 entry->validate();
381 SkASSERT(fCache.find(entry->key()));
382 count += 1; 349 count += 1;
383 } 350 }
384 SkASSERT(count == fEntryCount); 351 SkASSERT(count == fEntryCount);
385 352
386 size_t bytes = this->countBytes(fList); 353 size_t bytes = this->countBytes(fList);
387 SkASSERT(bytes == fEntryBytes); 354 SkASSERT(bytes == fEntryBytes);
388 SkASSERT(fList.countEntries() == fEntryCount); 355 SkASSERT(fList.countEntries() == fEntryCount);
389 } 356 }
390 #endif // SK_DEBUG 357 #endif // SK_DEBUG
391 358
(...skipping 22 matching lines...) Expand all
414 SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes); 381 SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes);
415 SkDebugf("\t\tEntry Count: current %d (%d locked, %d scratch %.2g%% full), h igh %d\n", 382 SkDebugf("\t\tEntry Count: current %d (%d locked, %d scratch %.2g%% full), h igh %d\n",
416 fEntryCount, locked, scratch, countUtilization, fHighWaterEntryC ount); 383 fEntryCount, locked, scratch, countUtilization, fHighWaterEntryC ount);
417 SkDebugf("\t\tEntry Bytes: current %d (%.2g%% full) high %d\n", 384 SkDebugf("\t\tEntry Bytes: current %d (%.2g%% full) high %d\n",
418 fEntryBytes, byteUtilization, fHighWaterEntryBytes); 385 fEntryBytes, byteUtilization, fHighWaterEntryBytes);
419 } 386 }
420 387
421 #endif 388 #endif
422 389
423 /////////////////////////////////////////////////////////////////////////////// 390 ///////////////////////////////////////////////////////////////////////////////
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698