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() {
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(); }
56
Visitor__anonb1ec22a60111::RRectBlurRec57 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) {
58 const RRectBlurRec& rec = static_cast<const RRectBlurRec&>(baseRec);
59 MaskValue* result = (MaskValue*)contextData;
60
61 SkCachedData* tmpData = rec.fValue.fData;
62 tmpData->ref();
63 if (NULL == tmpData->data()) {
64 tmpData->unref();
65 return false;
66 }
67 *result = rec.fValue;
68 return true;
69 }
70 };
71 } // namespace
72
FindAndRef(SkScalar sigma,SkBlurStyle style,SkBlurQuality quality,const SkRRect & rrect,SkMask * mask,SkResourceCache * localCache)73 SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
74 const SkRRect& rrect, SkMask* mask, SkResourceCache* localCache) {
75 MaskValue result;
76 RRectBlurKey key(sigma, rrect, style, quality);
77 if (!CHECK_LOCAL(localCache, find, Find, key, RRectBlurRec::Visitor, &result)) {
78 return NULL;
79 }
80
81 *mask = result.fMask;
82 mask->fImage = (uint8_t*)(result.fData->data());
83 return result.fData;
84 }
85
Add(SkScalar sigma,SkBlurStyle style,SkBlurQuality quality,const SkRRect & rrect,const SkMask & mask,SkCachedData * data,SkResourceCache * localCache)86 void SkMaskCache::Add(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
87 const SkRRect& rrect, const SkMask& mask, SkCachedData* data,
88 SkResourceCache* localCache) {
89 RRectBlurKey key(sigma, rrect, style, quality);
90 return CHECK_LOCAL(localCache, add, Add, SkNEW_ARGS(RRectBlurRec, (key, mask, data)));
91 }
92
93 //////////////////////////////////////////////////////////////////////////////////////////
94
95 namespace {
96 static unsigned gRectsBlurKeyNamespaceLabel;
97
98 struct RectsBlurKey : public SkResourceCache::Key {
99 public:
RectsBlurKey__anonb1ec22a60211::RectsBlurKey100 RectsBlurKey(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
101 const SkRect rects[], int count)
102 : fSigma(sigma)
103 , fStyle(style)
104 , fQuality(quality)
105 {
106 SkASSERT(1 == count || 2 == count);
107 SkIRect ir;
108 rects[0].roundOut(&ir);
109 fSizes[0] = SkSize::Make(0, 0);
110 fSizes[1] = SkSize::Make(0, 0);
111 fSizes[2] = SkSize::Make(0, 0);
112 fSizes[3] = SkSize::Make(rects[0].x() - ir.x(), rects[0].y() - ir.y());
113 for (int i = 0; i < count; i++) {
114 fSizes[i] = SkSize::Make(rects[i].width(), rects[i].height());
115 }
116 if (2 == count) {
117 fSizes[2] = SkSize::Make(rects[0].x() - rects[1].x(), rects[0].y() - rects[1].y());
118 }
119
120 this->init(&gRectsBlurKeyNamespaceLabel, 0,
121 sizeof(fSigma) + sizeof(fStyle) + sizeof(fQuality) + sizeof(fSizes));
122 }
123
124 SkScalar fSigma;
125 int32_t fStyle;
126 int32_t fQuality;
127 SkSize fSizes[4];
128 };
129
130 struct RectsBlurRec : public SkResourceCache::Rec {
RectsBlurRec__anonb1ec22a60211::RectsBlurRec131 RectsBlurRec(RectsBlurKey key, const SkMask& mask, SkCachedData* data)
132 : fKey(key)
133 {
134 fValue.fMask = mask;
135 fValue.fData = data;
136 fValue.fData->attachToCacheAndRef();
137 }
~RectsBlurRec__anonb1ec22a60211::RectsBlurRec138 ~RectsBlurRec() {
139 fValue.fData->detachFromCacheAndUnref();
140 }
141
142 RectsBlurKey fKey;
143 MaskValue fValue;
144
getKey__anonb1ec22a60211::RectsBlurRec145 const Key& getKey() const override { return fKey; }
bytesUsed__anonb1ec22a60211::RectsBlurRec146 size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
147
Visitor__anonb1ec22a60211::RectsBlurRec148 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) {
149 const RectsBlurRec& rec = static_cast<const RectsBlurRec&>(baseRec);
150 MaskValue* result = static_cast<MaskValue*>(contextData);
151
152 SkCachedData* tmpData = rec.fValue.fData;
153 tmpData->ref();
154 if (NULL == tmpData->data()) {
155 tmpData->unref();
156 return false;
157 }
158 *result = rec.fValue;
159 return true;
160 }
161 };
162 } // namespace
163
FindAndRef(SkScalar sigma,SkBlurStyle style,SkBlurQuality quality,const SkRect rects[],int count,SkMask * mask,SkResourceCache * localCache)164 SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
165 const SkRect rects[], int count, SkMask* mask,
166 SkResourceCache* localCache) {
167 MaskValue result;
168 RectsBlurKey key(sigma, style, quality, rects, count);
169 if (!CHECK_LOCAL(localCache, find, Find, key, RectsBlurRec::Visitor, &result)) {
170 return NULL;
171 }
172
173 *mask = result.fMask;
174 mask->fImage = (uint8_t*)(result.fData->data());
175 return result.fData;
176 }
177
Add(SkScalar sigma,SkBlurStyle style,SkBlurQuality quality,const SkRect rects[],int count,const SkMask & mask,SkCachedData * data,SkResourceCache * localCache)178 void SkMaskCache::Add(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
179 const SkRect rects[], int count, const SkMask& mask, SkCachedData* data,
180 SkResourceCache* localCache) {
181 RectsBlurKey key(sigma, style, quality, rects, count);
182 return CHECK_LOCAL(localCache, add, Add, SkNEW_ARGS(RectsBlurRec, (key, mask, data)));
183 }
184