aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/gpu/GrResourceKey.h
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2015-01-23 04:24:04 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-01-23 04:24:05 -0800
commit24db3b1c35fb935660229da164fc5ad31977387f (patch)
treebe22e794f54605ff37ef09df79b3e0869572b053 /include/gpu/GrResourceKey.h
parentf98f2bb0e72df68320f707c8584e3c877ce98ec3 (diff)
Add specialized content key class for resources.
Diffstat (limited to 'include/gpu/GrResourceKey.h')
-rw-r--r--include/gpu/GrResourceKey.h227
1 files changed, 145 insertions, 82 deletions
diff --git a/include/gpu/GrResourceKey.h b/include/gpu/GrResourceKey.h
index 9922c8f5d0..9cf955be98 100644
--- a/include/gpu/GrResourceKey.h
+++ b/include/gpu/GrResourceKey.h
@@ -13,149 +13,212 @@
#include "SkTemplates.h"
#include "GrBinHashKey.h"
-/**
- * A key used for scratch resources. The key consists of a resource type (subclass) identifier, a
- * hash, a data length, and type-specific data. A Builder object is used to initialize the
- * key contents. The contents must be initialized before the key can be used.
- */
-class GrScratchKey {
+uint32_t GrResourceKeyHash(const uint32_t* data, size_t size);
+
+class GrResourceKey {
public:
- /** Uniquely identifies the type of resource that is cached as scratch. */
- typedef uint32_t ResourceType;
- /** Generate a unique ResourceType. */
- static ResourceType GenerateResourceType();
+ uint32_t hash() const {
+ this->validate();
+ return fKey[kHash_MetaDataIdx];
+ }
- GrScratchKey() { this->reset(); }
- GrScratchKey(const GrScratchKey& that) { *this = that; }
+ size_t size() const {
+ this->validate();
+ return this->internalSize();
+ }
+
+ const uint32_t* data() const {
+ this->validate();
+ return &fKey[kMetaDataCnt];
+ }
+
+protected:
+ static const uint32_t kInvalidDomain = 0;
+
+ GrResourceKey() { this->reset(); }
/** Reset to an invalid key. */
void reset() {
+ GR_STATIC_ASSERT((uint16_t)kInvalidDomain == kInvalidDomain);
fKey.reset(kMetaDataCnt);
fKey[kHash_MetaDataIdx] = 0;
- fKey[kTypeAndSize_MetaDataIdx] = kInvalidResourceType;
+ fKey[kDomainAndSize_MetaDataIdx] = kInvalidDomain;
}
- bool isValid() const { return kInvalidResourceType != this->resourceType(); }
-
- ResourceType resourceType() const { return fKey[kTypeAndSize_MetaDataIdx] & 0xffff; }
-
- uint32_t hash() const { return fKey[kHash_MetaDataIdx]; }
-
- size_t size() const { return SkToInt(fKey[kTypeAndSize_MetaDataIdx] >> 16); }
-
- const uint32_t* data() const { return &fKey[kMetaDataCnt]; }
+ bool operator==(const GrResourceKey& that) const {
+ return 0 == memcmp(fKey.get(), that.fKey.get(), this->size());
+ }
- GrScratchKey& operator=(const GrScratchKey& that) {
+ GrResourceKey& operator=(const GrResourceKey& that) {
size_t bytes = that.size();
+ SkASSERT(SkIsAlign4(bytes));
fKey.reset(SkToInt(bytes / sizeof(uint32_t)));
memcpy(fKey.get(), that.fKey.get(), bytes);
return *this;
}
- bool operator==(const GrScratchKey& that) const {
- return 0 == memcmp(fKey.get(), that.fKey.get(), this->size());
- }
- bool operator!=(const GrScratchKey& that) const { return !(*this == that); }
+ bool isValid() const { return kInvalidDomain != this->domain(); }
- /** Used to initialize scratch key. */
+ uint32_t domain() const { return fKey[kDomainAndSize_MetaDataIdx] & 0xffff; }
+
+ /** Used to initialize a key. */
class Builder {
public:
- Builder(GrScratchKey* key, ResourceType type, int data32Count) : fKey(key) {
+ Builder(GrResourceKey* key, uint32_t domain, int data32Count) : fKey(key) {
SkASSERT(data32Count >= 0);
- SkASSERT(type != kInvalidResourceType);
+ SkASSERT(domain != kInvalidDomain);
key->fKey.reset(kMetaDataCnt + data32Count);
- SkASSERT(type <= SK_MaxU16);
int size = (data32Count + kMetaDataCnt) * sizeof(uint32_t);
- SkASSERT(size <= SK_MaxU16);
- key->fKey[kTypeAndSize_MetaDataIdx] = type | (size << 16);
+ SkASSERT(SkToU16(size) == size);
+ SkASSERT(SkToU16(domain) == domain);
+ key->fKey[kDomainAndSize_MetaDataIdx] = domain | (size << 16);
}
~Builder() { this->finish(); }
- void finish();
+ void finish() {
+ if (NULL == fKey) {
+ return;
+ }
+ GR_STATIC_ASSERT(0 == kHash_MetaDataIdx);
+ uint32_t* hash = &fKey->fKey[kHash_MetaDataIdx];
+ *hash = GrResourceKeyHash(hash + 1, fKey->internalSize() - sizeof(uint32_t));
+ fKey->validate();
+ fKey = NULL;
+ }
uint32_t& operator[](int dataIdx) {
SkASSERT(fKey);
- SkDEBUGCODE(size_t dataCount = fKey->size() / sizeof(uint32_t) - kMetaDataCnt;)
+ SkDEBUGCODE(size_t dataCount = fKey->internalSize() / sizeof(uint32_t) - kMetaDataCnt;)
SkASSERT(SkToU32(dataIdx) < dataCount);
return fKey->fKey[kMetaDataCnt + dataIdx];
}
private:
- GrScratchKey* fKey;
+ GrResourceKey* fKey;
};
private:
+ size_t internalSize() const {
+ return fKey[kDomainAndSize_MetaDataIdx] >> 16;
+ }
+
+ void validate() const {
+ SkASSERT(fKey[kHash_MetaDataIdx] ==
+ GrResourceKeyHash(&fKey[kHash_MetaDataIdx] + 1,
+ this->internalSize() - sizeof(uint32_t)));
+ }
+
enum MetaDataIdx {
kHash_MetaDataIdx,
- // The resource type and size are packed into a single uint32_t.
- kTypeAndSize_MetaDataIdx,
+ // The key domain and size are packed into a single uint32_t.
+ kDomainAndSize_MetaDataIdx,
- kLastMetaDataIdx = kTypeAndSize_MetaDataIdx
+ kLastMetaDataIdx = kDomainAndSize_MetaDataIdx
};
- static const uint32_t kInvalidResourceType = 0;
static const uint32_t kMetaDataCnt = kLastMetaDataIdx + 1;
friend class TestResource; // For unit test to access kMetaDataCnt.
- // Stencil and textures each require 2 uint32_t values.
- SkAutoSTArray<kMetaDataCnt + 2, uint32_t> fKey;
+ // bmp textures require 4 uint32_t values.
+ SkAutoSTArray<kMetaDataCnt + 4, uint32_t> fKey;
};
-class GrResourceKey {
+/**
+ * A key used for scratch resources. The key consists of a resource type (subclass) identifier, a
+ * hash, a data length, and type-specific data. A Builder object is used to initialize the
+ * key contents. The contents must be initialized before the key can be used.
+ */
+class GrScratchKey : public GrResourceKey {
+private:
+ typedef GrResourceKey INHERITED;
+
public:
- /** Flags set by the GrGpuResource subclass. */
- typedef uint8_t ResourceFlags;
+ /** Uniquely identifies the type of resource that is cached as scratch. */
+ typedef uint32_t ResourceType;
- /** Creates a key for resource */
- GrResourceKey(const GrCacheID& id, ResourceFlags flags) {
- this->init(id.getDomain(), id.getKey(), flags);
- };
+ /** Generate a unique ResourceType. */
+ static ResourceType GenerateResourceType();
- GrResourceKey(const GrResourceKey& src) { fKey = src.fKey; }
+ /** Creates an invalid scratch key. It must be initialized using a Builder object before use. */
+ GrScratchKey() {}
- GrResourceKey() { fKey.reset(); }
+ GrScratchKey(const GrScratchKey& that) { *this = that; }
- void reset(const GrCacheID& id, ResourceFlags flags) {
- this->init(id.getDomain(), id.getKey(), flags);
- }
+ /** reset() returns the key to the invalid state. */
+ using INHERITED::reset;
+
+ using INHERITED::isValid;
- uint32_t getHash() const { return fKey.getHash(); }
+ ResourceType resourceType() const { return this->domain(); }
- ResourceFlags getResourceFlags() const {
- return *reinterpret_cast<const ResourceFlags*>(fKey.getData() +
- kResourceFlagsOffset);
+ GrScratchKey& operator=(const GrScratchKey& that) {
+ this->INHERITED::operator=(that);
+ return *this;
}
- bool operator==(const GrResourceKey& other) const { return fKey == other.fKey; }
+ bool operator==(const GrScratchKey& that) const {
+ return this->INHERITED::operator==(that);
+ }
+ bool operator!=(const GrScratchKey& that) const { return !(*this == that); }
- // A key indicating that the resource is not usable as a scratch resource.
- static GrResourceKey& NullScratchKey();
+ class Builder : public INHERITED::Builder {
+ public:
+ Builder(GrScratchKey* key, ResourceType type, int data32Count)
+ : INHERITED::Builder(key, type, data32Count) {}
+ };
+};
+/**
+ * A key used to cache resources based on their content. The key consists of a domain type (use
+ * case for the cache), a hash, a data length, and domain-specific data. A Builder object is used to
+ * initialize the key contents. The contents must be initialized before the key can be used.
+ */
+class GrContentKey : public GrResourceKey {
private:
- enum {
- kCacheIDKeyOffset = 0,
- kCacheIDDomainOffset = kCacheIDKeyOffset + sizeof(GrCacheID::Key),
- kResourceFlagsOffset = kCacheIDDomainOffset + sizeof(GrCacheID::Domain),
- kPadOffset = kResourceFlagsOffset + sizeof(ResourceFlags),
- kKeySize = SkAlign4(kPadOffset),
- kPadSize = kKeySize - kPadOffset
- };
+ typedef GrResourceKey INHERITED;
+
+public:
+ typedef uint32_t Domain;
+ /** Generate a unique Domain of content keys. */
+ static Domain GenerateDomain();
+
+ /** Creates an invalid content key. It must be initialized using a Builder object before use. */
+ GrContentKey() {}
+
+ GrContentKey(const GrContentKey& that) { *this = that; }
- void init(const GrCacheID::Domain domain, const GrCacheID::Key& key, ResourceFlags flags) {
- union {
- uint8_t fKey8[kKeySize];
- uint32_t fKey32[kKeySize / 4];
- } keyData;
-
- uint8_t* k = keyData.fKey8;
- memcpy(k + kCacheIDKeyOffset, key.fData8, sizeof(GrCacheID::Key));
- memcpy(k + kCacheIDDomainOffset, &domain, sizeof(GrCacheID::Domain));
- memcpy(k + kResourceFlagsOffset, &flags, sizeof(ResourceFlags));
- memset(k + kPadOffset, 0, kPadSize);
- fKey.setKeyData(keyData.fKey32);
+ /** reset() returns the key to the invalid state. */
+ using INHERITED::reset;
+
+ using INHERITED::isValid;
+
+ GrContentKey& operator=(const GrContentKey& that) {
+ this->INHERITED::operator=(that);
+ return *this;
+ }
+
+ bool operator==(const GrContentKey& that) const {
+ return this->INHERITED::operator==(that);
}
- GrBinHashKey<kKeySize> fKey;
+ bool operator!=(const GrContentKey& that) const { return !(*this == that); }
+
+ class Builder : public INHERITED::Builder {
+ public:
+ Builder(GrContentKey* key, Domain domain, int data32Count)
+ : INHERITED::Builder(key, domain, data32Count) {}
+
+ /** Used to build a key that wraps another key and adds additional data. */
+ Builder(GrContentKey* key, const GrContentKey& innerKey, Domain domain,
+ int extraData32Cnt)
+ : INHERITED::Builder(key, domain, (SkToInt(innerKey.size()) >> 2) + extraData32Cnt) {
+ int innerKeyCnt = SkToInt(innerKey.size()) >> 2;
+ // add the inner key to the end of the key so that op[] can be indexed normally.
+ for (int i = 0; i < innerKeyCnt; ++i) {
+ this->operator[](extraData32Cnt + i) = innerKey.data()[i];
+ }
+ }
+ };
};
#endif