diff options
Diffstat (limited to 'include/gpu')
-rw-r--r-- | include/gpu/GrGpuResource.h | 2 | ||||
-rw-r--r-- | include/gpu/GrResourceKey.h | 363 |
2 files changed, 1 insertions, 364 deletions
diff --git a/include/gpu/GrGpuResource.h b/include/gpu/GrGpuResource.h index 5ba12c80a8..6271db8649 100644 --- a/include/gpu/GrGpuResource.h +++ b/include/gpu/GrGpuResource.h @@ -8,9 +8,9 @@ #ifndef GrGpuResource_DEFINED #define GrGpuResource_DEFINED +#include "../private/GrResourceKey.h" #include "../private/GrTypesPriv.h" #include "../private/SkNoncopyable.h" -#include "GrResourceKey.h" class GrContext; class GrGpu; diff --git a/include/gpu/GrResourceKey.h b/include/gpu/GrResourceKey.h deleted file mode 100644 index b599874ca2..0000000000 --- a/include/gpu/GrResourceKey.h +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Copyright 2014 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrResourceKey_DEFINED -#define GrResourceKey_DEFINED - -#include "../private/SkOnce.h" -#include "../private/SkTemplates.h" -#include "../private/SkTo.h" -#include "GrTypes.h" -#include "SkData.h" -#include "SkString.h" - -#include <new> - -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 { - this->validate(); - return fKey[kHash_MetaDataIdx]; - } - - size_t size() const { - this->validate(); - SkASSERT(this->isValid()); - return this->internalSize(); - } - -protected: - static const uint32_t kInvalidDomain = 0; - - GrResourceKey() { this->reset(); } - - /** Reset to an invalid key. */ - void reset() { - GR_STATIC_ASSERT((uint16_t)kInvalidDomain == kInvalidDomain); - fKey.reset(kMetaDataCnt); - fKey[kHash_MetaDataIdx] = 0; - fKey[kDomainAndSize_MetaDataIdx] = kInvalidDomain; - } - - bool operator==(const GrResourceKey& that) const { - return this->hash() == that.hash() && - 0 == memcmp(&fKey[kHash_MetaDataIdx + 1], - &that.fKey[kHash_MetaDataIdx + 1], - this->internalSize() - sizeof(uint32_t)); - } - - GrResourceKey& operator=(const GrResourceKey& that) { - SkASSERT(that.isValid()); - if (this != &that) { - size_t bytes = that.size(); - SkASSERT(SkIsAlign4(bytes)); - fKey.reset(SkToInt(bytes / sizeof(uint32_t))); - memcpy(fKey.get(), that.fKey.get(), bytes); - this->validate(); - } - return *this; - } - - bool isValid() const { return kInvalidDomain != this->domain(); } - - uint32_t domain() const { return fKey[kDomainAndSize_MetaDataIdx] & 0xffff; } - - /** size of the key data, excluding meta-data (hash, domain, etc). */ - size_t dataSize() const { return this->size() - 4 * kMetaDataCnt; } - - /** ptr to the key data, excluding meta-data (hash, domain, etc). */ - const uint32_t* data() const { - this->validate(); - return &fKey[kMetaDataCnt]; - } - -#ifdef SK_DEBUG - void dump() const { - if (!this->isValid()) { - SkDebugf("Invalid Key\n"); - } else { - SkDebugf("hash: %d ", this->hash()); - SkDebugf("domain: %d ", this->domain()); - SkDebugf("size: %dB ", this->internalSize()); - for (size_t i = 0; i < this->internalSize(); ++i) { - SkDebugf("%d ", fKey[SkTo<int>(i)]); - } - SkDebugf("\n"); - } - } -#endif - - /** Used to initialize a key. */ - class Builder { - public: - Builder(GrResourceKey* key, uint32_t domain, int data32Count) : fKey(key) { - SkASSERT(data32Count >= 0); - SkASSERT(domain != kInvalidDomain); - key->fKey.reset(kMetaDataCnt + data32Count); - int size = (data32Count + kMetaDataCnt) * sizeof(uint32_t); - SkASSERT(SkToU16(size) == size); - SkASSERT(SkToU16(domain) == domain); - key->fKey[kDomainAndSize_MetaDataIdx] = domain | (size << 16); - } - - ~Builder() { this->finish(); } - - void finish() { - if (nullptr == fKey) { - return; - } - GR_STATIC_ASSERT(0 == kHash_MetaDataIdx); - uint32_t* hash = &fKey->fKey[kHash_MetaDataIdx]; - *hash = GrResourceKeyHash(hash + 1, fKey->internalSize() - sizeof(uint32_t)); - fKey->validate(); - fKey = nullptr; - } - - uint32_t& operator[](int dataIdx) { - SkASSERT(fKey); - SkDEBUGCODE(size_t dataCount = fKey->internalSize() / sizeof(uint32_t) - kMetaDataCnt;) - SkASSERT(SkToU32(dataIdx) < dataCount); - return fKey->fKey[kMetaDataCnt + dataIdx]; - } - - private: - GrResourceKey* fKey; - }; - -private: - enum MetaDataIdx { - kHash_MetaDataIdx, - // The key domain and size are packed into a single uint32_t. - kDomainAndSize_MetaDataIdx, - - kLastMetaDataIdx = kDomainAndSize_MetaDataIdx - }; - static const uint32_t kMetaDataCnt = kLastMetaDataIdx + 1; - - size_t internalSize() const { - return fKey[kDomainAndSize_MetaDataIdx] >> 16; - } - - void validate() const { - SkASSERT(fKey[kHash_MetaDataIdx] == - GrResourceKeyHash(&fKey[kHash_MetaDataIdx] + 1, - this->internalSize() - sizeof(uint32_t))); - SkASSERT(SkIsAlign4(this->internalSize())); - } - - friend class TestResource; // For unit test to access kMetaDataCnt. - - // bmp textures require 5 uint32_t values. - SkAutoSTMalloc<kMetaDataCnt + 5, uint32_t> fKey; -}; - -/** - * 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: - typedef GrResourceKey INHERITED; - -public: - /** Uniquely identifies the type of resource that is cached as scratch. */ - typedef uint32_t ResourceType; - - /** Generate a unique ResourceType. */ - static ResourceType GenerateResourceType(); - - /** Creates an invalid scratch key. It must be initialized using a Builder object before use. */ - GrScratchKey() {} - - GrScratchKey(const GrScratchKey& that) { *this = that; } - - /** reset() returns the key to the invalid state. */ - using INHERITED::reset; - - using INHERITED::isValid; - - ResourceType resourceType() const { return this->domain(); } - - GrScratchKey& operator=(const GrScratchKey& that) { - this->INHERITED::operator=(that); - return *this; - } - - bool operator==(const GrScratchKey& that) const { - return this->INHERITED::operator==(that); - } - bool operator!=(const GrScratchKey& that) const { return !(*this == that); } - - class Builder : public INHERITED::Builder { - public: - Builder(GrScratchKey* key, ResourceType type, int data32Count) - : INHERITED::Builder(key, type, data32Count) {} - }; -}; - -/** - * 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 GrUniqueKey : public GrResourceKey { -private: - typedef GrResourceKey INHERITED; - -public: - typedef uint32_t Domain; - /** Generate a Domain for unique keys. */ - static Domain GenerateDomain(); - - /** Creates an invalid unique key. It must be initialized using a Builder object before use. */ - GrUniqueKey() : fTag(nullptr) {} - - GrUniqueKey(const GrUniqueKey& that) { *this = that; } - - /** reset() returns the key to the invalid state. */ - using INHERITED::reset; - - using INHERITED::isValid; - - GrUniqueKey& operator=(const GrUniqueKey& that) { - this->INHERITED::operator=(that); - this->setCustomData(sk_ref_sp(that.getCustomData())); - fTag = that.fTag; - return *this; - } - - bool operator==(const GrUniqueKey& that) const { - return this->INHERITED::operator==(that); - } - bool operator!=(const GrUniqueKey& that) const { return !(*this == that); } - - void setCustomData(sk_sp<SkData> data) { - fData = std::move(data); - } - SkData* getCustomData() const { - return fData.get(); - } - - const char* tag() const { return fTag; } - -#ifdef SK_DEBUG - void dump(const char* label) const { - SkDebugf("%s tag: %s\n", label, fTag ? fTag : "None"); - this->INHERITED::dump(); - } -#endif - - class Builder : public INHERITED::Builder { - public: - Builder(GrUniqueKey* key, Domain type, int data32Count, const char* tag = nullptr) - : INHERITED::Builder(key, type, data32Count) { - key->fTag = tag; - } - - /** Used to build a key that wraps another key and adds additional data. */ - Builder(GrUniqueKey* key, const GrUniqueKey& innerKey, Domain domain, int extraData32Cnt, - const char* tag = nullptr) - : INHERITED::Builder(key, domain, Data32CntForInnerKey(innerKey) + extraData32Cnt) { - SkASSERT(&innerKey != key); - // add the inner key to the end of the key so that op[] can be indexed normally. - uint32_t* innerKeyData = &this->operator[](extraData32Cnt); - const uint32_t* srcData = innerKey.data(); - (*innerKeyData++) = innerKey.domain(); - memcpy(innerKeyData, srcData, innerKey.dataSize()); - key->fTag = tag; - } - - private: - static int Data32CntForInnerKey(const GrUniqueKey& innerKey) { - // key data + domain - return SkToInt((innerKey.dataSize() >> 2) + 1); - } - }; - -private: - sk_sp<SkData> fData; - const char* fTag; -}; - -/** - * It is common to need a frequently reused GrUniqueKey where the only requirement is that the key - * is unique. These macros create such a key in a thread safe manner so the key can be truly global - * and only constructed once. - */ - -/** Place outside of function/class definitions. */ -#define GR_DECLARE_STATIC_UNIQUE_KEY(name) static SkOnce name##_once - -/** Place inside function where the key is used. */ -#define GR_DEFINE_STATIC_UNIQUE_KEY(name) \ - static SkAlignedSTStorage<1, GrUniqueKey> name##_storage; \ - name##_once(gr_init_static_unique_key_once, &name##_storage); \ - static const GrUniqueKey& name = *reinterpret_cast<GrUniqueKey*>(name##_storage.get()) - -static inline void gr_init_static_unique_key_once(SkAlignedSTStorage<1,GrUniqueKey>* keyStorage) { - GrUniqueKey* key = new (keyStorage->get()) GrUniqueKey; - GrUniqueKey::Builder builder(key, GrUniqueKey::GenerateDomain(), 0); -} - -// The cache listens for these messages to purge junk resources proactively. -class GrUniqueKeyInvalidatedMessage { -public: - GrUniqueKeyInvalidatedMessage(const GrUniqueKey& key, uint32_t contextUniqueID) - : fKey(key), fContextID(contextUniqueID) { - SkASSERT(SK_InvalidUniqueID != contextUniqueID); - } - - GrUniqueKeyInvalidatedMessage(const GrUniqueKeyInvalidatedMessage&) = default; - - GrUniqueKeyInvalidatedMessage& operator=(const GrUniqueKeyInvalidatedMessage&) = default; - - const GrUniqueKey& key() const { return fKey; } - uint32_t contextID() const { return fContextID; } - -private: - GrUniqueKey fKey; - uint32_t fContextID; -}; - -static inline bool SkShouldPostMessageToBus( - const GrUniqueKeyInvalidatedMessage& msg, uint32_t msgBusUniqueID) { - return msg.contextID() == msgBusUniqueID; -} - -#endif |