diff options
Diffstat (limited to 'chromium/third_party/skia/src/effects/SkMorphologyImageFilter.cpp')
-rw-r--r-- | chromium/third_party/skia/src/effects/SkMorphologyImageFilter.cpp | 284 |
1 files changed, 121 insertions, 163 deletions
diff --git a/chromium/third_party/skia/src/effects/SkMorphologyImageFilter.cpp b/chromium/third_party/skia/src/effects/SkMorphologyImageFilter.cpp index 0d00c359d85..19a9b68aa8d 100644 --- a/chromium/third_party/skia/src/effects/SkMorphologyImageFilter.cpp +++ b/chromium/third_party/skia/src/effects/SkMorphologyImageFilter.cpp @@ -8,7 +8,8 @@ #include "SkMorphologyImageFilter.h" #include "SkBitmap.h" #include "SkColorPriv.h" -#include "SkFlattenableBuffers.h" +#include "SkReadBuffer.h" +#include "SkWriteBuffer.h" #include "SkRect.h" #include "SkMorphology_opts.h" #if SK_SUPPORT_GPU @@ -17,10 +18,9 @@ #include "GrTBackendEffectFactory.h" #include "gl/GrGLEffect.h" #include "effects/Gr1DKernelEffect.h" -#include "SkImageFilterUtils.h" #endif -SkMorphologyImageFilter::SkMorphologyImageFilter(SkFlattenableReadBuffer& buffer) +SkMorphologyImageFilter::SkMorphologyImageFilter(SkReadBuffer& buffer) : INHERITED(1, buffer) { fRadius.fWidth = buffer.readInt(); fRadius.fHeight = buffer.readInt(); @@ -28,12 +28,15 @@ SkMorphologyImageFilter::SkMorphologyImageFilter(SkFlattenableReadBuffer& buffer (fRadius.fHeight >= 0)); } -SkMorphologyImageFilter::SkMorphologyImageFilter(int radiusX, int radiusY, SkImageFilter* input, const CropRect* cropRect) +SkMorphologyImageFilter::SkMorphologyImageFilter(int radiusX, + int radiusY, + SkImageFilter* input, + const CropRect* cropRect) : INHERITED(input, cropRect), fRadius(SkISize::Make(radiusX, radiusY)) { } -void SkMorphologyImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const { +void SkMorphologyImageFilter::flatten(SkWriteBuffer& buffer) const { this->INHERITED::flatten(buffer); buffer.writeInt(fRadius.fWidth); buffer.writeInt(fRadius.fHeight); @@ -81,28 +84,6 @@ static void erode(const SkPMColor* src, SkPMColor* dst, } } -static void erodeX(const SkBitmap& src, SkBitmap* dst, int radiusX, const SkIRect& bounds) -{ - 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) -{ - 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, @@ -141,43 +122,39 @@ static void dilate(const SkPMColor* src, SkPMColor* dst, } } -static void dilateX(const SkBitmap& src, SkBitmap* dst, int radiusX, const SkIRect& bounds) +static void callProcX(SkMorphologyImageFilter::Proc procX, const SkBitmap& src, SkBitmap* dst, int radiusX, const SkIRect& bounds) { - 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()); + procX(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) +static void callProcY(SkMorphologyImageFilter::Proc procY, const SkBitmap& src, SkBitmap* dst, int radiusY, const SkIRect& bounds) { - 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()); + procY(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0), + radiusY, bounds.height(), bounds.width(), + src.rowBytesAsPixels(), dst->rowBytesAsPixels()); } -bool SkErodeImageFilter::onFilterImage(Proxy* proxy, - const SkBitmap& source, const SkMatrix& ctm, - SkBitmap* dst, SkIPoint* offset) { +bool SkMorphologyImageFilter::filterImageGeneric(SkMorphologyImageFilter::Proc procX, + SkMorphologyImageFilter::Proc procY, + Proxy* proxy, + const SkBitmap& source, + const Context& ctx, + SkBitmap* dst, + SkIPoint* offset) const { SkBitmap src = source; - if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctm, &src, offset)) { + SkIPoint srcOffset = SkIPoint::Make(0, 0); + if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcOffset)) { return false; } - if (src.config() != SkBitmap::kARGB_8888_Config) { + if (src.colorType() != kN32_SkColorType) { return false; } SkIRect bounds; - src.getBounds(&bounds); - if (!this->applyCropRect(&bounds, ctm)) { + if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) { return false; } @@ -186,105 +163,97 @@ bool SkErodeImageFilter::onFilterImage(Proxy* proxy, return false; } - dst->setConfig(src.config(), bounds.width(), bounds.height()); - dst->allocPixels(); - if (!dst->getPixels()) { + if (!dst->allocPixels(src.info().makeWH(bounds.width(), bounds.height()))) { return false; } - int width = radius().width(); - int height = radius().height(); + SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), + SkIntToScalar(this->radius().height())); + ctx.ctm().mapVectors(&radius, 1); + int width = SkScalarFloorToInt(radius.fX); + int height = SkScalarFloorToInt(radius.fY); if (width < 0 || height < 0) { return false; } + SkIRect srcBounds = bounds; + srcBounds.offset(-srcOffset); + if (width == 0 && height == 0) { - src.extractSubset(dst, bounds); - offset->fX += bounds.left(); - offset->fY += bounds.top(); + src.extractSubset(dst, srcBounds); + offset->fX = bounds.left(); + offset->fY = bounds.top(); return true; } SkBitmap temp; - temp.setConfig(dst->config(), dst->width(), dst->height()); - if (!temp.allocPixels()) { + if (!temp.allocPixels(dst->info())) { return false; } if (width > 0 && height > 0) { - erodeX(src, &temp, width, bounds); - SkIRect tmpBounds = SkIRect::MakeWH(bounds.width(), bounds.height()); - erodeY(temp, dst, height, tmpBounds); + callProcX(procX, src, &temp, width, srcBounds); + SkIRect tmpBounds = SkIRect::MakeWH(srcBounds.width(), srcBounds.height()); + callProcY(procY, temp, dst, height, tmpBounds); } else if (width > 0) { - erodeX(src, dst, width, bounds); + callProcX(procX, src, dst, width, srcBounds); } else if (height > 0) { - erodeY(src, dst, height, bounds); + callProcY(procY, src, dst, height, srcBounds); } - offset->fX += bounds.left(); - offset->fY += bounds.top(); + offset->fX = bounds.left(); + offset->fY = bounds.top(); return true; } -bool SkDilateImageFilter::onFilterImage(Proxy* proxy, - const SkBitmap& source, const SkMatrix& ctm, - SkBitmap* dst, SkIPoint* offset) { - SkBitmap src = source; - if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctm, &src, offset)) { - return false; - } - if (src.config() != SkBitmap::kARGB_8888_Config) { - return false; - } - - SkIRect bounds; - src.getBounds(&bounds); - if (!this->applyCropRect(&bounds, ctm)) { - return false; +bool SkErodeImageFilter::onFilterImage(Proxy* proxy, + const SkBitmap& source, const Context& ctx, + SkBitmap* dst, SkIPoint* offset) const { + Proc erodeXProc = SkMorphologyGetPlatformProc(kErodeX_SkMorphologyProcType); + if (!erodeXProc) { + erodeXProc = erode<kX>; } - - SkAutoLockPixels alp(src); - if (!src.getPixels()) { - return false; + Proc erodeYProc = SkMorphologyGetPlatformProc(kErodeY_SkMorphologyProcType); + if (!erodeYProc) { + erodeYProc = erode<kY>; } + return this->filterImageGeneric(erodeXProc, erodeYProc, proxy, source, ctx, dst, offset); +} - dst->setConfig(src.config(), bounds.width(), bounds.height()); - dst->allocPixels(); - if (!dst->getPixels()) { - return false; +bool SkDilateImageFilter::onFilterImage(Proxy* proxy, + const SkBitmap& source, const Context& ctx, + SkBitmap* dst, SkIPoint* offset) const { + Proc dilateXProc = SkMorphologyGetPlatformProc(kDilateX_SkMorphologyProcType); + if (!dilateXProc) { + dilateXProc = dilate<kX>; } - - int width = radius().width(); - int height = radius().height(); - - if (width < 0 || height < 0) { - return false; + Proc dilateYProc = SkMorphologyGetPlatformProc(kDilateY_SkMorphologyProcType); + if (!dilateYProc) { + dilateYProc = dilate<kY>; } + return this->filterImageGeneric(dilateXProc, dilateYProc, proxy, source, ctx, dst, offset); +} - if (width == 0 && height == 0) { - src.extractSubset(dst, bounds); - offset->fX += bounds.left(); - offset->fY += bounds.top(); - return true; +void SkMorphologyImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const { + if (getInput(0)) { + getInput(0)->computeFastBounds(src, dst); + } else { + *dst = src; } + dst->outset(SkIntToScalar(fRadius.width()), SkIntToScalar(fRadius.height())); +} - SkBitmap temp; - temp.setConfig(dst->config(), dst->width(), dst->height()); - if (!temp.allocPixels()) { +bool SkMorphologyImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, + SkIRect* dst) const { + SkIRect bounds = src; + if (getInput(0) && !getInput(0)->filterBounds(src, ctm, &bounds)) { return false; } - - if (width > 0 && height > 0) { - dilateX(src, &temp, width, bounds); - SkIRect tmpBounds = SkIRect::MakeWH(bounds.width(), bounds.height()); - dilateY(temp, dst, height, tmpBounds); - } else if (width > 0) { - dilateX(src, dst, width, bounds); - } else if (height > 0) { - dilateY(src, dst, height, bounds); - } - offset->fX += bounds.left(); - offset->fY += bounds.top(); + SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), + SkIntToScalar(this->radius().height())); + ctm.mapVectors(&radius, 1); + bounds.outset(SkScalarCeilToInt(radius.x()), SkScalarCeilToInt(radius.y())); + *dst = bounds; return true; } @@ -397,7 +366,7 @@ void GrGLMorphologyEffect::emitCode(GrGLShaderBuilder* builder, func = "max"; break; default: - GrCrash("Unexpected type"); + SkFAIL("Unexpected type"); func = ""; // suppress warning break; } @@ -438,7 +407,7 @@ void GrGLMorphologyEffect::setData(const GrGLUniformManager& uman, imageIncrement[1] = 1.0f / texture.height(); break; default: - GrCrash("Unknown filter direction."); + SkFAIL("Unknown filter direction."); } uman.set2fv(fImageIncrementUni, 1, imageIncrement); } @@ -555,75 +524,64 @@ bool apply_morphology(const SkBitmap& input, morphType, Gr1DKernelEffect::kY_Direction); src.reset(ast.detach()); } - return SkImageFilterUtils::WrapTexture(src, rect.width(), rect.height(), dst); + SkImageFilter::WrapTexture(src, rect.width(), rect.height(), dst); + return true; } }; -bool SkDilateImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm, - SkBitmap* result, SkIPoint* offset) { - SkBitmap input; - if (!SkImageFilterUtils::GetInputResultGPU(getInput(0), proxy, src, ctm, &input, offset)) { +bool SkMorphologyImageFilter::filterImageGPUGeneric(bool dilate, + Proxy* proxy, + const SkBitmap& src, + const Context& ctx, + SkBitmap* result, + SkIPoint* offset) const { + SkBitmap input = src; + SkIPoint srcOffset = SkIPoint::Make(0, 0); + if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &input, &srcOffset)) { return false; } SkIRect bounds; - src.getBounds(&bounds); - if (!this->applyCropRect(&bounds, ctm)) { + if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &bounds, &input)) { return false; } - int width = radius().width(); - int height = radius().height(); + SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), + SkIntToScalar(this->radius().height())); + ctx.ctm().mapVectors(&radius, 1); + int width = SkScalarFloorToInt(radius.fX); + int height = SkScalarFloorToInt(radius.fY); if (width < 0 || height < 0) { return false; } + SkIRect srcBounds = bounds; + srcBounds.offset(-srcOffset); if (width == 0 && height == 0) { - src.extractSubset(result, bounds); - offset->fX += bounds.left(); - offset->fY += bounds.top(); + input.extractSubset(result, srcBounds); + offset->fX = bounds.left(); + offset->fY = bounds.top(); return true; } - if (!apply_morphology(input, bounds, GrMorphologyEffect::kDilate_MorphologyType, radius(), result)) { + GrMorphologyEffect::MorphologyType type = dilate ? GrMorphologyEffect::kDilate_MorphologyType : GrMorphologyEffect::kErode_MorphologyType; + if (!apply_morphology(input, srcBounds, type, + SkISize::Make(width, height), result)) { return false; } - offset->fX += bounds.left(); - offset->fY += bounds.top(); + offset->fX = bounds.left(); + offset->fY = bounds.top(); return true; } -bool SkErodeImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm, - SkBitmap* result, SkIPoint* offset) { - SkBitmap input; - if (!SkImageFilterUtils::GetInputResultGPU(getInput(0), proxy, src, ctm, &input, offset)) { - return false; - } - SkIRect bounds; - src.getBounds(&bounds); - if (!this->applyCropRect(&bounds, ctm)) { - return false; - } - int width = radius().width(); - int height = radius().height(); - - if (width < 0 || height < 0) { - return false; - } - - if (width == 0 && height == 0) { - src.extractSubset(result, bounds); - offset->fX += bounds.left(); - offset->fY += bounds.top(); - return true; - } +bool SkDilateImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, + SkBitmap* result, SkIPoint* offset) const { + return this->filterImageGPUGeneric(true, proxy, src, ctx, result, offset); +} - if (!apply_morphology(input, bounds, GrMorphologyEffect::kErode_MorphologyType, radius(), result)) { - return false; - } - offset->fX += bounds.left(); - offset->fY += bounds.top(); - return true; +bool SkErodeImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, + SkBitmap* result, SkIPoint* offset) const { + return this->filterImageGPUGeneric(false, proxy, src, ctx, result, offset); } #endif |