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 #define CHECK_LOCAL(localCache, localName, globalName, ...) \
11 ((localCache) ? localCache->localName(__VA_ARGS__) : SkResourceCache::globalName(__VA_ARGS__))
12
13 struct MaskValue {
14 SkMask fMask;
15 SkCachedData* fData;
16 };
17
18 namespace {
19 static unsigned gRRectBlurKeyNamespaceLabel;
20
21 struct RRectBlurKey : public SkResourceCache::Key {
22 public:
RRectBlurKey__anonb1ec22a60111::RRectBlurKey23 RRectBlurKey(SkScalar sigma, const SkRRect& rrect, SkBlurStyle style)
24 : fSigma(sigma)
25 , fStyle(style)
26 , fRRect(rrect)
27 {
28 this->init(&gRRectBlurKeyNamespaceLabel, 0,
29 sizeof(fSigma) + sizeof(fStyle) + sizeof(fRRect));
30 }
31
32 SkScalar fSigma;
33 int32_t fStyle;
34 SkRRect fRRect;
35 };
36
37 struct RRectBlurRec : public SkResourceCache::Rec {
RRectBlurRec__anonb1ec22a60111::RRectBlurRec38 RRectBlurRec(RRectBlurKey key, const SkMask& mask, SkCachedData* data)
39 : fKey(key)
40 {
41 fValue.fMask = mask;
42 fValue.fData = data;
43 fValue.fData->attachToCacheAndRef();
44 }
~RRectBlurRec__anonb1ec22a60111::RRectBlurRec45 ~RRectBlurRec() override {
46 fValue.fData->detachFromCacheAndUnref();
47 }
48
49 RRectBlurKey fKey;
50 MaskValue fValue;
51
getKey__anonb1ec22a60111::RRectBlurRec52 const Key& getKey() const override { return fKey; }
bytesUsed__anonb1ec22a60111::RRectBlurRec53 size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
getCategory__anonb1ec22a60111::RRectBlurRec54 const char* getCategory() const override { return "rrect-blur"; }
diagnostic_only_getDiscardable__anonb1ec22a60111::RRectBlurRec55 SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
56 return fValue.fData->diagnostic_only_getDiscardable();
57 }
58
Visitor__anonb1ec22a60111::RRectBlurRec59 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) {
60 const RRectBlurRec& rec = static_cast<const RRectBlurRec&>(baseRec);
61 MaskValue* result = (MaskValue*)contextData;
62
63 SkCachedData* tmpData = rec.fValue.fData;
64 tmpData->ref();
65 if (nullptr == tmpData->data()) {
66 tmpData->unref();
67 return false;
68 }
69 *result = rec.fValue;
70 return true;
71 }
72 };
73 } // namespace
74
FindAndRef(SkScalar sigma,SkBlurStyle style,const SkRRect & rrect,SkMask * mask,SkResourceCache * localCache)75 SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style,
76 const SkRRect& rrect, SkMask* mask, SkResourceCache* localCache) {
77 MaskValue result;
78 RRectBlurKey key(sigma, rrect, style);
79 if (!CHECK_LOCAL(localCache, find, Find, key, RRectBlurRec::Visitor, &result)) {
80 return nullptr;
81 }
82
83 *mask = result.fMask;
84 mask->fImage = (uint8_t*)(result.fData->data());
85 return result.fData;
86 }
87
Add(SkScalar sigma,SkBlurStyle style,const SkRRect & rrect,const SkMask & mask,SkCachedData * data,SkResourceCache * localCache)88 void SkMaskCache::Add(SkScalar sigma, SkBlurStyle style,
89 const SkRRect& rrect, const SkMask& mask, SkCachedData* data,
90 SkResourceCache* localCache) {
91 RRectBlurKey key(sigma, rrect, style);
92 return CHECK_LOCAL(localCache, add, Add, new RRectBlurRec(key, mask, data));
93 }
94
95 //////////////////////////////////////////////////////////////////////////////////////////
96
97 namespace {
98 static unsigned gRectsBlurKeyNamespaceLabel;
99
100 struct RectsBlurKey : public SkResourceCache::Key {
101 public:
RectsBlurKey__anonb1ec22a60211::RectsBlurKey102 RectsBlurKey(SkScalar sigma, SkBlurStyle style, const SkRect rects[], int count)
103 : fSigma(sigma)
104 , fStyle(style)
105 {
106 SkASSERT(1 == count || 2 == count);
107 SkIRect ir;
108 rects[0].roundOut(&ir);
109 fSizes[0] = SkSize{rects[0].width(), rects[0].height()};
110 if (2 == count) {
111 fSizes[1] = SkSize{rects[1].width(), rects[1].height()};
112 fSizes[2] = SkSize{rects[0].x() - rects[1].x(), rects[0].y() - rects[1].y()};
113 } else {
114 fSizes[1] = SkSize{0, 0};
115 fSizes[2] = SkSize{0, 0};
116 }
117 fSizes[3] = SkSize{rects[0].x() - ir.x(), rects[0].y() - ir.y()};
118
119 this->init(&gRectsBlurKeyNamespaceLabel, 0,
120 sizeof(fSigma) + sizeof(fStyle) + sizeof(fSizes));
121 }
122
123 SkScalar fSigma;
124 int32_t fStyle;
125 SkSize fSizes[4];
126 };
127
128 struct RectsBlurRec : public SkResourceCache::Rec {
RectsBlurRec__anonb1ec22a60211::RectsBlurRec129 RectsBlurRec(RectsBlurKey key, const SkMask& mask, SkCachedData* data)
130 : fKey(key)
131 {
132 fValue.fMask = mask;
133 fValue.fData = data;
134 fValue.fData->attachToCacheAndRef();
135 }
~RectsBlurRec__anonb1ec22a60211::RectsBlurRec136 ~RectsBlurRec() override {
137 fValue.fData->detachFromCacheAndUnref();
138 }
139
140 RectsBlurKey fKey;
141 MaskValue fValue;
142
getKey__anonb1ec22a60211::RectsBlurRec143 const Key& getKey() const override { return fKey; }
bytesUsed__anonb1ec22a60211::RectsBlurRec144 size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
getCategory__anonb1ec22a60211::RectsBlurRec145 const char* getCategory() const override { return "rects-blur"; }
diagnostic_only_getDiscardable__anonb1ec22a60211::RectsBlurRec146 SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
147 return fValue.fData->diagnostic_only_getDiscardable();
148 }
149
Visitor__anonb1ec22a60211::RectsBlurRec150 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) {
151 const RectsBlurRec& rec = static_cast<const RectsBlurRec&>(baseRec);
152 MaskValue* result = static_cast<MaskValue*>(contextData);
153
154 SkCachedData* tmpData = rec.fValue.fData;
155 tmpData->ref();
156 if (nullptr == tmpData->data()) {
157 tmpData->unref();
158 return false;
159 }
160 *result = rec.fValue;
161 return true;
162 }
163 };
164 } // namespace
165
FindAndRef(SkScalar sigma,SkBlurStyle style,const SkRect rects[],int count,SkMask * mask,SkResourceCache * localCache)166 SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style,
167 const SkRect rects[], int count, SkMask* mask,
168 SkResourceCache* localCache) {
169 MaskValue result;
170 RectsBlurKey key(sigma, style, rects, count);
171 if (!CHECK_LOCAL(localCache, find, Find, key, RectsBlurRec::Visitor, &result)) {
172 return nullptr;
173 }
174
175 *mask = result.fMask;
176 mask->fImage = (uint8_t*)(result.fData->data());
177 return result.fData;
178 }
179
Add(SkScalar sigma,SkBlurStyle style,const SkRect rects[],int count,const SkMask & mask,SkCachedData * data,SkResourceCache * localCache)180 void SkMaskCache::Add(SkScalar sigma, SkBlurStyle style,
181 const SkRect rects[], int count, const SkMask& mask, SkCachedData* data,
182 SkResourceCache* localCache) {
183 RectsBlurKey key(sigma, style, rects, count);
184 return CHECK_LOCAL(localCache, add, Add, new RectsBlurRec(key, mask, data));
185 }
186