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