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__anon104ef4720111::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__anon104ef4720111::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__anon104ef4720111::RRectBlurRec47 ~RRectBlurRec() {
48 fValue.fData->detachFromCacheAndUnref();
49 }
50
51 RRectBlurKey fKey;
52 MaskValue fValue;
53
getKey__anon104ef4720111::RRectBlurRec54 const Key& getKey() const override { return fKey; }
bytesUsed__anon104ef4720111::RRectBlurRec55 size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
getCategory__anon104ef4720111::RRectBlurRec56 const char* getCategory() const override { return "rrect-blur"; }
diagnostic_only_getDiscardable__anon104ef4720111::RRectBlurRec57 SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
58 return fValue.fData->diagnostic_only_getDiscardable();
59 }
60
Visitor__anon104ef4720111::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__anon104ef4720211::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(0, 0);
114 fSizes[1] = SkSize::Make(0, 0);
115 fSizes[2] = SkSize::Make(0, 0);
116 fSizes[3] = SkSize::Make(rects[0].x() - ir.x(), rects[0].y() - ir.y());
117 for (int i = 0; i < count; i++) {
118 fSizes[i] = SkSize::Make(rects[i].width(), rects[i].height());
119 }
120 if (2 == count) {
121 fSizes[2] = SkSize::Make(rects[0].x() - rects[1].x(), rects[0].y() - rects[1].y());
122 }
123
124 this->init(&gRectsBlurKeyNamespaceLabel, 0,
125 sizeof(fSigma) + sizeof(fStyle) + sizeof(fQuality) + sizeof(fSizes));
126 }
127
128 SkScalar fSigma;
129 int32_t fStyle;
130 int32_t fQuality;
131 SkSize fSizes[4];
132 };
133
134 struct RectsBlurRec : public SkResourceCache::Rec {
RectsBlurRec__anon104ef4720211::RectsBlurRec135 RectsBlurRec(RectsBlurKey key, const SkMask& mask, SkCachedData* data)
136 : fKey(key)
137 {
138 fValue.fMask = mask;
139 fValue.fData = data;
140 fValue.fData->attachToCacheAndRef();
141 }
~RectsBlurRec__anon104ef4720211::RectsBlurRec142 ~RectsBlurRec() {
143 fValue.fData->detachFromCacheAndUnref();
144 }
145
146 RectsBlurKey fKey;
147 MaskValue fValue;
148
getKey__anon104ef4720211::RectsBlurRec149 const Key& getKey() const override { return fKey; }
bytesUsed__anon104ef4720211::RectsBlurRec150 size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
getCategory__anon104ef4720211::RectsBlurRec151 const char* getCategory() const override { return "rects-blur"; }
diagnostic_only_getDiscardable__anon104ef4720211::RectsBlurRec152 SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
153 return fValue.fData->diagnostic_only_getDiscardable();
154 }
155
Visitor__anon104ef4720211::RectsBlurRec156 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) {
157 const RectsBlurRec& rec = static_cast<const RectsBlurRec&>(baseRec);
158 MaskValue* result = static_cast<MaskValue*>(contextData);
159
160 SkCachedData* tmpData = rec.fValue.fData;
161 tmpData->ref();
162 if (nullptr == tmpData->data()) {
163 tmpData->unref();
164 return false;
165 }
166 *result = rec.fValue;
167 return true;
168 }
169 };
170 } // namespace
171
FindAndRef(SkScalar sigma,SkBlurStyle style,SkBlurQuality quality,const SkRect rects[],int count,SkMask * mask,SkResourceCache * localCache)172 SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
173 const SkRect rects[], int count, SkMask* mask,
174 SkResourceCache* localCache) {
175 MaskValue result;
176 RectsBlurKey key(sigma, style, quality, rects, count);
177 if (!CHECK_LOCAL(localCache, find, Find, key, RectsBlurRec::Visitor, &result)) {
178 return nullptr;
179 }
180
181 *mask = result.fMask;
182 mask->fImage = (uint8_t*)(result.fData->data());
183 return result.fData;
184 }
185
Add(SkScalar sigma,SkBlurStyle style,SkBlurQuality quality,const SkRect rects[],int count,const SkMask & mask,SkCachedData * data,SkResourceCache * localCache)186 void SkMaskCache::Add(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
187 const SkRect rects[], int count, const SkMask& mask, SkCachedData* data,
188 SkResourceCache* localCache) {
189 RectsBlurKey key(sigma, style, quality, rects, count);
190 return CHECK_LOCAL(localCache, add, Add, new RectsBlurRec(key, mask, data));
191 }
192