Index: src/core/SkMaskCache.cpp |
diff --git a/src/core/SkMaskCache.cpp b/src/core/SkMaskCache.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c0cd60f40ea0c76bf8b0fa4af86ae35cd9246622 |
--- /dev/null |
+++ b/src/core/SkMaskCache.cpp |
@@ -0,0 +1,153 @@ |
+/* |
+ * Copyright 2014 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "SkMaskCache.h" |
+ |
+#define CHECK_LOCAL(localCache, localName, globalName, ...) \ |
+ ((localCache) ? localCache->localName(__VA_ARGS__) : SkResourceCache::globalName(__VA_ARGS__)) |
+ |
+struct MaskValue { |
+ SkMask fMask; |
+ SkCachedData* fData; |
+}; |
+ |
+struct RRectBlurKey : public SkResourceCache::Key { |
+public: |
+ RRectBlurKey(SkScalar sigma, const SkRRect& rrect) |
+ : fSigma(sigma) |
+ , fRRect(rrect) { |
+ this->init(sizeof(fSigma) + sizeof(fRRect)); |
+ } |
+ |
+ SkScalar fSigma; |
+ SkRRect fRRect; |
+}; |
+ |
+struct RRectBlurRec : public SkResourceCache::Rec { |
+ RRectBlurRec(SkScalar sigma, const SkRRect& rrect, const SkMask& mask, SkCachedData* data) |
+ : fKey(sigma, rrect) |
+ { |
+ fValue.fMask = mask; |
+ fValue.fData = data; |
+ fValue.fData->attachToCacheAndRef(); |
+ } |
+ ~RRectBlurRec() { |
+ fValue.fData->detachFromCacheAndUnref(); |
+ } |
+ |
+ RRectBlurKey fKey; |
+ MaskValue fValue; |
+ |
+ virtual const Key& getKey() const SK_OVERRIDE { return fKey; } |
+ virtual size_t bytesUsed() const SK_OVERRIDE { return sizeof(*this) + fValue.fData->size(); } |
+ |
+ static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) { |
+ const RRectBlurRec& rec = static_cast<const RRectBlurRec&>(baseRec); |
+ MaskValue* result = (MaskValue*)contextData; |
+ |
+ SkCachedData* tmpData = rec.fValue.fData; |
+ tmpData->ref(); |
+ if (NULL == tmpData->data()) { |
+ tmpData->unref(); |
+ return false; |
+ } |
+ *result = rec.fValue; |
+ return true; |
+ } |
+}; |
+ |
+SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, const SkRRect& rrect, |
+ SkMask* mask, SkResourceCache* localCache) { |
+ MaskValue result; |
+ RRectBlurKey key(sigma, rrect); |
+ if (!CHECK_LOCAL(localCache, find, Find, key, RRectBlurRec::Visitor, &result)) { |
+ return NULL; |
+ } |
+ |
+ *mask = result.fMask; |
+ mask->fImage = (uint8_t*)(result.fData->data()); |
+ return result.fData; |
+} |
+ |
+void SkMaskCache::Add(SkScalar sigma, const SkRRect& rrect, |
+ const SkMask& mask, SkCachedData* data, |
+ SkResourceCache* localCache) { |
+ return CHECK_LOCAL(localCache, add, Add, SkNEW_ARGS(RRectBlurRec, (sigma, rrect, mask, data))); |
+} |
+ |
+////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+struct RectsBlurKey : public SkResourceCache::Key { |
+public: |
+ RectsBlurKey(SkScalar sigma, int32_t count, const SkRect rects[]) |
+ : fSigma(sigma) |
+ , fRecCount(count) { |
+ SkASSERT(1 == count || 2 == count); |
+ for (int i = 0; i < count; i++) { |
+ fRects[i] = rects[i]; |
+ } |
+ this->init(sizeof(fSigma) + sizeof(fRecCount) + sizeof(SkRect) * fRecCount); |
+ } |
+ |
+ SkScalar fSigma; |
+ int32_t fRecCount; |
+ SkRect fRects[2]; |
+}; |
+ |
+struct RectsBlurRec : public SkResourceCache::Rec { |
+ RectsBlurRec(SkScalar sigma, unsigned count, const SkRect rects[], |
+ const SkMask& mask, SkCachedData* data) |
+ : fKey(sigma, count, rects) |
+ { |
+ fValue.fMask = mask; |
+ fValue.fData = data; |
+ fValue.fData->attachToCacheAndRef(); |
+ } |
+ ~RectsBlurRec() { |
+ fValue.fData->detachFromCacheAndUnref(); |
+ } |
+ |
+ RectsBlurKey fKey; |
+ MaskValue fValue; |
+ |
+ virtual const Key& getKey() const SK_OVERRIDE { return fKey; } |
+ virtual size_t bytesUsed() const SK_OVERRIDE { return sizeof(*this) + fValue.fData->size(); } |
+ |
+ static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) { |
+ const RectsBlurRec& rec = static_cast<const RectsBlurRec&>(baseRec); |
+ MaskValue* result = (MaskValue*)contextData; |
+ |
+ SkCachedData* tmpData = rec.fValue.fData; |
+ tmpData->ref(); |
+ if (NULL == tmpData->data()) { |
+ tmpData->unref(); |
+ return false; |
+ } |
+ *result = rec.fValue; |
+ return true; |
+ } |
+}; |
+ |
+SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, const SkRect rects[], int32_t count, |
+ SkMask* mask, SkResourceCache* localCache) { |
+ MaskValue result; |
+ RectsBlurKey key(sigma, count, rects); |
+ if (!CHECK_LOCAL(localCache, find, Find, key, RectsBlurRec::Visitor, &result)) { |
+ return NULL; |
+ } |
+ |
+ *mask = result.fMask; |
+ mask->fImage = (uint8_t*)(result.fData->data()); |
+ return result.fData; |
+} |
+ |
+void SkMaskCache::Add(SkScalar sigma, const SkRect rects[], int count, |
+ const SkMask& mask, SkCachedData* data, |
+ SkResourceCache* localCache) { |
+ return CHECK_LOCAL(localCache, add, Add, SkNEW_ARGS(RectsBlurRec, |
+ (sigma, count, rects, mask, data))); |
+} |