summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/skia/src/effects/SkMorphologyImageFilter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/skia/src/effects/SkMorphologyImageFilter.cpp')
-rw-r--r--chromium/third_party/skia/src/effects/SkMorphologyImageFilter.cpp284
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