blob: a049f1d8071e725d9dc96a3a1ac5b09a1c9dadbf [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
egdaniel89af44a2014-09-26 06:15:04 -070011
commit-bot@chromium.org24ab3b02013-08-14 21:56:37 +000012#include "GrBlend.h"
egdanielc0648242014-09-22 13:17:02 -070013#include "GrDrawTargetCaps.h"
bsalomon6251d172014-10-15 10:50:36 -070014#include "GrGeometryProcessor.h"
bsalomonf96ba022014-09-17 08:05:40 -070015#include "GrGpuResourceRef.h"
bsalomonae59b772014-11-19 08:23:49 -080016#include "GrFragmentStage.h"
egdanielb6cbc382014-11-13 11:00:34 -080017#include "GrProcOptInfo.h"
egdaniel89af44a2014-09-26 06:15:04 -070018#include "GrRenderTarget.h"
19#include "GrStencil.h"
20#include "SkMatrix.h"
bsalomon@google.com68b58c92013-01-17 16:50:08 +000021#include "effects/GrSimpleTextureEffect.h"
tomhudson@google.com93813632011-10-27 20:21:16 +000022
egdaniel89af44a2014-09-26 06:15:04 -070023class GrDrawTargetCaps;
egdaniel89af44a2014-09-26 06:15:04 -070024class GrPaint;
25class GrTexture;
egdaniel170f90b2014-09-16 12:54:40 -070026
joshualitt9853cce2014-11-17 14:22:48 -080027class GrDrawState {
bsalomon@google.com2e3d1442012-03-26 20:33:54 +000028public:
egdaniel69bb90c2014-11-11 07:32:45 -080029 GrDrawState() {
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +000030 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
bsalomon@google.comeb6879f2013-06-13 19:34:18 +000031 this->reset();
32 }
tomhudson@google.com93813632011-10-27 20:21:16 +000033
egdaniel69bb90c2014-11-11 07:32:45 -080034 GrDrawState(const SkMatrix& initialViewMatrix) {
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +000035 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
bsalomon@google.comeb6879f2013-06-13 19:34:18 +000036 this->reset(initialViewMatrix);
37 }
bsalomon@google.com137f1342013-05-29 21:27:53 +000038
39 /**
40 * Copies another draw state.
41 **/
joshualitt9853cce2014-11-17 14:22:48 -080042 GrDrawState(const GrDrawState& state) {
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +000043 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
bsalomon@google.com46f7afb2012-01-18 19:51:55 +000044 *this = state;
45 }
46
bsalomon@google.com137f1342013-05-29 21:27:53 +000047 /**
48 * Copies another draw state with a preconcat to the view matrix.
49 **/
bsalomon8f727332014-08-05 07:50:06 -070050 GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix);
robertphillips@google.com9ec07532012-06-22 12:01:30 +000051
egdaniel170f90b2014-09-16 12:54:40 -070052 virtual ~GrDrawState();
bsalomon@google.com137f1342013-05-29 21:27:53 +000053
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000054 /**
joshualittb0a8a372014-09-23 09:50:21 -070055 * Resets to the default state. GrProcessors will be removed from all stages.
rmistry@google.comd6176b02012-08-23 18:14:13 +000056 */
bsalomon@google.com137f1342013-05-29 21:27:53 +000057 void reset() { this->onReset(NULL); }
robertphillips@google.com9ec07532012-06-22 12:01:30 +000058
bsalomon@google.com137f1342013-05-29 21:27:53 +000059 void reset(const SkMatrix& initialViewMatrix) { this->onReset(&initialViewMatrix); }
bsalomon@google.comaf84e742012-10-05 13:23:24 +000060
61 /**
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +000062 * Initializes the GrDrawState based on a GrPaint, view matrix and render target. Note that
63 * GrDrawState encompasses more than GrPaint. Aspects of GrDrawState that have no GrPaint
bsalomon9c0822a2014-08-11 11:07:48 -070064 * equivalents are set to default values with the exception of vertex attribute state which
65 * is unmodified by this function and clipping which will be enabled.
bsalomon@google.comaf84e742012-10-05 13:23:24 +000066 */
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +000067 void setFromPaint(const GrPaint& , const SkMatrix& viewMatrix, GrRenderTarget*);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000068
69 ///////////////////////////////////////////////////////////////////////////
jvanverth@google.com9b855c72013-03-01 18:21:22 +000070 /// @name Vertex Attributes
jvanverth@google.comcc782382013-01-28 20:39:48 +000071 ////
72
egdaniel89af44a2014-09-26 06:15:04 -070073 enum {
74 kMaxVertexAttribCnt = kLast_GrVertexAttribBinding + 4,
75 };
76
77 const GrVertexAttrib* getVertexAttribs() const { return fVAPtr; }
78 int getVertexAttribCount() const { return fVACount; }
79
80 size_t getVertexStride() const { return fVAStride; }
81
82 bool hasLocalCoordAttribute() const {
83 return -1 != fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
84 }
85 bool hasColorVertexAttribute() const {
86 return -1 != fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
87 }
88 bool hasCoverageVertexAttribute() const {
89 return -1 != fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
90 }
91
92 const int* getFixedFunctionVertexAttribIndices() const {
93 return fFixedFunctionVertexAttribIndices;
94 }
95
96 bool validateVertexAttribs() const;
97
jvanverth@google.com9b855c72013-03-01 18:21:22 +000098 /**
jvanverth@google.com054ae992013-04-01 20:06:51 +000099 * The format of vertices is represented as an array of GrVertexAttribs, with each representing
100 * the type of the attribute, its offset, and semantic binding (see GrVertexAttrib in
101 * GrTypesPriv.h).
jvanverth@google.comb8b705b2013-02-28 16:28:34 +0000102 *
joshualittb0a8a372014-09-23 09:50:21 -0700103 * The mapping of attributes with kEffect bindings to GrProcessor inputs is specified when
jvanverth@google.com054ae992013-04-01 20:06:51 +0000104 * setEffect is called.
jvanverth@google.comb8b705b2013-02-28 16:28:34 +0000105 */
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000106
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000107 /**
robertphillips@google.com42903302013-04-20 12:26:07 +0000108 * Sets vertex attributes for next draw. The object driving the templatization
109 * should be a global GrVertexAttrib array that is never changed.
egdaniel7b3d5ee2014-08-28 05:41:14 -0700110 *
111 * @param count the number of attributes being set, limited to kMaxVertexAttribCnt.
112 * @param stride the number of bytes between successive vertex data.
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000113 */
egdaniel7b3d5ee2014-08-28 05:41:14 -0700114 template <const GrVertexAttrib A[]> void setVertexAttribs(int count, size_t stride) {
115 this->internalSetVertexAttribs(A, count, stride);
robertphillips@google.com42903302013-04-20 12:26:07 +0000116 }
jvanverth@google.comb8b705b2013-02-28 16:28:34 +0000117
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000118 /**
jvanverth@google.com054ae992013-04-01 20:06:51 +0000119 * Sets default vertex attributes for next draw. The default is a single attribute:
120 * {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribType}
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000121 */
122 void setDefaultVertexAttribs();
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000123
jvanverth@google.com054ae992013-04-01 20:06:51 +0000124 /**
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000125 * Helper to save/restore vertex attribs
126 */
127 class AutoVertexAttribRestore {
128 public:
bsalomon8f727332014-08-05 07:50:06 -0700129 AutoVertexAttribRestore(GrDrawState* drawState);
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000130
egdaniel3658f382014-09-15 07:01:59 -0700131 ~AutoVertexAttribRestore() { fDrawState->internalSetVertexAttribs(fVAPtr, fVACount,
132 fVAStride); }
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000133
134 private:
robertphillips@google.com42903302013-04-20 12:26:07 +0000135 GrDrawState* fDrawState;
136 const GrVertexAttrib* fVAPtr;
137 int fVACount;
egdaniel7b3d5ee2014-08-28 05:41:14 -0700138 size_t fVAStride;
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000139 };
140
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000141 /// @}
142
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000143 /**
bsalomon62c447d2014-08-08 08:08:50 -0700144 * Depending on features available in the underlying 3D API and the color blend mode requested
145 * it may or may not be possible to correctly blend with fractional pixel coverage generated by
146 * the fragment shader.
147 *
148 * This function considers the current draw state and the draw target's capabilities to
149 * determine whether coverage can be handled correctly. This function assumes that the caller
150 * intends to specify fractional pixel coverage (via setCoverage(), through a coverage vertex
151 * attribute, or a coverage effect) but may not have specified it yet.
152 */
153 bool couldApplyCoverage(const GrDrawTargetCaps& caps) const;
154
egdaniel89af44a2014-09-26 06:15:04 -0700155 /**
156 * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
157 */
158 bool hasSolidCoverage() const;
159
egdanielcd8b6302014-11-11 14:46:05 -0800160 /**
161 * This function returns true if the render target destination pixel values will be read for
162 * blending during draw.
163 */
164 bool willBlendWithDst() const;
165
jvanverth@google.comcc782382013-01-28 20:39:48 +0000166 /// @}
167
168 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000169 /// @name Color
170 ////
171
egdaniel89af44a2014-09-26 06:15:04 -0700172 GrColor getColor() const { return fColor; }
173
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000174 /**
175 * Sets color for next draw to a premultiplied-alpha color.
176 *
177 * @param color the color to set.
178 */
egdaniel9514d242014-07-18 06:15:43 -0700179 void setColor(GrColor color) {
egdaniel3658f382014-09-15 07:01:59 -0700180 if (color != fColor) {
181 fColor = color;
egdanielb6cbc382014-11-13 11:00:34 -0800182 fColorProcInfoValid = false;
egdaniel3658f382014-09-15 07:01:59 -0700183 }
egdaniel9514d242014-07-18 06:15:43 -0700184 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000185
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000186 /**
187 * Sets the color to be used for the next draw to be
188 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
189 *
190 * @param alpha The alpha value to set as the color.
191 */
bsalomon62c447d2014-08-08 08:08:50 -0700192 void setAlpha(uint8_t a) { this->setColor((a << 24) | (a << 16) | (a << 8) | a); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000193
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000194 /// @}
195
196 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000197 /// @name Coverage
198 ////
199
egdaniel89af44a2014-09-26 06:15:04 -0700200 uint8_t getCoverage() const { return fCoverage; }
201
202 GrColor getCoverageColor() const {
203 return GrColorPackRGBA(fCoverage, fCoverage, fCoverage, fCoverage);
204 }
205
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000206 /**
rmistry@google.comd6176b02012-08-23 18:14:13 +0000207 * Sets a constant fractional coverage to be applied to the draw. The
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000208 * initial value (after construction or reset()) is 0xff. The constant
209 * coverage is ignored when per-vertex coverage is provided.
210 */
211 void setCoverage(uint8_t coverage) {
egdaniel3658f382014-09-15 07:01:59 -0700212 if (coverage != fCoverage) {
213 fCoverage = coverage;
egdanielb6cbc382014-11-13 11:00:34 -0800214 fCoverageProcInfoValid = false;
egdaniel3658f382014-09-15 07:01:59 -0700215 }
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000216 }
217
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000218 /// @}
219
joshualittbd769d02014-09-04 08:56:46 -0700220 /**
221 * The geometry processor is the sole element of the skia pipeline which can use the vertex,
222 * geometry, and tesselation shaders. The GP may also compute a coverage in its fragment shader
223 * but is never put in the color processing pipeline.
224 */
225
joshualittb0a8a372014-09-23 09:50:21 -0700226 const GrGeometryProcessor* setGeometryProcessor(const GrGeometryProcessor* geometryProcessor) {
227 SkASSERT(geometryProcessor);
joshualittbd769d02014-09-04 08:56:46 -0700228 SkASSERT(!this->hasGeometryProcessor());
joshualitta5305a12014-10-10 17:47:00 -0700229 fGeometryProcessor.reset(SkRef(geometryProcessor));
egdanielb6cbc382014-11-13 11:00:34 -0800230 fCoverageProcInfoValid = false;
joshualittb0a8a372014-09-23 09:50:21 -0700231 return geometryProcessor;
joshualittbd769d02014-09-04 08:56:46 -0700232 }
233
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000234 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.comadc65362013-01-28 14:26:09 +0000235 /// @name Effect Stages
joshualittb0a8a372014-09-23 09:50:21 -0700236 /// Each stage hosts a GrProcessor. The effect produces an output color or coverage in the
237 /// fragment shader. Its inputs are the output from the previous stage as well as some variables
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000238 /// available to it in the fragment and vertex shader (e.g. the vertex position, the dst color,
239 /// the fragment position, local coordinates).
240 ///
241 /// The stages are divided into two sets, color-computing and coverage-computing. The final
242 /// color stage produces the final pixel color. The coverage-computing stages function exactly
243 /// as the color-computing but the output of the final coverage stage is treated as a fractional
244 /// pixel coverage rather than as input to the src/dst color blend step.
245 ///
246 /// The input color to the first color-stage is either the constant color or interpolated
247 /// per-vertex colors. The input to the first coverage stage is either a constant coverage
248 /// (usually full-coverage) or interpolated per-vertex coverage.
249 ///
250 /// See the documentation of kCoverageDrawing_StateBit for information about disabling the
251 /// the color / coverage distinction.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000252 ////
253
egdaniel89af44a2014-09-26 06:15:04 -0700254 int numColorStages() const { return fColorStages.count(); }
255 int numCoverageStages() const { return fCoverageStages.count(); }
joshualitt4dd99882014-11-11 08:51:30 -0800256 int numFragmentStages() const { return this->numColorStages() + this->numCoverageStages(); }
egdaniel89af44a2014-09-26 06:15:04 -0700257 int numTotalStages() const {
joshualitt4dd99882014-11-11 08:51:30 -0800258 return this->numFragmentStages() + (this->hasGeometryProcessor() ? 1 : 0);
egdaniel89af44a2014-09-26 06:15:04 -0700259 }
260
261 bool hasGeometryProcessor() const { return SkToBool(fGeometryProcessor.get()); }
joshualitta5305a12014-10-10 17:47:00 -0700262 const GrGeometryProcessor* getGeometryProcessor() const { return fGeometryProcessor.get(); }
egdaniel89af44a2014-09-26 06:15:04 -0700263 const GrFragmentStage& getColorStage(int idx) const { return fColorStages[idx]; }
264 const GrFragmentStage& getCoverageStage(int idx) const { return fCoverageStages[idx]; }
265
266 /**
267 * Checks whether any of the effects will read the dst pixel color.
268 */
269 bool willEffectReadDstColor() const;
270
joshualittb0a8a372014-09-23 09:50:21 -0700271 const GrFragmentProcessor* addColorProcessor(const GrFragmentProcessor* effect) {
bsalomon49f085d2014-09-05 13:34:00 -0700272 SkASSERT(effect);
joshualittb0a8a372014-09-23 09:50:21 -0700273 SkNEW_APPEND_TO_TARRAY(&fColorStages, GrFragmentStage, (effect));
egdanielb6cbc382014-11-13 11:00:34 -0800274 fColorProcInfoValid = false;
jvanverth@google.com65eb4d52013-03-19 18:51:02 +0000275 return effect;
276 }
skia.committer@gmail.com01c34ee2013-03-20 07:01:02 +0000277
joshualittb0a8a372014-09-23 09:50:21 -0700278 const GrFragmentProcessor* addCoverageProcessor(const GrFragmentProcessor* effect) {
bsalomon49f085d2014-09-05 13:34:00 -0700279 SkASSERT(effect);
joshualittb0a8a372014-09-23 09:50:21 -0700280 SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrFragmentStage, (effect));
egdanielb6cbc382014-11-13 11:00:34 -0800281 fCoverageProcInfoValid = false;
bsalomon@google.comadc65362013-01-28 14:26:09 +0000282 return effect;
283 }
284
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000285 /**
bsalomon@google.comc7818882013-03-20 19:19:53 +0000286 * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
tomhudson@google.com1e8f0162012-07-20 16:25:18 +0000287 */
joshualittb0a8a372014-09-23 09:50:21 -0700288 void addColorTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
289 this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000290 }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000291
joshualittb0a8a372014-09-23 09:50:21 -0700292 void addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
293 this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000294 }
295
joshualittb0a8a372014-09-23 09:50:21 -0700296 void addColorTextureProcessor(GrTexture* texture,
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000297 const SkMatrix& matrix,
298 const GrTextureParams& params) {
joshualittb0a8a372014-09-23 09:50:21 -0700299 this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
300 }
301
302 void addCoverageTextureProcessor(GrTexture* texture,
303 const SkMatrix& matrix,
304 const GrTextureParams& params) {
305 this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000306 }
tomhudson@google.com676e6602012-07-10 17:21:48 +0000307
robertphillips@google.com972265d2012-06-13 18:49:30 +0000308 /**
bsalomon9b536522014-09-05 09:18:51 -0700309 * When this object is destroyed it will remove any color/coverage effects from the draw state
310 * that were added after its constructor.
311 *
312 * This class has strange behavior around geometry processor. If there is a GP on the draw state
313 * it will assert that the GP is not modified until after the destructor of the ARE. If the
314 * draw state has a NULL GP when the ARE is constructed then it will reset it to null in the
315 * destructor.
316 *
317 * TODO: We'd prefer for the ARE to just save and restore the GP. However, this would add
318 * significant complexity to the multi-ref architecture for deferred drawing. Once GrDrawState
319 * and GrOptDrawState are fully separated then GrDrawState will never be in the deferred
320 * execution state and GrOptDrawState always will be (and will be immutable and therefore
321 * unable to have an ARE). At this point we can restore sanity and have the ARE save and restore
322 * the GP.
robertphillips@google.com972265d2012-06-13 18:49:30 +0000323 */
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +0000324 class AutoRestoreEffects : public ::SkNoncopyable {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000325 public:
bsalomon9b536522014-09-05 09:18:51 -0700326 AutoRestoreEffects()
327 : fDrawState(NULL)
bsalomon52e9d632014-09-05 12:23:12 -0700328 , fOriginalGPID(SK_InvalidUniqueID)
bsalomon9b536522014-09-05 09:18:51 -0700329 , fColorEffectCnt(0)
330 , fCoverageEffectCnt(0) {}
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000331
bsalomon9b536522014-09-05 09:18:51 -0700332 AutoRestoreEffects(GrDrawState* ds)
333 : fDrawState(NULL)
bsalomon52e9d632014-09-05 12:23:12 -0700334 , fOriginalGPID(SK_InvalidUniqueID)
bsalomon9b536522014-09-05 09:18:51 -0700335 , fColorEffectCnt(0)
336 , fCoverageEffectCnt(0) {
skia.committer@gmail.com5c493d52013-06-14 07:00:49 +0000337 this->set(ds);
robertphillips@google.comf09b87d2013-06-13 20:06:44 +0000338 }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000339
340 ~AutoRestoreEffects() { this->set(NULL); }
341
bsalomon8f727332014-08-05 07:50:06 -0700342 void set(GrDrawState* ds);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000343
bsalomon49f085d2014-09-05 13:34:00 -0700344 bool isSet() const { return SkToBool(fDrawState); }
bsalomon8af05232014-06-03 06:34:58 -0700345
robertphillips@google.com972265d2012-06-13 18:49:30 +0000346 private:
bsalomon9b536522014-09-05 09:18:51 -0700347 GrDrawState* fDrawState;
bsalomon52e9d632014-09-05 12:23:12 -0700348 uint32_t fOriginalGPID;
bsalomon9b536522014-09-05 09:18:51 -0700349 int fColorEffectCnt;
350 int fCoverageEffectCnt;
robertphillips@google.com972265d2012-06-13 18:49:30 +0000351 };
352
joshualitta58fe352014-10-27 08:39:00 -0700353 /**
354 * AutoRestoreStencil
355 *
356 * This simple struct saves and restores the stencil settings
357 */
358 class AutoRestoreStencil : public ::SkNoncopyable {
359 public:
360 AutoRestoreStencil() : fDrawState(NULL) {}
361
362 AutoRestoreStencil(GrDrawState* ds) : fDrawState(NULL) { this->set(ds); }
363
364 ~AutoRestoreStencil() { this->set(NULL); }
365
366 void set(GrDrawState* ds) {
367 if (fDrawState) {
368 fDrawState->setStencil(fStencilSettings);
369 }
370 fDrawState = ds;
371 if (ds) {
372 fStencilSettings = ds->getStencil();
373 }
374 }
375
376 bool isSet() const { return SkToBool(fDrawState); }
377
378 private:
379 GrDrawState* fDrawState;
380 GrStencilSettings fStencilSettings;
381 };
382
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000383 /// @}
384
385 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000386 /// @name Blending
387 ////
388
egdaniel89af44a2014-09-26 06:15:04 -0700389 GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
390 GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }
391
392 /**
393 * Retrieves the last value set by setBlendConstant()
394 * @return the blending constant value
395 */
396 GrColor getBlendConstant() const { return fBlendConstant; }
397
398 /**
399 * Determines whether multiplying the computed per-pixel color by the pixel's fractional
400 * coverage before the blend will give the correct final destination color. In general it
401 * will not as coverage is applied after blending.
402 */
403 bool canTweakAlphaForCoverage() const;
404
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000405 /**
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000406 * Sets the blending function coefficients.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000407 *
408 * The blend function will be:
409 * D' = sat(S*srcCoef + D*dstCoef)
410 *
411 * where D is the existing destination color, S is the incoming source
412 * color, and D' is the new destination color that will be written. sat()
413 * is the saturation function.
414 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000415 * @param srcCoef coefficient applied to the src color.
416 * @param dstCoef coefficient applied to the dst color.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000417 */
418 void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
bsalomon04ddf892014-11-19 12:36:22 -0800419 fSrcBlend = srcCoeff;
420 fDstBlend = dstCoeff;
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000421 #ifdef SK_DEBUG
commit-bot@chromium.org24ab3b02013-08-14 21:56:37 +0000422 if (GrBlendCoeffRefsDst(dstCoeff)) {
tfarina38406c82014-10-31 07:11:12 -0700423 SkDebugf("Unexpected dst blend coeff. Won't work correctly with coverage stages.\n");
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000424 }
commit-bot@chromium.org24ab3b02013-08-14 21:56:37 +0000425 if (GrBlendCoeffRefsSrc(srcCoeff)) {
tfarina38406c82014-10-31 07:11:12 -0700426 SkDebugf("Unexpected src blend coeff. Won't work correctly with coverage stages.\n");
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000427 }
428 #endif
429 }
430
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000431 /**
432 * Sets the blending function constant referenced by the following blending
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000433 * coefficients:
bsalomon@google.com47059542012-06-06 20:51:20 +0000434 * kConstC_GrBlendCoeff
435 * kIConstC_GrBlendCoeff
436 * kConstA_GrBlendCoeff
437 * kIConstA_GrBlendCoeff
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000438 *
439 * @param constant the constant to set
440 */
bsalomon04ddf892014-11-19 12:36:22 -0800441 void setBlendConstant(GrColor constant) { fBlendConstant = constant; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000442
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000443 /// @}
444
445 ///////////////////////////////////////////////////////////////////////////
446 /// @name View Matrix
447 ////
448
449 /**
egdaniel89af44a2014-09-26 06:15:04 -0700450 * Retrieves the current view matrix
451 * @return the current view matrix.
452 */
453 const SkMatrix& getViewMatrix() const { return fViewMatrix; }
454
455 /**
456 * Retrieves the inverse of the current view matrix.
457 *
458 * If the current view matrix is invertible, return true, and if matrix
459 * is non-null, copy the inverse into it. If the current view matrix is
460 * non-invertible, return false and ignore the matrix parameter.
461 *
462 * @param matrix if not null, will receive a copy of the current inverse.
463 */
464 bool getViewInverse(SkMatrix* matrix) const {
465 SkMatrix inverse;
466 if (fViewMatrix.invert(&inverse)) {
467 if (matrix) {
468 *matrix = inverse;
469 }
470 return true;
471 }
472 return false;
473 }
474
475 /**
bsalomon@google.com137f1342013-05-29 21:27:53 +0000476 * Sets the view matrix to identity and updates any installed effects to compensate for the
477 * coord system change.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000478 */
bsalomon@google.com137f1342013-05-29 21:27:53 +0000479 bool setIdentityViewMatrix();
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000480
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000481 ////////////////////////////////////////////////////////////////////////////
482
483 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000484 * Preconcats the current view matrix and restores the previous view matrix in the destructor.
bsalomon@google.com137f1342013-05-29 21:27:53 +0000485 * Effect matrices are automatically adjusted to compensate and adjusted back in the destructor.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000486 */
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +0000487 class AutoViewMatrixRestore : public ::SkNoncopyable {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000488 public:
489 AutoViewMatrixRestore() : fDrawState(NULL) {}
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000490
bsalomon@google.comc7818882013-03-20 19:19:53 +0000491 AutoViewMatrixRestore(GrDrawState* ds, const SkMatrix& preconcatMatrix) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000492 fDrawState = NULL;
bsalomon@google.comc7818882013-03-20 19:19:53 +0000493 this->set(ds, preconcatMatrix);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000494 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000495
496 ~AutoViewMatrixRestore() { this->restore(); }
497
bsalomon@google.coma8347462012-10-08 18:59:39 +0000498 /**
499 * Can be called prior to destructor to restore the original matrix.
500 */
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000501 void restore();
skia.committer@gmail.comf467ce72012-10-09 02:01:37 +0000502
bsalomon@google.comc7818882013-03-20 19:19:53 +0000503 void set(GrDrawState* drawState, const SkMatrix& preconcatMatrix);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000504
bsalomon@google.com137f1342013-05-29 21:27:53 +0000505 /** Sets the draw state's matrix to identity. This can fail because the current view matrix
506 is not invertible. */
507 bool setIdentity(GrDrawState* drawState);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000508
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000509 private:
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000510 void doEffectCoordChanges(const SkMatrix& coordChangeMatrix);
511
joshualittb0a8a372014-09-23 09:50:21 -0700512 GrDrawState* fDrawState;
513 SkMatrix fViewMatrix;
514 int fNumColorStages;
joshualitta5305a12014-10-10 17:47:00 -0700515 SkAutoSTArray<8, GrFragmentStage::SavedCoordChange> fSavedCoordChanges;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000516 };
517
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000518 /// @}
519
520 ///////////////////////////////////////////////////////////////////////////
521 /// @name Render Target
522 ////
523
524 /**
egdaniel89af44a2014-09-26 06:15:04 -0700525 * Retrieves the currently set render-target.
526 *
527 * @return The currently set render target.
528 */
bsalomon37dd3312014-11-03 08:47:23 -0800529 GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
egdaniel89af44a2014-09-26 06:15:04 -0700530
531 /**
bsalomon@google.comca432082013-01-23 19:53:46 +0000532 * Sets the render-target used at the next drawing call
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000533 *
534 * @param target The render target to set.
535 */
bsalomonae59b772014-11-19 08:23:49 -0800536 void setRenderTarget(GrRenderTarget* target) { fRenderTarget.reset(SkSafeRef(target)); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000537
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000538 /// @}
539
540 ///////////////////////////////////////////////////////////////////////////
541 /// @name Stencil
542 ////
543
egdaniel89af44a2014-09-26 06:15:04 -0700544 const GrStencilSettings& getStencil() const { return fStencilSettings; }
545
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000546 /**
547 * Sets the stencil settings to use for the next draw.
548 * Changing the clip has the side-effect of possibly zeroing
549 * out the client settable stencil bits. So multipass algorithms
550 * using stencil should not change the clip between passes.
551 * @param settings the stencil settings to use.
552 */
bsalomon04ddf892014-11-19 12:36:22 -0800553 void setStencil(const GrStencilSettings& settings) { fStencilSettings = settings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000554
555 /**
556 * Shortcut to disable stencil testing and ops.
557 */
bsalomon04ddf892014-11-19 12:36:22 -0800558 void disableStencil() { fStencilSettings.setDisabled(); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000559
bsalomon2ed5ef82014-07-07 08:44:05 -0700560 GrStencilSettings* stencil() { return &fStencilSettings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000561
562 /// @}
563
564 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000565 /// @name State Flags
566 ////
tomhudson@google.com62b09682011-11-09 16:39:17 +0000567
egdaniel89af44a2014-09-26 06:15:04 -0700568 /**
569 * Flags that affect rendering. Controlled using enable/disableState(). All
570 * default to disabled.
571 */
572 enum StateBits {
573 /**
574 * Perform dithering. TODO: Re-evaluate whether we need this bit
575 */
576 kDither_StateBit = 0x01,
577 /**
578 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
579 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
580 * the 3D API.
581 */
582 kHWAntialias_StateBit = 0x02,
583 /**
584 * Draws will respect the clip, otherwise the clip is ignored.
585 */
586 kClip_StateBit = 0x04,
587 /**
588 * Disables writing to the color buffer. Useful when performing stencil
589 * operations.
590 */
591 kNoColorWrites_StateBit = 0x08,
592
593 /**
594 * Usually coverage is applied after color blending. The color is blended using the coeffs
595 * specified by setBlendFunc(). The blended color is then combined with dst using coeffs
596 * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In
597 * this case there is no distinction between coverage and color and the caller needs direct
598 * control over the blend coeffs. When set, there will be a single blend step controlled by
599 * setBlendFunc() which will use coverage*color as the src color.
600 */
601 kCoverageDrawing_StateBit = 0x10,
joshualitt7a6184f2014-10-29 18:29:27 -0700602 kLast_StateBit = kCoverageDrawing_StateBit,
egdaniel89af44a2014-09-26 06:15:04 -0700603 };
604
egdaniel89af44a2014-09-26 06:15:04 -0700605 bool isClipState() const { return 0 != (fFlagBits & kClip_StateBit); }
606 bool isColorWriteDisabled() const { return 0 != (fFlagBits & kNoColorWrites_StateBit); }
607 bool isCoverageDrawing() const { return 0 != (fFlagBits & kCoverageDrawing_StateBit); }
bsalomon04ddf892014-11-19 12:36:22 -0800608 bool isDither() const { return 0 != (fFlagBits & kDither_StateBit); }
609 bool isHWAntialias() const { return 0 != (fFlagBits & kHWAntialias_StateBit); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000610
611 /**
612 * Enable render state settings.
613 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000614 * @param stateBits bitfield of StateBits specifying the states to enable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000615 */
bsalomon04ddf892014-11-19 12:36:22 -0800616 void enableState(uint32_t stateBits) { fFlagBits |= stateBits; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000617
618 /**
619 * Disable render state settings.
620 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000621 * @param stateBits bitfield of StateBits specifying the states to disable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000622 */
bsalomon04ddf892014-11-19 12:36:22 -0800623 void disableState(uint32_t stateBits) { fFlagBits &= ~(stateBits); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000624
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000625 /**
626 * Enable or disable stateBits based on a boolean.
627 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000628 * @param stateBits bitfield of StateBits to enable or disable
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000629 * @param enable if true enable stateBits, otherwise disable
630 */
631 void setState(uint32_t stateBits, bool enable) {
632 if (enable) {
633 this->enableState(stateBits);
634 } else {
635 this->disableState(stateBits);
636 }
637 }
638
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000639 /// @}
640
641 ///////////////////////////////////////////////////////////////////////////
642 /// @name Face Culling
643 ////
644
egdaniel89af44a2014-09-26 06:15:04 -0700645 enum DrawFace {
646 kInvalid_DrawFace = -1,
647
648 kBoth_DrawFace,
649 kCCW_DrawFace,
650 kCW_DrawFace,
651 };
652
653 /**
654 * Gets whether the target is drawing clockwise, counterclockwise,
655 * or both faces.
656 * @return the current draw face(s).
657 */
658 DrawFace getDrawFace() const { return fDrawFace; }
659
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000660 /**
661 * Controls whether clockwise, counterclockwise, or both faces are drawn.
662 * @param face the face(s) to draw.
663 */
664 void setDrawFace(DrawFace face) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000665 SkASSERT(kInvalid_DrawFace != face);
bsalomon2ed5ef82014-07-07 08:44:05 -0700666 fDrawFace = face;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000667 }
668
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000669 /// @}
670
671 ///////////////////////////////////////////////////////////////////////////
bsalomon62c447d2014-08-08 08:08:50 -0700672 /// @name Hints
673 /// Hints that when provided can enable optimizations.
674 ////
675
joshualitt65171342014-10-09 07:25:36 -0700676 enum Hints {
677 kVertexColorsAreOpaque_Hint = 0x1,
678 kLast_Hint = kVertexColorsAreOpaque_Hint
679 };
egdaniel89af44a2014-09-26 06:15:04 -0700680
bsalomon62c447d2014-08-08 08:08:50 -0700681 void setHint(Hints hint, bool value) { fHints = value ? (fHints | hint) : (fHints & ~hint); }
682
egdaniel89af44a2014-09-26 06:15:04 -0700683 bool vertexColorsAreOpaque() const { return kVertexColorsAreOpaque_Hint & fHints; }
684
bsalomon62c447d2014-08-08 08:08:50 -0700685 /// @}
686
687 ///////////////////////////////////////////////////////////////////////////
tomhudson@google.com62b09682011-11-09 16:39:17 +0000688
bsalomon8f727332014-08-05 07:50:06 -0700689 GrDrawState& operator= (const GrDrawState& that);
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000690
691private:
egdaniel89af44a2014-09-26 06:15:04 -0700692 bool isEqual(const GrDrawState& that) const;
693
694 /**
695 * Optimizations for blending / coverage to that can be applied based on the current state.
696 */
bsalomon04ddf892014-11-19 12:36:22 -0800697 enum BlendOpt {
egdaniel89af44a2014-09-26 06:15:04 -0700698 /**
699 * No optimization
700 */
bsalomon04ddf892014-11-19 12:36:22 -0800701 kNone_BlendOpt,
egdaniel89af44a2014-09-26 06:15:04 -0700702 /**
703 * Don't draw at all
704 */
bsalomon04ddf892014-11-19 12:36:22 -0800705 kSkipDraw_BlendOpt,
egdaniel89af44a2014-09-26 06:15:04 -0700706 /**
707 * The coverage value does not have to be computed separately from alpha, the the output
708 * color can be the modulation of the two.
709 */
bsalomon04ddf892014-11-19 12:36:22 -0800710 kCoverageAsAlpha_BlendOpt,
egdaniel89af44a2014-09-26 06:15:04 -0700711 /**
712 * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are
713 * "don't cares".
714 */
bsalomon04ddf892014-11-19 12:36:22 -0800715 kEmitCoverage_BlendOpt,
egdaniel89af44a2014-09-26 06:15:04 -0700716 /**
717 * Emit transparent black instead of the src color, no need to compute coverage.
718 */
bsalomon04ddf892014-11-19 12:36:22 -0800719 kEmitTransBlack_BlendOpt
egdaniel89af44a2014-09-26 06:15:04 -0700720 };
egdaniel89af44a2014-09-26 06:15:04 -0700721
722 /**
723 * Determines what optimizations can be applied based on the blend. The coefficients may have
724 * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional
725 * params that receive the tweaked coefficients. Normally the function looks at the current
726 * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively
727 * determine the blend optimizations that would be used if there was partial pixel coverage.
728 *
bsalomon04ddf892014-11-19 12:36:22 -0800729 * This is used internally and when constructing a GrOptDrawState.
egdaniel89af44a2014-09-26 06:15:04 -0700730 */
bsalomon04ddf892014-11-19 12:36:22 -0800731 BlendOpt getBlendOpt(bool forceCoverage = false,
732 GrBlendCoeff* srcCoeff = NULL,
733 GrBlendCoeff* dstCoeff = NULL) const;
egdaniel89af44a2014-09-26 06:15:04 -0700734
egdaniel912b3d22014-11-17 07:45:53 -0800735 const GrProcOptInfo& colorProcInfo() const {
736 this->calcColorInvariantOutput();
737 return fColorProcInfo;
738 }
739
740 const GrProcOptInfo& coverageProcInfo() const {
741 this->calcCoverageInvariantOutput();
742 return fCoverageProcInfo;
743 }
744
egdaniel89af44a2014-09-26 06:15:04 -0700745 /**
746 * Determines whether src alpha is guaranteed to be one for all src pixels
747 */
748 bool srcAlphaWillBeOne() const;
749
egdanielb6cbc382014-11-13 11:00:34 -0800750 /**
751 * If fColorProcInfoValid is false, function calculates the invariant output for the color
752 * stages and results are stored in fColorProcInfo.
753 */
754 void calcColorInvariantOutput() const;
755
756 /**
757 * If fCoverageProcInfoValid is false, function calculates the invariant output for the coverage
758 * stages and results are stored in fCoverageProcInfo.
759 */
760 void calcCoverageInvariantOutput() const;
761
bsalomon8f727332014-08-05 07:50:06 -0700762 void onReset(const SkMatrix* initialViewMatrix);
bsalomon@google.com137f1342013-05-29 21:27:53 +0000763
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000764 // Some of the auto restore objects assume that no effects are removed during their lifetime.
765 // This is used to assert that this condition holds.
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +0000766 SkDEBUGCODE(int fBlockEffectRemovalCnt;)
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000767
egdaniel7b3d5ee2014-08-28 05:41:14 -0700768 void internalSetVertexAttribs(const GrVertexAttrib attribs[], int count, size_t stride);
robertphillips@google.com42903302013-04-20 12:26:07 +0000769
joshualitta5305a12014-10-10 17:47:00 -0700770 typedef SkSTArray<4, GrFragmentStage> FragmentStageArray;
egdaniel89af44a2014-09-26 06:15:04 -0700771
bsalomonae59b772014-11-19 08:23:49 -0800772 SkAutoTUnref<GrRenderTarget> fRenderTarget;
773 GrColor fColor;
774 SkMatrix fViewMatrix;
775 GrColor fBlendConstant;
776 uint32_t fFlagBits;
777 const GrVertexAttrib* fVAPtr;
778 int fVACount;
779 size_t fVAStride;
780 GrStencilSettings fStencilSettings;
781 uint8_t fCoverage;
782 DrawFace fDrawFace;
783 GrBlendCoeff fSrcBlend;
784 GrBlendCoeff fDstBlend;
785 SkAutoTUnref<const GrGeometryProcessor> fGeometryProcessor;
786 FragmentStageArray fColorStages;
787 FragmentStageArray fCoverageStages;
788 uint32_t fHints;
egdaniel89af44a2014-09-26 06:15:04 -0700789
790 // This is simply a different representation of info in fVertexAttribs and thus does
791 // not need to be compared in op==.
792 int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt];
793
egdanielb6cbc382014-11-13 11:00:34 -0800794 mutable GrProcOptInfo fColorProcInfo;
795 mutable GrProcOptInfo fCoverageProcInfo;
796 mutable bool fColorProcInfoValid;
797 mutable bool fCoverageProcInfoValid;
798
egdanielb109ac22014-10-07 06:45:44 -0700799 friend class GrOptDrawState;
tomhudson@google.com93813632011-10-27 20:21:16 +0000800};
801
802#endif