diff options
author | bsalomon <bsalomon@google.com> | 2015-01-23 04:24:04 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-23 04:24:05 -0800 |
commit | 24db3b1c35fb935660229da164fc5ad31977387f (patch) | |
tree | be22e794f54605ff37ef09df79b3e0869572b053 /include/gpu/GrResourceKey.h | |
parent | f98f2bb0e72df68320f707c8584e3c877ce98ec3 (diff) |
Add specialized content key class for resources.
Review URL: https://codereview.chromium.org/858123002
Diffstat (limited to 'include/gpu/GrResourceKey.h')
-rw-r--r-- | include/gpu/GrResourceKey.h | 227 |
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 |