Index: include/gpu/GrResourceKey.h |
diff --git a/include/gpu/GrResourceKey.h b/include/gpu/GrResourceKey.h |
index 6a9ff895212c53c81f349701f6139287a50c4fb5..f662ed5511e36aa29ce3a0ac1ad8bc6d0a723d61 100644 |
--- a/include/gpu/GrResourceKey.h |
+++ b/include/gpu/GrResourceKey.h |
@@ -10,48 +10,116 @@ |
#define GrResourceKey_DEFINED |
#include "GrTypes.h" |
+#include "SkTemplates.h" |
#include "GrBinHashKey.h" |
-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: |
- static GrCacheID::Domain ScratchDomain(); |
+ /** Uniquely identifies the type of resource that is cached as scratch. */ |
+ typedef uint32_t ResourceType; |
+ /** Generate a unique ResourceType. */ |
+ static ResourceType GenerateResourceType(); |
+ |
+ GrScratchKey() { this->reset(); } |
+ GrScratchKey(const GrScratchKey& that) { *this = that; } |
+ |
+ /** Reset to an invalid key. */ |
+ void reset() { |
+ fKey.reset(kMetaDataCnt); |
+ fKey[kHash_MetaDataIdx] = 0; |
+ fKey[kTypeAndSize_MetaDataIdx] = kInvalidResourceType; |
+ } |
+ |
+ 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]; } |
+ |
+ GrScratchKey& operator=(const GrScratchKey& that) { |
+ size_t size = that.size(); |
+ fKey.reset(SkToInt(size)); |
+ memcpy(fKey.get(), that.fKey.get(), size); |
+ 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); } |
+ |
+ /** Used to initialize scratch key. */ |
+ class Builder { |
+ public: |
+ Builder(GrScratchKey* key, ResourceType type, int data32Count) : fKey(key) { |
+ SkASSERT(data32Count >= 0); |
+ SkASSERT(type != kInvalidResourceType); |
+ 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); |
+ } |
+ |
+ ~Builder() { this->finish(); } |
+ |
+ void finish(); |
+ |
+ uint32_t& operator[](int dataIdx) { |
+ SkASSERT(fKey); |
+ SkDEBUGCODE(size_t dataCount = fKey->size() / sizeof(uint32_t) - kMetaDataCnt;) |
+ SkASSERT(SkToU32(dataIdx) < dataCount); |
+ return fKey->fKey[kMetaDataCnt + dataIdx]; |
+ } |
+ |
+ private: |
+ GrScratchKey* fKey; |
+ }; |
- /** Uniquely identifies the GrGpuResource subclass in the key to avoid collisions |
- across resource types. */ |
- typedef uint8_t ResourceType; |
+private: |
+ enum MetaDataIdx { |
+ kHash_MetaDataIdx, |
+ // The resource type and size are packed into a single uint32_t. |
+ kTypeAndSize_MetaDataIdx, |
+ |
+ kLastMetaDataIdx = kTypeAndSize_MetaDataIdx |
+ }; |
+ static const uint32_t kInvalidResourceType = 0; |
+ static const uint32_t kMetaDataCnt = kLastMetaDataIdx + 1; |
+ |
+ // Stencil and textures each require 2 uint32_t values. |
+ SkAutoSTArray<kMetaDataCnt + 2, uint32_t> fKey; |
+}; |
+class GrResourceKey { |
+public: |
/** Flags set by the GrGpuResource subclass. */ |
typedef uint8_t ResourceFlags; |
- /** Generate a unique ResourceType */ |
- static ResourceType GenerateResourceType(); |
- |
/** Creates a key for resource */ |
- GrResourceKey(const GrCacheID& id, ResourceType type, ResourceFlags flags) { |
- this->init(id.getDomain(), id.getKey(), type, flags); |
+ GrResourceKey(const GrCacheID& id, ResourceFlags flags) { |
+ this->init(id.getDomain(), id.getKey(), flags); |
}; |
GrResourceKey(const GrResourceKey& src) { fKey = src.fKey; } |
GrResourceKey() { fKey.reset(); } |
- void reset(const GrCacheID& id, ResourceType type, ResourceFlags flags) { |
- this->init(id.getDomain(), id.getKey(), type, flags); |
+ void reset(const GrCacheID& id, ResourceFlags flags) { |
+ this->init(id.getDomain(), id.getKey(), flags); |
} |
uint32_t getHash() const { return fKey.getHash(); } |
- bool isScratch() const { |
- return ScratchDomain() == |
- *reinterpret_cast<const GrCacheID::Domain*>(fKey.getData() + |
- kCacheIDDomainOffset); |
- } |
- |
- ResourceType getResourceType() const { |
- return *reinterpret_cast<const ResourceType*>(fKey.getData() + |
- kResourceTypeOffset); |
- } |
- |
ResourceFlags getResourceFlags() const { |
return *reinterpret_cast<const ResourceFlags*>(fKey.getData() + |
kResourceFlagsOffset); |
@@ -62,27 +130,17 @@ public: |
// A key indicating that the resource is not usable as a scratch resource. |
static GrResourceKey& NullScratchKey(); |
- bool isNullScratch() const { |
- return this->isScratch() && NoneResourceType() == this->getResourceType(); |
- } |
- |
private: |
enum { |
kCacheIDKeyOffset = 0, |
kCacheIDDomainOffset = kCacheIDKeyOffset + sizeof(GrCacheID::Key), |
- kResourceTypeOffset = kCacheIDDomainOffset + sizeof(GrCacheID::Domain), |
- kResourceFlagsOffset = kResourceTypeOffset + sizeof(ResourceType), |
+ kResourceFlagsOffset = kCacheIDDomainOffset + sizeof(GrCacheID::Domain), |
kPadOffset = kResourceFlagsOffset + sizeof(ResourceFlags), |
kKeySize = SkAlign4(kPadOffset), |
kPadSize = kKeySize - kPadOffset |
}; |
- static ResourceType NoneResourceType(); |
- |
- void init(const GrCacheID::Domain domain, |
- const GrCacheID::Key& key, |
- ResourceType type, |
- ResourceFlags flags) { |
+ void init(const GrCacheID::Domain domain, const GrCacheID::Key& key, ResourceFlags flags) { |
union { |
uint8_t fKey8[kKeySize]; |
uint32_t fKey32[kKeySize / 4]; |
@@ -91,7 +149,6 @@ private: |
uint8_t* k = keyData.fKey8; |
memcpy(k + kCacheIDKeyOffset, key.fData8, sizeof(GrCacheID::Key)); |
memcpy(k + kCacheIDDomainOffset, &domain, sizeof(GrCacheID::Domain)); |
- memcpy(k + kResourceTypeOffset, &type, sizeof(ResourceType)); |
memcpy(k + kResourceFlagsOffset, &flags, sizeof(ResourceFlags)); |
memset(k + kPadOffset, 0, kPadSize); |
fKey.setKeyData(keyData.fKey32); |