OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2014 Google Inc. | 3 * Copyright 2014 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 #ifndef GrResourceKey_DEFINED | 9 #ifndef GrResourceKey_DEFINED |
10 #define GrResourceKey_DEFINED | 10 #define GrResourceKey_DEFINED |
11 | 11 |
12 #include "GrTypes.h" | 12 #include "GrTypes.h" |
13 #include "SkTemplates.h" | 13 #include "SkTemplates.h" |
14 | 14 |
15 uint32_t GrResourceKeyHash(const uint32_t* data, size_t size); | 15 uint32_t GrResourceKeyHash(const uint32_t* data, size_t size); |
16 | 16 |
| 17 /** |
| 18 * Base class for all GrGpuResource cache keys. There are two types of cache key
s. Refer to the |
| 19 * comments for each key type below. |
| 20 */ |
17 class GrResourceKey { | 21 class GrResourceKey { |
18 public: | 22 public: |
19 uint32_t hash() const { | 23 uint32_t hash() const { |
20 this->validate(); | 24 this->validate(); |
21 return fKey[kHash_MetaDataIdx]; | 25 return fKey[kHash_MetaDataIdx]; |
22 } | 26 } |
23 | 27 |
24 size_t size() const { | 28 size_t size() const { |
25 this->validate(); | 29 this->validate(); |
26 SkASSERT(this->isValid()); | 30 SkASSERT(this->isValid()); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 SkASSERT(SkIsAlign4(this->internalSize())); | 132 SkASSERT(SkIsAlign4(this->internalSize())); |
129 } | 133 } |
130 | 134 |
131 friend class TestResource; // For unit test to access kMetaDataCnt. | 135 friend class TestResource; // For unit test to access kMetaDataCnt. |
132 | 136 |
133 // bmp textures require 4 uint32_t values. | 137 // bmp textures require 4 uint32_t values. |
134 SkAutoSTMalloc<kMetaDataCnt + 4, uint32_t> fKey; | 138 SkAutoSTMalloc<kMetaDataCnt + 4, uint32_t> fKey; |
135 }; | 139 }; |
136 | 140 |
137 /** | 141 /** |
138 * A key used for scratch resources. The key consists of a resource type (subcla
ss) identifier, a | 142 * A key used for scratch resources. There are three important rules about scrat
ch keys: |
139 * hash, a data length, and type-specific data. A Builder object is used to init
ialize the | 143 * * Multiple resources can share the same scratch key. Therefore resourc
es assigned the same |
140 * key contents. The contents must be initialized before the key can be used. | 144 * scratch key should be interchangeable with respect to the code that
uses them. |
| 145 * * A resource can have at most one scratch key and it is set at resourc
e creation by the |
| 146 * resource itself. |
| 147 * * When a scratch resource is ref'ed it will not be returned from the |
| 148 * cache for a subsequent cache request until all refs are released. Th
is facilitates using |
| 149 * a scratch key for multiple render-to-texture scenarios. An example i
s a separable blur: |
| 150 * |
| 151 * GrTexture* texture[2]; |
| 152 * texture[0] = get_scratch_texture(scratchKey); |
| 153 * texture[1] = get_scratch_texture(scratchKey); // texture[0] is already owned
so we will get a |
| 154 * // different one for texture[1
] |
| 155 * draw_mask(texture[0], path); // draws path mask to texture[0] |
| 156 * blur_x(texture[0], texture[1]); // blurs texture[0] in y and stores resu
lt in texture[1] |
| 157 * blur_y(texture[1], texture[0]); // blurs texture[1] in y and stores resu
lt in texture[0] |
| 158 * texture[1]->unref(); // texture 1 can now be recycled for the next request
with scratchKey |
| 159 * consume_blur(texture[0]); |
| 160 * texture[0]->unref(); // texture 0 can now be recycled for the next request
with scratchKey |
141 */ | 161 */ |
142 class GrScratchKey : public GrResourceKey { | 162 class GrScratchKey : public GrResourceKey { |
143 private: | 163 private: |
144 typedef GrResourceKey INHERITED; | 164 typedef GrResourceKey INHERITED; |
145 | 165 |
146 public: | 166 public: |
147 /** Uniquely identifies the type of resource that is cached as scratch. */ | 167 /** Uniquely identifies the type of resource that is cached as scratch. */ |
148 typedef uint32_t ResourceType; | 168 typedef uint32_t ResourceType; |
149 | 169 |
150 /** Generate a unique ResourceType. */ | 170 /** Generate a unique ResourceType. */ |
(...skipping 22 matching lines...) Expand all Loading... |
173 bool operator!=(const GrScratchKey& that) const { return !(*this == that); } | 193 bool operator!=(const GrScratchKey& that) const { return !(*this == that); } |
174 | 194 |
175 class Builder : public INHERITED::Builder { | 195 class Builder : public INHERITED::Builder { |
176 public: | 196 public: |
177 Builder(GrScratchKey* key, ResourceType type, int data32Count) | 197 Builder(GrScratchKey* key, ResourceType type, int data32Count) |
178 : INHERITED::Builder(key, type, data32Count) {} | 198 : INHERITED::Builder(key, type, data32Count) {} |
179 }; | 199 }; |
180 }; | 200 }; |
181 | 201 |
182 /** | 202 /** |
183 * A key used to cache resources based on their content. The key consists of a d
omain type (use | 203 * A key that allows for exclusive use of a resource for a use case (AKA "domain
"). There are three |
184 * case for the cache), a hash, a data length, and domain-specific data. A Build
er object is used to | 204 * rules governing the use of unique keys: |
185 * initialize the key contents. The contents must be initialized before the key
can be used. | 205 * * Only one resource can have a given unique key at a time. Hence, "uni
que". |
| 206 * * A resource can have at most one unique key at a time. |
| 207 * * Unlike scratch keys, multiple requests for a unique key will return
the same |
| 208 * resource even if the resource already has refs. |
| 209 * This key type allows a code path to create cached resources for which it is t
he exclusive user. |
| 210 * The code path creates a domain which it sets on its keys. This guarantees tha
t there are no |
| 211 * cross-domain collisions. |
| 212 * |
| 213 * Unique keys preempt scratch keys. While a resource has a unique key it is ina
ccessible via its |
| 214 * scratch key. It can become scratch again if the unique key is removed. |
186 */ | 215 */ |
187 class GrContentKey : public GrResourceKey { | 216 class GrUniqueKey : public GrResourceKey { |
188 private: | 217 private: |
189 typedef GrResourceKey INHERITED; | 218 typedef GrResourceKey INHERITED; |
190 | 219 |
191 public: | 220 public: |
192 typedef uint32_t Domain; | 221 typedef uint32_t Domain; |
193 /** Generate a unique Domain of content keys. */ | 222 /** Generate a Domain for unique keys. */ |
194 static Domain GenerateDomain(); | 223 static Domain GenerateDomain(); |
195 | 224 |
196 /** Creates an invalid content key. It must be initialized using a Builder o
bject before use. */ | 225 /** Creates an invalid unique key. It must be initialized using a Builder ob
ject before use. */ |
197 GrContentKey() {} | 226 GrUniqueKey() {} |
198 | 227 |
199 GrContentKey(const GrContentKey& that) { *this = that; } | 228 GrUniqueKey(const GrUniqueKey& that) { *this = that; } |
200 | 229 |
201 /** reset() returns the key to the invalid state. */ | 230 /** reset() returns the key to the invalid state. */ |
202 using INHERITED::reset; | 231 using INHERITED::reset; |
203 | 232 |
204 using INHERITED::isValid; | 233 using INHERITED::isValid; |
205 | 234 |
206 GrContentKey& operator=(const GrContentKey& that) { | 235 GrUniqueKey& operator=(const GrUniqueKey& that) { |
207 this->INHERITED::operator=(that); | 236 this->INHERITED::operator=(that); |
208 return *this; | 237 return *this; |
209 } | 238 } |
210 | 239 |
211 bool operator==(const GrContentKey& that) const { | 240 bool operator==(const GrUniqueKey& that) const { |
212 return this->INHERITED::operator==(that); | 241 return this->INHERITED::operator==(that); |
213 } | 242 } |
214 bool operator!=(const GrContentKey& that) const { return !(*this == that); } | 243 bool operator!=(const GrUniqueKey& that) const { return !(*this == that); } |
215 | 244 |
216 class Builder : public INHERITED::Builder { | 245 class Builder : public INHERITED::Builder { |
217 public: | 246 public: |
218 Builder(GrContentKey* key, Domain domain, int data32Count) | 247 Builder(GrUniqueKey* key, Domain domain, int data32Count) |
219 : INHERITED::Builder(key, domain, data32Count) {} | 248 : INHERITED::Builder(key, domain, data32Count) {} |
220 | 249 |
221 /** Used to build a key that wraps another key and adds additional data.
*/ | 250 /** Used to build a key that wraps another key and adds additional data.
*/ |
222 Builder(GrContentKey* key, const GrContentKey& innerKey, Domain domain, | 251 Builder(GrUniqueKey* key, const GrUniqueKey& innerKey, Domain domain, |
223 int extraData32Cnt) | 252 int extraData32Cnt) |
224 : INHERITED::Builder(key, domain, Data32CntForInnerKey(innerKey) + e
xtraData32Cnt) { | 253 : INHERITED::Builder(key, domain, Data32CntForInnerKey(innerKey) + e
xtraData32Cnt) { |
225 SkASSERT(&innerKey != key); | 254 SkASSERT(&innerKey != key); |
226 // add the inner key to the end of the key so that op[] can be index
ed normally. | 255 // add the inner key to the end of the key so that op[] can be index
ed normally. |
227 uint32_t* innerKeyData = &this->operator[](extraData32Cnt); | 256 uint32_t* innerKeyData = &this->operator[](extraData32Cnt); |
228 const uint32_t* srcData = innerKey.data(); | 257 const uint32_t* srcData = innerKey.data(); |
229 (*innerKeyData++) = innerKey.domain(); | 258 (*innerKeyData++) = innerKey.domain(); |
230 memcpy(innerKeyData, srcData, innerKey.dataSize()); | 259 memcpy(innerKeyData, srcData, innerKey.dataSize()); |
231 } | 260 } |
232 | 261 |
233 private: | 262 private: |
234 static int Data32CntForInnerKey(const GrContentKey& innerKey) { | 263 static int Data32CntForInnerKey(const GrUniqueKey& innerKey) { |
235 // key data + domain | 264 // key data + domain |
236 return SkToInt((innerKey.dataSize() >> 2) + 1); | 265 return SkToInt((innerKey.dataSize() >> 2) + 1); |
237 } | 266 } |
238 }; | 267 }; |
239 }; | 268 }; |
240 | 269 |
241 // The cache listens for these messages to purge junk resources proactively. | 270 // The cache listens for these messages to purge junk resources proactively. |
242 class GrContentKeyInvalidatedMessage { | 271 class GrUniqueKeyInvalidatedMessage { |
243 public: | 272 public: |
244 explicit GrContentKeyInvalidatedMessage(const GrContentKey& key) : fKey(key)
{} | 273 explicit GrUniqueKeyInvalidatedMessage(const GrUniqueKey& key) : fKey(key) {
} |
245 GrContentKeyInvalidatedMessage(const GrContentKeyInvalidatedMessage& that) :
fKey(that.fKey) {} | 274 |
246 GrContentKeyInvalidatedMessage& operator=(const GrContentKeyInvalidatedMessa
ge& that) { | 275 GrUniqueKeyInvalidatedMessage(const GrUniqueKeyInvalidatedMessage& that) : f
Key(that.fKey) {} |
| 276 |
| 277 GrUniqueKeyInvalidatedMessage& operator=(const GrUniqueKeyInvalidatedMessage
& that) { |
247 fKey = that.fKey; | 278 fKey = that.fKey; |
248 return *this; | 279 return *this; |
249 } | 280 } |
250 const GrContentKey& key() const { return fKey; } | 281 |
| 282 const GrUniqueKey& key() const { return fKey; } |
| 283 |
251 private: | 284 private: |
252 GrContentKey fKey; | 285 GrUniqueKey fKey; |
253 }; | 286 }; |
254 #endif | 287 #endif |
OLD | NEW |