Implement morphology as a custom effect

Review URL: http://codereview.appspot.com/6250073/



git-svn-id: http://skia.googlecode.com/svn/trunk@4102 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index c9c15df..8768528 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -617,6 +617,14 @@
                              float sigmaX, float sigmaY);
 
     /**
+     * This enum is used with the function below, applyMorphology.
+     */
+    enum MorphologyType {
+        kErode_MorphologyType,
+        kDilate_MorphologyType,
+    };
+
+    /**
      * Applies a 2D morphology to a given texture.
      * @param srcTexture      The source texture to be blurred.
      * @param rect            The destination rectangle.
@@ -632,7 +640,7 @@
     GrTexture* applyMorphology(GrTexture* srcTexture,
                                const GrRect& rect,
                                GrTexture* temp1, GrTexture* temp2,
-                               GrSamplerState::Filter filter,
+                               MorphologyType type,
                                SkISize radius);
     
     ///////////////////////////////////////////////////////////////////////////
diff --git a/include/gpu/GrCustomStage.h b/include/gpu/GrCustomStage.h
index cb9471e..5eea9f4 100644
--- a/include/gpu/GrCustomStage.h
+++ b/include/gpu/GrCustomStage.h
@@ -57,7 +57,7 @@
         For equivalence (that they will generate the same
         shader, but perhaps have different uniforms), check equality
         of the stageKey produced by the GrProgramStageFactory. */
-    virtual bool isEqual(const GrCustomStage *) const = 0;
+    virtual bool isEqual(const GrCustomStage&) const = 0;
 
      /** Human-meaningful string to identify this effect; may be embedded
          in generated shader code. */
diff --git a/include/gpu/GrProgramStageFactory.h b/include/gpu/GrProgramStageFactory.h
index 2795deb..0fac7db 100644
--- a/include/gpu/GrProgramStageFactory.h
+++ b/include/gpu/GrProgramStageFactory.h
@@ -26,9 +26,9 @@
         kProgramStageKeyBits = 10,
     };
 
-    virtual StageKey glStageKey(const GrCustomStage* stage) const = 0;
+    virtual StageKey glStageKey(const GrCustomStage& stage) const = 0;
     virtual GrGLProgramStage* createGLInstance(
-        const GrCustomStage* stage) const = 0;
+        const GrCustomStage& stage) const = 0;
 
     bool operator ==(const GrProgramStageFactory& b) const {
         return fStageClassID == b.fStageClassID;
@@ -79,7 +79,7 @@
         id identifies the GrCustomShader subclass. The remainder is based
         on the aspects of the GrCustomStage object's configuration that affect
         GLSL code generation. */
-    virtual StageKey glStageKey(const GrCustomStage* stage) const SK_OVERRIDE {
+    virtual StageKey glStageKey(const GrCustomStage& stage) const SK_OVERRIDE {
         GrAssert(kIllegalStageClassID != fStageClassID);
         StageKey stageID = GLProgramStage::GenKey(stage);
 #if GR_DEBUG
@@ -94,7 +94,7 @@
      for the given GrCustomStage; caller is responsible for deleting
      the object. */
     virtual GLProgramStage* createGLInstance(
-                        const GrCustomStage* stage) const SK_OVERRIDE {
+                        const GrCustomStage& stage) const SK_OVERRIDE {
         return new GLProgramStage(*this, stage);
     }
 
diff --git a/include/gpu/GrSamplerState.h b/include/gpu/GrSamplerState.h
index 952169c..4d2d5f2 100644
--- a/include/gpu/GrSamplerState.h
+++ b/include/gpu/GrSamplerState.h
@@ -15,8 +15,6 @@
 #include "GrMatrix.h"
 #include "GrTypes.h"
 
-#define MAX_KERNEL_WIDTH 25
-
 class GrSamplerState {
 public:
     enum Filter {
@@ -36,18 +34,6 @@
          * on shader backends.
          */
         k4x4Downsample_Filter,
-        /**
-         * 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
     };
@@ -96,17 +82,6 @@
     };
 
     /**
-     * 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.
      */
@@ -135,7 +110,7 @@
                 (fCustomStage && s.fCustomStage &&
                  (fCustomStage->getFactory() ==
                      s.fCustomStage->getFactory()) &&
-                 fCustomStage->isEqual(s.fCustomStage)));
+                 fCustomStage->isEqual(*s.fCustomStage)));
     }
     bool operator !=(const GrSamplerState& s) const { return !(*this == s); }
 
@@ -143,7 +118,6 @@
         // memcpy() breaks refcounting
         fWrapX = s.fWrapX;
         fWrapY = s.fWrapY;
-        fFilterDirection = s.fFilterDirection;
         fSampleMode = s.fSampleMode;
         fFilter = s.fFilter;
         fMatrix = s.fMatrix;
@@ -154,11 +128,6 @@
         fRadial2Radius0 = s.fRadial2Radius0;
         fRadial2PosRoot = s.fRadial2PosRoot;
 
-        fKernelWidth = s.fKernelWidth;
-        if (kConvolution_Filter == fFilter) {
-            memcpy(fKernel, s.fKernel, MAX_KERNEL_WIDTH * sizeof(float));
-        }
-
         fCustomStage = s.fCustomStage;
         SkSafeRef(fCustomStage);
 
@@ -167,16 +136,12 @@
 
     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; }
     bool hasTextureDomain() const {return SkIntToScalar(0) != fTextureDomain.right();}
     Filter getFilter() const { return fFilter; }
-    int getKernelWidth() const { return fKernelWidth; }
-    const float* getKernel() const { return fKernel; }
     bool swapsRAndB() const { return fSwapRAndB; }
-
     bool isGradient() const {
         return  kRadial_SampleMode == fSampleMode ||
                 kRadial2_SampleMode == fSampleMode ||
@@ -186,7 +151,6 @@
     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
@@ -227,30 +191,24 @@
 
     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;
         GrSafeSetNull(fCustomStage);
     }
-    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, kDefault_FilterDirection, GrMatrix::I());
+    void reset(WrapMode wrapXAndY, Filter filter) {
+        this->reset(wrapXAndY, filter, GrMatrix::I());
     }
     void reset(const GrMatrix& matrix) {
-        this->reset(kDefault_WrapMode, kDefault_Filter, kDefault_FilterDirection, matrix);
+        this->reset(kDefault_WrapMode, kDefault_Filter, matrix);
     }
     void reset() {
-        this->reset(kDefault_WrapMode, kDefault_Filter, kDefault_FilterDirection, GrMatrix::I());
+        this->reset(kDefault_WrapMode, kDefault_Filter, GrMatrix::I());
     }
 
     GrScalar getRadial2CenterX1() const { return fRadial2CenterX1; }
@@ -273,19 +231,6 @@
         fRadial2PosRoot = posRoot;
     }
 
-    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));
-        }
-    }
-
-    void setMorphologyRadius(int radius) {
-        GrAssert(radius >= 0 && radius <= MAX_KERNEL_WIDTH);
-        fKernelWidth = radius;
-    }
-
     void setCustomStage(GrCustomStage* stage) {
         GrSafeAssign(fCustomStage, stage);
     }
@@ -294,7 +239,6 @@
 private:
     WrapMode            fWrapX : 8;
     WrapMode            fWrapY : 8;
-    FilterDirection     fFilterDirection : 8;
     SampleMode          fSampleMode : 8;
     Filter              fFilter : 8;
     GrMatrix            fMatrix;
@@ -306,10 +250,6 @@
     GrScalar            fRadial2Radius0;
     SkBool8             fRadial2PosRoot;
 
-    // These are undefined unless fFilter == kConvolution_Filter
-    uint8_t             fKernelWidth;
-    float               fKernel[MAX_KERNEL_WIDTH];
-
     GrCustomStage*      fCustomStage;
 };