Use GrCustomStage to implement color matrix.

R=robertphillips@google.com
Review URL: https://codereview.appspot.com/6716044

git-svn-id: http://skia.googlecode.com/svn/trunk@5975 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkColorFilter.h b/include/core/SkColorFilter.h
index 935b691..44d3f85 100644
--- a/include/core/SkColorFilter.h
+++ b/include/core/SkColorFilter.h
@@ -15,6 +15,8 @@
 #include "SkXfermode.h"
 
 class SkBitmap;
+class GrCustomStage;
+class GrContext;
 
 class SK_API SkColorFilter : public SkFlattenable {
 public:
@@ -113,6 +115,11 @@
     */
     static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add);
 
+    /** A subclass may implement this factory function to work with the GPU backend. If the return
+        is non-NULL then the caller owns a ref on the returned object.
+     */
+    virtual GrCustomStage* asNewCustomStage(GrContext*) const;
+
     SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
 protected:
     SkColorFilter() {}
diff --git a/include/effects/SkColorMatrix.h b/include/effects/SkColorMatrix.h
index ff02d9d..84a3b7c 100644
--- a/include/effects/SkColorMatrix.h
+++ b/include/effects/SkColorMatrix.h
@@ -39,6 +39,12 @@
     void setSaturation(SkScalar sat);
     void setRGB2YUV();
     void setYUV2RGB();
+
+    bool operator==(const SkColorMatrix& other) const {
+        return 0 == memcmp(fMat, other.fMat, sizeof(fMat));
+    }
+
+    bool operator!=(const SkColorMatrix& other) const { return !((*this) == other); }
 };
 
 #endif
diff --git a/include/effects/SkColorMatrixFilter.h b/include/effects/SkColorMatrixFilter.h
index 005781f..08eef5d 100644
--- a/include/effects/SkColorMatrixFilter.h
+++ b/include/effects/SkColorMatrixFilter.h
@@ -21,6 +21,9 @@
     virtual void filterSpan16(const uint16_t src[], int count, uint16_t[]) SK_OVERRIDE;
     virtual uint32_t getFlags() SK_OVERRIDE;
     virtual bool asColorMatrix(SkScalar matrix[20]) SK_OVERRIDE;
+#if SK_SUPPORT_GPU
+    virtual GrCustomStage* asNewCustomStage(GrContext*) const SK_OVERRIDE;
+#endif
 
     struct State {
         int32_t fArray[20];
diff --git a/include/gpu/GrCustomStageUnitTest.h b/include/gpu/GrCustomStageUnitTest.h
index e0f179d..0e12f2d 100644
--- a/include/gpu/GrCustomStageUnitTest.h
+++ b/include/gpu/GrCustomStageUnitTest.h
@@ -58,7 +58,7 @@
 
 /** GrCustomStage subclasses should insert this macro in their implemenation file. They must then
  *  also implement this static function:
- *      GrCustomStage* CreateStage(SkRandom*, GrContext*, GrTexture* dummyTextures[2]);
+ *      GrCustomStage* TestCreate(SkRandom*, GrContext*, GrTexture* dummyTextures[2]);
  *  dummyTextures[] are valied textures that they can optionally use for their texture accesses. The
   * first texture has config kSkia8888_PM_GrPixelConfig and the second has kAlpha_8_GrPixelConfig.
   * TestCreate functions are also free to create additional textures using the GrContext.
diff --git a/include/gpu/GrPaint.h b/include/gpu/GrPaint.h
index 843a934..06c16af 100644
--- a/include/gpu/GrPaint.h
+++ b/include/gpu/GrPaint.h
@@ -25,8 +25,7 @@
  * The primitive color computation starts with the color specified by setColor(). This color is the
  * input to the first color stage. Each color stage feeds its output to the next color stage. The
  * final color stage's output color is input to the color filter specified by
- * setXfermodeColorFilter which it turn feeds into the color matrix. The output of the color matrix
- * is the final source color, S.
+ * setXfermodeColorFilter which produces the final source color, S.
  *
  * Fractional pixel coverage follows a similar flow. The coverage is initially the value specified
  * by setCoverage(). This is input to the first coverage stage. Coverage stages are chained
@@ -40,7 +39,7 @@
  * Note that the coverage is applied after the blend. This is why they are computed as distinct
  * values.
  *
- * TODO: Encapsulate setXfermodeColorFilter and color matrix in stages and remove from GrPaint.
+ * TODO: Encapsulate setXfermodeColorFilter in a GrCustomStage and remove from GrPaint.
  */
 class GrPaint {
 public:
@@ -104,28 +103,11 @@
     GrColor getColorFilterColor() const { return fColorFilterColor; }
 
     /**
-     * Turns off application of a color matrix. By default the color matrix is disabled.
-     */
-    void disableColorMatrix() { fColorMatrixEnabled = false; }
-
-    /**
-     * Specifies and enables a 4 x 5 color matrix.
-     */
-    void setColorMatrix(const float matrix[20]) {
-        fColorMatrixEnabled = true;
-        memcpy(fColorMatrix, matrix, sizeof(fColorMatrix));
-    }
-
-    bool isColorMatrixEnabled() const { return fColorMatrixEnabled; }
-    const float* getColorMatrix() const { return fColorMatrix; }
-
-    /**
-     * Disables both the matrix and SkXfermode::Mode color filters.
+     * Disables the SkXfermode::Mode color filter.
      */
     void resetColorFilter() {
         fColorFilterXfermode = SkXfermode::kDst_Mode;
         fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
-        fColorMatrixEnabled = false;
     }
 
     /**
@@ -246,10 +228,6 @@
 
         fColorFilterColor = paint.fColorFilterColor;
         fColorFilterXfermode = paint.fColorFilterXfermode;
-        fColorMatrixEnabled = paint.fColorMatrixEnabled;
-        if (fColorMatrixEnabled) {
-            memcpy(fColorMatrix, paint.fColorMatrix, sizeof(fColorMatrix));
-        }
 
         for (int i = 0; i < kMaxColorStages; ++i) {
             if (paint.isColorStageEnabled(i)) {
@@ -295,14 +273,12 @@
     GrBlendCoeff                fDstBlendCoeff;
     bool                        fAntiAlias;
     bool                        fDither;
-    bool                        fColorMatrixEnabled;
 
     GrColor                     fColor;
     uint8_t                     fCoverage;
 
     GrColor                     fColorFilterColor;
     SkXfermode::Mode            fColorFilterXfermode;
-    float                       fColorMatrix[20];
 
     void resetBlend() {
         fSrcBlendCoeff = kOne_GrBlendCoeff;