aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkMaskBlurFilter.cpp
diff options
context:
space:
mode:
authorGravatar Herb Derby <herb@google.com>2017-11-10 12:55:24 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-11-10 20:19:57 +0000
commit9f9041813e7f71a76c3139dfe745697eedc00270 (patch)
tree507b441b5f1c0d2e26ce43ea9b4da4cd46b4937c /src/core/SkMaskBlurFilter.cpp
parent48723156c597ec4d7be8e0648548ff27ef6c4e02 (diff)
Extract code for safely creating SkMasks try 2
This is in preparation for adding a faster small radii blur. Be sure to obey the original semantics about handling dst when src.fImage is null. Change-Id: Ic0ff0ac81494799e2d5037283904f1094309c622 Reviewed-on: https://skia-review.googlesource.com/70025 Commit-Queue: Florin Malita <fmalita@chromium.org> Reviewed-by: Florin Malita <fmalita@chromium.org>
Diffstat (limited to 'src/core/SkMaskBlurFilter.cpp')
-rw-r--r--src/core/SkMaskBlurFilter.cpp63
1 files changed, 37 insertions, 26 deletions
diff --git a/src/core/SkMaskBlurFilter.cpp b/src/core/SkMaskBlurFilter.cpp
index 282f395792..fea98d6e77 100644
--- a/src/core/SkMaskBlurFilter.cpp
+++ b/src/core/SkMaskBlurFilter.cpp
@@ -542,46 +542,57 @@ bool SkMaskBlurFilter::hasNoBlur() const {
return (3 * fSigmaW <= 1) && (3 * fSigmaH <= 1);
}
-SkIPoint SkMaskBlurFilter::blur(const SkMask& src, SkMask* dst) const {
+static SkMask prepare_destination(int radiusX, int radiusY, const SkMask& src) {
+ SkSafeMath safe;
- // 1024 is a place holder guess until more analysis can be done.
- SkSTArenaAlloc<1024> alloc;
+ SkMask dst;
+ // dstW = srcW + 2 * radiusX;
+ int dstW = safe.add(src.fBounds.width(), safe.add(radiusX, radiusX));
+ // dstH = srcH + 2 * radiusY;
+ int dstH = safe.add(src.fBounds.height(), safe.add(radiusY, radiusY));
- PlanningInterface* planW = make_plan(&alloc, fSigmaW);
- PlanningInterface* planH = make_plan(&alloc, fSigmaH);
+ dst.fBounds.set(0, 0, dstW, dstH);
+ dst.fBounds.offset(src.fBounds.x(), src.fBounds.y());
+ dst.fBounds.offset(-SkTo<int32_t>(radiusX), -SkTo<int32_t>(radiusY));
- size_t borderW = planW->border();
- size_t borderH = planH->border();
+ dst.fImage = nullptr;
+ dst.fRowBytes = SkTo<uint32_t>(dstW);
+ dst.fFormat = SkMask::kA8_Format;
- auto srcW = SkTo<size_t>(src.fBounds.width());
- auto srcH = SkTo<size_t>(src.fBounds.height());
+ size_t toAlloc = safe.mul(dstW, dstH);
- SkSafeMath safe;
+ if (safe && src.fImage != nullptr) {
+ dst.fImage = SkMask::AllocImage(toAlloc);
+ }
- // size_t dstW = srcW + 2 * borderW;
- size_t dstW = safe.add(srcW, safe.add(borderW, borderW));
- //size_t dstH = srcH + 2 * borderH;
- size_t dstH = safe.add(srcH, safe.add(borderH, borderH));
+ return dst;
+}
- dst->fBounds.set(0, 0, dstW, dstH);
- dst->fBounds.offset(src.fBounds.x(), src.fBounds.y());
- dst->fBounds.offset(-SkTo<int32_t>(borderW), -SkTo<int32_t>(borderH));
+SkIPoint SkMaskBlurFilter::blur(const SkMask& src, SkMask* dst) const {
- dst->fImage = nullptr;
- dst->fRowBytes = SkTo<uint32_t>(dstW);
- dst->fFormat = SkMask::kA8_Format;
+ // 1024 is a place holder guess until more analysis can be done.
+ SkSTArenaAlloc<1024> alloc;
+
+ PlanningInterface* planW = make_plan(&alloc, fSigmaW);
+ PlanningInterface* planH = make_plan(&alloc, fSigmaH);
+
+ size_t borderW = planW->border(),
+ borderH = planH->border();
+ *dst = prepare_destination(borderW, borderH, src);
if (src.fImage == nullptr) {
return {SkTo<int32_t>(borderW), SkTo<int32_t>(borderH)};
}
-
- size_t toAlloc = safe.mul(dstW, dstH);
- if (!safe) {
- dst->fBounds = SkIRect::MakeEmpty();
- // There is no border offset because we are not drawing.
+ if (dst->fImage == nullptr) {
+ dst->fBounds.setEmpty();
return {0, 0};
}
- dst->fImage = SkMask::AllocImage(toAlloc);
+
+ auto srcW = SkTo<size_t>(src.fBounds.width());
+ auto srcH = SkTo<size_t>(src.fBounds.height());
+
+ size_t dstW = dst->fBounds.width(),
+ dstH = dst->fBounds.height();
auto bufferSize = std::max(planW->bufferSize(), planH->bufferSize());
auto buffer = alloc.makeArrayDefault<uint32_t>(bufferSize);