| 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);
|
| +}
|
| +
|
|
|