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