blob: aadd6484348aed7a7199a8d6c9fc230b11f66c6f [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
bsalomon@google.com27847de2011-02-22 20:59:41 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * 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.
bsalomon@google.com27847de2011-02-22 20:59:41 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
bsalomon@google.com27847de2011-02-22 20:59:41 +000010#ifndef GrPaint_DEFINED
11#define GrPaint_DEFINED
12
13#include "GrTexture.h"
14#include "GrColor.h"
15#include "GrSamplerState.h"
16
Scroggo97c88c22011-05-11 14:05:25 +000017#include "SkXfermode.h"
18
bsalomon@google.com27847de2011-02-22 20:59:41 +000019/**
20 * The paint describes how pixels are colored when the context draws to
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000021 * them. TODO: Make this a "real" class with getters and setters, default
22 * values, and documentation.
bsalomon@google.com27847de2011-02-22 20:59:41 +000023 */
24class GrPaint {
25public:
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000026 enum {
27 kMaxTextures = 1,
28 kMaxMasks = 1,
29 };
bsalomon@google.com27847de2011-02-22 20:59:41 +000030
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000031 // All the paint fields are public except textures/samplers
bsalomon@google.com27847de2011-02-22 20:59:41 +000032 GrBlendCoeff fSrcBlendCoeff;
33 GrBlendCoeff fDstBlendCoeff;
34 bool fAntiAlias;
35 bool fDither;
36
37 GrColor fColor;
38
Scroggo97c88c22011-05-11 14:05:25 +000039 GrColor fColorFilterColor;
40 SkXfermode::Mode fColorFilterXfermode;
41
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000042 void setTexture(int i, GrTexture* texture) {
43 GrAssert((unsigned)i < kMaxTextures);
bsalomon@google.com27847de2011-02-22 20:59:41 +000044 GrSafeRef(texture);
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000045 GrSafeUnref(fTextures[i]);
46 fTextures[i] = texture;
bsalomon@google.com27847de2011-02-22 20:59:41 +000047 }
48
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000049 GrTexture* getTexture(int i) const {
50 GrAssert((unsigned)i < kMaxTextures);
51 return fTextures[i];
52 }
53
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000054 GrSamplerState* textureSampler(int i) {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000055 GrAssert((unsigned)i < kMaxTextures);
56 return fTextureSamplers + i;
57 }
58
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000059 const GrSamplerState& getTextureSampler(int i) const {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000060 GrAssert((unsigned)i < kMaxTextures);
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000061 return fTextureSamplers[i];
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000062 }
63
64 // The mask can be alpha-only or per channel. It is applied
65 // after the colorfilter
66 void setMask(int i, GrTexture* mask) {
67 GrAssert((unsigned)i < kMaxMasks);
68 GrSafeRef(mask);
69 GrSafeUnref(fMaskTextures[i]);
70 fMaskTextures[i] = mask;
71 }
72
73 GrTexture* getMask(int i) const {
74 GrAssert((unsigned)i < kMaxMasks);
75 return fMaskTextures[i];
76 }
77
78 // mask's sampler matrix is always applied to the positions
79 // (i.e. no explicit texture coordinates)
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000080 GrSamplerState* maskSampler(int i) {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000081 GrAssert((unsigned)i < kMaxMasks);
82 return fMaskSamplers + i;
83 }
84
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000085 const GrSamplerState& getMaskSampler(int i) const {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000086 GrAssert((unsigned)i < kMaxMasks);
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000087 return fMaskSamplers[i];
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000088 }
89
90 // pre-concats sampler matrices for non-NULL textures and masks
91 void preConcatActiveSamplerMatrices(const GrMatrix& matrix) {
92 for (int i = 0; i < kMaxTextures; ++i) {
93 fTextureSamplers[i].preConcatMatrix(matrix);
94 }
95 for (int i = 0; i < kMaxMasks; ++i) {
96 fMaskSamplers[i].preConcatMatrix(matrix);
97 }
98 }
bsalomon@google.com27847de2011-02-22 20:59:41 +000099
100 // uninitialized
101 GrPaint() {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000102 for (int i = 0; i < kMaxTextures; ++i) {
103 fTextures[i] = NULL;
104 }
105 for (int i = 0; i < kMaxMasks; ++i) {
106 fMaskTextures[i] = NULL;
107 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000108 }
109
110 GrPaint(const GrPaint& paint) {
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000111 for (int i = 0; i < kMaxTextures; ++i) {
112 fTextures[i] = NULL;
113 }
114 for (int i = 0; i < kMaxMasks; ++i) {
115 fMaskTextures[i] = NULL;
116 }
117 *this = paint;
118 }
119
120 GrPaint& operator=(const GrPaint& paint) {
bsalomon@google.com27847de2011-02-22 20:59:41 +0000121 fSrcBlendCoeff = paint.fSrcBlendCoeff;
122 fDstBlendCoeff = paint.fDstBlendCoeff;
123 fAntiAlias = paint.fAntiAlias;
124 fDither = paint.fDither;
125
126 fColor = paint.fColor;
127
Scroggo97c88c22011-05-11 14:05:25 +0000128 fColorFilterColor = paint.fColorFilterColor;
129 fColorFilterXfermode = paint.fColorFilterXfermode;
130
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000131 for (int i = 0; i < kMaxTextures; ++i) {
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000132 GrSafeUnref(fTextures[i]);
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000133 fTextureSamplers[i] = paint.fTextureSamplers[i];
134 fTextures[i] = paint.fTextures[i];
135 GrSafeRef(fTextures[i]);
136 }
137 for (int i = 0; i < kMaxMasks; ++i) {
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000138 GrSafeUnref(fMaskTextures[i]);
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000139 fMaskSamplers[i] = paint.fMaskSamplers[i];
140 fMaskTextures[i] = paint.fMaskTextures[i];
141 GrSafeRef(fMaskTextures[i]);
142 }
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000143 return *this;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000144 }
145
146 ~GrPaint() {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000147 for (int i = 0; i < kMaxTextures; ++i) {
148 GrSafeUnref(fTextures[i]);
149 }
150 for (int i = 0; i < kMaxMasks; ++i) {
151 GrSafeUnref(fMaskTextures[i]);
152 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000153 }
154
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000155 // sets paint to src-over, solid white, no texture, no mask
bsalomon@google.com27847de2011-02-22 20:59:41 +0000156 void reset() {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000157 this->resetBlend();
158 this->resetOptions();
159 this->resetColor();
160 this->resetTextures();
161 this->resetColorFilter();
162 this->resetMasks();
Scroggo97c88c22011-05-11 14:05:25 +0000163 }
164
165 void resetColorFilter() {
166 fColorFilterXfermode = SkXfermode::kDst_Mode;
167 fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000168 }
169
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000170 bool hasTexture() const {
171 return 0 != this->getActiveTextureStageMask();
172 }
173
174 bool hasMask() const {
175 return 0 != this->getActiveMaskStageMask();
176 }
177
178 bool hasTextureOrMask() const {
179 return this->hasTexture() || this->hasMask();
180 }
181
182 // helpers for GrContext, GrTextContext
183 int getActiveTextureStageMask() const {
184 int mask = 0;
185 for (int i = 0; i < kMaxTextures; ++i) {
186 if (NULL != fTextures[i]) {
187 mask |= 1 << (i + kFirstTextureStage);
188 }
189 }
190 return mask;
191 }
192
193 int getActiveMaskStageMask() const {
bsalomon@google.com00e17c52011-05-18 19:02:42 +0000194 int mask = 0;
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000195 for (int i = 0; i < kMaxMasks; ++i) {
196 if (NULL != fMaskTextures[i]) {
197 mask |= 1 << (i + kFirstMaskStage);
198 }
199 }
200 return mask;
201 }
202
203 int getActiveStageMask() const {
204 return this->getActiveTextureStageMask() |
205 this->getActiveMaskStageMask();
206 }
207
208 // internal use
209 // GrPaint's textures and masks map to the first N stages
210 // of GrDrawTarget in that order (textures followed by masks)
211 enum {
212 kFirstTextureStage = 0,
213 kFirstMaskStage = kMaxTextures,
214 kTotalStages = kMaxTextures + kMaxMasks,
215 };
216
bsalomon@google.com27847de2011-02-22 20:59:41 +0000217private:
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000218
219 GrSamplerState fTextureSamplers[kMaxTextures];
220 GrSamplerState fMaskSamplers[kMaxMasks];
221
222 GrTexture* fTextures[kMaxTextures];
223 GrTexture* fMaskTextures[kMaxMasks];
bsalomon@google.com27847de2011-02-22 20:59:41 +0000224
225 void resetBlend() {
226 fSrcBlendCoeff = kOne_BlendCoeff;
227 fDstBlendCoeff = kZero_BlendCoeff;
228 }
229
230 void resetOptions() {
231 fAntiAlias = false;
232 fDither = false;
233 }
234
235 void resetColor() {
236 fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
237 }
238
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000239 void resetTextures() {
240 for (int i = 0; i < kMaxTextures; ++i) {
241 this->setTexture(i, NULL);
242 fTextureSamplers[i].setClampNoFilter();
243 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000244 }
245
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000246 void resetMasks() {
247 for (int i = 0; i < kMaxMasks; ++i) {
248 this->setMask(i, NULL);
249 fMaskSamplers[i].setClampNoFilter();
250 }
251 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000252};
253
254#endif