| Index: include/gpu/GrResourceKey.h
|
| diff --git a/include/gpu/GrResourceKey.h b/include/gpu/GrResourceKey.h
|
| index 1eb7d1fd07402138bb36f51631b504ba7f0e5e0f..ce3e76e2ab61dae415b10761741dd12c021dd50d 100644
|
| --- a/include/gpu/GrResourceKey.h
|
| +++ b/include/gpu/GrResourceKey.h
|
| @@ -14,6 +14,10 @@
|
|
|
| uint32_t GrResourceKeyHash(const uint32_t* data, size_t size);
|
|
|
| +/**
|
| + * Base class for all GrGpuResource cache keys. There are two types of cache keys. Refer to the
|
| + * comments for each key type below.
|
| + */
|
| class GrResourceKey {
|
| public:
|
| uint32_t hash() const {
|
| @@ -135,9 +139,25 @@ private:
|
| };
|
|
|
| /**
|
| - * 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.
|
| + * A key used for scratch resources. There are three important rules about scratch keys:
|
| + * * Multiple resources can share the same scratch key. Therefore resources assigned the same
|
| + * scratch key should be interchangeable with respect to the code that uses them.
|
| + * * A resource can have at most one scratch key and it is set at resource creation by the
|
| + * resource itself.
|
| + * * When a scratch resource is ref'ed it will not be returned from the
|
| + * cache for a subsequent cache request until all refs are released. This facilitates using
|
| + * a scratch key for multiple render-to-texture scenarios. An example is a separable blur:
|
| + *
|
| + * GrTexture* texture[2];
|
| + * texture[0] = get_scratch_texture(scratchKey);
|
| + * texture[1] = get_scratch_texture(scratchKey); // texture[0] is already owned so we will get a
|
| + * // different one for texture[1]
|
| + * draw_mask(texture[0], path); // draws path mask to texture[0]
|
| + * blur_x(texture[0], texture[1]); // blurs texture[0] in y and stores result in texture[1]
|
| + * blur_y(texture[1], texture[0]); // blurs texture[1] in y and stores result in texture[0]
|
| + * texture[1]->unref(); // texture 1 can now be recycled for the next request with scratchKey
|
| + * consume_blur(texture[0]);
|
| + * texture[0]->unref(); // texture 0 can now be recycled for the next request with scratchKey
|
| */
|
| class GrScratchKey : public GrResourceKey {
|
| private:
|
| @@ -180,46 +200,55 @@ public:
|
| };
|
|
|
| /**
|
| - * 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.
|
| + * A key that allows for exclusive use of a resource for a use case (AKA "domain"). There are three
|
| + * rules governing the use of unique keys:
|
| + * * Only one resource can have a given unique key at a time. Hence, "unique".
|
| + * * A resource can have at most one unique key at a time.
|
| + * * Unlike scratch keys, multiple requests for a unique key will return the same
|
| + * resource even if the resource already has refs.
|
| + * This key type allows a code path to create cached resources for which it is the exclusive user.
|
| + * The code path creates a domain which it sets on its keys. This guarantees that there are no
|
| + * cross-domain collisions.
|
| + *
|
| + * Unique keys preempt scratch keys. While a resource has a unique key it is inaccessible via its
|
| + * scratch key. It can become scratch again if the unique key is removed.
|
| */
|
| -class GrContentKey : public GrResourceKey {
|
| +class GrUniqueKey : public GrResourceKey {
|
| private:
|
| typedef GrResourceKey INHERITED;
|
|
|
| public:
|
| typedef uint32_t Domain;
|
| - /** Generate a unique Domain of content keys. */
|
| + /** Generate a Domain for unique keys. */
|
| static Domain GenerateDomain();
|
|
|
| - /** Creates an invalid content key. It must be initialized using a Builder object before use. */
|
| - GrContentKey() {}
|
| + /** Creates an invalid unique key. It must be initialized using a Builder object before use. */
|
| + GrUniqueKey() {}
|
|
|
| - GrContentKey(const GrContentKey& that) { *this = that; }
|
| + GrUniqueKey(const GrUniqueKey& that) { *this = that; }
|
|
|
| /** reset() returns the key to the invalid state. */
|
| using INHERITED::reset;
|
|
|
| using INHERITED::isValid;
|
|
|
| - GrContentKey& operator=(const GrContentKey& that) {
|
| + GrUniqueKey& operator=(const GrUniqueKey& that) {
|
| this->INHERITED::operator=(that);
|
| return *this;
|
| }
|
|
|
| - bool operator==(const GrContentKey& that) const {
|
| + bool operator==(const GrUniqueKey& that) const {
|
| return this->INHERITED::operator==(that);
|
| }
|
| - bool operator!=(const GrContentKey& that) const { return !(*this == that); }
|
| + bool operator!=(const GrUniqueKey& that) const { return !(*this == that); }
|
|
|
| class Builder : public INHERITED::Builder {
|
| public:
|
| - Builder(GrContentKey* key, Domain domain, int data32Count)
|
| + Builder(GrUniqueKey* 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,
|
| + Builder(GrUniqueKey* key, const GrUniqueKey& innerKey, Domain domain,
|
| int extraData32Cnt)
|
| : INHERITED::Builder(key, domain, Data32CntForInnerKey(innerKey) + extraData32Cnt) {
|
| SkASSERT(&innerKey != key);
|
| @@ -231,7 +260,7 @@ public:
|
| }
|
|
|
| private:
|
| - static int Data32CntForInnerKey(const GrContentKey& innerKey) {
|
| + static int Data32CntForInnerKey(const GrUniqueKey& innerKey) {
|
| // key data + domain
|
| return SkToInt((innerKey.dataSize() >> 2) + 1);
|
| }
|
| @@ -239,16 +268,20 @@ public:
|
| };
|
|
|
| // The cache listens for these messages to purge junk resources proactively.
|
| -class GrContentKeyInvalidatedMessage {
|
| +class GrUniqueKeyInvalidatedMessage {
|
| public:
|
| - explicit GrContentKeyInvalidatedMessage(const GrContentKey& key) : fKey(key) {}
|
| - GrContentKeyInvalidatedMessage(const GrContentKeyInvalidatedMessage& that) : fKey(that.fKey) {}
|
| - GrContentKeyInvalidatedMessage& operator=(const GrContentKeyInvalidatedMessage& that) {
|
| + explicit GrUniqueKeyInvalidatedMessage(const GrUniqueKey& key) : fKey(key) {}
|
| +
|
| + GrUniqueKeyInvalidatedMessage(const GrUniqueKeyInvalidatedMessage& that) : fKey(that.fKey) {}
|
| +
|
| + GrUniqueKeyInvalidatedMessage& operator=(const GrUniqueKeyInvalidatedMessage& that) {
|
| fKey = that.fKey;
|
| return *this;
|
| }
|
| - const GrContentKey& key() const { return fKey; }
|
| +
|
| + const GrUniqueKey& key() const { return fKey; }
|
| +
|
| private:
|
| - GrContentKey fKey;
|
| + GrUniqueKey fKey;
|
| };
|
| #endif
|
|
|