xref: /aosp_15_r20/external/skia/src/core/SkMaskCache.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2014 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 #include "src/core/SkMaskCache.h"
9 
10 #include "include/core/SkRRect.h"
11 #include "include/core/SkRect.h"
12 #include "include/core/SkSize.h"
13 #include "include/private/base/SkAssert.h"
14 #include "src/base/SkTLazy.h"
15 #include "src/core/SkCachedData.h"
16 #include "src/core/SkMask.h"
17 #include "src/core/SkResourceCache.h"
18 
19 #include <cstddef>
20 #include <cstdint>
21 
22 class SkDiscardableMemory;
23 enum SkBlurStyle : int;
24 
25 #define CHECK_LOCAL(localCache, localName, globalName, ...) \
26     ((localCache) ? localCache->localName(__VA_ARGS__) : SkResourceCache::globalName(__VA_ARGS__))
27 
28 struct MaskValue {
29     SkMask          fMask;
30     SkCachedData*   fData;
31 };
32 
33 namespace {
34 static unsigned gRRectBlurKeyNamespaceLabel;
35 
36 struct RRectBlurKey : public SkResourceCache::Key {
37 public:
RRectBlurKey__anona053665c0111::RRectBlurKey38     RRectBlurKey(SkScalar sigma, const SkRRect& rrect, SkBlurStyle style)
39         : fSigma(sigma)
40         , fStyle(style)
41         , fRRect(rrect)
42     {
43         this->init(&gRRectBlurKeyNamespaceLabel, 0,
44                    sizeof(fSigma) + sizeof(fStyle) + sizeof(fRRect));
45     }
46 
47     SkScalar   fSigma;
48     int32_t    fStyle;
49     SkRRect    fRRect;
50 };
51 
52 struct RRectBlurRec : public SkResourceCache::Rec {
RRectBlurRec__anona053665c0111::RRectBlurRec53     RRectBlurRec(RRectBlurKey key, const SkMask& mask, SkCachedData* data)
54         : fKey(key), fValue({{nullptr, mask.fBounds, mask.fRowBytes, mask.fFormat}, data})
55     {
56         fValue.fData->attachToCacheAndRef();
57     }
~RRectBlurRec__anona053665c0111::RRectBlurRec58     ~RRectBlurRec() override {
59         fValue.fData->detachFromCacheAndUnref();
60     }
61 
62     RRectBlurKey   fKey;
63     MaskValue      fValue;
64 
getKey__anona053665c0111::RRectBlurRec65     const Key& getKey() const override { return fKey; }
bytesUsed__anona053665c0111::RRectBlurRec66     size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
getCategory__anona053665c0111::RRectBlurRec67     const char* getCategory() const override { return "rrect-blur"; }
diagnostic_only_getDiscardable__anona053665c0111::RRectBlurRec68     SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
69         return fValue.fData->diagnostic_only_getDiscardable();
70     }
71 
Visitor__anona053665c0111::RRectBlurRec72     static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) {
73         const RRectBlurRec& rec = static_cast<const RRectBlurRec&>(baseRec);
74         SkTLazy<MaskValue>* result = (SkTLazy<MaskValue>*)contextData;
75 
76         SkCachedData* tmpData = rec.fValue.fData;
77         tmpData->ref();
78         if (nullptr == tmpData->data()) {
79             tmpData->unref();
80             return false;
81         }
82         result->init(rec.fValue);
83         return true;
84     }
85 };
86 } // namespace
87 
FindAndRef(SkScalar sigma,SkBlurStyle style,const SkRRect & rrect,SkTLazy<SkMask> * mask,SkResourceCache * localCache)88 SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style,
89                                       const SkRRect& rrect, SkTLazy<SkMask>* mask,
90                                       SkResourceCache* localCache) {
91     SkTLazy<MaskValue> result;
92     RRectBlurKey key(sigma, rrect, style);
93     if (!CHECK_LOCAL(localCache, find, Find, key, RRectBlurRec::Visitor, &result)) {
94         return nullptr;
95     }
96 
97     mask->init(static_cast<const uint8_t*>(result->fData->data()),
98                result->fMask.fBounds, result->fMask.fRowBytes, result->fMask.fFormat);
99     return result->fData;
100 }
101 
Add(SkScalar sigma,SkBlurStyle style,const SkRRect & rrect,const SkMask & mask,SkCachedData * data,SkResourceCache * localCache)102 void SkMaskCache::Add(SkScalar sigma, SkBlurStyle style,
103                       const SkRRect& rrect, const SkMask& mask, SkCachedData* data,
104                       SkResourceCache* localCache) {
105     RRectBlurKey key(sigma, rrect, style);
106     return CHECK_LOCAL(localCache, add, Add, new RRectBlurRec(key, mask, data));
107 }
108 
109 //////////////////////////////////////////////////////////////////////////////////////////
110 
111 namespace {
112 static unsigned gRectsBlurKeyNamespaceLabel;
113 
114 struct RectsBlurKey : public SkResourceCache::Key {
115 public:
RectsBlurKey__anona053665c0211::RectsBlurKey116     RectsBlurKey(SkScalar sigma, SkBlurStyle style, const SkRect rects[], int count)
117         : fSigma(sigma)
118         , fStyle(style)
119     {
120         SkASSERT(1 == count || 2 == count);
121         SkIRect ir;
122         rects[0].roundOut(&ir);
123         fSizes[0] = SkSize{rects[0].width(), rects[0].height()};
124         if (2 == count) {
125             fSizes[1] = SkSize{rects[1].width(), rects[1].height()};
126             fSizes[2] = SkSize{rects[0].x() - rects[1].x(), rects[0].y() - rects[1].y()};
127         } else {
128             fSizes[1] = SkSize{0, 0};
129             fSizes[2] = SkSize{0, 0};
130         }
131         fSizes[3] = SkSize{rects[0].x() - ir.x(), rects[0].y() - ir.y()};
132 
133         this->init(&gRectsBlurKeyNamespaceLabel, 0,
134                    sizeof(fSigma) + sizeof(fStyle) + sizeof(fSizes));
135     }
136 
137     SkScalar    fSigma;
138     int32_t     fStyle;
139     SkSize      fSizes[4];
140 };
141 
142 struct RectsBlurRec : public SkResourceCache::Rec {
RectsBlurRec__anona053665c0211::RectsBlurRec143     RectsBlurRec(RectsBlurKey key, const SkMask& mask, SkCachedData* data)
144         : fKey(key), fValue({{nullptr, mask.fBounds, mask.fRowBytes, mask.fFormat}, data})
145     {
146         fValue.fData->attachToCacheAndRef();
147     }
~RectsBlurRec__anona053665c0211::RectsBlurRec148     ~RectsBlurRec() override {
149         fValue.fData->detachFromCacheAndUnref();
150     }
151 
152     RectsBlurKey   fKey;
153     MaskValue      fValue;
154 
getKey__anona053665c0211::RectsBlurRec155     const Key& getKey() const override { return fKey; }
bytesUsed__anona053665c0211::RectsBlurRec156     size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
getCategory__anona053665c0211::RectsBlurRec157     const char* getCategory() const override { return "rects-blur"; }
diagnostic_only_getDiscardable__anona053665c0211::RectsBlurRec158     SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
159         return fValue.fData->diagnostic_only_getDiscardable();
160     }
161 
Visitor__anona053665c0211::RectsBlurRec162     static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) {
163         const RectsBlurRec& rec = static_cast<const RectsBlurRec&>(baseRec);
164         SkTLazy<MaskValue>* result = static_cast<SkTLazy<MaskValue>*>(contextData);
165 
166         SkCachedData* tmpData = rec.fValue.fData;
167         tmpData->ref();
168         if (nullptr == tmpData->data()) {
169             tmpData->unref();
170             return false;
171         }
172         result->init(rec.fValue);
173         return true;
174     }
175 };
176 } // namespace
177 
FindAndRef(SkScalar sigma,SkBlurStyle style,const SkRect rects[],int count,SkTLazy<SkMask> * mask,SkResourceCache * localCache)178 SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style,
179                                       const SkRect rects[], int count, SkTLazy<SkMask>* mask,
180                                       SkResourceCache* localCache) {
181     SkTLazy<MaskValue> result;
182     RectsBlurKey key(sigma, style, rects, count);
183     if (!CHECK_LOCAL(localCache, find, Find, key, RectsBlurRec::Visitor, &result)) {
184         return nullptr;
185     }
186 
187     mask->init(static_cast<const uint8_t*>(result->fData->data()),
188                result->fMask.fBounds, result->fMask.fRowBytes, result->fMask.fFormat);
189     return result->fData;
190 }
191 
Add(SkScalar sigma,SkBlurStyle style,const SkRect rects[],int count,const SkMask & mask,SkCachedData * data,SkResourceCache * localCache)192 void SkMaskCache::Add(SkScalar sigma, SkBlurStyle style,
193                       const SkRect rects[], int count, const SkMask& mask, SkCachedData* data,
194                       SkResourceCache* localCache) {
195     RectsBlurKey key(sigma, style, rects, count);
196     return CHECK_LOCAL(localCache, add, Add, new RectsBlurRec(key, mask, data));
197 }
198