| Index: src/effects/SkMorphologyImageFilter.cpp
|
| diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
|
| index df015cac7356fb2cf4d9b1c67612cf9c155fb7aa..6a6f6f0b3688b46968dcd00aabfebe3f2713b422 100644
|
| --- a/src/effects/SkMorphologyImageFilter.cpp
|
| +++ b/src/effects/SkMorphologyImageFilter.cpp
|
| @@ -10,6 +10,7 @@
|
| #include "SkColorPriv.h"
|
| #include "SkFlattenableBuffers.h"
|
| #include "SkRect.h"
|
| +#include "SkMorphology_opts.h"
|
| #if SK_SUPPORT_GPU
|
| #include "GrContext.h"
|
| #include "GrTexture.h"
|
| @@ -38,11 +39,19 @@ void SkMorphologyImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
|
| buffer.writeInt(fRadius.fHeight);
|
| }
|
|
|
| +enum MorphDirection {
|
| + kX, kY
|
| +};
|
| +
|
| +template<MorphDirection direction>
|
| static void erode(const SkPMColor* src, SkPMColor* dst,
|
| int radius, int width, int height,
|
| - int srcStrideX, int srcStrideY,
|
| - int dstStrideX, int dstStrideY)
|
| + int srcStride, int dstStride)
|
| {
|
| + const int srcStrideX = direction == kX ? 1 : srcStride;
|
| + const int dstStrideX = direction == kX ? 1 : dstStride;
|
| + const int srcStrideY = direction == kX ? srcStride : 1;
|
| + const int dstStrideY = direction == kX ? dstStride : 1;
|
| radius = SkMin32(radius, width - 1);
|
| const SkPMColor* upperSrc = src + radius * srcStrideX;
|
| for (int x = 0; x < width; ++x) {
|
| @@ -74,23 +83,35 @@ static void erode(const SkPMColor* src, SkPMColor* dst,
|
|
|
| static void erodeX(const SkBitmap& src, SkBitmap* dst, int radiusX, const SkIRect& bounds)
|
| {
|
| - erode(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0),
|
| - radiusX, bounds.width(), bounds.height(),
|
| - 1, src.rowBytesAsPixels(), 1, dst->rowBytesAsPixels());
|
| + SkMorphologyProc erodeXProc = SkMorphologyGetPlatformProc(kErodeX_SkMorphologyProcType);
|
| + if (!erodeXProc) {
|
| + erodeXProc = erode<kX>;
|
| + }
|
| + erodeXProc(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0),
|
| + radiusX, bounds.width(), bounds.height(),
|
| + src.rowBytesAsPixels(), dst->rowBytesAsPixels());
|
| }
|
|
|
| static void erodeY(const SkBitmap& src, SkBitmap* dst, int radiusY, const SkIRect& bounds)
|
| {
|
| - erode(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0),
|
| - radiusY, bounds.height(), bounds.width(),
|
| - src.rowBytesAsPixels(), 1, dst->rowBytesAsPixels(), 1);
|
| + SkMorphologyProc erodeYProc = SkMorphologyGetPlatformProc(kErodeY_SkMorphologyProcType);
|
| + if (!erodeYProc) {
|
| + erodeYProc = erode<kY>;
|
| + }
|
| + erodeYProc(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0),
|
| + radiusY, bounds.height(), bounds.width(),
|
| + src.rowBytesAsPixels(), dst->rowBytesAsPixels());
|
| }
|
|
|
| +template<MorphDirection direction>
|
| static void dilate(const SkPMColor* src, SkPMColor* dst,
|
| int radius, int width, int height,
|
| - int srcStrideX, int srcStrideY,
|
| - int dstStrideX, int dstStrideY)
|
| + int srcStride, int dstStride)
|
| {
|
| + const int srcStrideX = direction == kX ? 1 : srcStride;
|
| + const int dstStrideX = direction == kX ? 1 : dstStride;
|
| + const int srcStrideY = direction == kX ? srcStride : 1;
|
| + const int dstStrideY = direction == kX ? dstStride : 1;
|
| radius = SkMin32(radius, width - 1);
|
| const SkPMColor* upperSrc = src + radius * srcStrideX;
|
| for (int x = 0; x < width; ++x) {
|
| @@ -122,16 +143,24 @@ static void dilate(const SkPMColor* src, SkPMColor* dst,
|
|
|
| static void dilateX(const SkBitmap& src, SkBitmap* dst, int radiusX, const SkIRect& bounds)
|
| {
|
| - dilate(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0),
|
| - radiusX, bounds.width(), bounds.height(),
|
| - 1, src.rowBytesAsPixels(), 1, dst->rowBytesAsPixels());
|
| + SkMorphologyProc dilateXProc = SkMorphologyGetPlatformProc(kDilateX_SkMorphologyProcType);
|
| + if (!dilateXProc) {
|
| + dilateXProc = dilate<kX>;
|
| + }
|
| + dilateXProc(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0),
|
| + radiusX, bounds.width(), bounds.height(),
|
| + src.rowBytesAsPixels(), dst->rowBytesAsPixels());
|
| }
|
|
|
| static void dilateY(const SkBitmap& src, SkBitmap* dst, int radiusY, const SkIRect& bounds)
|
| {
|
| - dilate(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0),
|
| - radiusY, bounds.height(), bounds.width(),
|
| - src.rowBytesAsPixels(), 1, dst->rowBytesAsPixels(), 1);
|
| + SkMorphologyProc dilateYProc = SkMorphologyGetPlatformProc(kDilateY_SkMorphologyProcType);
|
| + if (!dilateYProc) {
|
| + dilateYProc = dilate<kY>;
|
| + }
|
| + dilateYProc(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0),
|
| + radiusY, bounds.height(), bounds.width(),
|
| + src.rowBytesAsPixels(), dst->rowBytesAsPixels());
|
| }
|
|
|
| bool SkErodeImageFilter::onFilterImage(Proxy* proxy,
|
|
|