blob: 65e522aafbae13b310600138b4fee6f229bdce98 [file] [log] [blame]
bsalomonc8dc1f72014-08-21 13:02:13 -07001
2/*
3 * Copyright 2014 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#include "GrResourceCache2.h"
bsalomonbcf0a522014-10-08 08:40:09 -070011#include "GrGpuResource.h"
bsalomonc8dc1f72014-08-21 13:02:13 -070012
13GrResourceCache2::~GrResourceCache2() {
14 this->releaseAll();
15}
16
17void GrResourceCache2::insertResource(GrGpuResource* resource) {
bsalomon49f085d2014-09-05 13:34:00 -070018 SkASSERT(resource);
bsalomonc8dc1f72014-08-21 13:02:13 -070019 SkASSERT(!resource->wasDestroyed());
bsalomon16961262014-08-26 14:01:07 -070020 SkASSERT(!this->isInCache(resource));
bsalomonc8dc1f72014-08-21 13:02:13 -070021 fResources.addToHead(resource);
22 ++fCount;
bsalomon744998e2014-08-28 09:54:34 -070023 if (!resource->getScratchKey().isNullScratch()) {
bsalomon8b79d232014-11-10 10:19:06 -080024 // TODO(bsalomon): Make this assertion possible.
25 // SkASSERT(!resource->isWrapped());
bsalomon744998e2014-08-28 09:54:34 -070026 fScratchMap.insert(resource->getScratchKey(), resource);
27 }
bsalomonc8dc1f72014-08-21 13:02:13 -070028}
29
30void GrResourceCache2::removeResource(GrGpuResource* resource) {
bsalomon16961262014-08-26 14:01:07 -070031 SkASSERT(this->isInCache(resource));
bsalomon744998e2014-08-28 09:54:34 -070032 fResources.remove(resource);
33 if (!resource->getScratchKey().isNullScratch()) {
34 fScratchMap.remove(resource->getScratchKey(), resource);
35 }
bsalomon8b79d232014-11-10 10:19:06 -080036 if (const GrResourceKey* contentKey = resource->getContentKey()) {
37 fContentHash.remove(*contentKey);
38 }
bsalomonc8dc1f72014-08-21 13:02:13 -070039 --fCount;
40}
41
42void GrResourceCache2::abandonAll() {
43 while (GrGpuResource* head = fResources.head()) {
44 SkASSERT(!head->wasDestroyed());
45 head->abandon();
46 // abandon should have already removed this from the list.
47 SkASSERT(head != fResources.head());
48 }
bsalomon744998e2014-08-28 09:54:34 -070049 SkASSERT(!fScratchMap.count());
bsalomon8b79d232014-11-10 10:19:06 -080050 SkASSERT(!fContentHash.count());
bsalomonc8dc1f72014-08-21 13:02:13 -070051 SkASSERT(!fCount);
52}
53
54void GrResourceCache2::releaseAll() {
55 while (GrGpuResource* head = fResources.head()) {
56 SkASSERT(!head->wasDestroyed());
57 head->release();
58 // release should have already removed this from the list.
59 SkASSERT(head != fResources.head());
60 }
bsalomon744998e2014-08-28 09:54:34 -070061 SkASSERT(!fScratchMap.count());
bsalomonc8dc1f72014-08-21 13:02:13 -070062 SkASSERT(!fCount);
63}
bsalomonbcf0a522014-10-08 08:40:09 -070064
65class GrResourceCache2::AvailableForScratchUse {
66public:
bsalomon000f8292014-10-15 19:04:14 -070067 AvailableForScratchUse(bool rejectPendingIO) : fRejectPendingIO(rejectPendingIO) { }
bsalomonbcf0a522014-10-08 08:40:09 -070068
69 bool operator()(const GrGpuResource* resource) const {
bsalomon000f8292014-10-15 19:04:14 -070070 if (!resource->reffedOnlyByCache() || !resource->isScratch()) {
71 return false;
bsalomonbcf0a522014-10-08 08:40:09 -070072 }
bsalomon000f8292014-10-15 19:04:14 -070073
74 return !fRejectPendingIO || !resource->internalHasPendingIO();
bsalomonbcf0a522014-10-08 08:40:09 -070075 }
bsalomon1e2530b2014-10-09 09:57:18 -070076
bsalomonbcf0a522014-10-08 08:40:09 -070077private:
bsalomon000f8292014-10-15 19:04:14 -070078 bool fRejectPendingIO;
bsalomonbcf0a522014-10-08 08:40:09 -070079};
80
81GrGpuResource* GrResourceCache2::findAndRefScratchResource(const GrResourceKey& scratchKey,
bsalomon000f8292014-10-15 19:04:14 -070082 uint32_t flags) {
bsalomonbcf0a522014-10-08 08:40:09 -070083 SkASSERT(scratchKey.isScratch());
bsalomon000f8292014-10-15 19:04:14 -070084
85 if (flags & (kPreferNoPendingIO_ScratchFlag | kRequireNoPendingIO_ScratchFlag)) {
86 GrGpuResource* resource = fScratchMap.find(scratchKey, AvailableForScratchUse(true));
87 if (resource) {
88 return SkRef(resource);
89 } else if (flags & kRequireNoPendingIO_ScratchFlag) {
90 return NULL;
91 }
92 // TODO: fail here when kPrefer is specified, we didn't find a resource without pending io,
93 // but there is still space in our budget for the resource.
94 }
95 return SkSafeRef(fScratchMap.find(scratchKey, AvailableForScratchUse(false)));
bsalomonbcf0a522014-10-08 08:40:09 -070096}
bsalomon8b79d232014-11-10 10:19:06 -080097
98void GrResourceCache2::willRemoveContentKey(const GrGpuResource* resource) {
99 SkASSERT(resource);
100 SkASSERT(resource->getContentKey());
101 SkDEBUGCODE(GrGpuResource* res = fContentHash.find(*resource->getContentKey()));
102 SkASSERT(res == resource);
103
104 fContentHash.remove(*resource->getContentKey());
105}
106
107bool GrResourceCache2::didAddContentKey(GrGpuResource* resource) {
108 SkASSERT(resource);
109 SkASSERT(resource->getContentKey());
110
111 GrGpuResource* res = fContentHash.find(*resource->getContentKey());
112 if (NULL != res) {
113 return false;
114 }
115
116 fContentHash.add(resource);
117 return true;
118}