aboutsummaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorGravatar senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-03-02 21:05:45 +0000
committerGravatar senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-03-02 21:05:45 +0000
commit05054f1a78a697b507580d0025db6c90423e033f (patch)
treefa00f0862980cdc712f21d2d792d59fe070ebcaa /include
parentc8ccfb0fbadfdcadcc860bc648c5ac42aa9277b1 (diff)
Erode and dilate image filter effects, CPU and GPU implementations.
Review URL: http://codereview.appspot.com/5656067/ git-svn-id: http://skia.googlecode.com/svn/trunk@3310 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include')
-rw-r--r--include/core/SkImageFilter.h16
-rw-r--r--include/effects/SkMorphologyImageFilter.h65
-rw-r--r--include/gpu/GrContext.h37
-rw-r--r--include/gpu/GrSamplerState.h71
4 files changed, 146 insertions, 43 deletions
diff --git a/include/core/SkImageFilter.h b/include/core/SkImageFilter.h
index 22b9569156..7d7c1404f1 100644
--- a/include/core/SkImageFilter.h
+++ b/include/core/SkImageFilter.h
@@ -80,6 +80,22 @@ public:
*/
virtual bool asABlur(SkSize* sigma) const;
+ /**
+ * Experimental.
+ *
+ * If the filter can be expressed as an erode, return true and
+ * set the radius in X and Y.
+ */
+ virtual bool asAnErode(SkISize* radius) const;
+
+ /**
+ * Experimental.
+ *
+ * If the filter can be expressed as a dilation, return true and
+ * set the radius in X and Y.
+ */
+ virtual bool asADilate(SkISize* radius) const;
+
protected:
SkImageFilter() {}
explicit SkImageFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {}
diff --git a/include/effects/SkMorphologyImageFilter.h b/include/effects/SkMorphologyImageFilter.h
new file mode 100644
index 0000000000..2297938cef
--- /dev/null
+++ b/include/effects/SkMorphologyImageFilter.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2012 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkMorphologyImageFilter_DEFINED
+#define SkMorphologyImageFilter_DEFINED
+
+#include "SkImageFilter.h"
+
+class SK_API SkMorphologyImageFilter : public SkImageFilter {
+public:
+ explicit SkMorphologyImageFilter(SkFlattenableReadBuffer& buffer);
+ SkMorphologyImageFilter(int radiusX, int radiusY);
+
+protected:
+ virtual void flatten(SkFlattenableWriteBuffer& buffer) SK_OVERRIDE;
+ SkISize radius() const { return fRadius; }
+
+private:
+ SkISize fRadius;
+ typedef SkImageFilter INHERITED;
+};
+
+class SK_API SkDilateImageFilter : public SkMorphologyImageFilter {
+public:
+ SkDilateImageFilter(int radiusX, int radiusY) : INHERITED(radiusX, radiusY) {}
+ explicit SkDilateImageFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
+
+ virtual bool asADilate(SkISize* radius) const SK_OVERRIDE;
+ virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
+ SkBitmap* result, SkIPoint* offset) SK_OVERRIDE;
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+ return SkNEW_ARGS(SkDilateImageFilter, (buffer));
+ }
+ virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }
+ SK_DECLARE_FLATTENABLE_REGISTRAR()
+
+ typedef SkMorphologyImageFilter INHERITED;
+};
+
+class SK_API SkErodeImageFilter : public SkMorphologyImageFilter {
+public:
+ SkErodeImageFilter(int radiusX, int radiusY) : INHERITED(radiusX, radiusY) {}
+ explicit SkErodeImageFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
+
+ virtual bool asAnErode(SkISize* radius) const SK_OVERRIDE;
+ virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
+ SkBitmap* result, SkIPoint* offset) SK_OVERRIDE;
+
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+ return SkNEW_ARGS(SkErodeImageFilter, (buffer));
+ }
+ virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }
+ SK_DECLARE_FLATTENABLE_REGISTRAR()
+
+private:
+ typedef SkMorphologyImageFilter INHERITED;
+};
+
+#endif
+
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index b939c9e37a..ffb5065925 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -577,30 +577,33 @@ public:
void resolveRenderTarget(GrRenderTarget* target);
/**
- * Applies a 1D convolution kernel in the X direction to a rectangle of
+ * Applies a 1D convolution kernel in the given direction to a rectangle of
* pixels from a given texture.
* @param texture the texture to read from
* @param rect the destination rectangle
* @param kernel the convolution kernel (kernelWidth elements)
* @param kernelWidth the width of the convolution kernel
+ * @param direction the direction in which to apply the kernel
*/
- void convolveInX(GrTexture* texture,
- const SkRect& rect,
- const float* kernel,
- int kernelWidth);
+ void convolve(GrTexture* texture,
+ const SkRect& rect,
+ const float* kernel,
+ int kernelWidth,
+ GrSamplerState::FilterDirection direction);
/**
- * Applies a 1D convolution kernel in the Y direction to a rectangle of
+ * Applies a 1D morphology in the given direction to a rectangle of
* pixels from a given texture.
- * direction.
* @param texture the texture to read from
* @param rect the destination rectangle
- * @param kernel the convolution kernel (kernelWidth elements)
- * @param kernelWidth the width of the convolution kernel
- */
- void convolveInY(GrTexture* texture,
- const SkRect& rect,
- const float* kernel,
- int kernelWidth);
+ * @param radius the radius of the morphological operator
+ * @param filter the filter kernel (must be kDilate or kErode)
+ * @param direction the direction in which to apply the morphology
+ */
+ void applyMorphology(GrTexture* texture,
+ const SkRect& rect,
+ int radius,
+ GrSamplerState::Filter filter,
+ GrSamplerState::FilterDirection direction);
///////////////////////////////////////////////////////////////////////////
// Helpers
@@ -699,12 +702,6 @@ private:
GrPathFill fill,
bool antiAlias);
- void convolve(GrTexture* texture,
- const SkRect& rect,
- float imageIncrement[2],
- const float* kernel,
- int kernelWidth);
-
/**
* Flags to the internal read/write pixels funcs
*/
diff --git a/include/gpu/GrSamplerState.h b/include/gpu/GrSamplerState.h
index 81dfdb3969..50a6cc9ec7 100644
--- a/include/gpu/GrSamplerState.h
+++ b/include/gpu/GrSamplerState.h
@@ -39,6 +39,14 @@ public:
* Apply a separable convolution kernel.
*/
kConvolution_Filter,
+ /**
+ * Apply a dilate filter (max over a 1D radius).
+ */
+ kDilate_Filter,
+ /**
+ * Apply an erode filter (min over a 1D radius).
+ */
+ kErode_Filter,
kDefault_Filter = kNearest_Filter
};
@@ -87,6 +95,17 @@ public:
};
/**
+ * For the filters which perform more than one texture sample (convolution,
+ * erode, dilate), this determines the direction in which the texture
+ * coordinates will be incremented.
+ */
+ enum FilterDirection {
+ kX_FilterDirection,
+ kY_FilterDirection,
+
+ kDefault_FilterDirection = kX_FilterDirection,
+ };
+ /**
* Default sampler state is set to clamp, use normal sampling mode, be
* unfiltered, and use identity matrix.
*/
@@ -99,6 +118,7 @@ public:
WrapMode getWrapX() const { return fWrapX; }
WrapMode getWrapY() const { return fWrapY; }
+ FilterDirection getFilterDirection() const { return fFilterDirection; }
SampleMode getSampleMode() const { return fSampleMode; }
const GrMatrix& getMatrix() const { return fMatrix; }
const GrRect& getTextureDomain() const { return fTextureDomain; }
@@ -106,7 +126,6 @@ public:
Filter getFilter() const { return fFilter; }
int getKernelWidth() const { return fKernelWidth; }
const float* getKernel() const { return fKernel; }
- const float* getImageIncrement() const { return fImageIncrement; }
bool swapsRAndB() const { return fSwapRAndB; }
bool isGradient() const {
@@ -118,6 +137,7 @@ public:
void setWrapX(WrapMode mode) { fWrapX = mode; }
void setWrapY(WrapMode mode) { fWrapY = mode; }
void setSampleMode(SampleMode mode) { fSampleMode = mode; }
+ void setFilterDirection(FilterDirection mode) { fFilterDirection = mode; }
/**
* Access the sampler's matrix. See SampleMode for explanation of
@@ -158,24 +178,29 @@ public:
void reset(WrapMode wrapXAndY,
Filter filter,
+ FilterDirection direction,
const GrMatrix& matrix) {
fWrapX = wrapXAndY;
fWrapY = wrapXAndY;
fSampleMode = kDefault_SampleMode;
fFilter = filter;
+ fFilterDirection = direction;
fMatrix = matrix;
fTextureDomain.setEmpty();
fSwapRAndB = false;
}
+ void reset(WrapMode wrapXAndY, Filter filter, const GrMatrix& matrix) {
+ this->reset(wrapXAndY, filter, kDefault_FilterDirection, matrix);
+ }
void reset(WrapMode wrapXAndY,
Filter filter) {
- this->reset(wrapXAndY, filter, GrMatrix::I());
+ this->reset(wrapXAndY, filter, kDefault_FilterDirection, GrMatrix::I());
}
void reset(const GrMatrix& matrix) {
- this->reset(kDefault_WrapMode, kDefault_Filter, matrix);
+ this->reset(kDefault_WrapMode, kDefault_Filter, kDefault_FilterDirection, matrix);
}
void reset() {
- this->reset(kDefault_WrapMode, kDefault_Filter, GrMatrix::I());
+ this->reset(kDefault_WrapMode, kDefault_Filter, kDefault_FilterDirection, GrMatrix::I());
}
GrScalar getRadial2CenterX1() const { return fRadial2CenterX1; }
@@ -198,37 +223,37 @@ public:
fRadial2PosRoot = posRoot;
}
- void setConvolutionParams(int kernelWidth, const float* kernel, float imageIncrement[2]) {
+ void setConvolutionParams(int kernelWidth, const float* kernel) {
GrAssert(kernelWidth >= 0 && kernelWidth <= MAX_KERNEL_WIDTH);
fKernelWidth = kernelWidth;
if (NULL != kernel) {
memcpy(fKernel, kernel, kernelWidth * sizeof(float));
}
- if (NULL != imageIncrement) {
- memcpy(fImageIncrement, imageIncrement, sizeof(fImageIncrement));
- } else {
- memset(fImageIncrement, 0, sizeof(fImageIncrement));
- }
+ }
+
+ void setMorphologyRadius(int radius) {
+ GrAssert(radius >= 0 && radius <= MAX_KERNEL_WIDTH);
+ fKernelWidth = radius;
}
private:
- WrapMode fWrapX : 8;
- WrapMode fWrapY : 8;
- SampleMode fSampleMode : 8;
- Filter fFilter : 8;
- GrMatrix fMatrix;
- bool fSwapRAndB;
- GrRect fTextureDomain;
+ WrapMode fWrapX : 8;
+ WrapMode fWrapY : 8;
+ FilterDirection fFilterDirection : 8;
+ SampleMode fSampleMode : 8;
+ Filter fFilter : 8;
+ GrMatrix fMatrix;
+ bool fSwapRAndB;
+ GrRect fTextureDomain;
// these are undefined unless fSampleMode == kRadial2_SampleMode
- GrScalar fRadial2CenterX1;
- GrScalar fRadial2Radius0;
- SkBool8 fRadial2PosRoot;
+ GrScalar fRadial2CenterX1;
+ GrScalar fRadial2Radius0;
+ SkBool8 fRadial2PosRoot;
// These are undefined unless fFilter == kConvolution_Filter
- uint8_t fKernelWidth;
- float fImageIncrement[2];
- float fKernel[MAX_KERNEL_WIDTH];
+ uint8_t fKernelWidth;
+ float fKernel[MAX_KERNEL_WIDTH];
};
#endif