SkMaskCache.cpp revision d9aac34eceeb197c5551f38583670be7729dd00a
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 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) 25 , fRRect(rrect) 26 , fStyle(style) 27 , fQuality(quality) { 28 this->init(&gRRectBlurKeyNamespaceLabel, 29 sizeof(fSigma) + sizeof(fRRect) + sizeof(fStyle) + sizeof(fQuality)); 30 } 31 32 SkScalar fSigma; 33 SkRRect fRRect; 34 int32_t fStyle; 35 int32_t fQuality; 36}; 37 38struct RRectBlurRec : public SkResourceCache::Rec { 39 RRectBlurRec(RRectBlurKey key, const SkMask& mask, SkCachedData* data) 40 : fKey(key) 41 { 42 fValue.fMask = mask; 43 fValue.fData = data; 44 fValue.fData->attachToCacheAndRef(); 45 } 46 ~RRectBlurRec() { 47 fValue.fData->detachFromCacheAndUnref(); 48 } 49 50 RRectBlurKey fKey; 51 MaskValue fValue; 52 53 virtual const Key& getKey() const SK_OVERRIDE { return fKey; } 54 virtual size_t bytesUsed() const SK_OVERRIDE { return sizeof(*this) + fValue.fData->size(); } 55 56 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) { 57 const RRectBlurRec& rec = static_cast<const RRectBlurRec&>(baseRec); 58 MaskValue* result = (MaskValue*)contextData; 59 60 SkCachedData* tmpData = rec.fValue.fData; 61 tmpData->ref(); 62 if (NULL == tmpData->data()) { 63 tmpData->unref(); 64 return false; 65 } 66 *result = rec.fValue; 67 return true; 68 } 69}; 70} // namespace 71 72SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, const SkRRect& rrect, SkBlurStyle style, 73 SkBlurQuality quality, SkMask* mask, 74 SkResourceCache* localCache) { 75 MaskValue result; 76 RRectBlurKey key(sigma, rrect, style, quality); 77 if (!CHECK_LOCAL(localCache, find, Find, key, RRectBlurRec::Visitor, &result)) { 78 return NULL; 79 } 80 81 *mask = result.fMask; 82 mask->fImage = (uint8_t*)(result.fData->data()); 83 return result.fData; 84} 85 86void SkMaskCache::Add(SkScalar sigma, const SkRRect& rrect, SkBlurStyle style, 87 SkBlurQuality quality, const SkMask& mask, SkCachedData* data, 88 SkResourceCache* localCache) { 89 RRectBlurKey key(sigma, rrect, style, quality); 90 return CHECK_LOCAL(localCache, add, Add, SkNEW_ARGS(RRectBlurRec, (key, mask, data))); 91} 92 93////////////////////////////////////////////////////////////////////////////////////////// 94 95namespace { 96static unsigned gRectsBlurKeyNamespaceLabel; 97 98struct RectsBlurKey : public SkResourceCache::Key { 99public: 100 RectsBlurKey(SkScalar sigma, int count, const SkRect rects[], SkBlurStyle style) 101 : fSigma(sigma) 102 , fRecCount(count) 103 , fStyle(style){ 104 SkASSERT(1 == count || 2 == count); 105 fRects[0] = SkRect::MakeEmpty(); 106 fRects[1] = SkRect::MakeEmpty(); 107 for (int i = 0; i < count; i++) { 108 fRects[i] = rects[i]; 109 } 110 this->init(&gRectsBlurKeyNamespaceLabel, 111 sizeof(fSigma) + sizeof(fRecCount) + sizeof(fRects) + sizeof(fStyle)); 112 } 113 114 SkScalar fSigma; 115 int fRecCount; 116 SkRect fRects[2]; 117 int32_t fStyle; 118}; 119 120struct RectsBlurRec : public SkResourceCache::Rec { 121 RectsBlurRec(RectsBlurKey key, const SkMask& mask, SkCachedData* data) 122 : fKey(key) 123 { 124 fValue.fMask = mask; 125 fValue.fData = data; 126 fValue.fData->attachToCacheAndRef(); 127 } 128 ~RectsBlurRec() { 129 fValue.fData->detachFromCacheAndUnref(); 130 } 131 132 RectsBlurKey fKey; 133 MaskValue fValue; 134 135 virtual const Key& getKey() const SK_OVERRIDE { return fKey; } 136 virtual size_t bytesUsed() const SK_OVERRIDE { return sizeof(*this) + fValue.fData->size(); } 137 138 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) { 139 const RectsBlurRec& rec = static_cast<const RectsBlurRec&>(baseRec); 140 MaskValue* result = (MaskValue*)contextData; 141 142 SkCachedData* tmpData = rec.fValue.fData; 143 tmpData->ref(); 144 if (NULL == tmpData->data()) { 145 tmpData->unref(); 146 return false; 147 } 148 *result = rec.fValue; 149 return true; 150 } 151}; 152} // namespace 153 154SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, const SkRect rects[], int count, 155 SkBlurStyle style, SkMask* mask, 156 SkResourceCache* localCache) { 157 MaskValue result; 158 RectsBlurKey key(sigma, count, rects, style); 159 if (!CHECK_LOCAL(localCache, find, Find, key, RectsBlurRec::Visitor, &result)) { 160 return NULL; 161 } 162 163 *mask = result.fMask; 164 mask->fImage = (uint8_t*)(result.fData->data()); 165 return result.fData; 166} 167 168void SkMaskCache::Add(SkScalar sigma, const SkRect rects[], int count, SkBlurStyle style, 169 const SkMask& mask, SkCachedData* data, 170 SkResourceCache* localCache) { 171 RectsBlurKey key(sigma, count, rects, style); 172 return CHECK_LOCAL(localCache, add, Add, SkNEW_ARGS(RectsBlurRec, (key, mask, data))); 173} 174