blob: 62ab1642754d734a81ef55465a52bb02aeb0d226 [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;
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +000036 bool fColorMatrixEnabled;
bsalomon@google.com27847de2011-02-22 20:59:41 +000037
38 GrColor fColor;
bsalomon@google.comdd1be602012-01-18 20:34:00 +000039 uint8_t fCoverage;
bsalomon@google.com27847de2011-02-22 20:59:41 +000040
Scroggo97c88c22011-05-11 14:05:25 +000041 GrColor fColorFilterColor;
42 SkXfermode::Mode fColorFilterXfermode;
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +000043 float fColorMatrix[20];
Scroggo97c88c22011-05-11 14:05:25 +000044
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000045 void setTexture(int i, GrTexture* texture) {
46 GrAssert((unsigned)i < kMaxTextures);
bsalomon@google.com27847de2011-02-22 20:59:41 +000047 GrSafeRef(texture);
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000048 GrSafeUnref(fTextures[i]);
49 fTextures[i] = texture;
bsalomon@google.com27847de2011-02-22 20:59:41 +000050 }
51
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000052 GrTexture* getTexture(int i) const {
53 GrAssert((unsigned)i < kMaxTextures);
54 return fTextures[i];
55 }
56
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000057 GrSamplerState* textureSampler(int i) {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000058 GrAssert((unsigned)i < kMaxTextures);
59 return fTextureSamplers + i;
60 }
61
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000062 const GrSamplerState& getTextureSampler(int i) const {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000063 GrAssert((unsigned)i < kMaxTextures);
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000064 return fTextureSamplers[i];
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000065 }
66
67 // The mask can be alpha-only or per channel. It is applied
68 // after the colorfilter
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
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)
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000083 GrSamplerState* maskSampler(int i) {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000084 GrAssert((unsigned)i < kMaxMasks);
85 return fMaskSamplers + i;
86 }
87
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000088 const GrSamplerState& getMaskSampler(int i) const {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000089 GrAssert((unsigned)i < kMaxMasks);
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000090 return fMaskSamplers[i];
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000091 }
92
93 // pre-concats sampler matrices for non-NULL textures and masks
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 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000102
103 // uninitialized
104 GrPaint() {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000105 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 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000111 }
112
113 GrPaint(const GrPaint& paint) {
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000114 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) {
bsalomon@google.com27847de2011-02-22 20:59:41 +0000124 fSrcBlendCoeff = paint.fSrcBlendCoeff;
125 fDstBlendCoeff = paint.fDstBlendCoeff;
126 fAntiAlias = paint.fAntiAlias;
127 fDither = paint.fDither;
128
129 fColor = paint.fColor;
bsalomon@google.comdd1be602012-01-18 20:34:00 +0000130 fCoverage = paint.fCoverage;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000131
Scroggo97c88c22011-05-11 14:05:25 +0000132 fColorFilterColor = paint.fColorFilterColor;
133 fColorFilterXfermode = paint.fColorFilterXfermode;
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +0000134 fColorMatrixEnabled = paint.fColorMatrixEnabled;
bsalomon@google.comdddf6f62012-03-16 17:50:37 +0000135 if (fColorMatrixEnabled) {
136 memcpy(fColorMatrix, paint.fColorMatrix, sizeof(fColorMatrix));
137 }
138
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000139 for (int i = 0; i < kMaxTextures; ++i) {
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000140 GrSafeUnref(fTextures[i]);
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000141 fTextures[i] = paint.fTextures[i];
bsalomon@google.comdddf6f62012-03-16 17:50:37 +0000142 if (NULL != fTextures[i]) {
143 fTextureSamplers[i] = paint.fTextureSamplers[i];
144 fTextures[i]->ref();
145 }
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000146 }
147 for (int i = 0; i < kMaxMasks; ++i) {
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000148 GrSafeUnref(fMaskTextures[i]);
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000149 fMaskTextures[i] = paint.fMaskTextures[i];
bsalomon@google.comdddf6f62012-03-16 17:50:37 +0000150 if (NULL != fMaskTextures[i]) {
151 fMaskSamplers[i] = paint.fMaskSamplers[i];
152 fMaskTextures[i]->ref();
153 }
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000154 }
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000155 return *this;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000156 }
157
158 ~GrPaint() {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000159 for (int i = 0; i < kMaxTextures; ++i) {
160 GrSafeUnref(fTextures[i]);
161 }
162 for (int i = 0; i < kMaxMasks; ++i) {
163 GrSafeUnref(fMaskTextures[i]);
164 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000165 }
166
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000167 // sets paint to src-over, solid white, no texture, no mask
bsalomon@google.com27847de2011-02-22 20:59:41 +0000168 void reset() {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000169 this->resetBlend();
170 this->resetOptions();
171 this->resetColor();
bsalomon@google.comdd1be602012-01-18 20:34:00 +0000172 this->resetCoverage();
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000173 this->resetTextures();
174 this->resetColorFilter();
175 this->resetMasks();
Scroggo97c88c22011-05-11 14:05:25 +0000176 }
177
178 void resetColorFilter() {
179 fColorFilterXfermode = SkXfermode::kDst_Mode;
180 fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +0000181 fColorMatrixEnabled = false;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000182 }
183
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000184 bool hasTexture() const {
185 return 0 != this->getActiveTextureStageMask();
186 }
187
188 bool hasMask() const {
189 return 0 != this->getActiveMaskStageMask();
190 }
191
192 bool hasTextureOrMask() const {
193 return this->hasTexture() || this->hasMask();
194 }
195
196 // helpers for GrContext, GrTextContext
197 int getActiveTextureStageMask() const {
198 int mask = 0;
199 for (int i = 0; i < kMaxTextures; ++i) {
200 if (NULL != fTextures[i]) {
201 mask |= 1 << (i + kFirstTextureStage);
202 }
203 }
204 return mask;
205 }
206
207 int getActiveMaskStageMask() const {
bsalomon@google.com00e17c52011-05-18 19:02:42 +0000208 int mask = 0;
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000209 for (int i = 0; i < kMaxMasks; ++i) {
210 if (NULL != fMaskTextures[i]) {
211 mask |= 1 << (i + kFirstMaskStage);
212 }
213 }
214 return mask;
215 }
216
217 int getActiveStageMask() const {
218 return this->getActiveTextureStageMask() |
219 this->getActiveMaskStageMask();
220 }
221
222 // internal use
223 // GrPaint's textures and masks map to the first N stages
224 // of GrDrawTarget in that order (textures followed by masks)
225 enum {
226 kFirstTextureStage = 0,
227 kFirstMaskStage = kMaxTextures,
228 kTotalStages = kMaxTextures + kMaxMasks,
229 };
230
bsalomon@google.com27847de2011-02-22 20:59:41 +0000231private:
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000232
233 GrSamplerState fTextureSamplers[kMaxTextures];
234 GrSamplerState fMaskSamplers[kMaxMasks];
235
236 GrTexture* fTextures[kMaxTextures];
237 GrTexture* fMaskTextures[kMaxMasks];
bsalomon@google.com27847de2011-02-22 20:59:41 +0000238
239 void resetBlend() {
240 fSrcBlendCoeff = kOne_BlendCoeff;
241 fDstBlendCoeff = kZero_BlendCoeff;
242 }
243
244 void resetOptions() {
245 fAntiAlias = false;
246 fDither = false;
247 }
248
249 void resetColor() {
250 fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
251 }
252
bsalomon@google.comdd1be602012-01-18 20:34:00 +0000253 void resetCoverage() {
254 fCoverage = 0xff;
255 }
256
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000257 void resetTextures() {
258 for (int i = 0; i < kMaxTextures; ++i) {
259 this->setTexture(i, NULL);
bsalomon@google.com97912912011-12-06 16:30:36 +0000260 fTextureSamplers[i].reset();
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000261 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000262 }
263
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000264 void resetMasks() {
265 for (int i = 0; i < kMaxMasks; ++i) {
266 this->setMask(i, NULL);
bsalomon@google.com97912912011-12-06 16:30:36 +0000267 fMaskSamplers[i].reset();
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000268 }
269 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000270};
271
272#endif