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    }
47d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    ~RRectBlurRec() {
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(); }
562880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    const char* getCategory() const override { return "rrect-blur"; }
572880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
582880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        return fValue.fData->diagnostic_only_getDiscardable();
592880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
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();
672880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        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)) {
822880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        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);
942880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    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);
11369469b570ceb8a5ab7f64778d1b128cd5c472e73qiankun.miao        fSizes[0] = SkSize::Make(0, 0);
11469469b570ceb8a5ab7f64778d1b128cd5c472e73qiankun.miao        fSizes[1] = SkSize::Make(0, 0);
11569469b570ceb8a5ab7f64778d1b128cd5c472e73qiankun.miao        fSizes[2] = SkSize::Make(0, 0);
11669469b570ceb8a5ab7f64778d1b128cd5c472e73qiankun.miao        fSizes[3] = SkSize::Make(rects[0].x() - ir.x(), rects[0].y() - ir.y());
117d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        for (int i = 0; i < count; i++) {
11869469b570ceb8a5ab7f64778d1b128cd5c472e73qiankun.miao            fSizes[i] = SkSize::Make(rects[i].width(), rects[i].height());
119d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        }
12069469b570ceb8a5ab7f64778d1b128cd5c472e73qiankun.miao        if (2 == count) {
12169469b570ceb8a5ab7f64778d1b128cd5c472e73qiankun.miao            fSizes[2] = SkSize::Make(rects[0].x() - rects[1].x(), rects[0].y() - rects[1].y());
12269469b570ceb8a5ab7f64778d1b128cd5c472e73qiankun.miao        }
12369469b570ceb8a5ab7f64778d1b128cd5c472e73qiankun.miao
1247eeba2587760a0802fd2b90765b4fd0e5e895375reed        this->init(&gRectsBlurKeyNamespaceLabel, 0,
12569469b570ceb8a5ab7f64778d1b128cd5c472e73qiankun.miao                   sizeof(fSigma) + sizeof(fStyle) + sizeof(fQuality) + sizeof(fSizes));
126d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    }
127d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
128d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    SkScalar    fSigma;
129d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    int32_t     fStyle;
1304dca7a829635b552be369186ff508a94aba6a903reed    int32_t     fQuality;
13169469b570ceb8a5ab7f64778d1b128cd5c472e73qiankun.miao    SkSize      fSizes[4];
132d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao};
133d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
134d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miaostruct RectsBlurRec : public SkResourceCache::Rec {
135d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    RectsBlurRec(RectsBlurKey key, const SkMask& mask, SkCachedData* data)
136d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        : fKey(key)
137d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    {
138d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        fValue.fMask = mask;
139d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        fValue.fData = data;
140d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        fValue.fData->attachToCacheAndRef();
141d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    }
142d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    ~RectsBlurRec() {
143d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        fValue.fData->detachFromCacheAndUnref();
144d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    }
145d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
146d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    RectsBlurKey   fKey;
147d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    MaskValue      fValue;
148d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
14936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const Key& getKey() const override { return fKey; }
15036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
1512880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    const char* getCategory() const override { return "rects-blur"; }
1522880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
1532880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        return fValue.fData->diagnostic_only_getDiscardable();
1542880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
155d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
156d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) {
157d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        const RectsBlurRec& rec = static_cast<const RectsBlurRec&>(baseRec);
158692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        MaskValue* result = static_cast<MaskValue*>(contextData);
159d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
160d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        SkCachedData* tmpData = rec.fValue.fData;
161d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        tmpData->ref();
1622880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        if (nullptr == tmpData->data()) {
163d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao            tmpData->unref();
164d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao            return false;
165d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        }
166d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        *result = rec.fValue;
167d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao        return true;
168d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    }
169d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao};
170d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao} // namespace
171d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
1724dca7a829635b552be369186ff508a94aba6a903reedSkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
1734dca7a829635b552be369186ff508a94aba6a903reed                                      const SkRect rects[], int count, SkMask* mask,
174d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao                                      SkResourceCache* localCache) {
175d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    MaskValue result;
1764dca7a829635b552be369186ff508a94aba6a903reed    RectsBlurKey key(sigma, style, quality, rects, count);
177d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    if (!CHECK_LOCAL(localCache, find, Find, key, RectsBlurRec::Visitor, &result)) {
1782880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        return nullptr;
179d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    }
180d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
181d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    *mask = result.fMask;
182d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    mask->fImage = (uint8_t*)(result.fData->data());
183d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao    return result.fData;
184d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao}
185d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao
1864dca7a829635b552be369186ff508a94aba6a903reedvoid SkMaskCache::Add(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
1874dca7a829635b552be369186ff508a94aba6a903reed                      const SkRect rects[], int count, const SkMask& mask, SkCachedData* data,
188d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao                      SkResourceCache* localCache) {
1894dca7a829635b552be369186ff508a94aba6a903reed    RectsBlurKey key(sigma, style, quality, rects, count);
1902880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    return CHECK_LOCAL(localCache, add, Add, new RectsBlurRec(key, mask, data));
191d9aac34eceeb197c5551f38583670be7729dd00aqiankun.miao}
192