blob: 68c71f020a3aff710d9b7c5c77cce70500ee420b [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"
egdaniel95131432014-12-09 11:15:43 -080020#include "GrXferProcessor.h"
egdaniel89af44a2014-09-26 06:15:04 -070021#include "SkMatrix.h"
egdaniel95131432014-12-09 11:15:43 -080022#include "effects/GrPorterDuffXferProcessor.h"
bsalomon@google.com68b58c92013-01-17 16:50:08 +000023#include "effects/GrSimpleTextureEffect.h"
tomhudson@google.com93813632011-10-27 20:21:16 +000024
egdaniel89af44a2014-09-26 06:15:04 -070025class GrDrawTargetCaps;
egdaniel89af44a2014-09-26 06:15:04 -070026class GrPaint;
27class GrTexture;
egdaniel170f90b2014-09-16 12:54:40 -070028
joshualitt9853cce2014-11-17 14:22:48 -080029class GrDrawState {
bsalomon@google.com2e3d1442012-03-26 20:33:54 +000030public:
egdaniel69bb90c2014-11-11 07:32:45 -080031 GrDrawState() {
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +000032 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
bsalomon@google.comeb6879f2013-06-13 19:34:18 +000033 this->reset();
34 }
tomhudson@google.com93813632011-10-27 20:21:16 +000035
egdaniel69bb90c2014-11-11 07:32:45 -080036 GrDrawState(const SkMatrix& initialViewMatrix) {
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +000037 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
bsalomon@google.comeb6879f2013-06-13 19:34:18 +000038 this->reset(initialViewMatrix);
39 }
bsalomon@google.com137f1342013-05-29 21:27:53 +000040
41 /**
42 * Copies another draw state.
43 **/
joshualitt9853cce2014-11-17 14:22:48 -080044 GrDrawState(const GrDrawState& state) {
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +000045 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
bsalomon@google.com46f7afb2012-01-18 19:51:55 +000046 *this = state;
47 }
48
bsalomon@google.com137f1342013-05-29 21:27:53 +000049 /**
50 * Copies another draw state with a preconcat to the view matrix.
51 **/
bsalomon8f727332014-08-05 07:50:06 -070052 GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix);
robertphillips@google.com9ec07532012-06-22 12:01:30 +000053
egdaniel170f90b2014-09-16 12:54:40 -070054 virtual ~GrDrawState();
bsalomon@google.com137f1342013-05-29 21:27:53 +000055
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000056 /**
joshualittb0a8a372014-09-23 09:50:21 -070057 * Resets to the default state. GrProcessors will be removed from all stages.
rmistry@google.comd6176b02012-08-23 18:14:13 +000058 */
bsalomon@google.com137f1342013-05-29 21:27:53 +000059 void reset() { this->onReset(NULL); }
robertphillips@google.com9ec07532012-06-22 12:01:30 +000060
bsalomon@google.com137f1342013-05-29 21:27:53 +000061 void reset(const SkMatrix& initialViewMatrix) { this->onReset(&initialViewMatrix); }
bsalomon@google.comaf84e742012-10-05 13:23:24 +000062
63 /**
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +000064 * Initializes the GrDrawState based on a GrPaint, view matrix and render target. Note that
65 * GrDrawState encompasses more than GrPaint. Aspects of GrDrawState that have no GrPaint
bsalomon9c0822a2014-08-11 11:07:48 -070066 * equivalents are set to default values with the exception of vertex attribute state which
67 * is unmodified by this function and clipping which will be enabled.
bsalomon@google.comaf84e742012-10-05 13:23:24 +000068 */
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +000069 void setFromPaint(const GrPaint& , const SkMatrix& viewMatrix, GrRenderTarget*);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000070
71 ///////////////////////////////////////////////////////////////////////////
jvanverth@google.com9b855c72013-03-01 18:21:22 +000072 /// @name Vertex Attributes
jvanverth@google.comcc782382013-01-28 20:39:48 +000073 ////
74
joshualitt2dd1ae02014-12-03 06:24:10 -080075 // TODO when we move this info off of GrGeometryProcessor, delete these
egdaniel89af44a2014-09-26 06:15:04 -070076 bool hasLocalCoordAttribute() const {
joshualitt2dd1ae02014-12-03 06:24:10 -080077 return this->hasGeometryProcessor() && this->getGeometryProcessor()->hasLocalCoords();
egdaniel89af44a2014-09-26 06:15:04 -070078 }
79 bool hasColorVertexAttribute() const {
joshualitt2dd1ae02014-12-03 06:24:10 -080080 return this->hasGeometryProcessor() && this->getGeometryProcessor()->hasVertexColor();
egdaniel89af44a2014-09-26 06:15:04 -070081 }
82 bool hasCoverageVertexAttribute() const {
joshualitt2dd1ae02014-12-03 06:24:10 -080083 return this->hasGeometryProcessor() && this->getGeometryProcessor()->hasVertexCoverage();
egdaniel89af44a2014-09-26 06:15:04 -070084 }
85
jvanverth@google.com9b855c72013-03-01 18:21:22 +000086 /// @}
87
jvanverth@google.com9b855c72013-03-01 18:21:22 +000088 /**
bsalomon62c447d2014-08-08 08:08:50 -070089 * Depending on features available in the underlying 3D API and the color blend mode requested
90 * it may or may not be possible to correctly blend with fractional pixel coverage generated by
91 * the fragment shader.
92 *
93 * This function considers the current draw state and the draw target's capabilities to
94 * determine whether coverage can be handled correctly. This function assumes that the caller
95 * intends to specify fractional pixel coverage (via setCoverage(), through a coverage vertex
96 * attribute, or a coverage effect) but may not have specified it yet.
97 */
98 bool couldApplyCoverage(const GrDrawTargetCaps& caps) const;
99
egdaniel89af44a2014-09-26 06:15:04 -0700100 /**
101 * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
102 */
103 bool hasSolidCoverage() const;
104
egdanielcd8b6302014-11-11 14:46:05 -0800105 /**
106 * This function returns true if the render target destination pixel values will be read for
107 * blending during draw.
108 */
109 bool willBlendWithDst() const;
110
jvanverth@google.comcc782382013-01-28 20:39:48 +0000111 /// @}
112
113 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000114 /// @name Color
115 ////
116
egdaniel89af44a2014-09-26 06:15:04 -0700117 GrColor getColor() const { return fColor; }
118
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000119 /**
120 * Sets color for next draw to a premultiplied-alpha color.
121 *
122 * @param color the color to set.
123 */
egdaniel9514d242014-07-18 06:15:43 -0700124 void setColor(GrColor color) {
egdaniel3658f382014-09-15 07:01:59 -0700125 if (color != fColor) {
126 fColor = color;
egdanielb6cbc382014-11-13 11:00:34 -0800127 fColorProcInfoValid = false;
egdaniel3658f382014-09-15 07:01:59 -0700128 }
egdaniel9514d242014-07-18 06:15:43 -0700129 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000130
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000131 /**
132 * Sets the color to be used for the next draw to be
133 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
134 *
135 * @param alpha The alpha value to set as the color.
136 */
bsalomon62c447d2014-08-08 08:08:50 -0700137 void setAlpha(uint8_t a) { this->setColor((a << 24) | (a << 16) | (a << 8) | a); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000138
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000139 /// @}
140
141 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000142 /// @name Coverage
143 ////
144
egdaniel89af44a2014-09-26 06:15:04 -0700145 uint8_t getCoverage() const { return fCoverage; }
146
147 GrColor getCoverageColor() const {
148 return GrColorPackRGBA(fCoverage, fCoverage, fCoverage, fCoverage);
149 }
150
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000151 /**
rmistry@google.comd6176b02012-08-23 18:14:13 +0000152 * Sets a constant fractional coverage to be applied to the draw. The
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000153 * initial value (after construction or reset()) is 0xff. The constant
154 * coverage is ignored when per-vertex coverage is provided.
155 */
156 void setCoverage(uint8_t coverage) {
egdaniel3658f382014-09-15 07:01:59 -0700157 if (coverage != fCoverage) {
158 fCoverage = coverage;
egdanielb6cbc382014-11-13 11:00:34 -0800159 fCoverageProcInfoValid = false;
egdaniel3658f382014-09-15 07:01:59 -0700160 }
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000161 }
162
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000163 /// @}
164
joshualittbd769d02014-09-04 08:56:46 -0700165 /**
166 * The geometry processor is the sole element of the skia pipeline which can use the vertex,
167 * geometry, and tesselation shaders. The GP may also compute a coverage in its fragment shader
168 * but is never put in the color processing pipeline.
169 */
170
joshualittb0a8a372014-09-23 09:50:21 -0700171 const GrGeometryProcessor* setGeometryProcessor(const GrGeometryProcessor* geometryProcessor) {
172 SkASSERT(geometryProcessor);
joshualittbd769d02014-09-04 08:56:46 -0700173 SkASSERT(!this->hasGeometryProcessor());
joshualitta5305a12014-10-10 17:47:00 -0700174 fGeometryProcessor.reset(SkRef(geometryProcessor));
egdanielb6cbc382014-11-13 11:00:34 -0800175 fCoverageProcInfoValid = false;
joshualittb0a8a372014-09-23 09:50:21 -0700176 return geometryProcessor;
joshualittbd769d02014-09-04 08:56:46 -0700177 }
178
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000179 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.comadc65362013-01-28 14:26:09 +0000180 /// @name Effect Stages
joshualittb0a8a372014-09-23 09:50:21 -0700181 /// Each stage hosts a GrProcessor. The effect produces an output color or coverage in the
182 /// fragment shader. Its inputs are the output from the previous stage as well as some variables
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000183 /// available to it in the fragment and vertex shader (e.g. the vertex position, the dst color,
184 /// the fragment position, local coordinates).
185 ///
186 /// The stages are divided into two sets, color-computing and coverage-computing. The final
187 /// color stage produces the final pixel color. The coverage-computing stages function exactly
188 /// as the color-computing but the output of the final coverage stage is treated as a fractional
189 /// pixel coverage rather than as input to the src/dst color blend step.
190 ///
191 /// The input color to the first color-stage is either the constant color or interpolated
192 /// per-vertex colors. The input to the first coverage stage is either a constant coverage
193 /// (usually full-coverage) or interpolated per-vertex coverage.
194 ///
195 /// See the documentation of kCoverageDrawing_StateBit for information about disabling the
196 /// the color / coverage distinction.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000197 ////
198
egdaniel89af44a2014-09-26 06:15:04 -0700199 int numColorStages() const { return fColorStages.count(); }
200 int numCoverageStages() const { return fCoverageStages.count(); }
joshualitt4dd99882014-11-11 08:51:30 -0800201 int numFragmentStages() const { return this->numColorStages() + this->numCoverageStages(); }
egdaniel89af44a2014-09-26 06:15:04 -0700202 int numTotalStages() const {
joshualitt4dd99882014-11-11 08:51:30 -0800203 return this->numFragmentStages() + (this->hasGeometryProcessor() ? 1 : 0);
egdaniel89af44a2014-09-26 06:15:04 -0700204 }
205
206 bool hasGeometryProcessor() const { return SkToBool(fGeometryProcessor.get()); }
joshualitta5305a12014-10-10 17:47:00 -0700207 const GrGeometryProcessor* getGeometryProcessor() const { return fGeometryProcessor.get(); }
egdaniel378092f2014-12-03 10:40:13 -0800208
209 const GrXPFactory* getXPFactory() const { return fXPFactory.get(); }
210
egdaniel89af44a2014-09-26 06:15:04 -0700211 const GrFragmentStage& getColorStage(int idx) const { return fColorStages[idx]; }
212 const GrFragmentStage& getCoverageStage(int idx) const { return fCoverageStages[idx]; }
213
214 /**
215 * Checks whether any of the effects will read the dst pixel color.
216 */
217 bool willEffectReadDstColor() const;
218
egdaniel95131432014-12-09 11:15:43 -0800219 /**
220 * The xfer processor factory.
221 */
222 const GrXPFactory* setXPFactory(const GrXPFactory* xpFactory) {
223 fXPFactory.reset(SkRef(xpFactory));
224 return xpFactory;
225 }
226
227 void setPorterDuffXPFactory(SkXfermode::Mode mode) {
228 fXPFactory.reset(GrPorterDuffXPFactory::Create(mode));
229 }
230
231 void setPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst) {
232 fXPFactory.reset(GrPorterDuffXPFactory::Create(src, dst));
233 }
234
joshualittb0a8a372014-09-23 09:50:21 -0700235 const GrFragmentProcessor* addColorProcessor(const GrFragmentProcessor* effect) {
bsalomon49f085d2014-09-05 13:34:00 -0700236 SkASSERT(effect);
joshualittb0a8a372014-09-23 09:50:21 -0700237 SkNEW_APPEND_TO_TARRAY(&fColorStages, GrFragmentStage, (effect));
egdanielb6cbc382014-11-13 11:00:34 -0800238 fColorProcInfoValid = false;
jvanverth@google.com65eb4d52013-03-19 18:51:02 +0000239 return effect;
240 }
skia.committer@gmail.com01c34ee2013-03-20 07:01:02 +0000241
joshualittb0a8a372014-09-23 09:50:21 -0700242 const GrFragmentProcessor* addCoverageProcessor(const GrFragmentProcessor* effect) {
bsalomon49f085d2014-09-05 13:34:00 -0700243 SkASSERT(effect);
joshualittb0a8a372014-09-23 09:50:21 -0700244 SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrFragmentStage, (effect));
egdanielb6cbc382014-11-13 11:00:34 -0800245 fCoverageProcInfoValid = false;
bsalomon@google.comadc65362013-01-28 14:26:09 +0000246 return effect;
247 }
248
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000249 /**
bsalomon@google.comc7818882013-03-20 19:19:53 +0000250 * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
tomhudson@google.com1e8f0162012-07-20 16:25:18 +0000251 */
joshualittb0a8a372014-09-23 09:50:21 -0700252 void addColorTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
253 this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000254 }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000255
joshualittb0a8a372014-09-23 09:50:21 -0700256 void addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
257 this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000258 }
259
joshualittb0a8a372014-09-23 09:50:21 -0700260 void addColorTextureProcessor(GrTexture* texture,
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000261 const SkMatrix& matrix,
262 const GrTextureParams& params) {
joshualittb0a8a372014-09-23 09:50:21 -0700263 this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
264 }
265
266 void addCoverageTextureProcessor(GrTexture* texture,
267 const SkMatrix& matrix,
268 const GrTextureParams& params) {
269 this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000270 }
tomhudson@google.com676e6602012-07-10 17:21:48 +0000271
robertphillips@google.com972265d2012-06-13 18:49:30 +0000272 /**
bsalomon9b536522014-09-05 09:18:51 -0700273 * When this object is destroyed it will remove any color/coverage effects from the draw state
274 * that were added after its constructor.
275 *
276 * This class has strange behavior around geometry processor. If there is a GP on the draw state
277 * it will assert that the GP is not modified until after the destructor of the ARE. If the
278 * draw state has a NULL GP when the ARE is constructed then it will reset it to null in the
279 * destructor.
280 *
281 * TODO: We'd prefer for the ARE to just save and restore the GP. However, this would add
282 * significant complexity to the multi-ref architecture for deferred drawing. Once GrDrawState
283 * and GrOptDrawState are fully separated then GrDrawState will never be in the deferred
284 * execution state and GrOptDrawState always will be (and will be immutable and therefore
285 * unable to have an ARE). At this point we can restore sanity and have the ARE save and restore
286 * the GP.
robertphillips@google.com972265d2012-06-13 18:49:30 +0000287 */
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +0000288 class AutoRestoreEffects : public ::SkNoncopyable {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000289 public:
bsalomon9b536522014-09-05 09:18:51 -0700290 AutoRestoreEffects()
291 : fDrawState(NULL)
bsalomon52e9d632014-09-05 12:23:12 -0700292 , fOriginalGPID(SK_InvalidUniqueID)
bsalomon9b536522014-09-05 09:18:51 -0700293 , fColorEffectCnt(0)
294 , fCoverageEffectCnt(0) {}
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000295
bsalomon9b536522014-09-05 09:18:51 -0700296 AutoRestoreEffects(GrDrawState* ds)
297 : fDrawState(NULL)
bsalomon52e9d632014-09-05 12:23:12 -0700298 , fOriginalGPID(SK_InvalidUniqueID)
bsalomon9b536522014-09-05 09:18:51 -0700299 , fColorEffectCnt(0)
300 , fCoverageEffectCnt(0) {
skia.committer@gmail.com5c493d52013-06-14 07:00:49 +0000301 this->set(ds);
robertphillips@google.comf09b87d2013-06-13 20:06:44 +0000302 }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000303
304 ~AutoRestoreEffects() { this->set(NULL); }
305
bsalomon8f727332014-08-05 07:50:06 -0700306 void set(GrDrawState* ds);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000307
bsalomon49f085d2014-09-05 13:34:00 -0700308 bool isSet() const { return SkToBool(fDrawState); }
bsalomon8af05232014-06-03 06:34:58 -0700309
robertphillips@google.com972265d2012-06-13 18:49:30 +0000310 private:
bsalomon9b536522014-09-05 09:18:51 -0700311 GrDrawState* fDrawState;
bsalomon52e9d632014-09-05 12:23:12 -0700312 uint32_t fOriginalGPID;
bsalomon9b536522014-09-05 09:18:51 -0700313 int fColorEffectCnt;
314 int fCoverageEffectCnt;
robertphillips@google.com972265d2012-06-13 18:49:30 +0000315 };
316
joshualitta58fe352014-10-27 08:39:00 -0700317 /**
318 * AutoRestoreStencil
319 *
320 * This simple struct saves and restores the stencil settings
321 */
322 class AutoRestoreStencil : public ::SkNoncopyable {
323 public:
324 AutoRestoreStencil() : fDrawState(NULL) {}
325
326 AutoRestoreStencil(GrDrawState* ds) : fDrawState(NULL) { this->set(ds); }
327
328 ~AutoRestoreStencil() { this->set(NULL); }
329
330 void set(GrDrawState* ds) {
331 if (fDrawState) {
332 fDrawState->setStencil(fStencilSettings);
333 }
334 fDrawState = ds;
335 if (ds) {
336 fStencilSettings = ds->getStencil();
337 }
338 }
339
340 bool isSet() const { return SkToBool(fDrawState); }
341
342 private:
343 GrDrawState* fDrawState;
344 GrStencilSettings fStencilSettings;
345 };
346
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000347 /// @}
348
349 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000350 /// @name Blending
351 ////
352
egdaniel89af44a2014-09-26 06:15:04 -0700353 /**
354 * Determines whether multiplying the computed per-pixel color by the pixel's fractional
355 * coverage before the blend will give the correct final destination color. In general it
356 * will not as coverage is applied after blending.
357 */
358 bool canTweakAlphaForCoverage() const;
359
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000360 /// @}
361
362 ///////////////////////////////////////////////////////////////////////////
363 /// @name View Matrix
364 ////
365
366 /**
egdaniel89af44a2014-09-26 06:15:04 -0700367 * Retrieves the current view matrix
368 * @return the current view matrix.
369 */
370 const SkMatrix& getViewMatrix() const { return fViewMatrix; }
371
372 /**
373 * Retrieves the inverse of the current view matrix.
374 *
375 * If the current view matrix is invertible, return true, and if matrix
376 * is non-null, copy the inverse into it. If the current view matrix is
377 * non-invertible, return false and ignore the matrix parameter.
378 *
379 * @param matrix if not null, will receive a copy of the current inverse.
380 */
381 bool getViewInverse(SkMatrix* matrix) const {
382 SkMatrix inverse;
383 if (fViewMatrix.invert(&inverse)) {
384 if (matrix) {
385 *matrix = inverse;
386 }
387 return true;
388 }
389 return false;
390 }
391
392 /**
bsalomon@google.com137f1342013-05-29 21:27:53 +0000393 * Sets the view matrix to identity and updates any installed effects to compensate for the
394 * coord system change.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000395 */
bsalomon@google.com137f1342013-05-29 21:27:53 +0000396 bool setIdentityViewMatrix();
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000397
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000398 ////////////////////////////////////////////////////////////////////////////
399
400 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000401 * Preconcats the current view matrix and restores the previous view matrix in the destructor.
bsalomon@google.com137f1342013-05-29 21:27:53 +0000402 * Effect matrices are automatically adjusted to compensate and adjusted back in the destructor.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000403 */
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +0000404 class AutoViewMatrixRestore : public ::SkNoncopyable {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000405 public:
406 AutoViewMatrixRestore() : fDrawState(NULL) {}
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000407
bsalomon@google.comc7818882013-03-20 19:19:53 +0000408 AutoViewMatrixRestore(GrDrawState* ds, const SkMatrix& preconcatMatrix) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000409 fDrawState = NULL;
bsalomon@google.comc7818882013-03-20 19:19:53 +0000410 this->set(ds, preconcatMatrix);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000411 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000412
413 ~AutoViewMatrixRestore() { this->restore(); }
414
bsalomon@google.coma8347462012-10-08 18:59:39 +0000415 /**
416 * Can be called prior to destructor to restore the original matrix.
417 */
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000418 void restore();
skia.committer@gmail.comf467ce72012-10-09 02:01:37 +0000419
bsalomon@google.comc7818882013-03-20 19:19:53 +0000420 void set(GrDrawState* drawState, const SkMatrix& preconcatMatrix);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000421
bsalomon@google.com137f1342013-05-29 21:27:53 +0000422 /** Sets the draw state's matrix to identity. This can fail because the current view matrix
423 is not invertible. */
424 bool setIdentity(GrDrawState* drawState);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000425
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000426 private:
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000427 void doEffectCoordChanges(const SkMatrix& coordChangeMatrix);
428
joshualittb0a8a372014-09-23 09:50:21 -0700429 GrDrawState* fDrawState;
430 SkMatrix fViewMatrix;
431 int fNumColorStages;
joshualitta5305a12014-10-10 17:47:00 -0700432 SkAutoSTArray<8, GrFragmentStage::SavedCoordChange> fSavedCoordChanges;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000433 };
434
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000435 /// @}
436
437 ///////////////////////////////////////////////////////////////////////////
438 /// @name Render Target
439 ////
440
441 /**
egdaniel89af44a2014-09-26 06:15:04 -0700442 * Retrieves the currently set render-target.
443 *
444 * @return The currently set render target.
445 */
bsalomon37dd3312014-11-03 08:47:23 -0800446 GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
egdaniel89af44a2014-09-26 06:15:04 -0700447
448 /**
bsalomon@google.comca432082013-01-23 19:53:46 +0000449 * Sets the render-target used at the next drawing call
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000450 *
451 * @param target The render target to set.
452 */
bsalomonae59b772014-11-19 08:23:49 -0800453 void setRenderTarget(GrRenderTarget* target) { fRenderTarget.reset(SkSafeRef(target)); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000454
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000455 /// @}
456
457 ///////////////////////////////////////////////////////////////////////////
458 /// @name Stencil
459 ////
460
egdaniel89af44a2014-09-26 06:15:04 -0700461 const GrStencilSettings& getStencil() const { return fStencilSettings; }
462
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000463 /**
464 * Sets the stencil settings to use for the next draw.
465 * Changing the clip has the side-effect of possibly zeroing
466 * out the client settable stencil bits. So multipass algorithms
467 * using stencil should not change the clip between passes.
468 * @param settings the stencil settings to use.
469 */
bsalomon04ddf892014-11-19 12:36:22 -0800470 void setStencil(const GrStencilSettings& settings) { fStencilSettings = settings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000471
472 /**
473 * Shortcut to disable stencil testing and ops.
474 */
bsalomon04ddf892014-11-19 12:36:22 -0800475 void disableStencil() { fStencilSettings.setDisabled(); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000476
bsalomon2ed5ef82014-07-07 08:44:05 -0700477 GrStencilSettings* stencil() { return &fStencilSettings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000478
479 /// @}
480
481 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000482 /// @name State Flags
483 ////
tomhudson@google.com62b09682011-11-09 16:39:17 +0000484
egdaniel89af44a2014-09-26 06:15:04 -0700485 /**
486 * Flags that affect rendering. Controlled using enable/disableState(). All
487 * default to disabled.
488 */
489 enum StateBits {
490 /**
491 * Perform dithering. TODO: Re-evaluate whether we need this bit
492 */
493 kDither_StateBit = 0x01,
494 /**
495 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
496 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
497 * the 3D API.
498 */
499 kHWAntialias_StateBit = 0x02,
500 /**
501 * Draws will respect the clip, otherwise the clip is ignored.
502 */
503 kClip_StateBit = 0x04,
504 /**
505 * Disables writing to the color buffer. Useful when performing stencil
506 * operations.
507 */
508 kNoColorWrites_StateBit = 0x08,
509
510 /**
511 * Usually coverage is applied after color blending. The color is blended using the coeffs
512 * specified by setBlendFunc(). The blended color is then combined with dst using coeffs
513 * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In
514 * this case there is no distinction between coverage and color and the caller needs direct
515 * control over the blend coeffs. When set, there will be a single blend step controlled by
516 * setBlendFunc() which will use coverage*color as the src color.
517 */
518 kCoverageDrawing_StateBit = 0x10,
joshualitt7a6184f2014-10-29 18:29:27 -0700519 kLast_StateBit = kCoverageDrawing_StateBit,
egdaniel89af44a2014-09-26 06:15:04 -0700520 };
521
egdaniel89af44a2014-09-26 06:15:04 -0700522 bool isClipState() const { return 0 != (fFlagBits & kClip_StateBit); }
523 bool isColorWriteDisabled() const { return 0 != (fFlagBits & kNoColorWrites_StateBit); }
524 bool isCoverageDrawing() const { return 0 != (fFlagBits & kCoverageDrawing_StateBit); }
bsalomon04ddf892014-11-19 12:36:22 -0800525 bool isDither() const { return 0 != (fFlagBits & kDither_StateBit); }
526 bool isHWAntialias() const { return 0 != (fFlagBits & kHWAntialias_StateBit); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000527
528 /**
529 * Enable render state settings.
530 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000531 * @param stateBits bitfield of StateBits specifying the states to enable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000532 */
bsalomon04ddf892014-11-19 12:36:22 -0800533 void enableState(uint32_t stateBits) { fFlagBits |= stateBits; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000534
535 /**
536 * Disable render state settings.
537 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000538 * @param stateBits bitfield of StateBits specifying the states to disable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000539 */
bsalomon04ddf892014-11-19 12:36:22 -0800540 void disableState(uint32_t stateBits) { fFlagBits &= ~(stateBits); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000541
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000542 /**
543 * Enable or disable stateBits based on a boolean.
544 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000545 * @param stateBits bitfield of StateBits to enable or disable
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000546 * @param enable if true enable stateBits, otherwise disable
547 */
548 void setState(uint32_t stateBits, bool enable) {
549 if (enable) {
550 this->enableState(stateBits);
551 } else {
552 this->disableState(stateBits);
553 }
554 }
555
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000556 /// @}
557
558 ///////////////////////////////////////////////////////////////////////////
559 /// @name Face Culling
560 ////
561
egdaniel89af44a2014-09-26 06:15:04 -0700562 enum DrawFace {
563 kInvalid_DrawFace = -1,
564
565 kBoth_DrawFace,
566 kCCW_DrawFace,
567 kCW_DrawFace,
568 };
569
570 /**
571 * Gets whether the target is drawing clockwise, counterclockwise,
572 * or both faces.
573 * @return the current draw face(s).
574 */
575 DrawFace getDrawFace() const { return fDrawFace; }
576
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000577 /**
578 * Controls whether clockwise, counterclockwise, or both faces are drawn.
579 * @param face the face(s) to draw.
580 */
581 void setDrawFace(DrawFace face) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000582 SkASSERT(kInvalid_DrawFace != face);
bsalomon2ed5ef82014-07-07 08:44:05 -0700583 fDrawFace = face;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000584 }
585
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000586 /// @}
587
588 ///////////////////////////////////////////////////////////////////////////
bsalomon62c447d2014-08-08 08:08:50 -0700589 /// @name Hints
590 /// Hints that when provided can enable optimizations.
591 ////
592
joshualitt65171342014-10-09 07:25:36 -0700593 enum Hints {
594 kVertexColorsAreOpaque_Hint = 0x1,
595 kLast_Hint = kVertexColorsAreOpaque_Hint
596 };
egdaniel89af44a2014-09-26 06:15:04 -0700597
bsalomon62c447d2014-08-08 08:08:50 -0700598 void setHint(Hints hint, bool value) { fHints = value ? (fHints | hint) : (fHints & ~hint); }
599
egdaniel89af44a2014-09-26 06:15:04 -0700600 bool vertexColorsAreOpaque() const { return kVertexColorsAreOpaque_Hint & fHints; }
601
bsalomon62c447d2014-08-08 08:08:50 -0700602 /// @}
603
604 ///////////////////////////////////////////////////////////////////////////
tomhudson@google.com62b09682011-11-09 16:39:17 +0000605
bsalomon8f727332014-08-05 07:50:06 -0700606 GrDrawState& operator= (const GrDrawState& that);
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000607
608private:
egdaniel89af44a2014-09-26 06:15:04 -0700609 bool isEqual(const GrDrawState& that) const;
610
egdaniel912b3d22014-11-17 07:45:53 -0800611 const GrProcOptInfo& colorProcInfo() const {
612 this->calcColorInvariantOutput();
613 return fColorProcInfo;
614 }
615
616 const GrProcOptInfo& coverageProcInfo() const {
617 this->calcCoverageInvariantOutput();
618 return fCoverageProcInfo;
619 }
620
egdaniel89af44a2014-09-26 06:15:04 -0700621 /**
622 * Determines whether src alpha is guaranteed to be one for all src pixels
623 */
624 bool srcAlphaWillBeOne() const;
625
egdanielb6cbc382014-11-13 11:00:34 -0800626 /**
627 * If fColorProcInfoValid is false, function calculates the invariant output for the color
628 * stages and results are stored in fColorProcInfo.
629 */
630 void calcColorInvariantOutput() const;
631
632 /**
633 * If fCoverageProcInfoValid is false, function calculates the invariant output for the coverage
634 * stages and results are stored in fCoverageProcInfo.
635 */
636 void calcCoverageInvariantOutput() const;
637
bsalomon8f727332014-08-05 07:50:06 -0700638 void onReset(const SkMatrix* initialViewMatrix);
bsalomon@google.com137f1342013-05-29 21:27:53 +0000639
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000640 // Some of the auto restore objects assume that no effects are removed during their lifetime.
641 // This is used to assert that this condition holds.
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +0000642 SkDEBUGCODE(int fBlockEffectRemovalCnt;)
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000643
joshualitta5305a12014-10-10 17:47:00 -0700644 typedef SkSTArray<4, GrFragmentStage> FragmentStageArray;
egdaniel89af44a2014-09-26 06:15:04 -0700645
bsalomonae59b772014-11-19 08:23:49 -0800646 SkAutoTUnref<GrRenderTarget> fRenderTarget;
647 GrColor fColor;
648 SkMatrix fViewMatrix;
bsalomonae59b772014-11-19 08:23:49 -0800649 uint32_t fFlagBits;
bsalomonae59b772014-11-19 08:23:49 -0800650 GrStencilSettings fStencilSettings;
651 uint8_t fCoverage;
652 DrawFace fDrawFace;
bsalomonae59b772014-11-19 08:23:49 -0800653 SkAutoTUnref<const GrGeometryProcessor> fGeometryProcessor;
egdaniel378092f2014-12-03 10:40:13 -0800654 SkAutoTUnref<const GrXPFactory> fXPFactory;
bsalomonae59b772014-11-19 08:23:49 -0800655 FragmentStageArray fColorStages;
656 FragmentStageArray fCoverageStages;
657 uint32_t fHints;
egdaniel89af44a2014-09-26 06:15:04 -0700658
egdanielb6cbc382014-11-13 11:00:34 -0800659 mutable GrProcOptInfo fColorProcInfo;
660 mutable GrProcOptInfo fCoverageProcInfo;
661 mutable bool fColorProcInfoValid;
662 mutable bool fCoverageProcInfoValid;
663
egdanielb109ac22014-10-07 06:45:44 -0700664 friend class GrOptDrawState;
tomhudson@google.com93813632011-10-27 20:21:16 +0000665};
666
667#endif