xref: /aosp_15_r20/external/skia/src/core/SkImageFilterCache.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkImageFilterCache_DEFINED
9 #define SkImageFilterCache_DEFINED
10 
11 #include "include/core/SkMatrix.h"
12 #include "include/core/SkRect.h"
13 #include "include/core/SkRefCnt.h"
14 #include "include/private/base/SkAssert.h"
15 #include "include/private/base/SkDebug.h"
16 
17 #include <cstddef>
18 #include <cstdint>
19 
20 class SkImageFilter;
21 namespace skif { class FilterResult; }
22 
23 struct SkImageFilterCacheKey {
SkImageFilterCacheKeySkImageFilterCacheKey24     SkImageFilterCacheKey(const uint32_t uniqueID, const SkMatrix& matrix,
25         const SkIRect& clipBounds, uint32_t srcGenID, const SkIRect& srcSubset)
26         : fUniqueID(uniqueID)
27         , fMatrix(matrix)
28         , fClipBounds(clipBounds)
29         , fSrcGenID(srcGenID)
30         , fSrcSubset(srcSubset) {
31         // Assert that Key is tightly-packed, since it is hashed.
32         static_assert(sizeof(SkImageFilterCacheKey) == sizeof(uint32_t) + sizeof(SkMatrix) +
33                                      sizeof(SkIRect) + sizeof(uint32_t) + 4 * sizeof(int32_t),
34                                      "image_filter_key_tight_packing");
35         fMatrix.getType();  // force initialization of type, so hashes match
36         SkASSERT(fMatrix.isFinite());   // otherwise we can't rely on == self when comparing keys
37     }
38 
39     uint32_t fUniqueID;
40     SkMatrix fMatrix;
41     SkIRect fClipBounds;
42     uint32_t fSrcGenID;
43     SkIRect fSrcSubset;
44 
45     bool operator==(const SkImageFilterCacheKey& other) const {
46         return fUniqueID == other.fUniqueID &&
47                fMatrix == other.fMatrix &&
48                fClipBounds == other.fClipBounds &&
49                fSrcGenID == other.fSrcGenID &&
50                fSrcSubset == other.fSrcSubset;
51     }
52 };
53 
54 // This cache maps from (filter's unique ID + CTM + clipBounds + src bitmap generation ID) to result
55 // NOTE: this is the _specific_ unique ID of the image filter, so refiltering the same image with a
56 // copy of the image filter (with exactly the same parameters) will not yield a cache hit.
57 class SkImageFilterCache : public SkRefCnt {
58 public:
59     static constexpr size_t kDefaultTransientSize = 32 * 1024 * 1024;
60 
~SkImageFilterCache()61     ~SkImageFilterCache() override {}
62     static sk_sp<SkImageFilterCache> Create(size_t maxBytes);
63 
64     // Whether to create the cache if it doesn't yet exist.
65     enum class CreateIfNecessary : bool { kNo, kYes };
66     static sk_sp<SkImageFilterCache> Get(CreateIfNecessary = CreateIfNecessary::kYes);
67 
68     // Returns true on cache hit and updates 'result' to be the cached result. Returns false when
69     // not in the cache, in which case 'result' is not modified.
70     virtual bool get(const SkImageFilterCacheKey& key,
71                      skif::FilterResult* result) const = 0;
72     // 'filter' is included in the caching to allow the purging of all of an image filter's cached
73     // results when it is destroyed.
74     virtual void set(const SkImageFilterCacheKey& key, const SkImageFilter* filter,
75                      const skif::FilterResult& result) = 0;
76     virtual void purge() = 0;
77     virtual void purgeByImageFilter(const SkImageFilter*) = 0;
78     SkDEBUGCODE(virtual int count() const = 0;)
79 };
80 
81 #endif
82