blob: f1d74b286089250c3fef542b167e05265206c37b [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;
39
Scroggo97c88c22011-05-11 14:05:25 +000040 GrColor fColorFilterColor;
41 SkXfermode::Mode fColorFilterXfermode;
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +000042 float fColorMatrix[20];
Scroggo97c88c22011-05-11 14:05:25 +000043
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000044 void setTexture(int i, GrTexture* texture) {
45 GrAssert((unsigned)i < kMaxTextures);
bsalomon@google.com27847de2011-02-22 20:59:41 +000046 GrSafeRef(texture);
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000047 GrSafeUnref(fTextures[i]);
48 fTextures[i] = texture;
bsalomon@google.com27847de2011-02-22 20:59:41 +000049 }
50
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000051 GrTexture* getTexture(int i) const {
52 GrAssert((unsigned)i < kMaxTextures);
53 return fTextures[i];
54 }
55
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000056 GrSamplerState* textureSampler(int i) {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000057 GrAssert((unsigned)i < kMaxTextures);
58 return fTextureSamplers + i;
59 }
60
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000061 const GrSamplerState& getTextureSampler(int i) const {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000062 GrAssert((unsigned)i < kMaxTextures);
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000063 return fTextureSamplers[i];
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000064 }
65
66 // The mask can be alpha-only or per channel. It is applied
67 // after the colorfilter
68 void setMask(int i, GrTexture* mask) {
69 GrAssert((unsigned)i < kMaxMasks);
70 GrSafeRef(mask);
71 GrSafeUnref(fMaskTextures[i]);
72 fMaskTextures[i] = mask;
73 }
74
75 GrTexture* getMask(int i) const {
76 GrAssert((unsigned)i < kMaxMasks);
77 return fMaskTextures[i];
78 }
79
80 // mask's sampler matrix is always applied to the positions
81 // (i.e. no explicit texture coordinates)
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000082 GrSamplerState* maskSampler(int i) {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000083 GrAssert((unsigned)i < kMaxMasks);
84 return fMaskSamplers + i;
85 }
86
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000087 const GrSamplerState& getMaskSampler(int i) const {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000088 GrAssert((unsigned)i < kMaxMasks);
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000089 return fMaskSamplers[i];
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000090 }
91
92 // pre-concats sampler matrices for non-NULL textures and masks
93 void preConcatActiveSamplerMatrices(const GrMatrix& matrix) {
94 for (int i = 0; i < kMaxTextures; ++i) {
95 fTextureSamplers[i].preConcatMatrix(matrix);
96 }
97 for (int i = 0; i < kMaxMasks; ++i) {
98 fMaskSamplers[i].preConcatMatrix(matrix);
99 }
100 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000101
102 // uninitialized
103 GrPaint() {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000104 for (int i = 0; i < kMaxTextures; ++i) {
105 fTextures[i] = NULL;
106 }
107 for (int i = 0; i < kMaxMasks; ++i) {
108 fMaskTextures[i] = NULL;
109 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000110 }
111
112 GrPaint(const GrPaint& paint) {
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000113 for (int i = 0; i < kMaxTextures; ++i) {
114 fTextures[i] = NULL;
115 }
116 for (int i = 0; i < kMaxMasks; ++i) {
117 fMaskTextures[i] = NULL;
118 }
119 *this = paint;
120 }
121
122 GrPaint& operator=(const GrPaint& paint) {
bsalomon@google.com27847de2011-02-22 20:59:41 +0000123 fSrcBlendCoeff = paint.fSrcBlendCoeff;
124 fDstBlendCoeff = paint.fDstBlendCoeff;
125 fAntiAlias = paint.fAntiAlias;
126 fDither = paint.fDither;
127
128 fColor = paint.fColor;
129
Scroggo97c88c22011-05-11 14:05:25 +0000130 fColorFilterColor = paint.fColorFilterColor;
131 fColorFilterXfermode = paint.fColorFilterXfermode;
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +0000132 memcpy(fColorMatrix, paint.fColorMatrix, sizeof(fColorMatrix));
133 fColorMatrixEnabled = paint.fColorMatrixEnabled;
Scroggo97c88c22011-05-11 14:05:25 +0000134
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000135 for (int i = 0; i < kMaxTextures; ++i) {
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000136 GrSafeUnref(fTextures[i]);
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000137 fTextureSamplers[i] = paint.fTextureSamplers[i];
138 fTextures[i] = paint.fTextures[i];
139 GrSafeRef(fTextures[i]);
140 }
141 for (int i = 0; i < kMaxMasks; ++i) {
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000142 GrSafeUnref(fMaskTextures[i]);
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000143 fMaskSamplers[i] = paint.fMaskSamplers[i];
144 fMaskTextures[i] = paint.fMaskTextures[i];
145 GrSafeRef(fMaskTextures[i]);
146 }
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000147 return *this;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000148 }
149
150 ~GrPaint() {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000151 for (int i = 0; i < kMaxTextures; ++i) {
152 GrSafeUnref(fTextures[i]);
153 }
154 for (int i = 0; i < kMaxMasks; ++i) {
155 GrSafeUnref(fMaskTextures[i]);
156 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000157 }
158
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000159 // sets paint to src-over, solid white, no texture, no mask
bsalomon@google.com27847de2011-02-22 20:59:41 +0000160 void reset() {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000161 this->resetBlend();
162 this->resetOptions();
163 this->resetColor();
164 this->resetTextures();
165 this->resetColorFilter();
166 this->resetMasks();
Scroggo97c88c22011-05-11 14:05:25 +0000167 }
168
169 void resetColorFilter() {
170 fColorFilterXfermode = SkXfermode::kDst_Mode;
171 fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +0000172 memset(fColorMatrix, 0, sizeof(fColorMatrix));
173 fColorMatrixEnabled = false;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000174 }
175
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000176 bool hasTexture() const {
177 return 0 != this->getActiveTextureStageMask();
178 }
179
180 bool hasMask() const {
181 return 0 != this->getActiveMaskStageMask();
182 }
183
184 bool hasTextureOrMask() const {
185 return this->hasTexture() || this->hasMask();
186 }
187
188 // helpers for GrContext, GrTextContext
189 int getActiveTextureStageMask() const {
190 int mask = 0;
191 for (int i = 0; i < kMaxTextures; ++i) {
192 if (NULL != fTextures[i]) {
193 mask |= 1 << (i + kFirstTextureStage);
194 }
195 }
196 return mask;
197 }
198
199 int getActiveMaskStageMask() const {
bsalomon@google.com00e17c52011-05-18 19:02:42 +0000200 int mask = 0;
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000201 for (int i = 0; i < kMaxMasks; ++i) {
202 if (NULL != fMaskTextures[i]) {
203 mask |= 1 << (i + kFirstMaskStage);
204 }
205 }
206 return mask;
207 }
208
209 int getActiveStageMask() const {
210 return this->getActiveTextureStageMask() |
211 this->getActiveMaskStageMask();
212 }
213
214 // internal use
215 // GrPaint's textures and masks map to the first N stages
216 // of GrDrawTarget in that order (textures followed by masks)
217 enum {
218 kFirstTextureStage = 0,
219 kFirstMaskStage = kMaxTextures,
220 kTotalStages = kMaxTextures + kMaxMasks,
221 };
222
bsalomon@google.com27847de2011-02-22 20:59:41 +0000223private:
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000224
225 GrSamplerState fTextureSamplers[kMaxTextures];
226 GrSamplerState fMaskSamplers[kMaxMasks];
227
228 GrTexture* fTextures[kMaxTextures];
229 GrTexture* fMaskTextures[kMaxMasks];
bsalomon@google.com27847de2011-02-22 20:59:41 +0000230
231 void resetBlend() {
232 fSrcBlendCoeff = kOne_BlendCoeff;
233 fDstBlendCoeff = kZero_BlendCoeff;
234 }
235
236 void resetOptions() {
237 fAntiAlias = false;
238 fDither = false;
239 }
240
241 void resetColor() {
242 fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
243 }
244
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000245 void resetTextures() {
246 for (int i = 0; i < kMaxTextures; ++i) {
247 this->setTexture(i, NULL);
bsalomon@google.com97912912011-12-06 16:30:36 +0000248 fTextureSamplers[i].reset();
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000249 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000250 }
251
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000252 void resetMasks() {
253 for (int i = 0; i < kMaxMasks; ++i) {
254 this->setMask(i, NULL);
bsalomon@google.com97912912011-12-06 16:30:36 +0000255 fMaskSamplers[i].reset();
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000256 }
257 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000258};
259
260#endif