aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--bench/GrResourceCacheBench.cpp3
-rw-r--r--include/gpu/GrGpuResource.h7
-rw-r--r--include/gpu/GrResourceKey.h129
-rwxr-xr-xsrc/gpu/GrContext.cpp10
-rw-r--r--src/gpu/GrGpu.cpp3
-rw-r--r--src/gpu/GrGpuResource.cpp17
-rw-r--r--src/gpu/GrGpuResourceCacheAccess.h7
-rw-r--r--src/gpu/GrPath.cpp3
-rw-r--r--src/gpu/GrPathRange.h8
-rw-r--r--src/gpu/GrResourceCache2.cpp46
-rw-r--r--src/gpu/GrResourceCache2.h13
-rw-r--r--src/gpu/GrStencilAndCoverTextContext.cpp3
-rw-r--r--src/gpu/GrStencilBuffer.cpp38
-rw-r--r--src/gpu/GrStencilBuffer.h6
-rw-r--r--src/gpu/GrTexture.cpp41
-rw-r--r--src/gpu/GrTexturePriv.h7
-rw-r--r--tests/ResourceCacheTest.cpp64
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));
}
}