use SkMaskCache inside SkBlurMaskFilter
depends on https://codereview.chromium.org/670063004/ BUG=skia: Review URL: https://codereview.chromium.org/669993003
This commit is contained in:
parent
4aa75b7980
commit
4dca7a8296
@ -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)));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
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);
|
||||
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;
|
||||
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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user