chromium/third_party/skia/src/gpu/ResourceKey.h

/*
 * 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