Skia
2DGraphicsLibrary
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GrResourceKey.h
1 
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 #ifndef GrResourceKey_DEFINED
10 #define GrResourceKey_DEFINED
11 
12 #include "../private/SkOnce.h"
13 #include "../private/SkTemplates.h"
14 #include "GrTypes.h"
15 #include "SkData.h"
16 #include "SkString.h"
17 
18 uint32_t GrResourceKeyHash(const uint32_t* data, size_t size);
19 
25 public:
26  uint32_t hash() const {
27  this->validate();
28  return fKey[kHash_MetaDataIdx];
29  }
30 
31  size_t size() const {
32  this->validate();
33  SkASSERT(this->isValid());
34  return this->internalSize();
35  }
36 
37 protected:
38  static const uint32_t kInvalidDomain = 0;
39 
40  GrResourceKey() { this->reset(); }
41 
43  void reset() {
44  GR_STATIC_ASSERT((uint16_t)kInvalidDomain == kInvalidDomain);
45  fKey.reset(kMetaDataCnt);
46  fKey[kHash_MetaDataIdx] = 0;
47  fKey[kDomainAndSize_MetaDataIdx] = kInvalidDomain;
48  }
49 
50  bool operator==(const GrResourceKey& that) const {
51  return this->hash() == that.hash() &&
52  0 == memcmp(&fKey[kHash_MetaDataIdx + 1],
53  &that.fKey[kHash_MetaDataIdx + 1],
54  this->internalSize() - sizeof(uint32_t));
55  }
56 
57  GrResourceKey& operator=(const GrResourceKey& that) {
58  SkASSERT(that.isValid());
59  if (this != &that) {
60  size_t bytes = that.size();
61  SkASSERT(SkIsAlign4(bytes));
62  fKey.reset(SkToInt(bytes / sizeof(uint32_t)));
63  memcpy(fKey.get(), that.fKey.get(), bytes);
64  this->validate();
65  }
66  return *this;
67  }
68 
69  bool isValid() const { return kInvalidDomain != this->domain(); }
70 
71  uint32_t domain() const { return fKey[kDomainAndSize_MetaDataIdx] & 0xffff; }
72 
74  size_t dataSize() const { return this->size() - 4 * kMetaDataCnt; }
75 
77  const uint32_t* data() const {
78  this->validate();
79  return &fKey[kMetaDataCnt];
80  }
81 
83  class Builder {
84  public:
85  Builder(GrResourceKey* key, uint32_t domain, int data32Count) : fKey(key) {
86  SkASSERT(data32Count >= 0);
87  SkASSERT(domain != kInvalidDomain);
88  key->fKey.reset(kMetaDataCnt + data32Count);
89  int size = (data32Count + kMetaDataCnt) * sizeof(uint32_t);
90  SkASSERT(SkToU16(size) == size);
91  SkASSERT(SkToU16(domain) == domain);
92  key->fKey[kDomainAndSize_MetaDataIdx] = domain | (size << 16);
93  }
94 
95  ~Builder() { this->finish(); }
96 
97  void finish() {
98  if (NULL == fKey) {
99  return;
100  }
101  GR_STATIC_ASSERT(0 == kHash_MetaDataIdx);
102  uint32_t* hash = &fKey->fKey[kHash_MetaDataIdx];
103  *hash = GrResourceKeyHash(hash + 1, fKey->internalSize() - sizeof(uint32_t));
104  fKey->validate();
105  fKey = NULL;
106  }
107 
108  uint32_t& operator[](int dataIdx) {
109  SkASSERT(fKey);
110  SkDEBUGCODE(size_t dataCount = fKey->internalSize() / sizeof(uint32_t) - kMetaDataCnt;)
111  SkASSERT(SkToU32(dataIdx) < dataCount);
112  return fKey->fKey[kMetaDataCnt + dataIdx];
113  }
114 
115  private:
116  GrResourceKey* fKey;
117  };
118 
119 private:
120  enum MetaDataIdx {
121  kHash_MetaDataIdx,
122  // The key domain and size are packed into a single uint32_t.
123  kDomainAndSize_MetaDataIdx,
124 
125  kLastMetaDataIdx = kDomainAndSize_MetaDataIdx
126  };
127  static const uint32_t kMetaDataCnt = kLastMetaDataIdx + 1;
128 
129  size_t internalSize() const {
130  return fKey[kDomainAndSize_MetaDataIdx] >> 16;
131  }
132 
133  void validate() const {
134  SkASSERT(fKey[kHash_MetaDataIdx] ==
135  GrResourceKeyHash(&fKey[kHash_MetaDataIdx] + 1,
136  this->internalSize() - sizeof(uint32_t)));
137  SkASSERT(SkIsAlign4(this->internalSize()));
138  }
139 
140  friend class TestResource; // For unit test to access kMetaDataCnt.
141 
142  // bmp textures require 7 uint32_t values (5 for the base key, and two more for image
143  // cacherator's decode format.
144  SkAutoSTMalloc<kMetaDataCnt + 7, uint32_t> fKey;
145 };
146 
168 class GrScratchKey : public GrResourceKey {
169 private:
170  typedef GrResourceKey INHERITED;
171 
172 public:
174  typedef uint32_t ResourceType;
175 
178 
181 
182  GrScratchKey(const GrScratchKey& that) { *this = that; }
183 
185  using INHERITED::reset;
186 
187  using INHERITED::isValid;
188 
189  ResourceType resourceType() const { return this->domain(); }
190 
191  GrScratchKey& operator=(const GrScratchKey& that) {
192  this->INHERITED::operator=(that);
193  return *this;
194  }
195 
196  bool operator==(const GrScratchKey& that) const {
197  return this->INHERITED::operator==(that);
198  }
199  bool operator!=(const GrScratchKey& that) const { return !(*this == that); }
200 
201  class Builder : public INHERITED::Builder {
202  public:
203  Builder(GrScratchKey* key, ResourceType type, int data32Count)
204  : INHERITED::Builder(key, type, data32Count) {}
205  };
206 };
207 
222 class GrUniqueKey : public GrResourceKey {
223 private:
224  typedef GrResourceKey INHERITED;
225 
226 public:
227  typedef uint32_t Domain;
229  static Domain GenerateDomain();
230 
233 
234  GrUniqueKey(const GrUniqueKey& that) { *this = that; }
235 
237  using INHERITED::reset;
238 
239  using INHERITED::isValid;
240 
241  GrUniqueKey& operator=(const GrUniqueKey& that) {
242  this->INHERITED::operator=(that);
243  this->setCustomData(sk_ref_sp(that.getCustomData()));
244  SkDEBUGCODE(fTag = that.fTag;)
245  return *this;
246  }
247 
248  bool operator==(const GrUniqueKey& that) const {
249  return this->INHERITED::operator==(that);
250  }
251  bool operator!=(const GrUniqueKey& that) const { return !(*this == that); }
252 
253  void setCustomData(sk_sp<SkData> data) {
254  fData = std::move(data);
255  }
256  SkData* getCustomData() const {
257  return fData.get();
258  }
259 
260  SkDEBUGCODE(const char* tag() const { return fTag.c_str(); })
261 
262  class Builder : public INHERITED::Builder {
263  public:
264  Builder(GrUniqueKey* key, Domain type, int data32Count, const char* tag = nullptr)
265  : INHERITED::Builder(key, type, data32Count) {
266  SkDEBUGCODE(key->fTag = tag;)
267  (void) tag; // suppress unused named param warning.
268  }
269 
271  Builder(GrUniqueKey* key, const GrUniqueKey& innerKey, Domain domain, int extraData32Cnt,
272  const char* tag = nullptr)
273  : INHERITED::Builder(key, domain, Data32CntForInnerKey(innerKey) + extraData32Cnt) {
274  SkASSERT(&innerKey != key);
275  // add the inner key to the end of the key so that op[] can be indexed normally.
276  uint32_t* innerKeyData = &this->operator[](extraData32Cnt);
277  const uint32_t* srcData = innerKey.data();
278  (*innerKeyData++) = innerKey.domain();
279  memcpy(innerKeyData, srcData, innerKey.dataSize());
280  SkDEBUGCODE(key->fTag = tag;)
281  (void) tag; // suppress unused named param warning.
282  }
283 
284  private:
285  static int Data32CntForInnerKey(const GrUniqueKey& innerKey) {
286  // key data + domain
287  return SkToInt((innerKey.dataSize() >> 2) + 1);
288  }
289  };
290 
291 private:
292  sk_sp<SkData> fData;
293  SkDEBUGCODE(SkString fTag;)
294 };
295 
303 #define GR_DECLARE_STATIC_UNIQUE_KEY(name) static SkOnce name##_once
304 
306 #define GR_DEFINE_STATIC_UNIQUE_KEY(name) \
307  static SkAlignedSTStorage<1, GrUniqueKey> name##_storage; \
308  name##_once(gr_init_static_unique_key_once, &name##_storage); \
309  static const GrUniqueKey& name = *reinterpret_cast<GrUniqueKey*>(name##_storage.get());
310 
311 static inline void gr_init_static_unique_key_once(SkAlignedSTStorage<1,GrUniqueKey>* keyStorage) {
312  GrUniqueKey* key = new (keyStorage->get()) GrUniqueKey;
314 }
315 
316 // The cache listens for these messages to purge junk resources proactively.
318 public:
319  explicit GrUniqueKeyInvalidatedMessage(const GrUniqueKey& key) : fKey(key) {}
320 
321  GrUniqueKeyInvalidatedMessage(const GrUniqueKeyInvalidatedMessage& that) : fKey(that.fKey) {}
322 
324  fKey = that.fKey;
325  return *this;
326  }
327 
328  const GrUniqueKey& key() const { return fKey; }
329 
330 private:
331  GrUniqueKey fKey;
332 };
333 #endif
GrUniqueKey()
Creates an invalid unique key.
Definition: GrResourceKey.h:232
A key that allows for exclusive use of a resource for a use case (AKA "domain").
Definition: GrResourceKey.h:222
Used to initialize a key.
Definition: GrResourceKey.h:83
const uint32_t * data() const
ptr to the key data, excluding meta-data (hash, domain, etc).
Definition: GrResourceKey.h:77
size_t dataSize() const
size of the key data, excluding meta-data (hash, domain, etc).
Definition: GrResourceKey.h:74
SkData holds an immutable data buffer.
Definition: SkData.h:22
Builder(GrUniqueKey *key, const GrUniqueKey &innerKey, Domain domain, int extraData32Cnt, const char *tag=nullptr)
Used to build a key that wraps another key and adds additional data.
Definition: GrResourceKey.h:271
static ResourceType GenerateResourceType()
Generate a unique ResourceType.
A key used for scratch resources.
Definition: GrResourceKey.h:168
void reset()
Reset to an invalid key.
Definition: GrResourceKey.h:43
Definition: GrResourceKey.h:317
Base class for all GrGpuResource cache keys.
Definition: GrResourceKey.h:24
uint32_t ResourceType
Uniquely identifies the type of resource that is cached as scratch.
Definition: GrResourceKey.h:174
static Domain GenerateDomain()
Generate a Domain for unique keys.
GrScratchKey()
Creates an invalid scratch key.
Definition: GrResourceKey.h:180
Definition: GrResourceKey.h:201
Light weight class for managing strings.
Definition: SkString.h:121