blob: eb7c8f0941f359ff226b6cf37accaf4e9b0507e0 [file] [log] [blame]
qiankun.miaod9aac342014-10-23 07:58:17 -07001/*
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
13struct MaskValue {
14 SkMask fMask;
15 SkCachedData* fData;
16};
17
18namespace {
19static unsigned gRRectBlurKeyNamespaceLabel;
20
21struct RRectBlurKey : public SkResourceCache::Key {
22public:
23 RRectBlurKey(SkScalar sigma, const SkRRect& rrect, SkBlurStyle style, SkBlurQuality quality)
24 : fSigma(sigma)
qiankun.miaod9aac342014-10-23 07:58:17 -070025 , fStyle(style)
reed4dca7a82014-10-23 12:42:46 -070026 , fQuality(quality)
27 , fRRect(rrect)
28 {
reed7eeba252015-02-24 13:54:23 -080029 this->init(&gRRectBlurKeyNamespaceLabel, 0,
reed4dca7a82014-10-23 12:42:46 -070030 sizeof(fSigma) + sizeof(fStyle) + sizeof(fQuality) + sizeof(fRRect));
qiankun.miaod9aac342014-10-23 07:58:17 -070031 }
32
33 SkScalar fSigma;
qiankun.miaod9aac342014-10-23 07:58:17 -070034 int32_t fStyle;
35 int32_t fQuality;
reed4dca7a82014-10-23 12:42:46 -070036 SkRRect fRRect;
qiankun.miaod9aac342014-10-23 07:58:17 -070037};
38
39struct RRectBlurRec : public SkResourceCache::Rec {
40 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 }
47 ~RRectBlurRec() {
48 fValue.fData->detachFromCacheAndUnref();
49 }
50
51 RRectBlurKey fKey;
52 MaskValue fValue;
53
mtklein36352bf2015-03-25 18:17:31 -070054 const Key& getKey() const override { return fKey; }
55 size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
reed216b6432015-08-19 12:25:40 -070056 const char* getCategory() const override { return "rrect-blur"; }
57 SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
58 return fValue.fData->diagnostic_only_getDiscardable();
59 }
qiankun.miaod9aac342014-10-23 07:58:17 -070060
61 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();
halcanary96fcdcc2015-08-27 07:41:13 -070067 if (nullptr == tmpData->data()) {
qiankun.miaod9aac342014-10-23 07:58:17 -070068 tmpData->unref();
69 return false;
70 }
71 *result = rec.fValue;
72 return true;
73 }
74};
75} // namespace
76
reed4dca7a82014-10-23 12:42:46 -070077SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
78 const SkRRect& rrect, SkMask* mask, SkResourceCache* localCache) {
qiankun.miaod9aac342014-10-23 07:58:17 -070079 MaskValue result;
80 RRectBlurKey key(sigma, rrect, style, quality);
81 if (!CHECK_LOCAL(localCache, find, Find, key, RRectBlurRec::Visitor, &result)) {
halcanary96fcdcc2015-08-27 07:41:13 -070082 return nullptr;
qiankun.miaod9aac342014-10-23 07:58:17 -070083 }
84
85 *mask = result.fMask;
86 mask->fImage = (uint8_t*)(result.fData->data());
87 return result.fData;
88}
89
reed4dca7a82014-10-23 12:42:46 -070090void SkMaskCache::Add(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
91 const SkRRect& rrect, const SkMask& mask, SkCachedData* data,
qiankun.miaod9aac342014-10-23 07:58:17 -070092 SkResourceCache* localCache) {
93 RRectBlurKey key(sigma, rrect, style, quality);
halcanary385fe4d2015-08-26 13:07:48 -070094 return CHECK_LOCAL(localCache, add, Add, new RRectBlurRec(key, mask, data));
qiankun.miaod9aac342014-10-23 07:58:17 -070095}
96
97//////////////////////////////////////////////////////////////////////////////////////////
98
99namespace {
100static unsigned gRectsBlurKeyNamespaceLabel;
101
102struct RectsBlurKey : public SkResourceCache::Key {
103public:
reed4dca7a82014-10-23 12:42:46 -0700104 RectsBlurKey(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
105 const SkRect rects[], int count)
qiankun.miaod9aac342014-10-23 07:58:17 -0700106 : fSigma(sigma)
reed4dca7a82014-10-23 12:42:46 -0700107 , fStyle(style)
108 , fQuality(quality)
109 {
qiankun.miaod9aac342014-10-23 07:58:17 -0700110 SkASSERT(1 == count || 2 == count);
qiankun.miao69469b52014-12-05 11:16:25 -0800111 SkIRect ir;
112 rects[0].roundOut(&ir);
jvanverth73e81ab2016-05-06 09:33:55 -0700113 fSizes[0] = SkSize::Make(rects[0].width(), rects[0].height());
qiankun.miao69469b52014-12-05 11:16:25 -0800114 if (2 == count) {
jvanverth73e81ab2016-05-06 09:33:55 -0700115 fSizes[1] = SkSize::Make(rects[1].width(), rects[1].height());
qiankun.miao69469b52014-12-05 11:16:25 -0800116 fSizes[2] = SkSize::Make(rects[0].x() - rects[1].x(), rects[0].y() - rects[1].y());
jvanverth73e81ab2016-05-06 09:33:55 -0700117 } else {
118 fSizes[1] = SkSize::Make(0, 0);
119 fSizes[2] = SkSize::Make(0, 0);
qiankun.miao69469b52014-12-05 11:16:25 -0800120 }
jvanverth73e81ab2016-05-06 09:33:55 -0700121 fSizes[3] = SkSize::Make(rects[0].x() - ir.x(), rects[0].y() - ir.y());
qiankun.miao69469b52014-12-05 11:16:25 -0800122
reed7eeba252015-02-24 13:54:23 -0800123 this->init(&gRectsBlurKeyNamespaceLabel, 0,
qiankun.miao69469b52014-12-05 11:16:25 -0800124 sizeof(fSigma) + sizeof(fStyle) + sizeof(fQuality) + sizeof(fSizes));
qiankun.miaod9aac342014-10-23 07:58:17 -0700125 }
126
127 SkScalar fSigma;
qiankun.miaod9aac342014-10-23 07:58:17 -0700128 int32_t fStyle;
reed4dca7a82014-10-23 12:42:46 -0700129 int32_t fQuality;
qiankun.miao69469b52014-12-05 11:16:25 -0800130 SkSize fSizes[4];
qiankun.miaod9aac342014-10-23 07:58:17 -0700131};
132
133struct RectsBlurRec : public SkResourceCache::Rec {
134 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 }
141 ~RectsBlurRec() {
142 fValue.fData->detachFromCacheAndUnref();
143 }
144
145 RectsBlurKey fKey;
146 MaskValue fValue;
147
mtklein36352bf2015-03-25 18:17:31 -0700148 const Key& getKey() const override { return fKey; }
149 size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
reed216b6432015-08-19 12:25:40 -0700150 const char* getCategory() const override { return "rects-blur"; }
151 SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
152 return fValue.fData->diagnostic_only_getDiscardable();
153 }
qiankun.miaod9aac342014-10-23 07:58:17 -0700154
155 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) {
156 const RectsBlurRec& rec = static_cast<const RectsBlurRec&>(baseRec);
sugoi692135f2015-01-19 10:10:27 -0800157 MaskValue* result = static_cast<MaskValue*>(contextData);
qiankun.miaod9aac342014-10-23 07:58:17 -0700158
159 SkCachedData* tmpData = rec.fValue.fData;
160 tmpData->ref();
halcanary96fcdcc2015-08-27 07:41:13 -0700161 if (nullptr == tmpData->data()) {
qiankun.miaod9aac342014-10-23 07:58:17 -0700162 tmpData->unref();
163 return false;
164 }
165 *result = rec.fValue;
166 return true;
167 }
168};
169} // namespace
170
reed4dca7a82014-10-23 12:42:46 -0700171SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
172 const SkRect rects[], int count, SkMask* mask,
qiankun.miaod9aac342014-10-23 07:58:17 -0700173 SkResourceCache* localCache) {
174 MaskValue result;
reed4dca7a82014-10-23 12:42:46 -0700175 RectsBlurKey key(sigma, style, quality, rects, count);
qiankun.miaod9aac342014-10-23 07:58:17 -0700176 if (!CHECK_LOCAL(localCache, find, Find, key, RectsBlurRec::Visitor, &result)) {
halcanary96fcdcc2015-08-27 07:41:13 -0700177 return nullptr;
qiankun.miaod9aac342014-10-23 07:58:17 -0700178 }
179
180 *mask = result.fMask;
181 mask->fImage = (uint8_t*)(result.fData->data());
182 return result.fData;
183}
184
reed4dca7a82014-10-23 12:42:46 -0700185void SkMaskCache::Add(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
186 const SkRect rects[], int count, const SkMask& mask, SkCachedData* data,
qiankun.miaod9aac342014-10-23 07:58:17 -0700187 SkResourceCache* localCache) {
reed4dca7a82014-10-23 12:42:46 -0700188 RectsBlurKey key(sigma, style, quality, rects, count);
halcanary385fe4d2015-08-26 13:07:48 -0700189 return CHECK_LOCAL(localCache, add, Add, new RectsBlurRec(key, mask, data));
qiankun.miaod9aac342014-10-23 07:58:17 -0700190}