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 "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, SkBlurQuality quality)
24 : fSigma(sigma)
25 , fStyle(style)
26 , fQuality(quality)
27 , fRRect(rrect)
28 {
29 this->init(&gRRectBlurKeyNamespaceLabel, 0,
30 sizeof(fSigma) + sizeof(fStyle) + sizeof(fQuality) + sizeof(fRRect));
31 }
32
33 SkScalar fSigma;
34 int32_t fStyle;
35 int32_t fQuality;
36 SkRRect fRRect;
37 };
38
39 struct RRectBlurRec : public SkResourceCache::Rec {
RRectBlurRec__anonb1ec22a60111::RRectBlurRec40 RRectBlurRec(RRectBlurKey key, const SkMask& mask, SkCachedData* data)
41 : fKey(key)
42 {
43 fValue.fMask = mask;
44 fValue.fData = data;
45 fValue.fData->attachToCacheAndRef();
46 }
~RRectBlurRec__anonb1ec22a60111::RRectBlurRec47 ~RRectBlurRec() override {
48 fValue.fData->detachFromCacheAndUnref();
49 }
50
51 RRectBlurKey fKey;
52 MaskValue fValue;
53
getKey__anonb1ec22a60111::RRectBlurRec54 const Key& getKey() const override { return fKey; }
bytesUsed__anonb1ec22a60111::RRectBlurRec55 size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
getCategory__anonb1ec22a60111::RRectBlurRec56 const char* getCategory() const override { return "rrect-blur"; }
diagnostic_only_getDiscardable__anonb1ec22a60111::RRectBlurRec57 SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
58 return fValue.fData->diagnostic_only_getDiscardable();
59 }
60
Visitor__anonb1ec22a60111::RRectBlurRec61 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) {
62 const RRectBlurRec& rec = static_cast<const RRectBlurRec&>(baseRec);
63 MaskValue* result = (MaskValue*)contextData;
64
65 SkCachedData* tmpData = rec.fValue.fData;
66 tmpData->ref();
67 if (nullptr == tmpData->data()) {
68 tmpData->unref();
69 return false;
70 }
71 *result = rec.fValue;
72 return true;
73 }
74 };
75 } // namespace
76
FindAndRef(SkScalar sigma,SkBlurStyle style,SkBlurQuality quality,const SkRRect & rrect,SkMask * mask,SkResourceCache * localCache)77 SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
78 const SkRRect& rrect, SkMask* mask, SkResourceCache* localCache) {
79 MaskValue result;
80 RRectBlurKey key(sigma, rrect, style, quality);
81 if (!CHECK_LOCAL(localCache, find, Find, key, RRectBlurRec::Visitor, &result)) {
82 return nullptr;
83 }
84
85 *mask = result.fMask;
86 mask->fImage = (uint8_t*)(result.fData->data());
87 return result.fData;
88 }
89
Add(SkScalar sigma,SkBlurStyle style,SkBlurQuality quality,const SkRRect & rrect,const SkMask & mask,SkCachedData * data,SkResourceCache * localCache)90 void SkMaskCache::Add(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
91 const SkRRect& rrect, const SkMask& mask, SkCachedData* data,
92 SkResourceCache* localCache) {
93 RRectBlurKey key(sigma, rrect, style, quality);
94 return CHECK_LOCAL(localCache, add, Add, new RRectBlurRec(key, mask, data));
95 }
96
97 //////////////////////////////////////////////////////////////////////////////////////////
98
99 namespace {
100 static unsigned gRectsBlurKeyNamespaceLabel;
101
102 struct RectsBlurKey : public SkResourceCache::Key {
103 public:
RectsBlurKey__anonb1ec22a60211::RectsBlurKey104 RectsBlurKey(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
105 const SkRect rects[], int count)
106 : fSigma(sigma)
107 , fStyle(style)
108 , fQuality(quality)
109 {
110 SkASSERT(1 == count || 2 == count);
111 SkIRect ir;
112 rects[0].roundOut(&ir);
113 fSizes[0] = SkSize::Make(rects[0].width(), rects[0].height());
114 if (2 == count) {
115 fSizes[1] = SkSize::Make(rects[1].width(), rects[1].height());
116 fSizes[2] = SkSize::Make(rects[0].x() - rects[1].x(), rects[0].y() - rects[1].y());
117 } else {
118 fSizes[1] = SkSize::Make(0, 0);
119 fSizes[2] = SkSize::Make(0, 0);
120 }
121 fSizes[3] = SkSize::Make(rects[0].x() - ir.x(), rects[0].y() - ir.y());
122
123 this->init(&gRectsBlurKeyNamespaceLabel, 0,
124 sizeof(fSigma) + sizeof(fStyle) + sizeof(fQuality) + sizeof(fSizes));
125 }
126
127 SkScalar fSigma;
128 int32_t fStyle;
129 int32_t fQuality;
130 SkSize fSizes[4];
131 };
132
133 struct RectsBlurRec : public SkResourceCache::Rec {
RectsBlurRec__anonb1ec22a60211::RectsBlurRec134 RectsBlurRec(RectsBlurKey key, const SkMask& mask, SkCachedData* data)
135 : fKey(key)
136 {
137 fValue.fMask = mask;
138 fValue.fData = data;
139 fValue.fData->attachToCacheAndRef();
140 }
~RectsBlurRec__anonb1ec22a60211::RectsBlurRec141 ~RectsBlurRec() override {
142 fValue.fData->detachFromCacheAndUnref();
143 }
144
145 RectsBlurKey fKey;
146 MaskValue fValue;
147
getKey__anonb1ec22a60211::RectsBlurRec148 const Key& getKey() const override { return fKey; }
bytesUsed__anonb1ec22a60211::RectsBlurRec149 size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
getCategory__anonb1ec22a60211::RectsBlurRec150 const char* getCategory() const override { return "rects-blur"; }
diagnostic_only_getDiscardable__anonb1ec22a60211::RectsBlurRec151 SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
152 return fValue.fData->diagnostic_only_getDiscardable();
153 }
154
Visitor__anonb1ec22a60211::RectsBlurRec155 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) {
156 const RectsBlurRec& rec = static_cast<const RectsBlurRec&>(baseRec);
157 MaskValue* result = static_cast<MaskValue*>(contextData);
158
159 SkCachedData* tmpData = rec.fValue.fData;
160 tmpData->ref();
161 if (nullptr == tmpData->data()) {
162 tmpData->unref();
163 return false;
164 }
165 *result = rec.fValue;
166 return true;
167 }
168 };
169 } // namespace
170
FindAndRef(SkScalar sigma,SkBlurStyle style,SkBlurQuality quality,const SkRect rects[],int count,SkMask * mask,SkResourceCache * localCache)171 SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
172 const SkRect rects[], int count, SkMask* mask,
173 SkResourceCache* localCache) {
174 MaskValue result;
175 RectsBlurKey key(sigma, style, quality, rects, count);
176 if (!CHECK_LOCAL(localCache, find, Find, key, RectsBlurRec::Visitor, &result)) {
177 return nullptr;
178 }
179
180 *mask = result.fMask;
181 mask->fImage = (uint8_t*)(result.fData->data());
182 return result.fData;
183 }
184
Add(SkScalar sigma,SkBlurStyle style,SkBlurQuality quality,const SkRect rects[],int count,const SkMask & mask,SkCachedData * data,SkResourceCache * localCache)185 void SkMaskCache::Add(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
186 const SkRect rects[], int count, const SkMask& mask, SkCachedData* data,
187 SkResourceCache* localCache) {
188 RectsBlurKey key(sigma, style, quality, rects, count);
189 return CHECK_LOCAL(localCache, add, Add, new RectsBlurRec(key, mask, data));
190 }
191