diff options
author | Herb Derby <herb@google.com> | 2017-11-10 12:55:24 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-11-10 20:19:57 +0000 |
commit | 9f9041813e7f71a76c3139dfe745697eedc00270 (patch) | |
tree | 507b441b5f1c0d2e26ce43ea9b4da4cd46b4937c /src/core | |
parent | 48723156c597ec4d7be8e0648548ff27ef6c4e02 (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')
-rw-r--r-- | src/core/SkMaskBlurFilter.cpp | 63 |
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); |