blob: f1dd2021a18a70c413d63f8514daf9a1e6444008 [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 {
twiz@google.com58071162012-07-18 21:41:50 +000027 kMaxTextures = 2,
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000028 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);
tomhudson@google.com1e8f0162012-07-20 16:25:18 +000054 //if (this->getTextureSampler(i).getCustomStage()) {
55 //return this->getTextureSampler(i).getCustomStage()->texture(i);
56 //}
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000057 return fTextures[i];
58 }
59
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000060 GrSamplerState* textureSampler(int i) {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000061 GrAssert((unsigned)i < kMaxTextures);
62 return fTextureSamplers + i;
63 }
64
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000065 const GrSamplerState& getTextureSampler(int i) const {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000066 GrAssert((unsigned)i < kMaxTextures);
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000067 return fTextureSamplers[i];
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000068 }
69
tomhudson@google.comf13f5882012-06-25 17:27:28 +000070 bool isTextureStageEnabled(int i) const {
71 GrAssert((unsigned)i < kMaxTextures);
72 return (NULL != fTextures[i]) ||
73 (NULL != fTextureSamplers[i].getCustomStage());
74 }
75
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000076 // The mask can be alpha-only or per channel. It is applied
77 // after the colorfilter
78 void setMask(int i, GrTexture* mask) {
79 GrAssert((unsigned)i < kMaxMasks);
80 GrSafeRef(mask);
81 GrSafeUnref(fMaskTextures[i]);
82 fMaskTextures[i] = mask;
83 }
84
85 GrTexture* getMask(int i) const {
86 GrAssert((unsigned)i < kMaxMasks);
tomhudson@google.com1e8f0162012-07-20 16:25:18 +000087 //if (this->getMaskSampler(i).getCustomStage()) {
88 //return this->getMaskSampler(i).getCustomStage()->texture(i);
89 //}
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000090 return fMaskTextures[i];
91 }
92
93 // mask's sampler matrix is always applied to the positions
94 // (i.e. no explicit texture coordinates)
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000095 GrSamplerState* maskSampler(int i) {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000096 GrAssert((unsigned)i < kMaxMasks);
97 return fMaskSamplers + i;
98 }
99
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +0000100 const GrSamplerState& getMaskSampler(int i) const {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000101 GrAssert((unsigned)i < kMaxMasks);
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +0000102 return fMaskSamplers[i];
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000103 }
104
tomhudson@google.comf13f5882012-06-25 17:27:28 +0000105 bool isMaskStageEnabled(int i) const {
106 GrAssert((unsigned)i < kMaxTextures);
107 return (NULL != fMaskTextures[i]) ||
108 (NULL != fMaskSamplers[i].getCustomStage());
109 }
110
bsalomon@google.come3d32162012-07-20 13:37:06 +0000111 bool hasMask() const {
112 for (int i = 0; i < kMaxMasks; ++i) {
113 if (this->isMaskStageEnabled(i)) {
114 return true;
115 }
116 }
117 return false;
118 }
119
120 bool hasTexture() const {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000121 for (int i = 0; i < kMaxTextures; ++i) {
bsalomon@google.come3d32162012-07-20 13:37:06 +0000122 if (this->isTextureStageEnabled(i)) {
123 return true;
124 }
125 }
126 return false;
127 }
128
129 bool hasTextureOrMask() const { return this->hasTexture() || this->hasMask(); }
130
131 /**
132 * Preconcats the matrix of all samplers in the mask with the inverse of a
133 * matrix. If the matrix inverse cannot be computed (and there is at least
134 * one enabled stage) then false is returned.
135 */
136 bool preConcatSamplerMatricesWithInverse(const GrMatrix& matrix) {
137 GrMatrix inv;
138 bool computed = false;
139 for (int i = 0; i < kMaxTextures; ++i) {
140 if (this->isTextureStageEnabled(i)) {
141 if (!computed && !matrix.invert(&inv)) {
142 return false;
143 } else {
144 computed = true;
145 }
146 fTextureSamplers[i].preConcatMatrix(inv);
147 }
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000148 }
149 for (int i = 0; i < kMaxMasks; ++i) {
bsalomon@google.come3d32162012-07-20 13:37:06 +0000150 if (this->isMaskStageEnabled(i)) {
151 if (!computed && !matrix.invert(&inv)) {
152 return false;
153 } else {
154 computed = true;
155 }
156 fMaskSamplers[i].preConcatMatrix(inv);
157 }
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000158 }
bsalomon@google.come3d32162012-07-20 13:37:06 +0000159 return true;
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000160 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000161
162 // uninitialized
163 GrPaint() {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000164 for (int i = 0; i < kMaxTextures; ++i) {
165 fTextures[i] = NULL;
166 }
167 for (int i = 0; i < kMaxMasks; ++i) {
168 fMaskTextures[i] = NULL;
169 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000170 }
171
172 GrPaint(const GrPaint& paint) {
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000173 for (int i = 0; i < kMaxTextures; ++i) {
174 fTextures[i] = NULL;
175 }
176 for (int i = 0; i < kMaxMasks; ++i) {
177 fMaskTextures[i] = NULL;
178 }
179 *this = paint;
180 }
181
182 GrPaint& operator=(const GrPaint& paint) {
bsalomon@google.com27847de2011-02-22 20:59:41 +0000183 fSrcBlendCoeff = paint.fSrcBlendCoeff;
184 fDstBlendCoeff = paint.fDstBlendCoeff;
185 fAntiAlias = paint.fAntiAlias;
186 fDither = paint.fDither;
187
188 fColor = paint.fColor;
bsalomon@google.comdd1be602012-01-18 20:34:00 +0000189 fCoverage = paint.fCoverage;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000190
Scroggo97c88c22011-05-11 14:05:25 +0000191 fColorFilterColor = paint.fColorFilterColor;
192 fColorFilterXfermode = paint.fColorFilterXfermode;
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +0000193 fColorMatrixEnabled = paint.fColorMatrixEnabled;
bsalomon@google.comdddf6f62012-03-16 17:50:37 +0000194 if (fColorMatrixEnabled) {
195 memcpy(fColorMatrix, paint.fColorMatrix, sizeof(fColorMatrix));
196 }
197
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000198 for (int i = 0; i < kMaxTextures; ++i) {
tomhudson@google.come742bf02012-07-13 19:54:19 +0000199 GrSafeAssign(fTextures[i], paint.fTextures[i]);
200 if (paint.isTextureStageEnabled(i)) {
bsalomon@google.comdddf6f62012-03-16 17:50:37 +0000201 fTextureSamplers[i] = paint.fTextureSamplers[i];
bsalomon@google.comdddf6f62012-03-16 17:50:37 +0000202 }
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000203 }
204 for (int i = 0; i < kMaxMasks; ++i) {
tomhudson@google.come742bf02012-07-13 19:54:19 +0000205 GrSafeAssign(fMaskTextures[i], paint.fMaskTextures[i]);
206 if (paint.isMaskStageEnabled(i)) {
bsalomon@google.comdddf6f62012-03-16 17:50:37 +0000207 fMaskSamplers[i] = paint.fMaskSamplers[i];
bsalomon@google.comdddf6f62012-03-16 17:50:37 +0000208 }
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000209 }
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000210 return *this;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000211 }
212
213 ~GrPaint() {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000214 for (int i = 0; i < kMaxTextures; ++i) {
215 GrSafeUnref(fTextures[i]);
216 }
217 for (int i = 0; i < kMaxMasks; ++i) {
218 GrSafeUnref(fMaskTextures[i]);
219 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000220 }
221
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000222 // sets paint to src-over, solid white, no texture, no mask
bsalomon@google.com27847de2011-02-22 20:59:41 +0000223 void reset() {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000224 this->resetBlend();
225 this->resetOptions();
226 this->resetColor();
bsalomon@google.comdd1be602012-01-18 20:34:00 +0000227 this->resetCoverage();
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000228 this->resetTextures();
229 this->resetColorFilter();
230 this->resetMasks();
Scroggo97c88c22011-05-11 14:05:25 +0000231 }
232
233 void resetColorFilter() {
234 fColorFilterXfermode = SkXfermode::kDst_Mode;
235 fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +0000236 fColorMatrixEnabled = false;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000237 }
238
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000239 // internal use
240 // GrPaint's textures and masks map to the first N stages
241 // of GrDrawTarget in that order (textures followed by masks)
242 enum {
243 kFirstTextureStage = 0,
244 kFirstMaskStage = kMaxTextures,
245 kTotalStages = kMaxTextures + kMaxMasks,
246 };
247
bsalomon@google.com27847de2011-02-22 20:59:41 +0000248private:
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000249
250 GrSamplerState fTextureSamplers[kMaxTextures];
251 GrSamplerState fMaskSamplers[kMaxMasks];
252
253 GrTexture* fTextures[kMaxTextures];
254 GrTexture* fMaskTextures[kMaxMasks];
bsalomon@google.com27847de2011-02-22 20:59:41 +0000255
256 void resetBlend() {
bsalomon@google.com47059542012-06-06 20:51:20 +0000257 fSrcBlendCoeff = kOne_GrBlendCoeff;
258 fDstBlendCoeff = kZero_GrBlendCoeff;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000259 }
260
261 void resetOptions() {
262 fAntiAlias = false;
263 fDither = false;
264 }
265
266 void resetColor() {
267 fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
268 }
269
bsalomon@google.comdd1be602012-01-18 20:34:00 +0000270 void resetCoverage() {
271 fCoverage = 0xff;
272 }
273
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000274 void resetTextures() {
275 for (int i = 0; i < kMaxTextures; ++i) {
276 this->setTexture(i, NULL);
bsalomon@google.com97912912011-12-06 16:30:36 +0000277 fTextureSamplers[i].reset();
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000278 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000279 }
280
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000281 void resetMasks() {
282 for (int i = 0; i < kMaxMasks; ++i) {
283 this->setMask(i, NULL);
bsalomon@google.com97912912011-12-06 16:30:36 +0000284 fMaskSamplers[i].reset();
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000285 }
286 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000287};
288
289#endif