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