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 "GrTexture.h" 14 #include "GrColor.h" 15 #include "GrSamplerState.h" 16 17 #include "SkXfermode.h" 18 19 /** 20 * The paint describes how pixels are colored when the context draws to 21 * them. TODO: Make this a "real" class with getters and setters, default 22 * values, and documentation. 23 */ 24 class GrPaint { 25 public: 26 enum { 27 kMaxTextures = 1, 28 kMaxMasks = 1, 29 }; 30 31 // All the paint fields are public except textures/samplers 32 GrBlendCoeff fSrcBlendCoeff; 33 GrBlendCoeff fDstBlendCoeff; 34 bool fAntiAlias; 35 bool fDither; 36 bool fColorMatrixEnabled; 37 38 GrColor fColor; 39 uint8_t fCoverage; 40 41 GrColor fColorFilterColor; 42 SkXfermode::Mode fColorFilterXfermode; 43 float fColorMatrix[20]; 44 setTexture(int i,GrTexture * texture)45 void setTexture(int i, GrTexture* texture) { 46 GrAssert((unsigned)i < kMaxTextures); 47 GrSafeRef(texture); 48 GrSafeUnref(fTextures[i]); 49 fTextures[i] = texture; 50 } 51 getTexture(int i)52 GrTexture* getTexture(int i) const { 53 GrAssert((unsigned)i < kMaxTextures); 54 return fTextures[i]; 55 } 56 textureSampler(int i)57 GrSamplerState* textureSampler(int i) { 58 GrAssert((unsigned)i < kMaxTextures); 59 return fTextureSamplers + i; 60 } 61 getTextureSampler(int i)62 const GrSamplerState& getTextureSampler(int i) const { 63 GrAssert((unsigned)i < kMaxTextures); 64 return fTextureSamplers[i]; 65 } 66 67 // The mask can be alpha-only or per channel. It is applied 68 // after the colorfilter setMask(int i,GrTexture * mask)69 void setMask(int i, GrTexture* mask) { 70 GrAssert((unsigned)i < kMaxMasks); 71 GrSafeRef(mask); 72 GrSafeUnref(fMaskTextures[i]); 73 fMaskTextures[i] = mask; 74 } 75 getMask(int i)76 GrTexture* getMask(int i) const { 77 GrAssert((unsigned)i < kMaxMasks); 78 return fMaskTextures[i]; 79 } 80 81 // mask's sampler matrix is always applied to the positions 82 // (i.e. no explicit texture coordinates) maskSampler(int i)83 GrSamplerState* maskSampler(int i) { 84 GrAssert((unsigned)i < kMaxMasks); 85 return fMaskSamplers + i; 86 } 87 getMaskSampler(int i)88 const GrSamplerState& getMaskSampler(int i) const { 89 GrAssert((unsigned)i < kMaxMasks); 90 return fMaskSamplers[i]; 91 } 92 93 // pre-concats sampler matrices for non-NULL textures and masks preConcatActiveSamplerMatrices(const GrMatrix & matrix)94 void preConcatActiveSamplerMatrices(const GrMatrix& matrix) { 95 for (int i = 0; i < kMaxTextures; ++i) { 96 fTextureSamplers[i].preConcatMatrix(matrix); 97 } 98 for (int i = 0; i < kMaxMasks; ++i) { 99 fMaskSamplers[i].preConcatMatrix(matrix); 100 } 101 } 102 103 // uninitialized GrPaint()104 GrPaint() { 105 for (int i = 0; i < kMaxTextures; ++i) { 106 fTextures[i] = NULL; 107 } 108 for (int i = 0; i < kMaxMasks; ++i) { 109 fMaskTextures[i] = NULL; 110 } 111 } 112 GrPaint(const GrPaint & paint)113 GrPaint(const GrPaint& paint) { 114 for (int i = 0; i < kMaxTextures; ++i) { 115 fTextures[i] = NULL; 116 } 117 for (int i = 0; i < kMaxMasks; ++i) { 118 fMaskTextures[i] = NULL; 119 } 120 *this = paint; 121 } 122 123 GrPaint& operator=(const GrPaint& paint) { 124 fSrcBlendCoeff = paint.fSrcBlendCoeff; 125 fDstBlendCoeff = paint.fDstBlendCoeff; 126 fAntiAlias = paint.fAntiAlias; 127 fDither = paint.fDither; 128 129 fColor = paint.fColor; 130 fCoverage = paint.fCoverage; 131 132 fColorFilterColor = paint.fColorFilterColor; 133 fColorFilterXfermode = paint.fColorFilterXfermode; 134 memcpy(fColorMatrix, paint.fColorMatrix, sizeof(fColorMatrix)); 135 fColorMatrixEnabled = paint.fColorMatrixEnabled; 136 137 for (int i = 0; i < kMaxTextures; ++i) { 138 GrSafeUnref(fTextures[i]); 139 fTextureSamplers[i] = paint.fTextureSamplers[i]; 140 fTextures[i] = paint.fTextures[i]; 141 GrSafeRef(fTextures[i]); 142 } 143 for (int i = 0; i < kMaxMasks; ++i) { 144 GrSafeUnref(fMaskTextures[i]); 145 fMaskSamplers[i] = paint.fMaskSamplers[i]; 146 fMaskTextures[i] = paint.fMaskTextures[i]; 147 GrSafeRef(fMaskTextures[i]); 148 } 149 return *this; 150 } 151 ~GrPaint()152 ~GrPaint() { 153 for (int i = 0; i < kMaxTextures; ++i) { 154 GrSafeUnref(fTextures[i]); 155 } 156 for (int i = 0; i < kMaxMasks; ++i) { 157 GrSafeUnref(fMaskTextures[i]); 158 } 159 } 160 161 // sets paint to src-over, solid white, no texture, no mask reset()162 void reset() { 163 this->resetBlend(); 164 this->resetOptions(); 165 this->resetColor(); 166 this->resetCoverage(); 167 this->resetTextures(); 168 this->resetColorFilter(); 169 this->resetMasks(); 170 } 171 resetColorFilter()172 void resetColorFilter() { 173 fColorFilterXfermode = SkXfermode::kDst_Mode; 174 fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff); 175 memset(fColorMatrix, 0, sizeof(fColorMatrix)); 176 fColorMatrixEnabled = false; 177 } 178 hasTexture()179 bool hasTexture() const { 180 return 0 != this->getActiveTextureStageMask(); 181 } 182 hasMask()183 bool hasMask() const { 184 return 0 != this->getActiveMaskStageMask(); 185 } 186 hasTextureOrMask()187 bool hasTextureOrMask() const { 188 return this->hasTexture() || this->hasMask(); 189 } 190 191 // helpers for GrContext, GrTextContext getActiveTextureStageMask()192 int getActiveTextureStageMask() const { 193 int mask = 0; 194 for (int i = 0; i < kMaxTextures; ++i) { 195 if (NULL != fTextures[i]) { 196 mask |= 1 << (i + kFirstTextureStage); 197 } 198 } 199 return mask; 200 } 201 getActiveMaskStageMask()202 int getActiveMaskStageMask() const { 203 int mask = 0; 204 for (int i = 0; i < kMaxMasks; ++i) { 205 if (NULL != fMaskTextures[i]) { 206 mask |= 1 << (i + kFirstMaskStage); 207 } 208 } 209 return mask; 210 } 211 getActiveStageMask()212 int getActiveStageMask() const { 213 return this->getActiveTextureStageMask() | 214 this->getActiveMaskStageMask(); 215 } 216 217 // internal use 218 // GrPaint's textures and masks map to the first N stages 219 // of GrDrawTarget in that order (textures followed by masks) 220 enum { 221 kFirstTextureStage = 0, 222 kFirstMaskStage = kMaxTextures, 223 kTotalStages = kMaxTextures + kMaxMasks, 224 }; 225 226 private: 227 228 GrSamplerState fTextureSamplers[kMaxTextures]; 229 GrSamplerState fMaskSamplers[kMaxMasks]; 230 231 GrTexture* fTextures[kMaxTextures]; 232 GrTexture* fMaskTextures[kMaxMasks]; 233 resetBlend()234 void resetBlend() { 235 fSrcBlendCoeff = kOne_BlendCoeff; 236 fDstBlendCoeff = kZero_BlendCoeff; 237 } 238 resetOptions()239 void resetOptions() { 240 fAntiAlias = false; 241 fDither = false; 242 } 243 resetColor()244 void resetColor() { 245 fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff); 246 } 247 resetCoverage()248 void resetCoverage() { 249 fCoverage = 0xff; 250 } 251 resetTextures()252 void resetTextures() { 253 for (int i = 0; i < kMaxTextures; ++i) { 254 this->setTexture(i, NULL); 255 fTextureSamplers[i].reset(); 256 } 257 } 258 resetMasks()259 void resetMasks() { 260 for (int i = 0; i < kMaxMasks; ++i) { 261 this->setMask(i, NULL); 262 fMaskSamplers[i].reset(); 263 } 264 } 265 }; 266 267 #endif 268