Index: src/core/SkMaskCache.cpp |
diff --git a/src/core/SkMaskCache.cpp b/src/core/SkMaskCache.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c6775ac7d5e3844d57a4e8c2a2b0c2baf47f6c34 |
--- /dev/null |
+++ b/src/core/SkMaskCache.cpp |
@@ -0,0 +1,141 @@ |
+/* |
+ * 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 "SkCachedData_priv.h" |
+#include "SkMaskCache.h" |
+#include "SkResourceCache.h" |
+#include "SkRRect.h" |
+ |
+struct MaskKey_Rects : public SkResourceCache::Key { |
+ MaskKey_Rects(SkScalar sigma, const SkRect& outer, const SkRect& inner) |
+ : fSigma(sigma) |
+ , fOuter(outer) |
+ , fInner(inner) |
+ { |
+ this->init(sizeof(fSigma) + sizeof(fOuter) + sizeof(fInner)); |
+ } |
+ |
+ SkScalar fSigma; |
+ SkRect fOuter; |
+ SkRect fInner; |
+}; |
+ |
+struct MaskKey_RRect : public SkResourceCache::Key { |
+ MaskKey_RRect(SkScalar sigma, const SkRRect& rrect) |
+ : fSigma(sigma) |
+ , fRRect(rrect) |
+ { |
+ this->init(sizeof(fSigma) + sizeof(fRRect)); |
+ } |
+ |
+ SkScalar fSigma; |
+ SkRRect fRRect; |
+}; |
+ |
+struct MaskValue { |
+ SkMask fMask; |
+ SkCachedData* fPixels; |
+}; |
+ |
+struct MaskRecBase : public SkResourceCache::Rec { |
+ MaskValue fValue; |
+}; |
+ |
+template <typename MaskKey> struct TMaskRec : public MaskRecBase { |
+ TMaskRec(const MaskKey& key, const SkMask& mask, SkCachedData* pixels) : fKey(key) { |
+ fValue.fMask = mask; |
+ fValue.fPixels = pixels; |
+ fValue.fPixels->ref_from_cache(); |
+ } |
+ virtual ~TMaskRec() { |
+ fValue.fPixels->unref_from_cache(); |
+ } |
+ |
+ MaskKey fKey; |
+ |
+ virtual const Key& getKey() const SK_OVERRIDE { return fKey; } |
+ |
+ virtual size_t bytesUsed() const SK_OVERRIDE { |
+ return sizeof(*this) + fValue.fPixels->size(); |
+ } |
+ |
+ static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextPayload) { |
+ const MaskRecBase& rec = static_cast<const MaskRecBase&>(baseRec); |
+ |
+ SkCachedData* pixels = rec.fValue.fPixels; |
+ pixels->ref(); |
+ if (NULL == pixels->data()) { |
+ pixels->unref(); |
+ return false; |
+ } |
+ |
+ // we return our pixels already (successfully) ref'd |
+ *static_cast<MaskValue*>(contextPayload) = rec.fValue; |
+ return true; |
+ } |
+}; |
+ |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+template <typename MaskKey> |
+static SkCachedData* find_and_lock(const MaskKey& key, SkMask* mask, SkResourceCache* localCache) { |
+ MaskValue value; |
+ |
+ bool found; |
+ if (localCache) { |
+ found = localCache->find(key, TMaskRec<MaskKey>::Visitor, &value); |
+ } else { |
+ found = SkResourceCache::Find(key, TMaskRec<MaskKey>::Visitor, &value); |
+ } |
+ if (!found) { |
+ return NULL; |
+ } |
+ |
+ if (mask) { |
+ *mask = value.fMask; |
+ mask->fImage = (uint8_t*)value.fPixels->data(); |
+ } |
+ return value.fPixels; |
+} |
+ |
+SkCachedData* SkMaskCache::FindAndLock(SkScalar sigma, const SkRect& r0, const SkRect& r1, |
+ SkMask* result, SkResourceCache* localCache) { |
+ return find_and_lock(MaskKey_Rects(sigma, r0, r1), result, localCache); |
+} |
+ |
+SkCachedData* SkMaskCache::FindAndLock(SkScalar sigma, const SkRRect& rrect, |
+ SkMask* result, SkResourceCache* localCache) { |
+ return find_and_lock(MaskKey_RRect(sigma, rrect), result, localCache); |
+} |
+ |
+static void add(SkResourceCache::Rec* rec, SkResourceCache* localCache) { |
+ localCache ? localCache->add(rec) : SkResourceCache::Add(rec); |
+} |
+ |
+void SkMaskCache::Add(SkScalar sigma, const SkRect& r0, const SkRect& r1, const SkMask& mask, |
+ SkCachedData* pixels, SkResourceCache* localCache) { |
+ add(SkNEW_ARGS(TMaskRec<MaskKey_Rects>, (MaskKey_Rects(sigma, r0, r1), mask, pixels)), localCache); |
+} |
+ |
+void SkMaskCache::Add(SkScalar sigma, const SkRRect& rrect, const SkMask& mask, |
+ SkCachedData* pixels, SkResourceCache* localCache) { |
+ add(SkNEW_ARGS(TMaskRec<MaskKey_RRect>, (MaskKey_RRect(sigma, rrect), mask, pixels)), localCache); |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+// 1 Rect just means 2 rects where the 2nd (inner) rect is empty |
+ |
+SkCachedData* SkMaskCache::FindAndLock(SkScalar sigma, const SkRect& rect, |
+ SkMask* result, SkResourceCache* localCache) { |
+ return FindAndLock(sigma, rect, SkRect::MakeEmpty(), result, localCache); |
+} |
+ |
+void SkMaskCache::Add(SkScalar sigma, const SkRect& rect, |
+ const SkMask& result, SkCachedData* data, SkResourceCache* localCache) { |
+ return Add(sigma, rect, SkRect::MakeEmpty(), result, data, localCache); |
+} |
+ |