aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core/SkMaskCache.cpp44
-rw-r--r--src/core/SkMaskCache.h18
-rw-r--r--src/effects/SkBlurMaskFilter.cpp114
-rw-r--r--tests/MaskCacheTest.cpp13
4 files changed, 127 insertions, 62 deletions
diff --git a/src/core/SkMaskCache.cpp b/src/core/SkMaskCache.cpp
index 4520e9775f..e203081655 100644
--- a/src/core/SkMaskCache.cpp
+++ b/src/core/SkMaskCache.cpp
@@ -22,17 +22,18 @@ struct RRectBlurKey : public SkResourceCache::Key {
public:
RRectBlurKey(SkScalar sigma, const SkRRect& rrect, SkBlurStyle style, SkBlurQuality quality)
: fSigma(sigma)
- , fRRect(rrect)
, fStyle(style)
- , fQuality(quality) {
+ , fQuality(quality)
+ , fRRect(rrect)
+ {
this->init(&gRRectBlurKeyNamespaceLabel,
- sizeof(fSigma) + sizeof(fRRect) + sizeof(fStyle) + sizeof(fQuality));
+ sizeof(fSigma) + sizeof(fStyle) + sizeof(fQuality) + sizeof(fRRect));
}
SkScalar fSigma;
- SkRRect fRRect;
int32_t fStyle;
int32_t fQuality;
+ SkRRect fRRect;
};
struct RRectBlurRec : public SkResourceCache::Rec {
@@ -69,9 +70,8 @@ struct RRectBlurRec : public SkResourceCache::Rec {
};
} // namespace
-SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, const SkRRect& rrect, SkBlurStyle style,
- SkBlurQuality quality, SkMask* mask,
- SkResourceCache* localCache) {
+SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
+ const SkRRect& rrect, SkMask* mask, SkResourceCache* localCache) {
MaskValue result;
RRectBlurKey key(sigma, rrect, style, quality);
if (!CHECK_LOCAL(localCache, find, Find, key, RRectBlurRec::Visitor, &result)) {
@@ -83,8 +83,8 @@ SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, const SkRRect& rrect, SkBl
return result.fData;
}
-void SkMaskCache::Add(SkScalar sigma, const SkRRect& rrect, SkBlurStyle style,
- SkBlurQuality quality, const SkMask& mask, SkCachedData* data,
+void SkMaskCache::Add(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
+ const SkRRect& rrect, const SkMask& mask, SkCachedData* data,
SkResourceCache* localCache) {
RRectBlurKey key(sigma, rrect, style, quality);
return CHECK_LOCAL(localCache, add, Add, SkNEW_ARGS(RRectBlurRec, (key, mask, data)));
@@ -97,10 +97,12 @@ static unsigned gRectsBlurKeyNamespaceLabel;
struct RectsBlurKey : public SkResourceCache::Key {
public:
- RectsBlurKey(SkScalar sigma, int count, const SkRect rects[], SkBlurStyle style)
+ RectsBlurKey(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
+ const SkRect rects[], int count)
: fSigma(sigma)
- , fRecCount(count)
- , fStyle(style){
+ , fStyle(style)
+ , fQuality(quality)
+ {
SkASSERT(1 == count || 2 == count);
fRects[0] = SkRect::MakeEmpty();
fRects[1] = SkRect::MakeEmpty();
@@ -108,13 +110,13 @@ public:
fRects[i] = rects[i];
}
this->init(&gRectsBlurKeyNamespaceLabel,
- sizeof(fSigma) + sizeof(fRecCount) + sizeof(fRects) + sizeof(fStyle));
+ sizeof(fSigma) + sizeof(fStyle) + sizeof(fQuality) + sizeof(fRects));
}
SkScalar fSigma;
- int fRecCount;
- SkRect fRects[2];
int32_t fStyle;
+ int32_t fQuality;
+ SkRect fRects[2];
};
struct RectsBlurRec : public SkResourceCache::Rec {
@@ -151,11 +153,11 @@ struct RectsBlurRec : public SkResourceCache::Rec {
};
} // namespace
-SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, const SkRect rects[], int count,
- SkBlurStyle style, SkMask* mask,
+SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
+ const SkRect rects[], int count, SkMask* mask,
SkResourceCache* localCache) {
MaskValue result;
- RectsBlurKey key(sigma, count, rects, style);
+ RectsBlurKey key(sigma, style, quality, rects, count);
if (!CHECK_LOCAL(localCache, find, Find, key, RectsBlurRec::Visitor, &result)) {
return NULL;
}
@@ -165,9 +167,9 @@ SkCachedData* SkMaskCache::FindAndRef(SkScalar sigma, const SkRect rects[], int
return result.fData;
}
-void SkMaskCache::Add(SkScalar sigma, const SkRect rects[], int count, SkBlurStyle style,
- const SkMask& mask, SkCachedData* data,
+void SkMaskCache::Add(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
+ const SkRect rects[], int count, const SkMask& mask, SkCachedData* data,
SkResourceCache* localCache) {
- RectsBlurKey key(sigma, count, rects, style);
+ RectsBlurKey key(sigma, style, quality, rects, count);
return CHECK_LOCAL(localCache, add, Add, SkNEW_ARGS(RectsBlurRec, (key, mask, data)));
}
diff --git a/src/core/SkMaskCache.h b/src/core/SkMaskCache.h
index f44ed3874c..f98387b206 100644
--- a/src/core/SkMaskCache.h
+++ b/src/core/SkMaskCache.h
@@ -23,20 +23,22 @@ public:
*
* On failure, return NULL.
*/
- static SkCachedData* FindAndRef(SkScalar sigma, const SkRRect& rrect, SkBlurStyle style,
- SkBlurQuality quality, SkMask* mask,
+ static SkCachedData* FindAndRef(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
+ const SkRRect& rrect, SkMask* mask,
SkResourceCache* localCache = NULL);
- static SkCachedData* FindAndRef(SkScalar sigma, const SkRect rects[], int count,
- SkBlurStyle style,SkMask* mask,
+ static SkCachedData* FindAndRef(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
+ const SkRect rects[], int count, SkMask* mask,
SkResourceCache* localCache = NULL);
/**
* Add a mask and its pixel-data to the cache.
*/
- static void Add(SkScalar sigma, const SkRRect& rrect, SkBlurStyle style, SkBlurQuality quality,
- const SkMask& mask, SkCachedData* data, SkResourceCache* localCache = NULL);
- static void Add(SkScalar sigma, const SkRect rects[], int count, SkBlurStyle style,
- const SkMask& mask, SkCachedData* data, SkResourceCache* localCache = NULL);
+ static void Add(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
+ const SkRRect& rrect, const SkMask& mask, SkCachedData* data,
+ SkResourceCache* localCache = NULL);
+ static void Add(SkScalar sigma, SkBlurStyle style, SkBlurQuality quality,
+ const SkRect rects[], int count, const SkMask& mask, SkCachedData* data,
+ SkResourceCache* localCache = NULL);
};
#endif
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index 6f69aaf4ab..f0bd3757a6 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -257,6 +257,58 @@ static bool rect_exceeds(const SkRect& r, SkScalar v) {
r.width() > v || r.height() > v;
}
+#include "SkMaskCache.h"
+
+static bool copy_cacheddata_to_mask(SkCachedData* data, SkMask* mask) {
+ const size_t size = data->size();
+ SkASSERT(mask->computeTotalImageSize() <= size);
+
+ mask->fImage = SkMask::AllocImage(size);
+ if (mask->fImage) {
+ memcpy(mask->fImage, data->data(), size);
+ return true;
+ }
+ return false;
+}
+
+static SkCachedData* copy_mask_to_cacheddata(const SkMask& mask) {
+ const size_t size = mask.computeTotalImageSize();
+ SkCachedData* data = SkResourceCache::NewCachedData(size);
+ if (data) {
+ memcpy(data->writable_data(), mask.fImage, size);
+ return data;
+ }
+ return NULL;
+}
+
+static bool find_cached_rrect(SkMask* mask, SkScalar sigma, SkBlurStyle style,
+ SkBlurQuality quality, const SkRRect& rrect) {
+ SkAutoTUnref<SkCachedData> data(SkMaskCache::FindAndRef(sigma, style, quality, rrect, mask));
+ return data.get() && copy_cacheddata_to_mask(data, mask);
+}
+
+static void add_cached_rrect(const SkMask& mask, SkScalar sigma, SkBlurStyle style,
+ SkBlurQuality quality, const SkRRect& rrect) {
+ SkAutoTUnref<SkCachedData> data(copy_mask_to_cacheddata(mask));
+ if (data.get()) {
+ SkMaskCache::Add(sigma, style, quality, rrect, mask, data);
+ }
+}
+
+static bool find_cached_rects(SkMask* mask, SkScalar sigma, SkBlurStyle style,
+ SkBlurQuality quality, const SkRect rects[], int count) {
+ SkAutoTUnref<SkCachedData> data(SkMaskCache::FindAndRef(sigma, style, quality, rects, count, mask));
+ return data.get() && copy_cacheddata_to_mask(data, mask);
+}
+
+static void add_cached_rects(const SkMask& mask, SkScalar sigma, SkBlurStyle style,
+ SkBlurQuality quality, const SkRect rects[], int count) {
+ SkAutoTUnref<SkCachedData> data(copy_mask_to_cacheddata(mask));
+ if (data.get()) {
+ SkMaskCache::Add(sigma, style, quality, rects, count, mask, data);
+ }
+}
+
#ifdef SK_IGNORE_FAST_RRECT_BLUR
SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect", false, "Use the faster analytic blur approach for ninepatch rects" );
#else
@@ -368,23 +420,27 @@ SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma
radii[SkRRect::kLowerLeft_Corner] = LL;
smallRR.setRectRadii(smallR, radii);
- bool analyticBlurWorked = false;
- if (c_analyticBlurRRect) {
- analyticBlurWorked =
- this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin,
- SkMask::kComputeBoundsAndRenderImage_CreateMode);
- }
-
- if (!analyticBlurWorked) {
- if (!draw_rrect_into_mask(smallRR, &srcM)) {
- return kFalse_FilterReturn;
+ const SkScalar sigma = this->computeXformedSigma(matrix);
+ if (!find_cached_rrect(&patch->fMask, sigma, fBlurStyle, this->getQuality(), smallRR)) {
+ bool analyticBlurWorked = false;
+ if (c_analyticBlurRRect) {
+ analyticBlurWorked =
+ this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin,
+ SkMask::kComputeBoundsAndRenderImage_CreateMode);
}
- SkAutoMaskFreeImage amf(srcM.fImage);
+ if (!analyticBlurWorked) {
+ if (!draw_rrect_into_mask(smallRR, &srcM)) {
+ return kFalse_FilterReturn;
+ }
- if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) {
- return kFalse_FilterReturn;
+ SkAutoMaskFreeImage amf(srcM.fImage);
+
+ if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) {
+ return kFalse_FilterReturn;
+ }
}
+ add_cached_rrect(patch->fMask, sigma, fBlurStyle, this->getQuality(), smallRR);
}
patch->fMask.fBounds.offsetTo(0, 0);
@@ -494,21 +550,25 @@ SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count,
SkASSERT(!smallR[1].isEmpty());
}
- if (count > 1 || !c_analyticBlurNinepatch) {
- if (!draw_rects_into_mask(smallR, count, &srcM)) {
- return kFalse_FilterReturn;
- }
-
- SkAutoMaskFreeImage amf(srcM.fImage);
-
- if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) {
- return kFalse_FilterReturn;
- }
- } else {
- if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin,
- SkMask::kComputeBoundsAndRenderImage_CreateMode)) {
- return kFalse_FilterReturn;
+ const SkScalar sigma = this->computeXformedSigma(matrix);
+ if (!find_cached_rects(&patch->fMask, sigma, fBlurStyle, this->getQuality(), rects, count)) {
+ if (count > 1 || !c_analyticBlurNinepatch) {
+ if (!draw_rects_into_mask(smallR, count, &srcM)) {
+ return kFalse_FilterReturn;
+ }
+
+ SkAutoMaskFreeImage amf(srcM.fImage);
+
+ if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) {
+ return kFalse_FilterReturn;
+ }
+ } else {
+ if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin,
+ SkMask::kComputeBoundsAndRenderImage_CreateMode)) {
+ return kFalse_FilterReturn;
+ }
}
+ add_cached_rects(patch->fMask, sigma, fBlurStyle, this->getQuality(), rects, count);
}
patch->fMask.fBounds.offsetTo(0, 0);
patch->fOuterRect = dstM.fBounds;
diff --git a/tests/MaskCacheTest.cpp b/tests/MaskCacheTest.cpp
index 0b83c62c00..f4e316c6c9 100644
--- a/tests/MaskCacheTest.cpp
+++ b/tests/MaskCacheTest.cpp
@@ -39,7 +39,7 @@ DEF_TEST(RRectMaskCache, reporter) {
SkBlurQuality quality = kLow_SkBlurQuality;
SkMask mask;
- SkCachedData* data = SkMaskCache::FindAndRef(sigma, rrect, style, quality, &mask, &cache);
+ SkCachedData* data = SkMaskCache::FindAndRef(sigma, style, quality, rrect, &mask, &cache);
REPORTER_ASSERT(reporter, NULL == data);
size_t size = 256;
@@ -48,14 +48,14 @@ DEF_TEST(RRectMaskCache, reporter) {
mask.fBounds.setXYWH(0, 0, 100, 100);
mask.fRowBytes = 100;
mask.fFormat = SkMask::kBW_Format;
- SkMaskCache::Add(sigma, rrect, style, quality, mask, data, &cache);
+ SkMaskCache::Add(sigma, style, quality, rrect, mask, data, &cache);
check_data(reporter, data, 2, kInCache, kLocked);
data->unref();
check_data(reporter, data, 1, kInCache, kUnlocked);
sk_bzero(&mask, sizeof(mask));
- data = SkMaskCache::FindAndRef(sigma, rrect, style, quality, &mask, &cache);
+ data = SkMaskCache::FindAndRef(sigma, style, quality, rrect, &mask, &cache);
REPORTER_ASSERT(reporter, data);
REPORTER_ASSERT(reporter, data->size() == size);
REPORTER_ASSERT(reporter, mask.fBounds.top() == 0 && mask.fBounds.bottom() == 100);
@@ -74,9 +74,10 @@ DEF_TEST(RectsMaskCache, reporter) {
SkRect rect = SkRect::MakeWH(100, 100);
SkRect rects[2] = {rect};
SkBlurStyle style = kNormal_SkBlurStyle;
+ SkBlurQuality quality = kLow_SkBlurQuality;
SkMask mask;
- SkCachedData* data = SkMaskCache::FindAndRef(sigma, rects, 1, style, &mask, &cache);
+ SkCachedData* data = SkMaskCache::FindAndRef(sigma, style, quality, rects, 1, &mask, &cache);
REPORTER_ASSERT(reporter, NULL == data);
size_t size = 256;
@@ -85,14 +86,14 @@ DEF_TEST(RectsMaskCache, reporter) {
mask.fBounds.setXYWH(0, 0, 100, 100);
mask.fRowBytes = 100;
mask.fFormat = SkMask::kBW_Format;
- SkMaskCache::Add(sigma, rects, 1, style, mask, data, &cache);
+ SkMaskCache::Add(sigma, style, quality, rects, 1, mask, data, &cache);
check_data(reporter, data, 2, kInCache, kLocked);
data->unref();
check_data(reporter, data, 1, kInCache, kUnlocked);
sk_bzero(&mask, sizeof(mask));
- data = SkMaskCache::FindAndRef(sigma, rects, 1, style, &mask, &cache);
+ data = SkMaskCache::FindAndRef(sigma, style, quality, rects, 1, &mask, &cache);
REPORTER_ASSERT(reporter, data);
REPORTER_ASSERT(reporter, data->size() == size);
REPORTER_ASSERT(reporter, mask.fBounds.top() == 0 && mask.fBounds.bottom() == 100);