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 "GrTypes.h" 13 #include "GrBinHashKey.h" 14 15 class GrResourceKey { 16 public: 17 static GrCacheID::Domain ScratchDomain() { 18 static const GrCacheID::Domain gDomain = GrCacheID::GenerateDomain(); 19 return gDomain; 20 } 21 22 /** Uniquely identifies the GrGpuResource subclass in the key to avoid collisions 23 across resource types. */ 24 typedef uint8_t ResourceType; 25 26 /** Flags set by the GrGpuResource subclass. */ 27 typedef uint8_t ResourceFlags; 28 29 /** Generate a unique ResourceType */ 30 static ResourceType GenerateResourceType(); 31 32 /** Creates a key for resource */ 33 GrResourceKey(const GrCacheID& id, ResourceType type, ResourceFlags flags) { 34 this->init(id.getDomain(), id.getKey(), type, flags); 35 }; 36 37 GrResourceKey(const GrResourceKey& src) { fKey = src.fKey; } 38 39 GrResourceKey() { fKey.reset(); } 40 41 void reset(const GrCacheID& id, ResourceType type, ResourceFlags flags) { 42 this->init(id.getDomain(), id.getKey(), type, flags); 43 } 44 45 uint32_t getHash() const { return fKey.getHash(); } 46 47 bool isScratch() const { 48 return ScratchDomain() == 49 *reinterpret_cast<const GrCacheID::Domain*>(fKey.getData() + 50 kCacheIDDomainOffset); 51 } 52 53 ResourceType getResourceType() const { 54 return *reinterpret_cast<const ResourceType*>(fKey.getData() + 55 kResourceTypeOffset); 56 } 57 58 ResourceFlags getResourceFlags() const { 59 return *reinterpret_cast<const ResourceFlags*>(fKey.getData() + 60 kResourceFlagsOffset); 61 } 62 63 bool operator==(const GrResourceKey& other) const { return fKey == other.fKey; } 64 65 // A key indicating that the resource is not usable as a scratch resource. 66 static GrResourceKey& NullScratchKey() { 67 static const GrCacheID::Key kBogusKey = { { {0} } }; 68 static GrCacheID kBogusID(ScratchDomain(), kBogusKey); 69 static GrResourceKey kNullScratchKey(kBogusID, NoneResourceType(), 0); 70 return kNullScratchKey; 71 } 72 73 bool isNullScratch() const { 74 return this->isScratch() && NoneResourceType() == this->getResourceType(); 75 } 76 77 private: 78 enum { 79 kCacheIDKeyOffset = 0, 80 kCacheIDDomainOffset = kCacheIDKeyOffset + sizeof(GrCacheID::Key), 81 kResourceTypeOffset = kCacheIDDomainOffset + sizeof(GrCacheID::Domain), 82 kResourceFlagsOffset = kResourceTypeOffset + sizeof(ResourceType), 83 kPadOffset = kResourceFlagsOffset + sizeof(ResourceFlags), 84 kKeySize = SkAlign4(kPadOffset), 85 kPadSize = kKeySize - kPadOffset 86 }; 87 88 static ResourceType NoneResourceType() { 89 static const ResourceType gNoneResourceType = GenerateResourceType(); 90 return gNoneResourceType; 91 } 92 93 void init(const GrCacheID::Domain domain, 94 const GrCacheID::Key& key, 95 ResourceType type, 96 ResourceFlags flags) { 97 union { 98 uint8_t fKey8[kKeySize]; 99 uint32_t fKey32[kKeySize / 4]; 100 } keyData; 101 102 uint8_t* k = keyData.fKey8; 103 memcpy(k + kCacheIDKeyOffset, key.fData8, sizeof(GrCacheID::Key)); 104 memcpy(k + kCacheIDDomainOffset, &domain, sizeof(GrCacheID::Domain)); 105 memcpy(k + kResourceTypeOffset, &type, sizeof(ResourceType)); 106 memcpy(k + kResourceFlagsOffset, &flags, sizeof(ResourceFlags)); 107 memset(k + kPadOffset, 0, kPadSize); 108 fKey.setKeyData(keyData.fKey32); 109 } 110 GrBinHashKey<kKeySize> fKey; 111 }; 112 113 #endif 114