blob: fa4d5b03f534e108879757e7f5644e86df5c3ca1 [file] [log] [blame]
tomhudson@google.com93813632011-10-27 20:21:16 +00001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrDrawState_DEFINED
9#define GrDrawState_DEFINED
10
commit-bot@chromium.org24ab3b02013-08-14 21:56:37 +000011#include "GrBlend.h"
tomhudson@google.com93813632011-10-27 20:21:16 +000012#include "GrColor.h"
bsalomon@google.com08283af2012-10-26 13:01:20 +000013#include "GrEffectStage.h"
jvanverth@google.comcc782382013-01-28 20:39:48 +000014#include "GrStencil.h"
bsalomon@google.com68b58c92013-01-17 16:50:08 +000015#include "effects/GrSimpleTextureEffect.h"
tomhudson@google.com93813632011-10-27 20:21:16 +000016
jvanverth@google.comcc782382013-01-28 20:39:48 +000017#include "SkMatrix.h"
bsalomon62c447d2014-08-08 08:08:50 -070018
19class GrDrawTargetCaps;
20class GrPaint;
21class GrRenderTarget;
22class GrTexture;
tomhudson@google.com93813632011-10-27 20:21:16 +000023
commit-bot@chromium.orga4de8c22013-09-09 13:38:37 +000024class GrDrawState : public SkRefCnt {
bsalomon@google.com2e3d1442012-03-26 20:33:54 +000025public:
reed@google.comfa35e3d2012-06-26 20:16:17 +000026 SK_DECLARE_INST_COUNT(GrDrawState)
rmistry@google.comd6176b02012-08-23 18:14:13 +000027
bsalomon@google.comeb6879f2013-06-13 19:34:18 +000028 GrDrawState() {
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +000029 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
bsalomon@google.comeb6879f2013-06-13 19:34:18 +000030 this->reset();
31 }
tomhudson@google.com93813632011-10-27 20:21:16 +000032
bsalomon@google.comeb6879f2013-06-13 19:34:18 +000033 GrDrawState(const SkMatrix& initialViewMatrix) {
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +000034 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
bsalomon@google.comeb6879f2013-06-13 19:34:18 +000035 this->reset(initialViewMatrix);
36 }
bsalomon@google.com137f1342013-05-29 21:27:53 +000037
38 /**
39 * Copies another draw state.
40 **/
commit-bot@chromium.orgfaa5ae42013-07-23 11:13:56 +000041 GrDrawState(const GrDrawState& state) : INHERITED() {
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +000042 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
bsalomon@google.com46f7afb2012-01-18 19:51:55 +000043 *this = state;
44 }
45
bsalomon@google.com137f1342013-05-29 21:27:53 +000046 /**
47 * Copies another draw state with a preconcat to the view matrix.
48 **/
bsalomon8f727332014-08-05 07:50:06 -070049 GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix);
robertphillips@google.com9ec07532012-06-22 12:01:30 +000050
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000051 virtual ~GrDrawState() { SkASSERT(0 == fBlockEffectRemovalCnt); }
bsalomon@google.com137f1342013-05-29 21:27:53 +000052
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000053 /**
bsalomon@google.com137f1342013-05-29 21:27:53 +000054 * Resets to the default state. GrEffects will be removed from all stages.
rmistry@google.comd6176b02012-08-23 18:14:13 +000055 */
bsalomon@google.com137f1342013-05-29 21:27:53 +000056 void reset() { this->onReset(NULL); }
robertphillips@google.com9ec07532012-06-22 12:01:30 +000057
bsalomon@google.com137f1342013-05-29 21:27:53 +000058 void reset(const SkMatrix& initialViewMatrix) { this->onReset(&initialViewMatrix); }
bsalomon@google.comaf84e742012-10-05 13:23:24 +000059
60 /**
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +000061 * Initializes the GrDrawState based on a GrPaint, view matrix and render target. Note that
62 * GrDrawState encompasses more than GrPaint. Aspects of GrDrawState that have no GrPaint
bsalomon@google.comeb6879f2013-06-13 19:34:18 +000063 * equivalents are set to default values. Clipping will be enabled.
bsalomon@google.comaf84e742012-10-05 13:23:24 +000064 */
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +000065 void setFromPaint(const GrPaint& , const SkMatrix& viewMatrix, GrRenderTarget*);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000066
67 ///////////////////////////////////////////////////////////////////////////
jvanverth@google.com9b855c72013-03-01 18:21:22 +000068 /// @name Vertex Attributes
jvanverth@google.comcc782382013-01-28 20:39:48 +000069 ////
70
jvanverth@google.com9b855c72013-03-01 18:21:22 +000071 enum {
jvanverth@google.com054ae992013-04-01 20:06:51 +000072 kMaxVertexAttribCnt = kLast_GrVertexAttribBinding + 4,
jvanverth@google.comb75b0a02013-02-05 20:33:30 +000073 };
74
jvanverth@google.com9b855c72013-03-01 18:21:22 +000075 /**
jvanverth@google.com054ae992013-04-01 20:06:51 +000076 * The format of vertices is represented as an array of GrVertexAttribs, with each representing
77 * the type of the attribute, its offset, and semantic binding (see GrVertexAttrib in
78 * GrTypesPriv.h).
jvanverth@google.comb8b705b2013-02-28 16:28:34 +000079 *
jvanverth@google.com054ae992013-04-01 20:06:51 +000080 * The mapping of attributes with kEffect bindings to GrEffect inputs is specified when
81 * setEffect is called.
jvanverth@google.comb8b705b2013-02-28 16:28:34 +000082 */
jvanverth@google.comb75b0a02013-02-05 20:33:30 +000083
jvanverth@google.com9b855c72013-03-01 18:21:22 +000084 /**
robertphillips@google.com42903302013-04-20 12:26:07 +000085 * Sets vertex attributes for next draw. The object driving the templatization
86 * should be a global GrVertexAttrib array that is never changed.
jvanverth@google.com9b855c72013-03-01 18:21:22 +000087 */
robertphillips@google.com42903302013-04-20 12:26:07 +000088 template <const GrVertexAttrib A[]> void setVertexAttribs(int count) {
89 this->setVertexAttribs(A, count);
90 }
jvanverth@google.comb8b705b2013-02-28 16:28:34 +000091
bsalomon2ed5ef82014-07-07 08:44:05 -070092 const GrVertexAttrib* getVertexAttribs() const { return fVAPtr; }
93 int getVertexAttribCount() const { return fVACount; }
jvanverth@google.com9b855c72013-03-01 18:21:22 +000094
95 size_t getVertexSize() const;
96
97 /**
jvanverth@google.com054ae992013-04-01 20:06:51 +000098 * Sets default vertex attributes for next draw. The default is a single attribute:
99 * {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribType}
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000100 */
101 void setDefaultVertexAttribs();
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000102
jvanverth@google.com054ae992013-04-01 20:06:51 +0000103 /**
104 * Getters for index into getVertexAttribs() for particular bindings. -1 is returned if the
105 * binding does not appear in the current attribs. These bindings should appear only once in
106 * the attrib array.
107 */
108
109 int positionAttributeIndex() const {
bsalomon2ed5ef82014-07-07 08:44:05 -0700110 return fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding];
jvanverth@google.com054ae992013-04-01 20:06:51 +0000111 }
112 int localCoordAttributeIndex() const {
bsalomon2ed5ef82014-07-07 08:44:05 -0700113 return fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
jvanverth@google.com054ae992013-04-01 20:06:51 +0000114 }
115 int colorVertexAttributeIndex() const {
bsalomon2ed5ef82014-07-07 08:44:05 -0700116 return fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
jvanverth@google.com054ae992013-04-01 20:06:51 +0000117 }
118 int coverageVertexAttributeIndex() const {
bsalomon2ed5ef82014-07-07 08:44:05 -0700119 return fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
jvanverth@google.com054ae992013-04-01 20:06:51 +0000120 }
121
122 bool hasLocalCoordAttribute() const {
bsalomon2ed5ef82014-07-07 08:44:05 -0700123 return -1 != fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
jvanverth@google.com054ae992013-04-01 20:06:51 +0000124 }
125 bool hasColorVertexAttribute() const {
bsalomon2ed5ef82014-07-07 08:44:05 -0700126 return -1 != fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
jvanverth@google.com054ae992013-04-01 20:06:51 +0000127 }
128 bool hasCoverageVertexAttribute() const {
bsalomon2ed5ef82014-07-07 08:44:05 -0700129 return -1 != fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
jvanverth@google.com054ae992013-04-01 20:06:51 +0000130 }
131
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000132 bool validateVertexAttribs() const;
133
jvanverth@google.comcc782382013-01-28 20:39:48 +0000134 /**
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000135 * Helper to save/restore vertex attribs
136 */
137 class AutoVertexAttribRestore {
138 public:
bsalomon8f727332014-08-05 07:50:06 -0700139 AutoVertexAttribRestore(GrDrawState* drawState);
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000140
bsalomon8f727332014-08-05 07:50:06 -0700141 ~AutoVertexAttribRestore() { fDrawState->setVertexAttribs(fVAPtr, fVACount); }
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000142
143 private:
robertphillips@google.com42903302013-04-20 12:26:07 +0000144 GrDrawState* fDrawState;
145 const GrVertexAttrib* fVAPtr;
146 int fVACount;
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000147 };
148
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000149 /// @}
150
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000151 /**
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000152 * Determines whether src alpha is guaranteed to be one for all src pixels
153 */
jvanverth@google.com054ae992013-04-01 20:06:51 +0000154 bool srcAlphaWillBeOne() const;
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000155
156 /**
157 * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
158 */
jvanverth@google.com054ae992013-04-01 20:06:51 +0000159 bool hasSolidCoverage() const;
jvanverth@google.comcc782382013-01-28 20:39:48 +0000160
bsalomon62c447d2014-08-08 08:08:50 -0700161 /**
162 * Depending on features available in the underlying 3D API and the color blend mode requested
163 * it may or may not be possible to correctly blend with fractional pixel coverage generated by
164 * the fragment shader.
165 *
166 * This function considers the current draw state and the draw target's capabilities to
167 * determine whether coverage can be handled correctly. This function assumes that the caller
168 * intends to specify fractional pixel coverage (via setCoverage(), through a coverage vertex
169 * attribute, or a coverage effect) but may not have specified it yet.
170 */
171 bool couldApplyCoverage(const GrDrawTargetCaps& caps) const;
172
jvanverth@google.comcc782382013-01-28 20:39:48 +0000173 /// @}
174
175 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000176 /// @name Color
177 ////
178
179 /**
180 * Sets color for next draw to a premultiplied-alpha color.
181 *
182 * @param color the color to set.
183 */
egdaniel9514d242014-07-18 06:15:43 -0700184 void setColor(GrColor color) {
185 fColor = color;
186 this->invalidateBlendOptFlags();
187 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000188
bsalomon2ed5ef82014-07-07 08:44:05 -0700189 GrColor getColor() const { return fColor; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000190
191 /**
192 * Sets the color to be used for the next draw to be
193 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
194 *
195 * @param alpha The alpha value to set as the color.
196 */
bsalomon62c447d2014-08-08 08:08:50 -0700197 void setAlpha(uint8_t a) { this->setColor((a << 24) | (a << 16) | (a << 8) | a); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000198
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000199 /// @}
200
201 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000202 /// @name Coverage
203 ////
204
205 /**
rmistry@google.comd6176b02012-08-23 18:14:13 +0000206 * Sets a constant fractional coverage to be applied to the draw. The
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000207 * initial value (after construction or reset()) is 0xff. The constant
208 * coverage is ignored when per-vertex coverage is provided.
209 */
210 void setCoverage(uint8_t coverage) {
bsalomon2ed5ef82014-07-07 08:44:05 -0700211 fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
egdaniel9514d242014-07-18 06:15:43 -0700212 this->invalidateBlendOptFlags();
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000213 }
214
bsalomon62c447d2014-08-08 08:08:50 -0700215 uint8_t getCoverage() const { return GrColorUnpackR(fCoverage); }
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000216
bsalomon62c447d2014-08-08 08:08:50 -0700217 GrColor getCoverageColor() const { return fCoverage; }
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000218
219 /// @}
220
egdaniel776bdbd2014-08-06 11:07:02 -0700221 /**
222 * This struct is here so that the GrDrawState can have multiple instances of state information.
223 * The use of this will come in a future revision when we want to keep track of the original
224 * draw state as well as an optimized version of it.
225 */
226 struct State {
227 State() {
228 this->reset();
229 }
230
231 State(const GrEffectStage* colorArray, int colorCount,
232 const GrEffectStage* coverageArray, int coverageCount)
233 : fColorStages(colorArray, colorCount), fCoverageStages(coverageArray, coverageCount) {
234 fSrcBlend = kOne_GrBlendCoeff;
235 fDstBlend = kZero_GrBlendCoeff;
236 }
237
238 static bool HaveCompatibleState(const State& a, const State& b, bool explicitLocalCoords);
239
240 void reset() {
241 fSrcBlend = kOne_GrBlendCoeff;
242 fDstBlend = kZero_GrBlendCoeff;
243 fColorStages.reset();
244 fCoverageStages.reset();
245 }
246
247 GrBlendCoeff fSrcBlend;
248 GrBlendCoeff fDstBlend;
249
250 typedef SkSTArray<4, GrEffectStage> EffectStageArray;
251 EffectStageArray fColorStages;
252 EffectStageArray fCoverageStages;
253 };
254
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000255 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.comadc65362013-01-28 14:26:09 +0000256 /// @name Effect Stages
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000257 /// Each stage hosts a GrEffect. The effect produces an output color or coverage in the fragment
258 /// shader. Its inputs are the output from the previous stage as well as some variables
259 /// available to it in the fragment and vertex shader (e.g. the vertex position, the dst color,
260 /// the fragment position, local coordinates).
261 ///
262 /// The stages are divided into two sets, color-computing and coverage-computing. The final
263 /// color stage produces the final pixel color. The coverage-computing stages function exactly
264 /// as the color-computing but the output of the final coverage stage is treated as a fractional
265 /// pixel coverage rather than as input to the src/dst color blend step.
266 ///
267 /// The input color to the first color-stage is either the constant color or interpolated
268 /// per-vertex colors. The input to the first coverage stage is either a constant coverage
269 /// (usually full-coverage) or interpolated per-vertex coverage.
270 ///
271 /// See the documentation of kCoverageDrawing_StateBit for information about disabling the
272 /// the color / coverage distinction.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000273 ////
274
bsalomon97b9ab72014-07-08 06:52:35 -0700275 const GrEffect* addColorEffect(const GrEffect* effect, int attr0 = -1, int attr1 = -1) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000276 SkASSERT(NULL != effect);
egdaniel776bdbd2014-08-06 11:07:02 -0700277 SkNEW_APPEND_TO_TARRAY(&fState.fColorStages, GrEffectStage, (effect, attr0, attr1));
egdaniel9514d242014-07-18 06:15:43 -0700278 this->invalidateBlendOptFlags();
jvanverth@google.com65eb4d52013-03-19 18:51:02 +0000279 return effect;
280 }
skia.committer@gmail.com01c34ee2013-03-20 07:01:02 +0000281
bsalomon97b9ab72014-07-08 06:52:35 -0700282 const GrEffect* addCoverageEffect(const GrEffect* effect, int attr0 = -1, int attr1 = -1) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000283 SkASSERT(NULL != effect);
egdaniel776bdbd2014-08-06 11:07:02 -0700284 SkNEW_APPEND_TO_TARRAY(&fState.fCoverageStages, GrEffectStage, (effect, attr0, attr1));
egdaniel9514d242014-07-18 06:15:43 -0700285 this->invalidateBlendOptFlags();
bsalomon@google.comadc65362013-01-28 14:26:09 +0000286 return effect;
287 }
288
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000289 /**
bsalomon@google.comc7818882013-03-20 19:19:53 +0000290 * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
tomhudson@google.com1e8f0162012-07-20 16:25:18 +0000291 */
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000292 void addColorTextureEffect(GrTexture* texture, const SkMatrix& matrix) {
bsalomon97b9ab72014-07-08 06:52:35 -0700293 this->addColorEffect(GrSimpleTextureEffect::Create(texture, matrix))->unref();
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000294 }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000295
296 void addCoverageTextureEffect(GrTexture* texture, const SkMatrix& matrix) {
bsalomon97b9ab72014-07-08 06:52:35 -0700297 this->addCoverageEffect(GrSimpleTextureEffect::Create(texture, matrix))->unref();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000298 }
299
300 void addColorTextureEffect(GrTexture* texture,
301 const SkMatrix& matrix,
302 const GrTextureParams& params) {
bsalomon97b9ab72014-07-08 06:52:35 -0700303 this->addColorEffect(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
bsalomon@google.com1ce49fc2012-09-18 14:14:49 +0000304 }
305
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000306 void addCoverageTextureEffect(GrTexture* texture,
307 const SkMatrix& matrix,
308 const GrTextureParams& params) {
bsalomon97b9ab72014-07-08 06:52:35 -0700309 this->addCoverageEffect(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000310 }
tomhudson@google.com676e6602012-07-10 17:21:48 +0000311
robertphillips@google.com972265d2012-06-13 18:49:30 +0000312 /**
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000313 * When this object is destroyed it will remove any effects from the draw state that were added
314 * after its constructor.
robertphillips@google.com972265d2012-06-13 18:49:30 +0000315 */
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +0000316 class AutoRestoreEffects : public ::SkNoncopyable {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000317 public:
bsalomon@google.com2fad5a82013-06-13 19:47:23 +0000318 AutoRestoreEffects() : fDrawState(NULL), fColorEffectCnt(0), fCoverageEffectCnt(0) {}
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000319
skia.committer@gmail.com5c493d52013-06-14 07:00:49 +0000320 AutoRestoreEffects(GrDrawState* ds) : fDrawState(NULL), fColorEffectCnt(0), fCoverageEffectCnt(0) {
321 this->set(ds);
robertphillips@google.comf09b87d2013-06-13 20:06:44 +0000322 }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000323
324 ~AutoRestoreEffects() { this->set(NULL); }
325
bsalomon8f727332014-08-05 07:50:06 -0700326 void set(GrDrawState* ds);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000327
bsalomon8af05232014-06-03 06:34:58 -0700328 bool isSet() const { return NULL != fDrawState; }
329
robertphillips@google.com972265d2012-06-13 18:49:30 +0000330 private:
331 GrDrawState* fDrawState;
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000332 int fColorEffectCnt;
333 int fCoverageEffectCnt;
robertphillips@google.com972265d2012-06-13 18:49:30 +0000334 };
335
egdaniel776bdbd2014-08-06 11:07:02 -0700336 int numColorStages() const { return fState.fColorStages.count(); }
337 int numCoverageStages() const { return fState.fCoverageStages.count(); }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000338 int numTotalStages() const { return this->numColorStages() + this->numCoverageStages(); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000339
egdaniel776bdbd2014-08-06 11:07:02 -0700340 const GrEffectStage& getColorStage(int stageIdx) const { return fState.fColorStages[stageIdx]; }
341 const GrEffectStage& getCoverageStage(int stageIdx) const { return fState.fCoverageStages[stageIdx]; }
skia.committer@gmail.com05a2ee02013-04-02 07:01:34 +0000342
commit-bot@chromium.orgbb5c4652013-04-01 12:49:31 +0000343 /**
344 * Checks whether any of the effects will read the dst pixel color.
345 */
bsalomon@google.comd09ab842013-05-15 17:30:26 +0000346 bool willEffectReadDstColor() const;
reed@google.com67e7cde2013-03-20 17:47:16 +0000347
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000348 /// @}
349
350 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000351 /// @name Blending
352 ////
353
354 /**
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000355 * Sets the blending function coefficients.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000356 *
357 * The blend function will be:
358 * D' = sat(S*srcCoef + D*dstCoef)
359 *
360 * where D is the existing destination color, S is the incoming source
361 * color, and D' is the new destination color that will be written. sat()
362 * is the saturation function.
363 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000364 * @param srcCoef coefficient applied to the src color.
365 * @param dstCoef coefficient applied to the dst color.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000366 */
367 void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
egdaniel776bdbd2014-08-06 11:07:02 -0700368 fState.fSrcBlend = srcCoeff;
369 fState.fDstBlend = dstCoeff;
egdaniel9514d242014-07-18 06:15:43 -0700370 this->invalidateBlendOptFlags();
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000371 #ifdef SK_DEBUG
commit-bot@chromium.org24ab3b02013-08-14 21:56:37 +0000372 if (GrBlendCoeffRefsDst(dstCoeff)) {
373 GrPrintf("Unexpected dst blend coeff. Won't work correctly with coverage stages.\n");
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000374 }
commit-bot@chromium.org24ab3b02013-08-14 21:56:37 +0000375 if (GrBlendCoeffRefsSrc(srcCoeff)) {
376 GrPrintf("Unexpected src blend coeff. Won't work correctly with coverage stages.\n");
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000377 }
378 #endif
379 }
380
egdaniel776bdbd2014-08-06 11:07:02 -0700381 GrBlendCoeff getSrcBlendCoeff() const { return fState.fSrcBlend; }
382 GrBlendCoeff getDstBlendCoeff() const { return fState.fDstBlend; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000383
384 void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
385 GrBlendCoeff* dstBlendCoeff) const {
egdaniel776bdbd2014-08-06 11:07:02 -0700386 *srcBlendCoeff = fState.fSrcBlend;
387 *dstBlendCoeff = fState.fDstBlend;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000388 }
389
390 /**
391 * Sets the blending function constant referenced by the following blending
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000392 * coefficients:
bsalomon@google.com47059542012-06-06 20:51:20 +0000393 * kConstC_GrBlendCoeff
394 * kIConstC_GrBlendCoeff
395 * kConstA_GrBlendCoeff
396 * kIConstA_GrBlendCoeff
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000397 *
398 * @param constant the constant to set
399 */
egdaniel9514d242014-07-18 06:15:43 -0700400 void setBlendConstant(GrColor constant) {
401 fBlendConstant = constant;
402 this->invalidateBlendOptFlags();
403 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000404
405 /**
406 * Retrieves the last value set by setBlendConstant()
407 * @return the blending constant value
408 */
bsalomon2ed5ef82014-07-07 08:44:05 -0700409 GrColor getBlendConstant() const { return fBlendConstant; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000410
bsalomon@google.com2b446732013-02-12 16:47:41 +0000411 /**
412 * Determines whether multiplying the computed per-pixel color by the pixel's fractional
413 * coverage before the blend will give the correct final destination color. In general it
414 * will not as coverage is applied after blending.
415 */
416 bool canTweakAlphaForCoverage() const;
417
418 /**
419 * Optimizations for blending / coverage to that can be applied based on the current state.
420 */
421 enum BlendOptFlags {
422 /**
423 * No optimization
424 */
425 kNone_BlendOpt = 0,
426 /**
427 * Don't draw at all
428 */
429 kSkipDraw_BlendOptFlag = 0x1,
430 /**
bsalomon@google.com2b446732013-02-12 16:47:41 +0000431 * The coverage value does not have to be computed separately from alpha, the the output
432 * color can be the modulation of the two.
433 */
egdaniel0f1a7c42014-07-30 13:18:32 -0700434 kCoverageAsAlpha_BlendOptFlag = 0x2,
bsalomon@google.com2b446732013-02-12 16:47:41 +0000435 /**
436 * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are
437 * "don't cares".
438 */
egdaniel0f1a7c42014-07-30 13:18:32 -0700439 kEmitCoverage_BlendOptFlag = 0x4,
bsalomon@google.com2b446732013-02-12 16:47:41 +0000440 /**
441 * Emit transparent black instead of the src color, no need to compute coverage.
442 */
egdaniel0f1a7c42014-07-30 13:18:32 -0700443 kEmitTransBlack_BlendOptFlag = 0x8,
egdaniel9514d242014-07-18 06:15:43 -0700444 /**
445 * Flag used to invalidate the cached BlendOptFlags, OptSrcCoeff, and OptDstCoeff cached by
446 * the get BlendOpts function.
447 */
egdaniel0f1a7c42014-07-30 13:18:32 -0700448 kInvalid_BlendOptFlag = 1 << 31,
bsalomon@google.com2b446732013-02-12 16:47:41 +0000449 };
450 GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
451
egdaniel9514d242014-07-18 06:15:43 -0700452 void invalidateBlendOptFlags() {
453 fBlendOptFlags = kInvalid_BlendOptFlag;
454 }
455
bsalomon@google.com2b446732013-02-12 16:47:41 +0000456 /**
egdaniel02cafcc2014-07-21 11:37:28 -0700457 * We don't use suplied vertex color attributes if our blend mode is EmitCoverage or
458 * EmitTransBlack
459 */
460 bool canIgnoreColorAttribute() const;
461
462 /**
bsalomon@google.com2b446732013-02-12 16:47:41 +0000463 * Determines what optimizations can be applied based on the blend. The coefficients may have
464 * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional
465 * params that receive the tweaked coefficients. Normally the function looks at the current
466 * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively
467 * determine the blend optimizations that would be used if there was partial pixel coverage.
468 *
469 * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for
470 * playback) must call this function and respect the flags that replace the output color.
egdaniel9514d242014-07-18 06:15:43 -0700471 *
472 * If the cached BlendOptFlags does not have the invalidate bit set, then getBlendOpts will
473 * simply returned the cached flags and coefficients. Otherwise it will calculate the values.
bsalomon@google.com2b446732013-02-12 16:47:41 +0000474 */
475 BlendOptFlags getBlendOpts(bool forceCoverage = false,
476 GrBlendCoeff* srcCoeff = NULL,
477 GrBlendCoeff* dstCoeff = NULL) const;
478
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000479 /// @}
480
481 ///////////////////////////////////////////////////////////////////////////
482 /// @name View Matrix
483 ////
484
485 /**
bsalomon@google.com137f1342013-05-29 21:27:53 +0000486 * Sets the view matrix to identity and updates any installed effects to compensate for the
487 * coord system change.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000488 */
bsalomon@google.com137f1342013-05-29 21:27:53 +0000489 bool setIdentityViewMatrix();
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000490
491 /**
492 * Retrieves the current view matrix
493 * @return the current view matrix.
494 */
bsalomon2ed5ef82014-07-07 08:44:05 -0700495 const SkMatrix& getViewMatrix() const { return fViewMatrix; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000496
497 /**
498 * Retrieves the inverse of the current view matrix.
499 *
500 * If the current view matrix is invertible, return true, and if matrix
501 * is non-null, copy the inverse into it. If the current view matrix is
502 * non-invertible, return false and ignore the matrix parameter.
503 *
504 * @param matrix if not null, will receive a copy of the current inverse.
505 */
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000506 bool getViewInverse(SkMatrix* matrix) const {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000507 // TODO: determine whether we really need to leave matrix unmodified
508 // at call sites when inversion fails.
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000509 SkMatrix inverse;
bsalomon2ed5ef82014-07-07 08:44:05 -0700510 if (fViewMatrix.invert(&inverse)) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000511 if (matrix) {
512 *matrix = inverse;
513 }
514 return true;
515 }
516 return false;
517 }
518
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000519 ////////////////////////////////////////////////////////////////////////////
520
521 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000522 * Preconcats the current view matrix and restores the previous view matrix in the destructor.
bsalomon@google.com137f1342013-05-29 21:27:53 +0000523 * Effect matrices are automatically adjusted to compensate and adjusted back in the destructor.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000524 */
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +0000525 class AutoViewMatrixRestore : public ::SkNoncopyable {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000526 public:
527 AutoViewMatrixRestore() : fDrawState(NULL) {}
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000528
bsalomon@google.comc7818882013-03-20 19:19:53 +0000529 AutoViewMatrixRestore(GrDrawState* ds, const SkMatrix& preconcatMatrix) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000530 fDrawState = NULL;
bsalomon@google.comc7818882013-03-20 19:19:53 +0000531 this->set(ds, preconcatMatrix);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000532 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000533
534 ~AutoViewMatrixRestore() { this->restore(); }
535
bsalomon@google.coma8347462012-10-08 18:59:39 +0000536 /**
537 * Can be called prior to destructor to restore the original matrix.
538 */
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000539 void restore();
skia.committer@gmail.comf467ce72012-10-09 02:01:37 +0000540
bsalomon@google.comc7818882013-03-20 19:19:53 +0000541 void set(GrDrawState* drawState, const SkMatrix& preconcatMatrix);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000542
bsalomon@google.com137f1342013-05-29 21:27:53 +0000543 /** Sets the draw state's matrix to identity. This can fail because the current view matrix
544 is not invertible. */
545 bool setIdentity(GrDrawState* drawState);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000546
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000547 private:
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000548 void doEffectCoordChanges(const SkMatrix& coordChangeMatrix);
549
550 GrDrawState* fDrawState;
551 SkMatrix fViewMatrix;
552 int fNumColorStages;
553 SkAutoSTArray<8, GrEffectStage::SavedCoordChange> fSavedCoordChanges;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000554 };
555
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000556 /// @}
557
558 ///////////////////////////////////////////////////////////////////////////
559 /// @name Render Target
560 ////
561
562 /**
bsalomon@google.comca432082013-01-23 19:53:46 +0000563 * Sets the render-target used at the next drawing call
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000564 *
565 * @param target The render target to set.
566 */
bsalomon62c447d2014-08-08 08:08:50 -0700567 void setRenderTarget(GrRenderTarget* target) { fRenderTarget.reset(SkSafeRef(target)); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000568
569 /**
bsalomon@google.comca432082013-01-23 19:53:46 +0000570 * Retrieves the currently set render-target.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000571 *
572 * @return The currently set render target.
573 */
bsalomon@google.comca432082013-01-23 19:53:46 +0000574 const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
575 GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000576
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +0000577 class AutoRenderTargetRestore : public ::SkNoncopyable {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000578 public:
bsalomon@google.comcadbcb82012-01-06 19:22:11 +0000579 AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000580 AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
581 fDrawState = NULL;
robertphillips@google.com7460b372012-04-25 16:54:51 +0000582 fSavedTarget = NULL;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000583 this->set(ds, newTarget);
584 }
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000585 ~AutoRenderTargetRestore() { this->restore(); }
586
587 void restore() {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000588 if (NULL != fDrawState) {
589 fDrawState->setRenderTarget(fSavedTarget);
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000590 fDrawState = NULL;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000591 }
commit-bot@chromium.orga4de8c22013-09-09 13:38:37 +0000592 SkSafeSetNull(fSavedTarget);
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000593 }
594
595 void set(GrDrawState* ds, GrRenderTarget* newTarget) {
596 this->restore();
597
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000598 if (NULL != ds) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000599 SkASSERT(NULL == fSavedTarget);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000600 fSavedTarget = ds->getRenderTarget();
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000601 SkSafeRef(fSavedTarget);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000602 ds->setRenderTarget(newTarget);
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000603 fDrawState = ds;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000604 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000605 }
606 private:
607 GrDrawState* fDrawState;
608 GrRenderTarget* fSavedTarget;
609 };
610
611 /// @}
612
613 ///////////////////////////////////////////////////////////////////////////
614 /// @name Stencil
615 ////
616
617 /**
618 * Sets the stencil settings to use for the next draw.
619 * Changing the clip has the side-effect of possibly zeroing
620 * out the client settable stencil bits. So multipass algorithms
621 * using stencil should not change the clip between passes.
622 * @param settings the stencil settings to use.
623 */
624 void setStencil(const GrStencilSettings& settings) {
bsalomon2ed5ef82014-07-07 08:44:05 -0700625 fStencilSettings = settings;
egdaniel9514d242014-07-18 06:15:43 -0700626 this->invalidateBlendOptFlags();
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000627 }
628
629 /**
630 * Shortcut to disable stencil testing and ops.
631 */
632 void disableStencil() {
bsalomon2ed5ef82014-07-07 08:44:05 -0700633 fStencilSettings.setDisabled();
egdaniel9514d242014-07-18 06:15:43 -0700634 this->invalidateBlendOptFlags();
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000635 }
636
bsalomon2ed5ef82014-07-07 08:44:05 -0700637 const GrStencilSettings& getStencil() const { return fStencilSettings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000638
bsalomon2ed5ef82014-07-07 08:44:05 -0700639 GrStencilSettings* stencil() { return &fStencilSettings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000640
641 /// @}
642
643 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000644 /// @name State Flags
645 ////
tomhudson@google.com62b09682011-11-09 16:39:17 +0000646
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000647 /**
648 * Flags that affect rendering. Controlled using enable/disableState(). All
649 * default to disabled.
650 */
651 enum StateBits {
652 /**
653 * Perform dithering. TODO: Re-evaluate whether we need this bit
654 */
655 kDither_StateBit = 0x01,
656 /**
bsalomon@google.comcf939ae2012-12-13 19:59:23 +0000657 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
658 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
659 * the 3D API.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000660 */
661 kHWAntialias_StateBit = 0x02,
662 /**
663 * Draws will respect the clip, otherwise the clip is ignored.
664 */
665 kClip_StateBit = 0x04,
666 /**
667 * Disables writing to the color buffer. Useful when performing stencil
668 * operations.
669 */
670 kNoColorWrites_StateBit = 0x08,
bsalomon@google.com0342a852012-08-20 19:22:38 +0000671
bsalomon@google.comcf939ae2012-12-13 19:59:23 +0000672 /**
673 * Usually coverage is applied after color blending. The color is blended using the coeffs
674 * specified by setBlendFunc(). The blended color is then combined with dst using coeffs
675 * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In
676 * this case there is no distinction between coverage and color and the caller needs direct
677 * control over the blend coeffs. When set, there will be a single blend step controlled by
678 * setBlendFunc() which will use coverage*color as the src color.
679 */
680 kCoverageDrawing_StateBit = 0x10,
681
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000682 // Users of the class may add additional bits to the vector
683 kDummyStateBit,
684 kLastPublicStateBit = kDummyStateBit-1,
685 };
686
687 void resetStateFlags() {
bsalomon2ed5ef82014-07-07 08:44:05 -0700688 fFlagBits = 0;
egdaniel9514d242014-07-18 06:15:43 -0700689 this->invalidateBlendOptFlags();
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000690 }
691
692 /**
693 * Enable render state settings.
694 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000695 * @param stateBits bitfield of StateBits specifying the states to enable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000696 */
697 void enableState(uint32_t stateBits) {
bsalomon2ed5ef82014-07-07 08:44:05 -0700698 fFlagBits |= stateBits;
egdaniel9514d242014-07-18 06:15:43 -0700699 this->invalidateBlendOptFlags();
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000700 }
701
702 /**
703 * Disable render state settings.
704 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000705 * @param stateBits bitfield of StateBits specifying the states to disable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000706 */
707 void disableState(uint32_t stateBits) {
bsalomon2ed5ef82014-07-07 08:44:05 -0700708 fFlagBits &= ~(stateBits);
egdaniel9514d242014-07-18 06:15:43 -0700709 this->invalidateBlendOptFlags();
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000710 }
711
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000712 /**
713 * Enable or disable stateBits based on a boolean.
714 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000715 * @param stateBits bitfield of StateBits to enable or disable
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000716 * @param enable if true enable stateBits, otherwise disable
717 */
718 void setState(uint32_t stateBits, bool enable) {
719 if (enable) {
720 this->enableState(stateBits);
721 } else {
722 this->disableState(stateBits);
723 }
724 }
725
bsalomon62c447d2014-08-08 08:08:50 -0700726 bool isStateFlagEnabled(uint32_t stateBit) const { return 0 != (stateBit & fFlagBits); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000727
bsalomon62c447d2014-08-08 08:08:50 -0700728 bool isDitherState() const { return 0 != (fFlagBits & kDither_StateBit); }
729 bool isHWAntialiasState() const { return 0 != (fFlagBits & kHWAntialias_StateBit); }
730 bool isClipState() const { return 0 != (fFlagBits & kClip_StateBit); }
731 bool isColorWriteDisabled() const { return 0 != (fFlagBits & kNoColorWrites_StateBit); }
732 bool isCoverageDrawing() const { return 0 != (fFlagBits & kCoverageDrawing_StateBit); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000733
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000734 /// @}
735
736 ///////////////////////////////////////////////////////////////////////////
737 /// @name Face Culling
738 ////
739
740 enum DrawFace {
bsalomon@google.com978c8c62012-05-21 14:45:49 +0000741 kInvalid_DrawFace = -1,
742
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000743 kBoth_DrawFace,
744 kCCW_DrawFace,
745 kCW_DrawFace,
746 };
747
748 /**
749 * Controls whether clockwise, counterclockwise, or both faces are drawn.
750 * @param face the face(s) to draw.
751 */
752 void setDrawFace(DrawFace face) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000753 SkASSERT(kInvalid_DrawFace != face);
bsalomon2ed5ef82014-07-07 08:44:05 -0700754 fDrawFace = face;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000755 }
756
757 /**
758 * Gets whether the target is drawing clockwise, counterclockwise,
759 * or both faces.
760 * @return the current draw face(s).
761 */
bsalomon2ed5ef82014-07-07 08:44:05 -0700762 DrawFace getDrawFace() const { return fDrawFace; }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000763
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000764 /// @}
765
766 ///////////////////////////////////////////////////////////////////////////
bsalomon62c447d2014-08-08 08:08:50 -0700767 /// @name Hints
768 /// Hints that when provided can enable optimizations.
769 ////
770
771 enum Hints { kVertexColorsAreOpaque_Hint = 0x1, };
772
773 void setHint(Hints hint, bool value) { fHints = value ? (fHints | hint) : (fHints & ~hint); }
774
775 /// @}
776
777 ///////////////////////////////////////////////////////////////////////////
tomhudson@google.com62b09682011-11-09 16:39:17 +0000778
bsalomon838f62d2014-08-05 07:15:57 -0700779 /** Return type for CombineIfPossible. */
780 enum CombinedState {
781 /** The GrDrawStates cannot be combined. */
782 kIncompatible_CombinedState,
783 /** Either draw state can be used in place of the other. */
784 kAOrB_CombinedState,
785 /** Use the first draw state. */
786 kA_CombinedState,
787 /** Use the second draw state. */
788 kB_CombinedState,
789 };
790
791 /** This function determines whether the GrDrawStates used for two draws can be combined into
792 a single GrDrawState. This is used to avoid storing redundant GrDrawStates and to determine
793 if draws can be batched. The return value indicates whether combining is possible and, if
794 so, which of the two inputs should be used. */
bsalomon62c447d2014-08-08 08:08:50 -0700795 static CombinedState CombineIfPossible(const GrDrawState& a, const GrDrawState& b,
796 const GrDrawTargetCaps& caps);
bsalomon72336ed2014-08-05 07:35:56 -0700797
bsalomon8f727332014-08-05 07:50:06 -0700798 GrDrawState& operator= (const GrDrawState& that);
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000799
800private:
bsalomon8f727332014-08-05 07:50:06 -0700801 void onReset(const SkMatrix* initialViewMatrix);
bsalomon@google.com137f1342013-05-29 21:27:53 +0000802
egdaniel9514d242014-07-18 06:15:43 -0700803 BlendOptFlags calcBlendOpts(bool forceCoverage = false,
bsalomon62c447d2014-08-08 08:08:50 -0700804 GrBlendCoeff* srcCoeff = NULL,
805 GrBlendCoeff* dstCoeff = NULL) const;
jvanverth@google.com054ae992013-04-01 20:06:51 +0000806
bsalomon2ed5ef82014-07-07 08:44:05 -0700807 // These fields are roughly sorted by decreasing likelihood of being different in op==
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000808 SkAutoTUnref<GrRenderTarget> fRenderTarget;
bsalomon2ed5ef82014-07-07 08:44:05 -0700809 GrColor fColor;
810 SkMatrix fViewMatrix;
bsalomon2ed5ef82014-07-07 08:44:05 -0700811 GrColor fBlendConstant;
812 uint32_t fFlagBits;
813 const GrVertexAttrib* fVAPtr;
814 int fVACount;
815 GrStencilSettings fStencilSettings;
816 GrColor fCoverage;
817 DrawFace fDrawFace;
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000818
egdaniel776bdbd2014-08-06 11:07:02 -0700819 State fState;
bsalomon62c447d2014-08-08 08:08:50 -0700820
821 uint32_t fHints;
egdaniel9514d242014-07-18 06:15:43 -0700822
bsalomon62c447d2014-08-08 08:08:50 -0700823 mutable GrBlendCoeff fOptSrcBlend;
824 mutable GrBlendCoeff fOptDstBlend;
825 mutable BlendOptFlags fBlendOptFlags;
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000826
bsalomon2ed5ef82014-07-07 08:44:05 -0700827 // This is simply a different representation of info in fVertexAttribs and thus does
828 // not need to be compared in op==.
829 int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt];
830
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000831 // Some of the auto restore objects assume that no effects are removed during their lifetime.
832 // This is used to assert that this condition holds.
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +0000833 SkDEBUGCODE(int fBlockEffectRemovalCnt;)
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000834
robertphillips@google.com42903302013-04-20 12:26:07 +0000835 /**
836 * Sets vertex attributes for next draw.
837 *
838 * @param attribs the array of vertex attributes to set.
839 * @param count the number of attributes being set, limited to kMaxVertexAttribCnt.
840 */
841 void setVertexAttribs(const GrVertexAttrib attribs[], int count);
842
commit-bot@chromium.orga4de8c22013-09-09 13:38:37 +0000843 typedef SkRefCnt INHERITED;
tomhudson@google.com93813632011-10-27 20:21:16 +0000844};
845
bsalomon@google.com2b446732013-02-12 16:47:41 +0000846GR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags);
847
tomhudson@google.com93813632011-10-27 20:21:16 +0000848#endif