1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2014 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/core/SkMaskCache.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#define CHECK_LOCAL(localCache, localName, globalName, ...) \ 11cb93a386Sopenharmony_ci ((localCache) ? localCache->localName(__VA_ARGS__) : SkResourceCache::globalName(__VA_ARGS__)) 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_cistruct MaskValue { 14cb93a386Sopenharmony_ci SkMask fMask; 15cb93a386Sopenharmony_ci SkCachedData* fData; 16cb93a386Sopenharmony_ci}; 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_cinamespace { 19cb93a386Sopenharmony_cistatic unsigned gRRectBlurKeyNamespaceLabel; 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_cistruct RRectBlurKey : public SkResourceCache::Key { 22cb93a386Sopenharmony_cipublic: 23cb93a386Sopenharmony_ci RRectBlurKey(SkScalar sigma, const SkRRect& rrect, SkBlurStyle style) 24cb93a386Sopenharmony_ci : fSigma(sigma) 25cb93a386Sopenharmony_ci , fStyle(style) 26cb93a386Sopenharmony_ci , fRRect(rrect) 27cb93a386Sopenharmony_ci { 28cb93a386Sopenharmony_ci this->init(&gRRectBlurKeyNamespaceLabel, 0, 29cb93a386Sopenharmony_ci sizeof(fSigma) + sizeof(fStyle) + sizeof(fRRect)); 30cb93a386Sopenharmony_ci } 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ci SkScalar fSigma; 33cb93a386Sopenharmony_ci int32_t fStyle; 34cb93a386Sopenharmony_ci SkRRect fRRect; 35cb93a386Sopenharmony_ci}; 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_cistruct RRectBlurRec : public SkResourceCache::Rec { 38cb93a386Sopenharmony_ci RRectBlurRec(RRectBlurKey key, const SkMask& mask, SkCachedData* data) 39cb93a386Sopenharmony_ci : fKey(key) 40cb93a386Sopenharmony_ci { 41cb93a386Sopenharmony_ci fValue.fMask = mask; 42cb93a386Sopenharmony_ci fValue.fData = data; 43cb93a386Sopenharmony_ci fValue.fData->attachToCacheAndRef(); 44cb93a386Sopenharmony_ci } 45cb93a386Sopenharmony_ci ~RRectBlurRec() override { 46cb93a386Sopenharmony_ci fValue.fData->detachFromCacheAndUnref(); 47cb93a386Sopenharmony_ci } 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_ci RRectBlurKey fKey; 50cb93a386Sopenharmony_ci MaskValue fValue; 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_ci const Key& getKey() const override { return fKey; } 53cb93a386Sopenharmony_ci size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); } 54cb93a386Sopenharmony_ci const char* getCategory() const override { return "rrect-blur"; } 55cb93a386Sopenharmony_ci SkDiscardableMemory* diagnostic_only_getDiscardable() const override { 56cb93a386Sopenharmony_ci return fValue.fData->diagnostic_only_getDiscardable(); 57cb93a386Sopenharmony_ci } 58cb93a386Sopenharmony_ci 59cb93a386Sopenharmony_ci static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) { 60cb93a386Sopenharmony_ci const RRectBlurRec& rec = static_cast<const RRectBlurRec&>(baseRec); 61cb93a386Sopenharmony_ci MaskValue* result = (MaskValue*)contextData; 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ci SkCachedData* tmpData = rec.fValue.fData; 64cb93a386Sopenharmony_ci tmpData->ref(); 65cb93a386Sopenharmony_ci if (nullptr == tmpData->data()) { 66cb93a386Sopenharmony_ci tmpData->unref(); 67cb93a386Sopenharmony_ci return false; 68cb93a386Sopenharmony_ci } 69cb93a386Sopenharmony_ci *result = rec.fValue; 70cb93a386Sopenharmony_ci return true; 71cb93a386Sopenharmony_ci } 72cb93a386Sopenharmony_ci}; 73cb93a386Sopenharmony_ci} // namespace 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_ciSkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style, 76cb93a386Sopenharmony_ci const SkRRect& rrect, SkMask* mask, SkResourceCache* localCache) { 77cb93a386Sopenharmony_ci MaskValue result; 78cb93a386Sopenharmony_ci RRectBlurKey key(sigma, rrect, style); 79cb93a386Sopenharmony_ci if (!CHECK_LOCAL(localCache, find, Find, key, RRectBlurRec::Visitor, &result)) { 80cb93a386Sopenharmony_ci return nullptr; 81cb93a386Sopenharmony_ci } 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_ci *mask = result.fMask; 84cb93a386Sopenharmony_ci mask->fImage = (uint8_t*)(result.fData->data()); 85cb93a386Sopenharmony_ci return result.fData; 86cb93a386Sopenharmony_ci} 87cb93a386Sopenharmony_ci 88cb93a386Sopenharmony_civoid SkMaskCache::Add(SkScalar sigma, SkBlurStyle style, 89cb93a386Sopenharmony_ci const SkRRect& rrect, const SkMask& mask, SkCachedData* data, 90cb93a386Sopenharmony_ci SkResourceCache* localCache) { 91cb93a386Sopenharmony_ci RRectBlurKey key(sigma, rrect, style); 92cb93a386Sopenharmony_ci return CHECK_LOCAL(localCache, add, Add, new RRectBlurRec(key, mask, data)); 93cb93a386Sopenharmony_ci} 94cb93a386Sopenharmony_ci 95cb93a386Sopenharmony_ci////////////////////////////////////////////////////////////////////////////////////////// 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_cinamespace { 98cb93a386Sopenharmony_cistatic unsigned gRectsBlurKeyNamespaceLabel; 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_cistruct RectsBlurKey : public SkResourceCache::Key { 101cb93a386Sopenharmony_cipublic: 102cb93a386Sopenharmony_ci RectsBlurKey(SkScalar sigma, SkBlurStyle style, const SkRect rects[], int count) 103cb93a386Sopenharmony_ci : fSigma(sigma) 104cb93a386Sopenharmony_ci , fStyle(style) 105cb93a386Sopenharmony_ci { 106cb93a386Sopenharmony_ci SkASSERT(1 == count || 2 == count); 107cb93a386Sopenharmony_ci SkIRect ir; 108cb93a386Sopenharmony_ci rects[0].roundOut(&ir); 109cb93a386Sopenharmony_ci fSizes[0] = SkSize{rects[0].width(), rects[0].height()}; 110cb93a386Sopenharmony_ci if (2 == count) { 111cb93a386Sopenharmony_ci fSizes[1] = SkSize{rects[1].width(), rects[1].height()}; 112cb93a386Sopenharmony_ci fSizes[2] = SkSize{rects[0].x() - rects[1].x(), rects[0].y() - rects[1].y()}; 113cb93a386Sopenharmony_ci } else { 114cb93a386Sopenharmony_ci fSizes[1] = SkSize{0, 0}; 115cb93a386Sopenharmony_ci fSizes[2] = SkSize{0, 0}; 116cb93a386Sopenharmony_ci } 117cb93a386Sopenharmony_ci fSizes[3] = SkSize{rects[0].x() - ir.x(), rects[0].y() - ir.y()}; 118cb93a386Sopenharmony_ci 119cb93a386Sopenharmony_ci this->init(&gRectsBlurKeyNamespaceLabel, 0, 120cb93a386Sopenharmony_ci sizeof(fSigma) + sizeof(fStyle) + sizeof(fSizes)); 121cb93a386Sopenharmony_ci } 122cb93a386Sopenharmony_ci 123cb93a386Sopenharmony_ci SkScalar fSigma; 124cb93a386Sopenharmony_ci int32_t fStyle; 125cb93a386Sopenharmony_ci SkSize fSizes[4]; 126cb93a386Sopenharmony_ci}; 127cb93a386Sopenharmony_ci 128cb93a386Sopenharmony_cistruct RectsBlurRec : public SkResourceCache::Rec { 129cb93a386Sopenharmony_ci RectsBlurRec(RectsBlurKey key, const SkMask& mask, SkCachedData* data) 130cb93a386Sopenharmony_ci : fKey(key) 131cb93a386Sopenharmony_ci { 132cb93a386Sopenharmony_ci fValue.fMask = mask; 133cb93a386Sopenharmony_ci fValue.fData = data; 134cb93a386Sopenharmony_ci fValue.fData->attachToCacheAndRef(); 135cb93a386Sopenharmony_ci } 136cb93a386Sopenharmony_ci ~RectsBlurRec() override { 137cb93a386Sopenharmony_ci fValue.fData->detachFromCacheAndUnref(); 138cb93a386Sopenharmony_ci } 139cb93a386Sopenharmony_ci 140cb93a386Sopenharmony_ci RectsBlurKey fKey; 141cb93a386Sopenharmony_ci MaskValue fValue; 142cb93a386Sopenharmony_ci 143cb93a386Sopenharmony_ci const Key& getKey() const override { return fKey; } 144cb93a386Sopenharmony_ci size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); } 145cb93a386Sopenharmony_ci const char* getCategory() const override { return "rects-blur"; } 146cb93a386Sopenharmony_ci SkDiscardableMemory* diagnostic_only_getDiscardable() const override { 147cb93a386Sopenharmony_ci return fValue.fData->diagnostic_only_getDiscardable(); 148cb93a386Sopenharmony_ci } 149cb93a386Sopenharmony_ci 150cb93a386Sopenharmony_ci static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) { 151cb93a386Sopenharmony_ci const RectsBlurRec& rec = static_cast<const RectsBlurRec&>(baseRec); 152cb93a386Sopenharmony_ci MaskValue* result = static_cast<MaskValue*>(contextData); 153cb93a386Sopenharmony_ci 154cb93a386Sopenharmony_ci SkCachedData* tmpData = rec.fValue.fData; 155cb93a386Sopenharmony_ci tmpData->ref(); 156cb93a386Sopenharmony_ci if (nullptr == tmpData->data()) { 157cb93a386Sopenharmony_ci tmpData->unref(); 158cb93a386Sopenharmony_ci return false; 159cb93a386Sopenharmony_ci } 160cb93a386Sopenharmony_ci *result = rec.fValue; 161cb93a386Sopenharmony_ci return true; 162cb93a386Sopenharmony_ci } 163cb93a386Sopenharmony_ci}; 164cb93a386Sopenharmony_ci} // namespace 165cb93a386Sopenharmony_ci 166cb93a386Sopenharmony_ciSkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style, 167cb93a386Sopenharmony_ci const SkRect rects[], int count, SkMask* mask, 168cb93a386Sopenharmony_ci SkResourceCache* localCache) { 169cb93a386Sopenharmony_ci MaskValue result; 170cb93a386Sopenharmony_ci RectsBlurKey key(sigma, style, rects, count); 171cb93a386Sopenharmony_ci if (!CHECK_LOCAL(localCache, find, Find, key, RectsBlurRec::Visitor, &result)) { 172cb93a386Sopenharmony_ci return nullptr; 173cb93a386Sopenharmony_ci } 174cb93a386Sopenharmony_ci 175cb93a386Sopenharmony_ci *mask = result.fMask; 176cb93a386Sopenharmony_ci mask->fImage = (uint8_t*)(result.fData->data()); 177cb93a386Sopenharmony_ci return result.fData; 178cb93a386Sopenharmony_ci} 179cb93a386Sopenharmony_ci 180cb93a386Sopenharmony_civoid SkMaskCache::Add(SkScalar sigma, SkBlurStyle style, 181cb93a386Sopenharmony_ci const SkRect rects[], int count, const SkMask& mask, SkCachedData* data, 182cb93a386Sopenharmony_ci SkResourceCache* localCache) { 183cb93a386Sopenharmony_ci RectsBlurKey key(sigma, style, rects, count); 184cb93a386Sopenharmony_ci return CHECK_LOCAL(localCache, add, Add, new RectsBlurRec(key, mask, data)); 185cb93a386Sopenharmony_ci} 186