GrPaint encapsulation.

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

git-svn-id: http://skia.googlecode.com/svn/trunk@5838 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/gpu/GrPaint.h b/include/gpu/GrPaint.h
index 9b07a4b..9f9403e 100644
--- a/include/gpu/GrPaint.h
+++ b/include/gpu/GrPaint.h
@@ -17,9 +17,31 @@
 #include "SkXfermode.h"
 
 /**
- * The paint describes how pixels are colored when the context draws to
- * them. TODO: Make this a "real" class with getters and setters, default
- * values, and documentation.
+ * The paint describes how color and coverage are computed at each pixel by GrContext draw
+ * functions and the how color is blended with the destination pixel.
+ *
+ * The paint allows installation of custom color and coverage stages. New types of stages are
+ * created by subclassing GrCustomStage.
+ *
+ * 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.
+ *
+ * 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
+ * together in the same manner as color stages. The output of the last stage is modulated by any
+ * fractional coverage produced by anti-aliasing. This last step produces the final coverage, C.
+ *
+ * setBlendFunc() specifies blending coefficients for S (described above) and D, the initial value
+ * of the destination pixel, labeled Bs and Bd respectively. The final value of the destination
+ * pixel is then D' = (1-C)*D + C*(Bd*D + Bs*S).
+ *
+ * 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.
  */
 class GrPaint {
 public:
@@ -28,20 +50,90 @@
         kMaxCoverageStages  = 1,
     };
 
-    // All the paint fields are public except textures/samplers
-    GrBlendCoeff                fSrcBlendCoeff;
-    GrBlendCoeff                fDstBlendCoeff;
-    bool                        fAntiAlias;
-    bool                        fDither;
-    bool                        fColorMatrixEnabled;
+    GrPaint() { this->reset(); }
 
-    GrColor                     fColor;
-    uint8_t                     fCoverage;
+    GrPaint(const GrPaint& paint) { *this = paint; }
 
-    GrColor                     fColorFilterColor;
-    SkXfermode::Mode            fColorFilterXfermode;
-    float                       fColorMatrix[20];
+    ~GrPaint() {}
 
+    /**
+     * Sets the blending coefficients to use to blend the final primitive color with the
+     * destination color. Defaults to kOne for src and kZero for dst (i.e. src mode).
+     */
+    void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
+        fSrcBlendCoeff = srcCoeff;
+        fDstBlendCoeff = dstCoeff;
+    }
+    GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlendCoeff; }
+    GrBlendCoeff getDstBlendCoeff() const { return fDstBlendCoeff; }
+
+    /**
+     * The initial color of the drawn primitive. Defaults to solid white.
+     */
+    void setColor(GrColor color) { fColor = color; }
+    GrColor getColor() const { return fColor; }
+
+    /**
+     * Applies fractional coverage to the entire drawn primitive. Defaults to 0xff.
+     */
+    void setCoverage(uint8_t coverage) { fCoverage = coverage; }
+    uint8_t getCoverage() const { return fCoverage; }
+
+    /**
+     * Should primitives be anti-aliased or not. Defaults to false.
+     */
+    void setAntiAlias(bool aa) { fAntiAlias = aa; }
+    bool isAntiAlias() const { return fAntiAlias; }
+
+    /**
+     * Should dithering be applied. Defaults to false.
+     */
+    void setDither(bool dither) { fDither = dither; }
+    bool isDither() const { return fDither; }
+
+    /**
+     * Enables a SkXfermode::Mode-based color filter applied to the primitive color. The constant
+     * color passed to this function is considered the "src" color and the primitive's color is
+     * considered the "dst" color. Defaults to kDst_Mode which equates to simply passing through
+     * the primitive color unmodified.
+     */
+    void setXfermodeColorFilter(SkXfermode::Mode mode, GrColor color) {
+        fColorFilterColor = color;
+        fColorFilterXfermode = mode;
+    }
+    SkXfermode::Mode getColorFilterMode() const { return fColorFilterXfermode; }
+    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.
+     */
+    void resetColorFilter() {
+        fColorFilterXfermode = SkXfermode::kDst_Mode;
+        fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
+        fColorMatrixEnabled = false;
+    }
+
+    /**
+     * Specifies a stage of the color pipeline. Usually the texture matrices of color stages apply
+     * to the primitive's positions. Some GrContext calls take explicit coords as an array or a
+     * rect. In this case these are the pre-matrix coords to colorSampler(0).
+     */
     GrSamplerState* colorSampler(int i) {
         GrAssert((unsigned)i < kMaxColorStages);
         return fColorSamplers + i;
@@ -57,8 +149,10 @@
         return (NULL != fColorSamplers[i].getCustomStage());
     }
 
-    // The coverage stage's sampler matrix is always applied to the positions
-    // (i.e. no explicit texture coordinates)
+    /**
+     * Specifies a stage of the coverage pipeline. Coverage stages' texture matrices are always
+     * applied to the primitive's position, never to explicit texture coords.
+     */
     GrSamplerState* coverageSampler(int i) {
         GrAssert((unsigned)i < kMaxCoverageStages);
         return fCoverageSamplers + i;
@@ -95,9 +189,9 @@
     bool hasStage() const { return this->hasColorStage() || this->hasCoverageStage(); }
 
     /**
-     * Preconcats the matrix of all samplers in the mask with the inverse of a
-     * matrix. If the matrix inverse cannot be computed (and there is at least
-     * one enabled stage) then false is returned.
+     * Preconcats the matrix of all samplers in the mask with the inverse of a matrix. If the
+     * matrix inverse cannot be computed (and there is at least one enabled stage) then false is
+     * returned.
      */
     bool preConcatSamplerMatricesWithInverse(const GrMatrix& matrix) {
         GrMatrix inv;
@@ -125,16 +219,6 @@
         return true;
     }
 
-    // uninitialized
-    GrPaint() {
-    }
-
-    GrPaint(const GrPaint& paint) {
-        *this = paint;
-    }
-
-    ~GrPaint() {}
-
     GrPaint& operator=(const GrPaint& paint) {
         fSrcBlendCoeff = paint.fSrcBlendCoeff;
         fDstBlendCoeff = paint.fDstBlendCoeff;
@@ -164,7 +248,9 @@
         return *this;
     }
 
-    // sets paint to src-over, solid white, no texture, no mask
+    /**
+     * Resets the paint to the defaults.
+     */
     void reset() {
         this->resetBlend();
         this->resetOptions();
@@ -175,12 +261,6 @@
         this->resetMasks();
     }
 
-    void resetColorFilter() {
-        fColorFilterXfermode = SkXfermode::kDst_Mode;
-        fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
-        fColorMatrixEnabled = false;
-    }
-
     // internal use
     // GrPaint's textures and masks map to the first N stages
     // of GrDrawTarget in that order (textures followed by masks)
@@ -195,6 +275,19 @@
     GrSamplerState              fColorSamplers[kMaxColorStages];
     GrSamplerState              fCoverageSamplers[kMaxCoverageStages];
 
+    GrBlendCoeff                fSrcBlendCoeff;
+    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;
         fDstBlendCoeff = kZero_GrBlendCoeff;