1d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao/*
2d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao * Copyright 2014 Google Inc.
3d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao *
4d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao * Use of this source code is governed by a BSD-style license that can be
5d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao * found in the LICENSE file.
6d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao */
7d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
8d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao#include "SkMaskCache.h"
9d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
10d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao#define CHECK_LOCAL(localCache, localName, globalName, ...) \
11d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    ((localCache) ? localCache->localName(__VA_ARGS__) : SkResourceCache::globalName(__VA_ARGS__))
12d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
13d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miaostruct MaskValue {
14d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    SkMask          fMask;
15d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    SkCachedData*   fData;
16d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao};
17d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
18d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miaonamespace {
19d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miaostatic unsigned gRRectBlurKeyNamespaceLabel;
20d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
21d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miaostruct RRectBlurKey : public SkResourceCache::Key {
22d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miaopublic:
23d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    RRectBlurKey(SkScalar sigma, const SkRRect& rrect, SkBlurStyle style, SkBlurQuality quality)
24d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        : fSigma(sigma)
25d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        , fStyle(style)
264dca7a829635b552be369186ff508a94aba6a903reed        , fQuality(quality)
274dca7a829635b552be369186ff508a94aba6a903reed        , fRRect(rrect)
284dca7a829635b552be369186ff508a94aba6a903reed    {
297eeba2587760a0802fd2b90765b4fd0e5e895375reed        this->init(&gRRectBlurKeyNamespaceLabel, 0,
304dca7a829635b552be369186ff508a94aba6a903reed                   sizeof(fSigma) + sizeof(fStyle) + sizeof(fQuality) + sizeof(fRRect));
31d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    }
32d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
33d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    SkScalar   fSigma;
34d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    int32_t    fStyle;
35d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    int32_t    fQuality;
364dca7a829635b552be369186ff508a94aba6a903reed    SkRRect    fRRect;
37d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao};
38d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
39d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miaostruct RRectBlurRec : public SkResourceCache::Rec {
40d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    RRectBlurRec(RRectBlurKey key, const SkMask& mask, SkCachedData* data)
41d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        : fKey(key)
42d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    {
43d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        fValue.fMask = mask;
44d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        fValue.fData = data;
45d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        fValue.fData->attachToCacheAndRef();
46d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    }
47d3b65972aad96453ff4510caa3e25a2b847c6d1eBrian Salomon    ~RRectBlurRec() override {
48d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        fValue.fData->detachFromCacheAndUnref();
49d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    }
50d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
51d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    RRectBlurKey   fKey;
52d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    MaskValue      fValue;
53d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
5436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const Key& getKey() const override { return fKey; }
5536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
56216b643fc77e754a3fabbb0ed397e7cf55d1954dreed    const char* getCategory() const override { return "rrect-blur"; }
57216b643fc77e754a3fabbb0ed397e7cf55d1954dreed    SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
58216b643fc77e754a3fabbb0ed397e7cf55d1954dreed        return fValue.fData->diagnostic_only_getDiscardable();
59216b643fc77e754a3fabbb0ed397e7cf55d1954dreed    }
60d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
61d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) {
62d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        const RRectBlurRec& rec = static_cast<const RRectBlurRec&>(baseRec);
63d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        MaskValue* result = (MaskValue*)contextData;
64d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
65d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        SkCachedData* tmpData = rec.fValue.fData;
66d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        tmpData->ref();
6796fcdcc219d2a0d3579719b84b28bede76efba64halcanary        if (nullptr == tmpData->data()) {
68d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao            tmpData->unref();
69d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao            return false;
70d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        }
71d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        *result = rec.fValue;
72d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        return true;
73d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    }
74d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao};
75d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao} // namespace
76d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
774dca7a829635b552be369186ff508a94aba6a903reedSkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
784dca7a829635b552be369186ff508a94aba6a903reed                                  const SkRRect& rrect, SkMask* mask, SkResourceCache* localCache) {
79d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    MaskValue result;
80d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    RRectBlurKey key(sigma, rrect, style, quality);
81d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    if (!CHECK_LOCAL(localCache, find, Find, key, RRectBlurRec::Visitor, &result)) {
8296fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
83d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    }
84d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
85d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    *mask = result.fMask;
86d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    mask->fImage = (uint8_t*)(result.fData->data());
87d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    return result.fData;
88d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao}
89d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
904dca7a829635b552be369186ff508a94aba6a903reedvoid SkMaskCache::Add(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
914dca7a829635b552be369186ff508a94aba6a903reed                      const SkRRect& rrect, const SkMask& mask, SkCachedData* data,
92d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao                      SkResourceCache* localCache) {
93d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    RRectBlurKey key(sigma, rrect, style, quality);
94385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    return CHECK_LOCAL(localCache, add, Add, new RRectBlurRec(key, mask, data));
95d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao}
96d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
97d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao//////////////////////////////////////////////////////////////////////////////////////////
98d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
99d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miaonamespace {
100d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miaostatic unsigned gRectsBlurKeyNamespaceLabel;
101d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
102d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miaostruct RectsBlurKey : public SkResourceCache::Key {
103d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miaopublic:
1044dca7a829635b552be369186ff508a94aba6a903reed    RectsBlurKey(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
1054dca7a829635b552be369186ff508a94aba6a903reed                 const SkRect rects[], int count)
106d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        : fSigma(sigma)
1074dca7a829635b552be369186ff508a94aba6a903reed        , fStyle(style)
1084dca7a829635b552be369186ff508a94aba6a903reed        , fQuality(quality)
1094dca7a829635b552be369186ff508a94aba6a903reed    {
110d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        SkASSERT(1 == count || 2 == count);
11169469b570ceb8a5ab7f64778d1b128cd5c472e73qiankun.miao        SkIRect ir;
11269469b570ceb8a5ab7f64778d1b128cd5c472e73qiankun.miao        rects[0].roundOut(&ir);
11373e81abd5e87a6630a2e2725abf13e11af4c8792jvanverth        fSizes[0] = SkSize::Make(rects[0].width(), rects[0].height());
11469469b570ceb8a5ab7f64778d1b128cd5c472e73qiankun.miao        if (2 == count) {
11573e81abd5e87a6630a2e2725abf13e11af4c8792jvanverth            fSizes[1] = SkSize::Make(rects[1].width(), rects[1].height());
11669469b570ceb8a5ab7f64778d1b128cd5c472e73qiankun.miao            fSizes[2] = SkSize::Make(rects[0].x() - rects[1].x(), rects[0].y() - rects[1].y());
11773e81abd5e87a6630a2e2725abf13e11af4c8792jvanverth        } else {
11873e81abd5e87a6630a2e2725abf13e11af4c8792jvanverth            fSizes[1] = SkSize::Make(0, 0);
11973e81abd5e87a6630a2e2725abf13e11af4c8792jvanverth            fSizes[2] = SkSize::Make(0, 0);
12069469b570ceb8a5ab7f64778d1b128cd5c472e73qiankun.miao        }
12173e81abd5e87a6630a2e2725abf13e11af4c8792jvanverth        fSizes[3] = SkSize::Make(rects[0].x() - ir.x(), rects[0].y() - ir.y());
12269469b570ceb8a5ab7f64778d1b128cd5c472e73qiankun.miao
1237eeba2587760a0802fd2b90765b4fd0e5e895375reed        this->init(&gRectsBlurKeyNamespaceLabel, 0,
12469469b570ceb8a5ab7f64778d1b128cd5c472e73qiankun.miao                   sizeof(fSigma) + sizeof(fStyle) + sizeof(fQuality) + sizeof(fSizes));
125d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    }
126d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
127d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    SkScalar    fSigma;
128d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    int32_t     fStyle;
1294dca7a829635b552be369186ff508a94aba6a903reed    int32_t     fQuality;
13069469b570ceb8a5ab7f64778d1b128cd5c472e73qiankun.miao    SkSize      fSizes[4];
131d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao};
132d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
133d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miaostruct RectsBlurRec : public SkResourceCache::Rec {
134d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    RectsBlurRec(RectsBlurKey key, const SkMask& mask, SkCachedData* data)
135d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        : fKey(key)
136d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    {
137d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        fValue.fMask = mask;
138d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        fValue.fData = data;
139d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        fValue.fData->attachToCacheAndRef();
140d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    }
141d3b65972aad96453ff4510caa3e25a2b847c6d1eBrian Salomon    ~RectsBlurRec() override {
142d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        fValue.fData->detachFromCacheAndUnref();
143d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    }
144d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
145d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    RectsBlurKey   fKey;
146d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    MaskValue      fValue;
147d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
14836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const Key& getKey() const override { return fKey; }
14936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
150216b643fc77e754a3fabbb0ed397e7cf55d1954dreed    const char* getCategory() const override { return "rects-blur"; }
151216b643fc77e754a3fabbb0ed397e7cf55d1954dreed    SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
152216b643fc77e754a3fabbb0ed397e7cf55d1954dreed        return fValue.fData->diagnostic_only_getDiscardable();
153216b643fc77e754a3fabbb0ed397e7cf55d1954dreed    }
154d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
155d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) {
156d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        const RectsBlurRec& rec = static_cast<const RectsBlurRec&>(baseRec);
157692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        MaskValue* result = static_cast<MaskValue*>(contextData);
158d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
159d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        SkCachedData* tmpData = rec.fValue.fData;
160d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        tmpData->ref();
16196fcdcc219d2a0d3579719b84b28bede76efba64halcanary        if (nullptr == tmpData->data()) {
162d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao            tmpData->unref();
163d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao            return false;
164d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        }
165d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        *result = rec.fValue;
166d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        return true;
167d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    }
168d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao};
169d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao} // namespace
170d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
1714dca7a829635b552be369186ff508a94aba6a903reedSkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
1724dca7a829635b552be369186ff508a94aba6a903reed                                      const SkRect rects[], int count, SkMask* mask,
173d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao                                      SkResourceCache* localCache) {
174d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    MaskValue result;
1754dca7a829635b552be369186ff508a94aba6a903reed    RectsBlurKey key(sigma, style, quality, rects, count);
176d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    if (!CHECK_LOCAL(localCache, find, Find, key, RectsBlurRec::Visitor, &result)) {
17796fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
178d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    }
179d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
180d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    *mask = result.fMask;
181d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    mask->fImage = (uint8_t*)(result.fData->data());
182d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    return result.fData;
183d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao}
184d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
1854dca7a829635b552be369186ff508a94aba6a903reedvoid SkMaskCache::Add(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
1864dca7a829635b552be369186ff508a94aba6a903reed                      const SkRect rects[], int count, const SkMask& mask, SkCachedData* data,
187d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao                      SkResourceCache* localCache) {
1884dca7a829635b552be369186ff508a94aba6a903reed    RectsBlurKey key(sigma, style, quality, rects, count);
189385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    return CHECK_LOCAL(localCache, add, Add, new RectsBlurRec(key, mask, data));
190d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao}
191