/* * 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 skgpu_ResourceKey_DEFINED #define skgpu_ResourceKey_DEFINED #include "include/core/SkData.h" #include "include/core/SkRefCnt.h" #include "include/core/SkTypes.h" #include "include/private/base/SkAlign.h" #include "include/private/base/SkAlignedStorage.h" #include "include/private/base/SkDebug.h" #include "include/private/base/SkTemplates.h" #include "include/private/base/SkTo.h" #include <cstdint> #include <cstring> #include <new> #include <utility> class TestResource; namespace skgpu { uint32_t ResourceKeyHash(const uint32_t* data, size_t size); /** * Base class for all gpu Resource cache keys. There are two types of cache keys. Refer to the * comments for each key type below. */ class ResourceKey { … }; /** * 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 ScratchKey : public ResourceKey { … }; /** * 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 UniqueKey : public ResourceKey { … }; /** * It is common to need a frequently reused UniqueKey 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 SKGPU_DECLARE_STATIC_UNIQUE_KEY(name) … /** Place inside function where the key is used. */ #define SKGPU_DEFINE_STATIC_UNIQUE_KEY(name) … static inline void skgpu_init_static_unique_key_once(SkAlignedSTStorage<1, UniqueKey>* keyStorage) { … } // The cache listens for these messages to purge junk resources proactively. class UniqueKeyInvalidatedMessage { … }; static inline bool SkShouldPostMessageToBus(const UniqueKeyInvalidatedMessage& msg, uint32_t msgBusUniqueID) { … } class UniqueKeyInvalidatedMsg_Graphite { … }; static inline bool SkShouldPostMessageToBus(const UniqueKeyInvalidatedMsg_Graphite& msg, uint32_t msgBusUniqueID) { … } /** * This is a special key that doesn't have domain and can only be used in a dedicated cache. * Unlike UniqueKey & ScratchKey, this key has compile time size (in number of uint32_t) * and doesn't need dynamic allocations. In comparison, UniqueKey & ScratchKey will need * dynamic allocation if a key is larger than 6 uint32_ts. */ template <size_t SizeInUInt32> class FixedSizeKey { … }; } // namespace skgpu #endif // skgpu_ResourceKey_DEFINED