diff options
-rw-r--r-- | bench/GrResourceCacheBench.cpp | 3 | ||||
-rw-r--r-- | include/gpu/GrGpuResource.h | 7 | ||||
-rw-r--r-- | include/gpu/GrResourceKey.h | 129 | ||||
-rwxr-xr-x | src/gpu/GrContext.cpp | 10 | ||||
-rw-r--r-- | src/gpu/GrGpu.cpp | 3 | ||||
-rw-r--r-- | src/gpu/GrGpuResource.cpp | 17 | ||||
-rw-r--r-- | src/gpu/GrGpuResourceCacheAccess.h | 7 | ||||
-rw-r--r-- | src/gpu/GrPath.cpp | 3 | ||||
-rw-r--r-- | src/gpu/GrPathRange.h | 8 | ||||
-rw-r--r-- | src/gpu/GrResourceCache2.cpp | 46 | ||||
-rw-r--r-- | src/gpu/GrResourceCache2.h | 13 | ||||
-rw-r--r-- | src/gpu/GrStencilAndCoverTextContext.cpp | 3 | ||||
-rw-r--r-- | src/gpu/GrStencilBuffer.cpp | 38 | ||||
-rw-r--r-- | src/gpu/GrStencilBuffer.h | 6 | ||||
-rw-r--r-- | src/gpu/GrTexture.cpp | 41 | ||||
-rw-r--r-- | src/gpu/GrTexturePriv.h | 7 | ||||
-rw-r--r-- | tests/ResourceCacheTest.cpp | 64 |
17 files changed, 207 insertions, 198 deletions
diff --git a/bench/GrResourceCacheBench.cpp b/bench/GrResourceCacheBench.cpp index e30dd3052f..491823b5b8 100644 --- a/bench/GrResourceCacheBench.cpp +++ b/bench/GrResourceCacheBench.cpp @@ -32,9 +32,8 @@ public: GrCacheID::Key key; memset(&key, 0, sizeof(key)); key.fData32[0] = i; - static int gType = GrResourceKey::GenerateResourceType(); static int gDomain = GrCacheID::GenerateDomain(); - return GrResourceKey(GrCacheID(gDomain, key), gType, 0); + return GrResourceKey(GrCacheID(gDomain, key), 0); } diff --git a/include/gpu/GrGpuResource.h b/include/gpu/GrGpuResource.h index 338e161ac3..8c888410bf 100644 --- a/include/gpu/GrGpuResource.h +++ b/include/gpu/GrGpuResource.h @@ -228,7 +228,7 @@ protected: * Optionally called by the GrGpuResource subclass if the resource can be used as scratch. * By default resources are not usable as scratch. This should only be called once. **/ - void setScratchKey(const GrResourceKey& scratchKey); + void setScratchKey(const GrScratchKey& scratchKey); private: /** @@ -274,9 +274,8 @@ private: kContentKeySet_Flag = 0x4, }; - // TODO(bsalomon): Remove GrResourceKey and use different simpler types for content and scratch - // keys. - GrResourceKey fScratchKey; + GrScratchKey fScratchKey; + // TODO(bsalomon): Remove GrResourceKey and use different simpler type for content keys. GrResourceKey fContentKey; // This is not ref'ed but abandon() or release() will be called before the GrGpu object diff --git a/include/gpu/GrResourceKey.h b/include/gpu/GrResourceKey.h index 6a9ff89521..f662ed5511 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); diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 3c23032416..e6fd3589ac 100755 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -411,7 +411,8 @@ GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& inDesc, ScratchTexM } do { - GrResourceKey key = GrTexturePriv::ComputeScratchKey(*desc); + GrScratchKey key; + GrTexturePriv::ComputeScratchKey(*desc, &key); uint32_t scratchFlags = 0; if (calledDuringFlush) { scratchFlags = GrResourceCache2::kRequireNoPendingIO_ScratchFlag; @@ -445,8 +446,11 @@ GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& inDesc, ScratchTexM } GrTexture* texture = fGpu->createTexture(*desc, NULL, 0); - SkASSERT(NULL == texture || - texture->cacheAccess().getScratchKey() == GrTexturePriv::ComputeScratchKey(*desc)); +#ifdef SK_DEBUG + GrScratchKey key; + GrTexturePriv::ComputeScratchKey(*desc, &key); + SkASSERT(NULL == texture || texture->cacheAccess().getScratchKey() == key); +#endif return texture; } diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index de9e26fe95..23a7fde9e9 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -76,7 +76,8 @@ GrTexture* GrGpu::createTexture(const GrSurfaceDesc& desc, bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) { SkASSERT(NULL == rt->getStencilBuffer()); - GrResourceKey sbKey = GrStencilBuffer::ComputeKey(rt->width(), rt->height(), rt->numSamples()); + GrScratchKey sbKey; + GrStencilBuffer::ComputeKey(rt->width(), rt->height(), rt->numSamples(), &sbKey); SkAutoTUnref<GrStencilBuffer> sb(static_cast<GrStencilBuffer*>( this->getContext()->getResourceCache2()->findAndRefScratchResource(sbKey))); if (sb) { diff --git a/src/gpu/GrGpuResource.cpp b/src/gpu/GrGpuResource.cpp index 2a5718aefa..b2fad0b3f7 100644 --- a/src/gpu/GrGpuResource.cpp +++ b/src/gpu/GrGpuResource.cpp @@ -19,8 +19,7 @@ static inline GrResourceCache2* get_resource_cache2(GrGpu* gpu) { } GrGpuResource::GrGpuResource(GrGpu* gpu, bool isWrapped) - : fScratchKey(GrResourceKey::NullScratchKey()) - , fGpu(gpu) + : fGpu(gpu) , fGpuMemorySize(kInvalidGpuMemorySize) , fUniqueID(CreateUniqueID()) { if (isWrapped) { @@ -91,7 +90,6 @@ void GrGpuResource::didChangeGpuMemorySize() const { bool GrGpuResource::setContentKey(const GrResourceKey& contentKey) { // Currently this can only be called once and can't be called when the resource is scratch. - SkASSERT(!contentKey.isScratch()); SkASSERT(this->internalHasRef()); // Wrapped resources can never have a key. @@ -123,11 +121,10 @@ void GrGpuResource::notifyIsPurgable() const { } } -void GrGpuResource::setScratchKey(const GrResourceKey& scratchKey) { - SkASSERT(fScratchKey.isNullScratch()); - SkASSERT(scratchKey.isScratch()); - SkASSERT(!scratchKey.isNullScratch()); - // Wrapped resources can never have a key. +void GrGpuResource::setScratchKey(const GrScratchKey& scratchKey) { + SkASSERT(!fScratchKey.isValid()); + SkASSERT(scratchKey.isValid()); + // Wrapped resources can never have a scratch key. if (this->isWrapped()) { return; } @@ -135,9 +132,9 @@ void GrGpuResource::setScratchKey(const GrResourceKey& scratchKey) { } void GrGpuResource::removeScratchKey() { - if (!this->wasDestroyed() && !fScratchKey.isNullScratch()) { + if (!this->wasDestroyed() && fScratchKey.isValid()) { get_resource_cache2(fGpu)->resourceAccess().willRemoveScratchKey(this); - fScratchKey = GrResourceKey::NullScratchKey(); + fScratchKey.reset(); } } diff --git a/src/gpu/GrGpuResourceCacheAccess.h b/src/gpu/GrGpuResourceCacheAccess.h index e220e5f263..475317ddb2 100644 --- a/src/gpu/GrGpuResourceCacheAccess.h +++ b/src/gpu/GrGpuResourceCacheAccess.h @@ -38,16 +38,15 @@ public: * not have a content key. */ bool isScratch() const { - SkASSERT(fResource->fScratchKey.isScratch()); - return NULL == this->getContentKey() && !fResource->fScratchKey.isNullScratch(); + return NULL == this->getContentKey() && fResource->fScratchKey.isValid(); } /** * If this resource can be used as a scratch resource this returns a valid scratch key. * Otherwise it returns a key for which isNullScratch is true. The resource may currently be - * used as content resource rather than scratch. Check isScratch(). + * used as a content resource rather than scratch. Check isScratch(). */ - const GrResourceKey& getScratchKey() const { return fResource->fScratchKey; } + const GrScratchKey& getScratchKey() const { return fResource->fScratchKey; } /** * If the resource has a scratch key, the key will be removed. Since scratch keys are installed diff --git a/src/gpu/GrPath.cpp b/src/gpu/GrPath.cpp index 5426e498f0..eb956fbf65 100644 --- a/src/gpu/GrPath.cpp +++ b/src/gpu/GrPath.cpp @@ -14,7 +14,6 @@ template<int NumBits> static uint64_t get_top_n_float_bits(float f) { } GrResourceKey GrPath::ComputeKey(const SkPath& path, const SkStrokeRec& stroke) { - static const GrResourceKey::ResourceType gPathResourceType = GrResourceKey::GenerateResourceType(); static const GrCacheID::Domain gPathDomain = GrCacheID::GenerateDomain(); GrCacheID::Key key; @@ -22,7 +21,7 @@ GrResourceKey GrPath::ComputeKey(const SkPath& path, const SkStrokeRec& stroke) keyData[0] = path.getGenerationID(); keyData[1] = ComputeStrokeKey(stroke); - return GrResourceKey(GrCacheID(gPathDomain, key), gPathResourceType, 0); + return GrResourceKey(GrCacheID(gPathDomain, key), 0); } uint64_t GrPath::ComputeStrokeKey(const SkStrokeRec& stroke) { diff --git a/src/gpu/GrPathRange.h b/src/gpu/GrPathRange.h index a1431b93c7..014b7ece74 100644 --- a/src/gpu/GrPathRange.h +++ b/src/gpu/GrPathRange.h @@ -28,14 +28,6 @@ public: static const bool kIsWrapped = false; - /** - * Return the resourceType intended for cache lookups involving GrPathRange. - */ - static GrResourceKey::ResourceType resourceType() { - static const GrResourceKey::ResourceType type = GrResourceKey::GenerateResourceType(); - return type; - } - enum PathIndexType { kU8_PathIndexType, //!< uint8_t kU16_PathIndexType, //!< uint16_t diff --git a/src/gpu/GrResourceCache2.cpp b/src/gpu/GrResourceCache2.cpp index 39181554d2..ccfe382733 100644 --- a/src/gpu/GrResourceCache2.cpp +++ b/src/gpu/GrResourceCache2.cpp @@ -10,6 +10,7 @@ #include "GrResourceCache2.h" #include "GrGpuResource.h" +#include "SkChecksum.h" #include "SkGr.h" #include "SkMessageBus.h" @@ -17,32 +18,26 @@ DECLARE_SKMESSAGEBUS_MESSAGE(GrResourceInvalidatedMessage); ////////////////////////////////////////////////////////////////////////////// -GrResourceKey& GrResourceKey::NullScratchKey() { - static const GrCacheID::Key kBogusKey = { { {0} } }; - static GrCacheID kBogusID(ScratchDomain(), kBogusKey); - static GrResourceKey kNullScratchKey(kBogusID, NoneResourceType(), 0); - return kNullScratchKey; -} +GrScratchKey::ResourceType GrScratchKey::GenerateResourceType() { + static int32_t gType = kInvalidResourceType + 1; -GrResourceKey::ResourceType GrResourceKey::NoneResourceType() { - static const ResourceType gNoneResourceType = GenerateResourceType(); - return gNoneResourceType; -} + int32_t type = sk_atomic_inc(&gType); + if (kInvalidResourceType == type) { + SkFAIL("Too many Resource Types"); + } -GrCacheID::Domain GrResourceKey::ScratchDomain() { - static const GrCacheID::Domain gDomain = GrCacheID::GenerateDomain(); - return gDomain; + return static_cast<ResourceType>(type); } -GrResourceKey::ResourceType GrResourceKey::GenerateResourceType() { - static int32_t gNextType = 0; - int32_t type = sk_atomic_inc(&gNextType); - if (type >= (1 << 8 * sizeof(ResourceType))) { - SkFAIL("Too many Resource Types"); +void GrScratchKey::Builder::finish() { + if (NULL == fKey) { + return; } - - return static_cast<ResourceType>(type); + GR_STATIC_ASSERT(0 == kHash_MetaDataIdx); + fKey->fKey[kHash_MetaDataIdx] = + SkChecksum::Compute(&fKey->fKey[kHash_MetaDataIdx + 1], fKey->size() - sizeof(uint32_t)); + fKey = NULL; } ////////////////////////////////////////////////////////////////////////////// @@ -111,7 +106,7 @@ void GrResourceCache2::insertResource(GrGpuResource* resource) { fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes); #endif } - if (!resource->cacheAccess().getScratchKey().isNullScratch()) { + if (resource->cacheAccess().getScratchKey().isValid()) { SkASSERT(!resource->cacheAccess().isWrapped()); fScratchMap.insert(resource->cacheAccess().getScratchKey(), resource); } @@ -131,7 +126,7 @@ void GrResourceCache2::removeResource(GrGpuResource* resource) { } fResources.remove(resource); - if (!resource->cacheAccess().getScratchKey().isNullScratch()) { + if (resource->cacheAccess().getScratchKey().isValid()) { fScratchMap.remove(resource->cacheAccess().getScratchKey(), resource); } if (const GrResourceKey* contentKey = resource->cacheAccess().getContentKey()) { @@ -190,10 +185,10 @@ private: bool fRejectPendingIO; }; -GrGpuResource* GrResourceCache2::findAndRefScratchResource(const GrResourceKey& scratchKey, +GrGpuResource* GrResourceCache2::findAndRefScratchResource(const GrScratchKey& scratchKey, uint32_t flags) { SkASSERT(!fPurging); - SkASSERT(scratchKey.isScratch()); + SkASSERT(scratchKey.isValid()); GrGpuResource* resource; if (flags & (kPreferNoPendingIO_ScratchFlag | kRequireNoPendingIO_ScratchFlag)) { @@ -228,7 +223,6 @@ bool GrResourceCache2::didSetContentKey(GrGpuResource* resource) { SkASSERT(resource); SkASSERT(this->isInCache(resource)); SkASSERT(resource->cacheAccess().getContentKey()); - SkASSERT(!resource->cacheAccess().getContentKey()->isScratch()); GrGpuResource* res = fContentHash.find(*resource->cacheAccess().getContentKey()); if (NULL != res) { @@ -414,7 +408,7 @@ void GrResourceCache2::validate() const { ++scratch; SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchKey())); SkASSERT(!resource->cacheAccess().isWrapped()); - } else if (!resource->cacheAccess().getScratchKey().isNullScratch()) { + } else if (resource->cacheAccess().getScratchKey().isValid()) { SkASSERT(NULL != resource->cacheAccess().getContentKey()); ++couldBeScratch; SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchKey())); diff --git a/src/gpu/GrResourceCache2.h b/src/gpu/GrResourceCache2.h index 038e3bc242..5733cff664 100644 --- a/src/gpu/GrResourceCache2.h +++ b/src/gpu/GrResourceCache2.h @@ -98,12 +98,11 @@ public: /** * Find a resource that matches a scratch key. */ - GrGpuResource* findAndRefScratchResource(const GrResourceKey& scratchKey, uint32_t flags = 0); + GrGpuResource* findAndRefScratchResource(const GrScratchKey& scratchKey, uint32_t flags = 0); #ifdef SK_DEBUG // This is not particularly fast and only used for validation, so debug only. - int countScratchEntriesForKey(const GrResourceKey& scratchKey) const { - SkASSERT(scratchKey.isScratch()); + int countScratchEntriesForKey(const GrScratchKey& scratchKey) const { return fScratchMap.countForKey(scratchKey); } #endif @@ -112,7 +111,6 @@ public: * Find a resource that matches a content key. */ GrGpuResource* findAndRefContentResource(const GrResourceKey& contentKey) { - SkASSERT(!contentKey.isScratch()); GrGpuResource* resource = fContentHash.find(contentKey); if (resource) { resource->ref(); @@ -125,7 +123,6 @@ public: * Query whether a content key exists in the cache. */ bool hasContentKey(const GrResourceKey& contentKey) const { - SkASSERT(!contentKey.isScratch()); return SkToBool(fContentHash.find(contentKey)); } @@ -187,13 +184,13 @@ private: class AvailableForScratchUse; struct ScratchMapTraits { - static const GrResourceKey& GetKey(const GrGpuResource& r) { + static const GrScratchKey& GetKey(const GrGpuResource& r) { return r.cacheAccess().getScratchKey(); } - static uint32_t Hash(const GrResourceKey& key) { return key.getHash(); } + static uint32_t Hash(const GrScratchKey& key) { return key.hash(); } }; - typedef SkTMultiMap<GrGpuResource, GrResourceKey, ScratchMapTraits> ScratchMap; + typedef SkTMultiMap<GrGpuResource, GrScratchKey, ScratchMapTraits> ScratchMap; struct ContentHashTraits { static const GrResourceKey& GetKey(const GrGpuResource& r) { diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp index 59995d0760..6447ca523a 100644 --- a/src/gpu/GrStencilAndCoverTextContext.cpp +++ b/src/gpu/GrStencilAndCoverTextContext.cpp @@ -212,8 +212,7 @@ static GrPathRange* get_gr_glyphs(GrContext* ctx, keyData[0] = desc ? desc->getChecksum() : 0; keyData[0] = (keyData[0] << 32) | (typeface ? typeface->uniqueID() : 0); keyData[1] = GrPath::ComputeStrokeKey(stroke); - GrResourceKey resourceKey = GrResourceKey(GrCacheID(gGlyphsDomain, key), - GrPathRange::resourceType(), 0); + GrResourceKey resourceKey = GrResourceKey(GrCacheID(gGlyphsDomain, key), 0); SkAutoTUnref<GrPathRange> glyphs( static_cast<GrPathRange*>(ctx->findAndRefCachedResource(resourceKey))); diff --git a/src/gpu/GrStencilBuffer.cpp b/src/gpu/GrStencilBuffer.cpp index 5aa56e0717..be463a0ccf 100644 --- a/src/gpu/GrStencilBuffer.cpp +++ b/src/gpu/GrStencilBuffer.cpp @@ -7,35 +7,13 @@ */ #include "GrStencilBuffer.h" +#include "GrResourceKey.h" -#include "GrContext.h" -#include "GrGpu.h" -#include "GrResourceCache2.h" - -namespace { -// we should never have more than one stencil buffer with same combo of (width,height,samplecount) -void gen_cache_id(int width, int height, int sampleCnt, GrCacheID* cacheID) { - static const GrCacheID::Domain gStencilBufferDomain = GrResourceKey::ScratchDomain(); - GrCacheID::Key key; - uint32_t* keyData = key.fData32; - keyData[0] = width; - keyData[1] = height; - keyData[2] = sampleCnt; - memset(keyData + 3, 0, sizeof(key) - 3 * sizeof(uint32_t)); - GR_STATIC_ASSERT(sizeof(key) >= 3 * sizeof(uint32_t)); - cacheID->reset(gStencilBufferDomain, key); -} -} - -GrResourceKey GrStencilBuffer::ComputeKey(int width, - int height, - int sampleCnt) { - // All SBs are created internally to attach to RTs so they all use the same domain. - static const GrResourceKey::ResourceType gStencilBufferResourceType = - GrResourceKey::GenerateResourceType(); - GrCacheID id; - gen_cache_id(width, height, sampleCnt, &id); - - // we don't use any flags for SBs currently. - return GrResourceKey(id, gStencilBufferResourceType, 0); +void GrStencilBuffer::ComputeKey(int width, int height, int sampleCnt, GrScratchKey* key) { + static const GrScratchKey::ResourceType kType = GrScratchKey::GenerateResourceType(); + GrScratchKey::Builder builder(key, kType, 2); + SkASSERT(width <= SK_MaxU16); + SkASSERT(height <= SK_MaxU16); + builder[0] = width | (height << 16); + builder[1] = sampleCnt; } diff --git a/src/gpu/GrStencilBuffer.h b/src/gpu/GrStencilBuffer.h index 187556bd4c..11eceddb4e 100644 --- a/src/gpu/GrStencilBuffer.h +++ b/src/gpu/GrStencilBuffer.h @@ -47,7 +47,7 @@ public: !fLastClipStackRect.contains(clipSpaceRect); } - static GrResourceKey ComputeKey(int width, int height, int sampleCnt); + static void ComputeKey(int width, int height, int sampleCnt, GrScratchKey* key); protected: GrStencilBuffer(GrGpu* gpu, bool isWrapped, int width, int height, int bits, int sampleCnt) @@ -57,7 +57,9 @@ protected: , fBits(bits) , fSampleCnt(sampleCnt) , fLastClipStackGenID(SkClipStack::kInvalidGenID) { - this->setScratchKey(ComputeKey(width, height, sampleCnt)); + GrScratchKey key; + ComputeKey(width, height, sampleCnt, &key); + this->setScratchKey(key); fLastClipStackRect.setEmpty(); } diff --git a/src/gpu/GrTexture.cpp b/src/gpu/GrTexture.cpp index e5d0fcc032..eb518f5635 100644 --- a/src/gpu/GrTexture.cpp +++ b/src/gpu/GrTexture.cpp @@ -9,6 +9,7 @@ #include "GrContext.h" #include "GrDrawTargetCaps.h" #include "GrGpu.h" +#include "GrResourceKey.h" #include "GrTexture.h" #include "GrTexturePriv.h" @@ -122,7 +123,9 @@ GrTexture::GrTexture(GrGpu* gpu, bool isWrapped, const GrSurfaceDesc& desc) , fMipMapsStatus(kNotAllocated_MipMapsStatus) { if (!isWrapped) { - this->setScratchKey(GrTexturePriv::ComputeScratchKey(desc)); + GrScratchKey key; + GrTexturePriv::ComputeScratchKey(desc, &key); + this->setScratchKey(key); } // only make sense if alloc size is pow2 fShiftFixedX = 31 - SkCLZ(fDesc.fWidth); @@ -134,26 +137,26 @@ GrResourceKey GrTexturePriv::ComputeKey(const GrGpu* gpu, const GrSurfaceDesc& desc, const GrCacheID& cacheID) { GrResourceKey::ResourceFlags flags = get_texture_flags(gpu, params, desc); - return GrResourceKey(cacheID, ResourceType(), flags); + return GrResourceKey(cacheID, flags); } -GrResourceKey GrTexturePriv::ComputeScratchKey(const GrSurfaceDesc& desc) { - GrCacheID::Key idKey; - // Instead of a client-provided key of the texture contents we create a key from the - // descriptor. - GR_STATIC_ASSERT(sizeof(idKey) >= 16); - SkASSERT(desc.fHeight < (1 << 16)); - SkASSERT(desc.fWidth < (1 << 16)); - idKey.fData32[0] = (desc.fWidth) | (desc.fHeight << 16); - idKey.fData32[1] = desc.fConfig | desc.fSampleCnt << 16; - idKey.fData32[2] = desc.fFlags; - idKey.fData32[3] = resolve_origin(desc); // Only needs 2 bits actually - static const int kPadSize = sizeof(idKey) - 16; - GR_STATIC_ASSERT(kPadSize >= 0); - memset(idKey.fData8 + 16, 0, kPadSize); - - GrCacheID cacheID(GrResourceKey::ScratchDomain(), idKey); - return GrResourceKey(cacheID, ResourceType(), 0); +void GrTexturePriv::ComputeScratchKey(const GrSurfaceDesc& desc, GrScratchKey* key) { + static const GrScratchKey::ResourceType kType = GrScratchKey::GenerateResourceType(); + + GrScratchKey::Builder builder(key, kType, 2); + + GrSurfaceOrigin origin = resolve_origin(desc); + uint32_t flags = desc.fFlags & ~kCheckAllocation_GrSurfaceFlag; + + SkASSERT(desc.fWidth <= SK_MaxU16); + SkASSERT(desc.fHeight <= SK_MaxU16); + SkASSERT(static_cast<int>(desc.fConfig) < (1 << 6)); + SkASSERT(desc.fSampleCnt < (1 << 8)); + SkASSERT(flags < (1 << 10)); + SkASSERT(static_cast<int>(origin) < (1 << 8)); + + builder[0] = desc.fWidth | (desc.fHeight << 16); + builder[1] = desc.fConfig | (desc.fSampleCnt << 6) | (flags << 14) | (origin << 24); } bool GrTexturePriv::NeedsResizing(const GrResourceKey& key) { diff --git a/src/gpu/GrTexturePriv.h b/src/gpu/GrTexturePriv.h index d6c2dc2bf8..c093a9bbc6 100644 --- a/src/gpu/GrTexturePriv.h +++ b/src/gpu/GrTexturePriv.h @@ -39,16 +39,11 @@ public: return GrTexture::kNotAllocated_MipMapsStatus != fTexture->fMipMapsStatus; } - static GrResourceKey::ResourceType ResourceType() { - static const GrResourceKey::ResourceType gType = GrResourceKey::GenerateResourceType(); - return gType; - } - static GrResourceKey ComputeKey(const GrGpu* gpu, const GrTextureParams* params, const GrSurfaceDesc& desc, const GrCacheID& cacheID); - static GrResourceKey ComputeScratchKey(const GrSurfaceDesc& desc); + static void ComputeScratchKey(const GrSurfaceDesc&, GrScratchKey*); static bool NeedsResizing(const GrResourceKey& key); static bool NeedsBilerp(const GrResourceKey& key); diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp index f925b07754..a1a594e1dd 100644 --- a/tests/ResourceCacheTest.cpp +++ b/tests/ResourceCacheTest.cpp @@ -82,7 +82,7 @@ public: this->registerWithCache(); } - TestResource(GrGpu* gpu, const GrResourceKey& scratchKey) + TestResource(GrGpu* gpu, const GrScratchKey& scratchKey) : INHERITED(gpu, false) , fToDelete(NULL) , fSize(kDefaultSize) { @@ -173,6 +173,11 @@ static void test_no_key(skiatest::Reporter* reporter) { REPORTER_ASSERT(reporter, 0 == cache2->getResourceBytes()); } +static void make_scratch_key(GrScratchKey* key) { + static GrScratchKey::ResourceType t = GrScratchKey::GenerateResourceType(); + GrScratchKey::Builder builder(key, t, 0); +} + static void test_budgeting(skiatest::Reporter* reporter) { SkAutoTUnref<GrContext> context(GrContext::CreateMockContext()); REPORTER_ASSERT(reporter, SkToBool(context)); @@ -185,11 +190,12 @@ static void test_budgeting(skiatest::Reporter* reporter) { SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes()); SkASSERT(0 == cache2->getBudgetedResourceCount() && 0 == cache2->getBudgetedResourceBytes()); + GrScratchKey scratchKey; + make_scratch_key(&scratchKey); + GrCacheID::Key keyData; memset(&keyData, 0, sizeof(keyData)); - GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); - GrResourceKey scratchKey(GrCacheID(GrResourceKey::ScratchDomain(), keyData), t, 0); - GrResourceKey contentKey(GrCacheID(GrCacheID::GenerateDomain(), keyData), t, 0); + GrResourceKey contentKey(GrCacheID(GrCacheID::GenerateDomain(), keyData), 0); // Create a scratch, a content, and a wrapped resource TestResource* scratch = new TestResource(context->getGpu(), scratchKey); @@ -205,7 +211,7 @@ static void test_budgeting(skiatest::Reporter* reporter) { // Make sure we can't add a content key to the wrapped resource keyData.fData8[0] = 1; - GrResourceKey contentKey2(GrCacheID(GrCacheID::GenerateDomain(), keyData), t, 0); + GrResourceKey contentKey2(GrCacheID(GrCacheID::GenerateDomain(), keyData), 0); REPORTER_ASSERT(reporter, !wrapped->cacheAccess().setContentKey(contentKey2)); REPORTER_ASSERT(reporter, NULL == cache2->findAndRefContentResource(contentKey2)); @@ -277,11 +283,8 @@ static void test_duplicate_scratch_key(skiatest::Reporter* reporter) { cache2->purgeAllUnlocked(); SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes()); - GrCacheID::Key keyData; - memset(&keyData, 0, sizeof(keyData)); - GrCacheID::Domain domain = GrResourceKey::ScratchDomain(); - GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); - GrResourceKey scratchKey(GrCacheID(domain, keyData), t, 0); + GrScratchKey scratchKey; + make_scratch_key(&scratchKey); // Create two resources that have the same scratch key. TestResource* a = new TestResource(context->getGpu(), scratchKey); @@ -324,11 +327,8 @@ static void test_remove_scratch_key(skiatest::Reporter* reporter) { cache2->purgeAllUnlocked(); SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes()); - GrCacheID::Key keyData; - memset(&keyData, 0, sizeof(keyData)); - GrCacheID::Domain domain = GrResourceKey::ScratchDomain(); - GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); - GrResourceKey scratchKey(GrCacheID(domain, keyData), t, 0); + GrScratchKey scratchKey; + make_scratch_key(&scratchKey); // Create two resources that have the same scratch key. TestResource* a = new TestResource(context->getGpu(), scratchKey); @@ -389,8 +389,7 @@ static void test_duplicate_content_key(skiatest::Reporter* reporter) { GrCacheID::Domain domain = GrCacheID::GenerateDomain(); GrCacheID::Key keyData; memset(&keyData, 0, sizeof(keyData)); - GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); - GrResourceKey key(GrCacheID(domain, keyData), t, 0); + GrResourceKey key(GrCacheID(domain, keyData), 0); // Create two resources that we will attempt to register with the same content key. TestResource* a = new TestResource(context->getGpu()); @@ -442,14 +441,12 @@ static void test_purge_invalidated(skiatest::Reporter* reporter) { GrCacheID::Key keyData; memset(&keyData, 0, sizeof(keyData)); - GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); - keyData.fData64[0] = 1; - GrResourceKey key1(GrCacheID(domain, keyData), t, 0); + GrResourceKey key1(GrCacheID(domain, keyData), 0); keyData.fData64[0] = 2; - GrResourceKey key2(GrCacheID(domain, keyData), t, 0); + GrResourceKey key2(GrCacheID(domain, keyData), 0); keyData.fData64[0] = 3; - GrResourceKey key3(GrCacheID(domain, keyData), t, 0); + GrResourceKey key3(GrCacheID(domain, keyData), 0); context->setResourceCacheLimits(5, 30000); GrResourceCache2* cache2 = context->getResourceCache2(); @@ -510,13 +507,12 @@ static void test_cache_chained_purge(skiatest::Reporter* reporter) { GrCacheID::Domain domain = GrCacheID::GenerateDomain(); GrCacheID::Key keyData; memset(&keyData, 0, sizeof(keyData)); - GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); keyData.fData64[0] = 1; - GrResourceKey key1(GrCacheID(domain, keyData), t, 0); + GrResourceKey key1(GrCacheID(domain, keyData), 0); keyData.fData64[0] = 2; - GrResourceKey key2(GrCacheID(domain, keyData), t, 0); + GrResourceKey key2(GrCacheID(domain, keyData), 0); { context->setResourceCacheLimits(3, 30000); @@ -560,17 +556,16 @@ static void test_resource_size_changed(skiatest::Reporter* reporter) { } GrCacheID::Domain domain = GrCacheID::GenerateDomain(); - GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); GrCacheID::Key key1Data; key1Data.fData64[0] = 0; key1Data.fData64[1] = 0; - GrResourceKey key1(GrCacheID(domain, key1Data), t, 0); + GrResourceKey key1(GrCacheID(domain, key1Data), 0); GrCacheID::Key key2Data; key2Data.fData64[0] = 1; key2Data.fData64[1] = 0; - GrResourceKey key2(GrCacheID(domain, key2Data), t, 0); + GrResourceKey key2(GrCacheID(domain, key2Data), 0); // Test changing resources sizes (both increase & decrease). { @@ -649,7 +644,6 @@ static void test_large_resource_count(skiatest::Reporter* reporter) { GrCacheID::Domain domain0 = GrCacheID::GenerateDomain(); GrCacheID::Domain domain1 = GrCacheID::GenerateDomain(); - GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); GrCacheID::Key keyData; memset(&keyData, 0, sizeof(keyData)); @@ -658,13 +652,13 @@ static void test_large_resource_count(skiatest::Reporter* reporter) { TestResource* resource; keyData.fData32[0] = i; - GrResourceKey key0(GrCacheID(domain0, keyData), t, 0); + GrResourceKey key0(GrCacheID(domain0, keyData), 0); resource = SkNEW_ARGS(TestResource, (context->getGpu())); resource->cacheAccess().setContentKey(key0); resource->setSize(1); resource->unref(); - GrResourceKey key1(GrCacheID(domain1, keyData), t, 0); + GrResourceKey key1(GrCacheID(domain1, keyData), 0); resource = SkNEW_ARGS(TestResource, (context->getGpu())); resource->cacheAccess().setContentKey(key1); resource->setSize(1); @@ -678,9 +672,9 @@ static void test_large_resource_count(skiatest::Reporter* reporter) { REPORTER_ASSERT(reporter, cache2->getResourceCount() == 2 * kResourceCnt); for (int i = 0; i < kResourceCnt; ++i) { keyData.fData32[0] = i; - GrResourceKey key0(GrCacheID(domain0, keyData), t, 0); + GrResourceKey key0(GrCacheID(domain0, keyData), 0); REPORTER_ASSERT(reporter, cache2->hasContentKey(key0)); - GrResourceKey key1(GrCacheID(domain0, keyData), t, 0); + GrResourceKey key1(GrCacheID(domain0, keyData), 0); REPORTER_ASSERT(reporter, cache2->hasContentKey(key1)); } @@ -693,9 +687,9 @@ static void test_large_resource_count(skiatest::Reporter* reporter) { for (int i = 0; i < kResourceCnt; ++i) { keyData.fData32[0] = i; - GrResourceKey key0(GrCacheID(domain0, keyData), t, 0); + GrResourceKey key0(GrCacheID(domain0, keyData), 0); REPORTER_ASSERT(reporter, !cache2->hasContentKey(key0)); - GrResourceKey key1(GrCacheID(domain0, keyData), t, 0); + GrResourceKey key1(GrCacheID(domain0, keyData), 0); REPORTER_ASSERT(reporter, !cache2->hasContentKey(key1)); } } |