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