blob: f9573bba93316edb640ba7a4752be0b0d5ece90b [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.com39ee0ff2011-12-06 15:32:52 +000045 GrSamplerState* textureSampler(int i) {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000046 GrAssert((unsigned)i < kMaxTextures);
47 return fTextureSamplers + i;
48 }
49
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000050 const GrSamplerState& getTextureSampler(int i) const {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000051 GrAssert((unsigned)i < kMaxTextures);
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000052 return fTextureSamplers[i];
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000053 }
54
tomhudson@google.comf13f5882012-06-25 17:27:28 +000055 bool isTextureStageEnabled(int i) const {
56 GrAssert((unsigned)i < kMaxTextures);
bsalomon@google.com1c31f632012-07-26 19:39:06 +000057 return (NULL != fTextureSamplers[i].getCustomStage());
tomhudson@google.comf13f5882012-06-25 17:27:28 +000058 }
59
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000060
61 // mask's sampler matrix is always applied to the positions
62 // (i.e. no explicit texture coordinates)
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000063 GrSamplerState* maskSampler(int i) {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000064 GrAssert((unsigned)i < kMaxMasks);
65 return fMaskSamplers + i;
66 }
67
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000068 const GrSamplerState& getMaskSampler(int i) const {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000069 GrAssert((unsigned)i < kMaxMasks);
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000070 return fMaskSamplers[i];
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000071 }
72
tomhudson@google.comf13f5882012-06-25 17:27:28 +000073 bool isMaskStageEnabled(int i) const {
74 GrAssert((unsigned)i < kMaxTextures);
bsalomon@google.com1c31f632012-07-26 19:39:06 +000075 return (NULL != fMaskSamplers[i].getCustomStage());
tomhudson@google.comf13f5882012-06-25 17:27:28 +000076 }
77
bsalomon@google.come3d32162012-07-20 13:37:06 +000078 bool hasMask() const {
79 for (int i = 0; i < kMaxMasks; ++i) {
80 if (this->isMaskStageEnabled(i)) {
81 return true;
82 }
83 }
84 return false;
85 }
86
87 bool hasTexture() const {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000088 for (int i = 0; i < kMaxTextures; ++i) {
bsalomon@google.come3d32162012-07-20 13:37:06 +000089 if (this->isTextureStageEnabled(i)) {
90 return true;
91 }
92 }
93 return false;
94 }
95
96 bool hasTextureOrMask() const { return this->hasTexture() || this->hasMask(); }
97
98 /**
99 * Preconcats the matrix of all samplers in the mask with the inverse of a
100 * matrix. If the matrix inverse cannot be computed (and there is at least
101 * one enabled stage) then false is returned.
102 */
103 bool preConcatSamplerMatricesWithInverse(const GrMatrix& matrix) {
104 GrMatrix inv;
105 bool computed = false;
106 for (int i = 0; i < kMaxTextures; ++i) {
107 if (this->isTextureStageEnabled(i)) {
108 if (!computed && !matrix.invert(&inv)) {
109 return false;
110 } else {
111 computed = true;
112 }
113 fTextureSamplers[i].preConcatMatrix(inv);
114 }
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000115 }
116 for (int i = 0; i < kMaxMasks; ++i) {
bsalomon@google.come3d32162012-07-20 13:37:06 +0000117 if (this->isMaskStageEnabled(i)) {
118 if (!computed && !matrix.invert(&inv)) {
119 return false;
120 } else {
121 computed = true;
122 }
123 fMaskSamplers[i].preConcatMatrix(inv);
124 }
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000125 }
bsalomon@google.come3d32162012-07-20 13:37:06 +0000126 return true;
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000127 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000128
129 // uninitialized
130 GrPaint() {
bsalomon@google.com27847de2011-02-22 20:59:41 +0000131 }
132
133 GrPaint(const GrPaint& paint) {
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000134 *this = paint;
135 }
136
bsalomon@google.com1c31f632012-07-26 19:39:06 +0000137 ~GrPaint() {}
138
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000139 GrPaint& operator=(const GrPaint& paint) {
bsalomon@google.com27847de2011-02-22 20:59:41 +0000140 fSrcBlendCoeff = paint.fSrcBlendCoeff;
141 fDstBlendCoeff = paint.fDstBlendCoeff;
142 fAntiAlias = paint.fAntiAlias;
143 fDither = paint.fDither;
144
145 fColor = paint.fColor;
bsalomon@google.comdd1be602012-01-18 20:34:00 +0000146 fCoverage = paint.fCoverage;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000147
Scroggo97c88c22011-05-11 14:05:25 +0000148 fColorFilterColor = paint.fColorFilterColor;
149 fColorFilterXfermode = paint.fColorFilterXfermode;
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +0000150 fColorMatrixEnabled = paint.fColorMatrixEnabled;
bsalomon@google.comdddf6f62012-03-16 17:50:37 +0000151 if (fColorMatrixEnabled) {
152 memcpy(fColorMatrix, paint.fColorMatrix, sizeof(fColorMatrix));
153 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000154
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000155 for (int i = 0; i < kMaxTextures; ++i) {
tomhudson@google.come742bf02012-07-13 19:54:19 +0000156 if (paint.isTextureStageEnabled(i)) {
bsalomon@google.comdddf6f62012-03-16 17:50:37 +0000157 fTextureSamplers[i] = paint.fTextureSamplers[i];
bsalomon@google.comdddf6f62012-03-16 17:50:37 +0000158 }
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000159 }
160 for (int i = 0; i < kMaxMasks; ++i) {
tomhudson@google.come742bf02012-07-13 19:54:19 +0000161 if (paint.isMaskStageEnabled(i)) {
bsalomon@google.comdddf6f62012-03-16 17:50:37 +0000162 fMaskSamplers[i] = paint.fMaskSamplers[i];
bsalomon@google.comdddf6f62012-03-16 17:50:37 +0000163 }
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000164 }
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000165 return *this;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000166 }
167
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000168 // sets paint to src-over, solid white, no texture, no mask
bsalomon@google.com27847de2011-02-22 20:59:41 +0000169 void reset() {
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000170 this->resetBlend();
171 this->resetOptions();
172 this->resetColor();
bsalomon@google.comdd1be602012-01-18 20:34:00 +0000173 this->resetCoverage();
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000174 this->resetTextures();
175 this->resetColorFilter();
176 this->resetMasks();
Scroggo97c88c22011-05-11 14:05:25 +0000177 }
178
179 void resetColorFilter() {
180 fColorFilterXfermode = SkXfermode::kDst_Mode;
181 fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +0000182 fColorMatrixEnabled = false;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000183 }
184
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000185 // internal use
186 // GrPaint's textures and masks map to the first N stages
187 // of GrDrawTarget in that order (textures followed by masks)
188 enum {
189 kFirstTextureStage = 0,
190 kFirstMaskStage = kMaxTextures,
191 kTotalStages = kMaxTextures + kMaxMasks,
192 };
193
bsalomon@google.com27847de2011-02-22 20:59:41 +0000194private:
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000195
196 GrSamplerState fTextureSamplers[kMaxTextures];
197 GrSamplerState fMaskSamplers[kMaxMasks];
198
bsalomon@google.com27847de2011-02-22 20:59:41 +0000199 void resetBlend() {
bsalomon@google.com47059542012-06-06 20:51:20 +0000200 fSrcBlendCoeff = kOne_GrBlendCoeff;
201 fDstBlendCoeff = kZero_GrBlendCoeff;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000202 }
203
204 void resetOptions() {
205 fAntiAlias = false;
206 fDither = false;
207 }
208
209 void resetColor() {
210 fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
211 }
212
bsalomon@google.comdd1be602012-01-18 20:34:00 +0000213 void resetCoverage() {
214 fCoverage = 0xff;
215 }
216
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000217 void resetTextures() {
218 for (int i = 0; i < kMaxTextures; ++i) {
bsalomon@google.com97912912011-12-06 16:30:36 +0000219 fTextureSamplers[i].reset();
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000220 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000221 }
222
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000223 void resetMasks() {
224 for (int i = 0; i < kMaxMasks; ++i) {
bsalomon@google.com97912912011-12-06 16:30:36 +0000225 fMaskSamplers[i].reset();
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000226 }
227 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000228};
229
230#endif