blob: 9b07a4be16af3a77aae7f3806c37243972db28bc [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 {
bsalomon@google.com88becf42012-10-05 14:54:42 +000027 kMaxColorStages = 2,
28 kMaxCoverageStages = 1,
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000029 };
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.com88becf42012-10-05 14:54:42 +000045 GrSamplerState* colorSampler(int i) {
46 GrAssert((unsigned)i < kMaxColorStages);
47 return fColorSamplers + i;
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000048 }
49
bsalomon@google.com88becf42012-10-05 14:54:42 +000050 const GrSamplerState& getColorSampler(int i) const {
51 GrAssert((unsigned)i < kMaxColorStages);
52 return fColorSamplers[i];
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000053 }
54
bsalomon@google.com88becf42012-10-05 14:54:42 +000055 bool isColorStageEnabled(int i) const {
56 GrAssert((unsigned)i < kMaxColorStages);
57 return (NULL != fColorSamplers[i].getCustomStage());
tomhudson@google.comf13f5882012-06-25 17:27:28 +000058 }
59
bsalomon@google.com88becf42012-10-05 14:54:42 +000060 // The coverage stage's sampler matrix is always applied to the positions
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000061 // (i.e. no explicit texture coordinates)
bsalomon@google.com88becf42012-10-05 14:54:42 +000062 GrSamplerState* coverageSampler(int i) {
63 GrAssert((unsigned)i < kMaxCoverageStages);
64 return fCoverageSamplers + i;
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000065 }
66
bsalomon@google.com88becf42012-10-05 14:54:42 +000067 const GrSamplerState& getCoverageSampler(int i) const {
68 GrAssert((unsigned)i < kMaxCoverageStages);
69 return fCoverageSamplers[i];
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +000070 }
71
bsalomon@google.com88becf42012-10-05 14:54:42 +000072 bool isCoverageStageEnabled(int i) const {
73 GrAssert((unsigned)i < kMaxCoverageStages);
74 return (NULL != fCoverageSamplers[i].getCustomStage());
tomhudson@google.comf13f5882012-06-25 17:27:28 +000075 }
76
bsalomon@google.com88becf42012-10-05 14:54:42 +000077 bool hasCoverageStage() const {
78 for (int i = 0; i < kMaxCoverageStages; ++i) {
79 if (this->isCoverageStageEnabled(i)) {
bsalomon@google.come3d32162012-07-20 13:37:06 +000080 return true;
81 }
82 }
83 return false;
84 }
85
bsalomon@google.com88becf42012-10-05 14:54:42 +000086 bool hasColorStage() const {
87 for (int i = 0; i < kMaxColorStages; ++i) {
88 if (this->isColorStageEnabled(i)) {
bsalomon@google.come3d32162012-07-20 13:37:06 +000089 return true;
90 }
91 }
92 return false;
93 }
94
bsalomon@google.com88becf42012-10-05 14:54:42 +000095 bool hasStage() const { return this->hasColorStage() || this->hasCoverageStage(); }
bsalomon@google.come3d32162012-07-20 13:37:06 +000096
97 /**
98 * Preconcats the matrix of all samplers in the mask with the inverse of a
99 * matrix. If the matrix inverse cannot be computed (and there is at least
100 * one enabled stage) then false is returned.
101 */
102 bool preConcatSamplerMatricesWithInverse(const GrMatrix& matrix) {
103 GrMatrix inv;
104 bool computed = false;
bsalomon@google.com88becf42012-10-05 14:54:42 +0000105 for (int i = 0; i < kMaxColorStages; ++i) {
106 if (this->isColorStageEnabled(i)) {
bsalomon@google.come3d32162012-07-20 13:37:06 +0000107 if (!computed && !matrix.invert(&inv)) {
108 return false;
109 } else {
110 computed = true;
111 }
bsalomon@google.com88becf42012-10-05 14:54:42 +0000112 fColorSamplers[i].preConcatMatrix(inv);
bsalomon@google.come3d32162012-07-20 13:37:06 +0000113 }
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000114 }
bsalomon@google.com88becf42012-10-05 14:54:42 +0000115 for (int i = 0; i < kMaxCoverageStages; ++i) {
116 if (this->isCoverageStageEnabled(i)) {
bsalomon@google.come3d32162012-07-20 13:37:06 +0000117 if (!computed && !matrix.invert(&inv)) {
118 return false;
119 } else {
120 computed = true;
121 }
bsalomon@google.com88becf42012-10-05 14:54:42 +0000122 fCoverageSamplers[i].preConcatMatrix(inv);
bsalomon@google.come3d32162012-07-20 13:37:06 +0000123 }
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000124 }
bsalomon@google.come3d32162012-07-20 13:37:06 +0000125 return true;
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000126 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000127
128 // uninitialized
129 GrPaint() {
bsalomon@google.com27847de2011-02-22 20:59:41 +0000130 }
131
132 GrPaint(const GrPaint& paint) {
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000133 *this = paint;
134 }
135
bsalomon@google.com1c31f632012-07-26 19:39:06 +0000136 ~GrPaint() {}
137
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000138 GrPaint& operator=(const GrPaint& paint) {
bsalomon@google.com27847de2011-02-22 20:59:41 +0000139 fSrcBlendCoeff = paint.fSrcBlendCoeff;
140 fDstBlendCoeff = paint.fDstBlendCoeff;
141 fAntiAlias = paint.fAntiAlias;
142 fDither = paint.fDither;
143
144 fColor = paint.fColor;
bsalomon@google.comdd1be602012-01-18 20:34:00 +0000145 fCoverage = paint.fCoverage;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000146
Scroggo97c88c22011-05-11 14:05:25 +0000147 fColorFilterColor = paint.fColorFilterColor;
148 fColorFilterXfermode = paint.fColorFilterXfermode;
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +0000149 fColorMatrixEnabled = paint.fColorMatrixEnabled;
bsalomon@google.comdddf6f62012-03-16 17:50:37 +0000150 if (fColorMatrixEnabled) {
151 memcpy(fColorMatrix, paint.fColorMatrix, sizeof(fColorMatrix));
152 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000153
bsalomon@google.com88becf42012-10-05 14:54:42 +0000154 for (int i = 0; i < kMaxColorStages; ++i) {
155 if (paint.isColorStageEnabled(i)) {
156 fColorSamplers[i] = paint.fColorSamplers[i];
bsalomon@google.comdddf6f62012-03-16 17:50:37 +0000157 }
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000158 }
bsalomon@google.com88becf42012-10-05 14:54:42 +0000159 for (int i = 0; i < kMaxCoverageStages; ++i) {
160 if (paint.isCoverageStageEnabled(i)) {
161 fCoverageSamplers[i] = paint.fCoverageSamplers[i];
bsalomon@google.comdddf6f62012-03-16 17:50:37 +0000162 }
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000163 }
bsalomon@google.com27c9b6d2011-09-12 14:30:27 +0000164 return *this;
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 // internal use
185 // GrPaint's textures and masks map to the first N stages
186 // of GrDrawTarget in that order (textures followed by masks)
187 enum {
bsalomon@google.com88becf42012-10-05 14:54:42 +0000188 kFirstColorStage = 0,
189 kFirstCoverageStage = kMaxColorStages,
190 kTotalStages = kFirstColorStage + kMaxColorStages + kMaxCoverageStages,
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000191 };
192
bsalomon@google.com27847de2011-02-22 20:59:41 +0000193private:
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000194
bsalomon@google.com88becf42012-10-05 14:54:42 +0000195 GrSamplerState fColorSamplers[kMaxColorStages];
196 GrSamplerState fCoverageSamplers[kMaxCoverageStages];
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000197
bsalomon@google.com27847de2011-02-22 20:59:41 +0000198 void resetBlend() {
bsalomon@google.com47059542012-06-06 20:51:20 +0000199 fSrcBlendCoeff = kOne_GrBlendCoeff;
200 fDstBlendCoeff = kZero_GrBlendCoeff;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000201 }
202
203 void resetOptions() {
204 fAntiAlias = false;
205 fDither = false;
206 }
207
208 void resetColor() {
209 fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
210 }
211
bsalomon@google.comdd1be602012-01-18 20:34:00 +0000212 void resetCoverage() {
213 fCoverage = 0xff;
214 }
215
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000216 void resetTextures() {
bsalomon@google.com88becf42012-10-05 14:54:42 +0000217 for (int i = 0; i < kMaxColorStages; ++i) {
218 fColorSamplers[i].reset();
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000219 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000220 }
221
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000222 void resetMasks() {
bsalomon@google.com88becf42012-10-05 14:54:42 +0000223 for (int i = 0; i < kMaxCoverageStages; ++i) {
224 fCoverageSamplers[i].reset();
bsalomon@google.com26c2d0a2011-05-17 20:15:30 +0000225 }
226 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000227};
228
229#endif