1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #ifndef GrPaint_DEFINED 11 #define GrPaint_DEFINED 12 13 #include "GrColor.h" 14 #include "GrFragmentStage.h" 15 #include "GrXferProcessor.h" 16 #include "effects/GrPorterDuffXferProcessor.h" 17 18 #include "SkRegion.h" 19 #include "SkXfermode.h" 20 21 /** 22 * The paint describes how color and coverage are computed at each pixel by GrContext draw 23 * functions and the how color is blended with the destination pixel. 24 * 25 * The paint allows installation of custom color and coverage stages. New types of stages are 26 * created by subclassing GrProcessor. 27 * 28 * The primitive color computation starts with the color specified by setColor(). This color is the 29 * input to the first color stage. Each color stage feeds its output to the next color stage. 30 * 31 * Fractional pixel coverage follows a similar flow. The coverage is initially the value specified 32 * by setCoverage(). This is input to the first coverage stage. Coverage stages are chained 33 * together in the same manner as color stages. The output of the last stage is modulated by any 34 * fractional coverage produced by anti-aliasing. This last step produces the final coverage, C. 35 * 36 * setXPFactory is used to control blending between the output color and dest. It also implements 37 * the application of fractional coverage from the coverage pipeline. 38 */ 39 class GrPaint { 40 public: 41 GrPaint(); 42 GrPaint(const GrPaint & paint)43 GrPaint(const GrPaint& paint) { *this = paint; } 44 ~GrPaint()45 ~GrPaint() {} 46 47 /** 48 * The initial color of the drawn primitive. Defaults to solid white. 49 */ setColor(GrColor color)50 void setColor(GrColor color) { fColor = color; } getColor()51 GrColor getColor() const { return fColor; } 52 53 /** 54 * Should primitives be anti-aliased or not. Defaults to false. 55 */ setAntiAlias(bool aa)56 void setAntiAlias(bool aa) { fAntiAlias = aa; } isAntiAlias()57 bool isAntiAlias() const { return fAntiAlias; } 58 59 /** 60 * Should dithering be applied. Defaults to false. 61 */ setDither(bool dither)62 void setDither(bool dither) { fDither = dither; } isDither()63 bool isDither() const { return fDither; } 64 setXPFactory(const GrXPFactory * xpFactory)65 const GrXPFactory* setXPFactory(const GrXPFactory* xpFactory) { 66 fXPFactory.reset(SkRef(xpFactory)); 67 return xpFactory; 68 } 69 setPorterDuffXPFactory(SkXfermode::Mode mode)70 void setPorterDuffXPFactory(SkXfermode::Mode mode) { 71 fXPFactory.reset(GrPorterDuffXPFactory::Create(mode)); 72 } 73 74 void setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage = false); 75 76 /** 77 * Appends an additional color processor to the color computation. 78 */ addColorProcessor(const GrFragmentProcessor * fp)79 const GrFragmentProcessor* addColorProcessor(const GrFragmentProcessor* fp) { 80 SkASSERT(fp); 81 SkNEW_APPEND_TO_TARRAY(&fColorStages, GrFragmentStage, (fp)); 82 return fp; 83 } 84 85 /** 86 * Appends an additional coverage processor to the coverage computation. 87 */ addCoverageProcessor(const GrFragmentProcessor * fp)88 const GrFragmentProcessor* addCoverageProcessor(const GrFragmentProcessor* fp) { 89 SkASSERT(fp); 90 SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrFragmentStage, (fp)); 91 return fp; 92 } 93 94 /** 95 * Helpers for adding color or coverage effects that sample a texture. The matrix is applied 96 * to the src space position to compute texture coordinates. 97 */ 98 void addColorTextureProcessor(GrTexture*, const SkMatrix&); 99 void addCoverageTextureProcessor(GrTexture*, const SkMatrix&); 100 void addColorTextureProcessor(GrTexture*, const SkMatrix&, const GrTextureParams&); 101 void addCoverageTextureProcessor(GrTexture*, const SkMatrix&, const GrTextureParams&); 102 numColorStages()103 int numColorStages() const { return fColorStages.count(); } numCoverageStages()104 int numCoverageStages() const { return fCoverageStages.count(); } numTotalStages()105 int numTotalStages() const { return this->numColorStages() + this->numCoverageStages(); } 106 getXPFactory()107 const GrXPFactory* getXPFactory() const { 108 if (!fXPFactory) { 109 fXPFactory.reset(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode)); 110 } 111 return fXPFactory.get(); 112 } 113 getColorStage(int s)114 const GrFragmentStage& getColorStage(int s) const { return fColorStages[s]; } getCoverageStage(int s)115 const GrFragmentStage& getCoverageStage(int s) const { return fCoverageStages[s]; } 116 117 GrPaint& operator=(const GrPaint& paint) { 118 fAntiAlias = paint.fAntiAlias; 119 fDither = paint.fDither; 120 121 fColor = paint.fColor; 122 123 fColorStages = paint.fColorStages; 124 fCoverageStages = paint.fCoverageStages; 125 126 fXPFactory.reset(SkRef(paint.getXPFactory())); 127 128 return *this; 129 } 130 131 /** 132 * Returns true if isOpaque would return true and the paint represents a solid constant color 133 * draw. If the result is true, constantColor will be updated to contain the constant color. 134 */ 135 bool isOpaqueAndConstantColor(GrColor* constantColor) const; 136 137 private: 138 mutable SkAutoTUnref<const GrXPFactory> fXPFactory; 139 SkSTArray<4, GrFragmentStage> fColorStages; 140 SkSTArray<2, GrFragmentStage> fCoverageStages; 141 142 bool fAntiAlias; 143 bool fDither; 144 145 GrColor fColor; 146 }; 147 148 #endif 149