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;