blob: 458fb958e64d8b9830beacf22e5a6af1e9a21ba1 [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"
bsalomonf96ba022014-09-17 08:05:40 -070012#include "GrGpuResourceRef.h"
bsalomon2a9ca782014-09-05 14:27:43 -070013#include "GrRODrawState.h"
bsalomon@google.com68b58c92013-01-17 16:50:08 +000014#include "effects/GrSimpleTextureEffect.h"
tomhudson@google.com93813632011-10-27 20:21:16 +000015
egdaniel170f90b2014-09-16 12:54:40 -070016class GrOptDrawState;
17
egdaniel21aed572014-08-26 12:24:06 -070018/**
19 * Modifiable subclass derived from GrRODrawState. The majority of the data that represents a draw
20 * state is stored in the parent class. GrDrawState contains methods for setting, adding to, etc.
21 * various data members of the draw state. This class is used to configure the state used when
22 * issuing draws via GrDrawTarget.
23 */
24class GrDrawState : public GrRODrawState {
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
egdaniel3658f382014-09-15 07:01:59 -070028 GrDrawState() : fCachedOptState(NULL) {
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
egdaniel3658f382014-09-15 07:01:59 -070033 GrDrawState(const SkMatrix& initialViewMatrix) : fCachedOptState(NULL) {
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 **/
egdaniel3658f382014-09-15 07:01:59 -070041 GrDrawState(const GrDrawState& state) : INHERITED(), fCachedOptState(NULL) {
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
egdaniel170f90b2014-09-16 12:54:40 -070051 virtual ~GrDrawState();
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
bsalomon9c0822a2014-08-11 11:07:48 -070063 * equivalents are set to default values with the exception of vertex attribute state which
64 * is unmodified by this function and clipping which will be enabled.
bsalomon@google.comaf84e742012-10-05 13:23:24 +000065 */
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +000066 void setFromPaint(const GrPaint& , const SkMatrix& viewMatrix, GrRenderTarget*);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000067
68 ///////////////////////////////////////////////////////////////////////////
jvanverth@google.com9b855c72013-03-01 18:21:22 +000069 /// @name Vertex Attributes
jvanverth@google.comcc782382013-01-28 20:39:48 +000070 ////
71
jvanverth@google.com9b855c72013-03-01 18:21:22 +000072 /**
jvanverth@google.com054ae992013-04-01 20:06:51 +000073 * The format of vertices is represented as an array of GrVertexAttribs, with each representing
74 * the type of the attribute, its offset, and semantic binding (see GrVertexAttrib in
75 * GrTypesPriv.h).
jvanverth@google.comb8b705b2013-02-28 16:28:34 +000076 *
jvanverth@google.com054ae992013-04-01 20:06:51 +000077 * The mapping of attributes with kEffect bindings to GrEffect inputs is specified when
78 * setEffect is called.
jvanverth@google.comb8b705b2013-02-28 16:28:34 +000079 */
jvanverth@google.comb75b0a02013-02-05 20:33:30 +000080
jvanverth@google.com9b855c72013-03-01 18:21:22 +000081 /**
robertphillips@google.com42903302013-04-20 12:26:07 +000082 * Sets vertex attributes for next draw. The object driving the templatization
83 * should be a global GrVertexAttrib array that is never changed.
egdaniel7b3d5ee2014-08-28 05:41:14 -070084 *
85 * @param count the number of attributes being set, limited to kMaxVertexAttribCnt.
86 * @param stride the number of bytes between successive vertex data.
jvanverth@google.com9b855c72013-03-01 18:21:22 +000087 */
egdaniel7b3d5ee2014-08-28 05:41:14 -070088 template <const GrVertexAttrib A[]> void setVertexAttribs(int count, size_t stride) {
89 this->internalSetVertexAttribs(A, count, stride);
robertphillips@google.com42903302013-04-20 12:26:07 +000090 }
jvanverth@google.comb8b705b2013-02-28 16:28:34 +000091
jvanverth@google.com9b855c72013-03-01 18:21:22 +000092 /**
jvanverth@google.com054ae992013-04-01 20:06:51 +000093 * Sets default vertex attributes for next draw. The default is a single attribute:
94 * {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribType}
jvanverth@google.com9b855c72013-03-01 18:21:22 +000095 */
96 void setDefaultVertexAttribs();
jvanverth@google.comb75b0a02013-02-05 20:33:30 +000097
jvanverth@google.com054ae992013-04-01 20:06:51 +000098 /**
bsalomon@google.com0406b9e2013-04-02 21:00:15 +000099 * Helper to save/restore vertex attribs
100 */
101 class AutoVertexAttribRestore {
102 public:
bsalomon8f727332014-08-05 07:50:06 -0700103 AutoVertexAttribRestore(GrDrawState* drawState);
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000104
egdaniel3658f382014-09-15 07:01:59 -0700105 ~AutoVertexAttribRestore() { fDrawState->internalSetVertexAttribs(fVAPtr, fVACount,
106 fVAStride); }
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000107
108 private:
robertphillips@google.com42903302013-04-20 12:26:07 +0000109 GrDrawState* fDrawState;
110 const GrVertexAttrib* fVAPtr;
111 int fVACount;
egdaniel7b3d5ee2014-08-28 05:41:14 -0700112 size_t fVAStride;
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000113 };
114
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000115 /// @}
116
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000117 /**
bsalomon62c447d2014-08-08 08:08:50 -0700118 * Depending on features available in the underlying 3D API and the color blend mode requested
119 * it may or may not be possible to correctly blend with fractional pixel coverage generated by
120 * the fragment shader.
121 *
122 * This function considers the current draw state and the draw target's capabilities to
123 * determine whether coverage can be handled correctly. This function assumes that the caller
124 * intends to specify fractional pixel coverage (via setCoverage(), through a coverage vertex
125 * attribute, or a coverage effect) but may not have specified it yet.
126 */
127 bool couldApplyCoverage(const GrDrawTargetCaps& caps) const;
128
jvanverth@google.comcc782382013-01-28 20:39:48 +0000129 /// @}
130
131 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000132 /// @name Color
133 ////
134
135 /**
136 * Sets color for next draw to a premultiplied-alpha color.
137 *
138 * @param color the color to set.
139 */
egdaniel9514d242014-07-18 06:15:43 -0700140 void setColor(GrColor color) {
egdaniel3658f382014-09-15 07:01:59 -0700141 if (color != fColor) {
142 fColor = color;
143 this->invalidateOptState();
144 }
egdaniel9514d242014-07-18 06:15:43 -0700145 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000146
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000147 /**
148 * Sets the color to be used for the next draw to be
149 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
150 *
151 * @param alpha The alpha value to set as the color.
152 */
bsalomon62c447d2014-08-08 08:08:50 -0700153 void setAlpha(uint8_t a) { this->setColor((a << 24) | (a << 16) | (a << 8) | a); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000154
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000155 /// @}
156
157 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000158 /// @name Coverage
159 ////
160
161 /**
rmistry@google.comd6176b02012-08-23 18:14:13 +0000162 * Sets a constant fractional coverage to be applied to the draw. The
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000163 * initial value (after construction or reset()) is 0xff. The constant
164 * coverage is ignored when per-vertex coverage is provided.
165 */
166 void setCoverage(uint8_t coverage) {
egdaniel3658f382014-09-15 07:01:59 -0700167 if (coverage != fCoverage) {
168 fCoverage = coverage;
169 this->invalidateOptState();
170 }
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000171 }
172
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000173 /// @}
174
joshualittbd769d02014-09-04 08:56:46 -0700175 /**
176 * The geometry processor is the sole element of the skia pipeline which can use the vertex,
177 * geometry, and tesselation shaders. The GP may also compute a coverage in its fragment shader
178 * but is never put in the color processing pipeline.
179 */
180
joshualitt249af152014-09-15 11:41:13 -0700181 const GrEffect* setGeometryProcessor(const GrEffect* effect) {
bsalomon49f085d2014-09-05 13:34:00 -0700182 SkASSERT(effect);
joshualitt249af152014-09-15 11:41:13 -0700183 SkASSERT(effect->requiresVertexShader());
joshualittbd769d02014-09-04 08:56:46 -0700184 SkASSERT(!this->hasGeometryProcessor());
joshualitt249af152014-09-15 11:41:13 -0700185 fGeometryProcessor.reset(new GrEffectStage(effect));
egdaniel3658f382014-09-15 07:01:59 -0700186 this->invalidateOptState();
joshualittbd769d02014-09-04 08:56:46 -0700187 return effect;
188 }
189
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000190 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.comadc65362013-01-28 14:26:09 +0000191 /// @name Effect Stages
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000192 /// Each stage hosts a GrEffect. The effect produces an output color or coverage in the fragment
193 /// shader. Its inputs are the output from the previous stage as well as some variables
194 /// available to it in the fragment and vertex shader (e.g. the vertex position, the dst color,
195 /// the fragment position, local coordinates).
196 ///
197 /// The stages are divided into two sets, color-computing and coverage-computing. The final
198 /// color stage produces the final pixel color. The coverage-computing stages function exactly
199 /// as the color-computing but the output of the final coverage stage is treated as a fractional
200 /// pixel coverage rather than as input to the src/dst color blend step.
201 ///
202 /// The input color to the first color-stage is either the constant color or interpolated
203 /// per-vertex colors. The input to the first coverage stage is either a constant coverage
204 /// (usually full-coverage) or interpolated per-vertex coverage.
205 ///
206 /// See the documentation of kCoverageDrawing_StateBit for information about disabling the
207 /// the color / coverage distinction.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000208 ////
209
joshualitt249af152014-09-15 11:41:13 -0700210 const GrEffect* addColorEffect(const GrEffect* effect) {
bsalomon49f085d2014-09-05 13:34:00 -0700211 SkASSERT(effect);
joshualitt249af152014-09-15 11:41:13 -0700212 SkASSERT(!effect->requiresVertexShader());
213 SkNEW_APPEND_TO_TARRAY(&fColorStages, GrEffectStage, (effect));
egdaniel3658f382014-09-15 07:01:59 -0700214 this->invalidateOptState();
jvanverth@google.com65eb4d52013-03-19 18:51:02 +0000215 return effect;
216 }
skia.committer@gmail.com01c34ee2013-03-20 07:01:02 +0000217
joshualitt249af152014-09-15 11:41:13 -0700218 const GrEffect* addCoverageEffect(const GrEffect* effect) {
bsalomon49f085d2014-09-05 13:34:00 -0700219 SkASSERT(effect);
joshualitt249af152014-09-15 11:41:13 -0700220 SkASSERT(!effect->requiresVertexShader());
221 SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrEffectStage, (effect));
egdaniel3658f382014-09-15 07:01:59 -0700222 this->invalidateOptState();
bsalomon@google.comadc65362013-01-28 14:26:09 +0000223 return effect;
224 }
225
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000226 /**
bsalomon@google.comc7818882013-03-20 19:19:53 +0000227 * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
tomhudson@google.com1e8f0162012-07-20 16:25:18 +0000228 */
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000229 void addColorTextureEffect(GrTexture* texture, const SkMatrix& matrix) {
bsalomon97b9ab72014-07-08 06:52:35 -0700230 this->addColorEffect(GrSimpleTextureEffect::Create(texture, matrix))->unref();
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000231 }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000232
233 void addCoverageTextureEffect(GrTexture* texture, const SkMatrix& matrix) {
bsalomon97b9ab72014-07-08 06:52:35 -0700234 this->addCoverageEffect(GrSimpleTextureEffect::Create(texture, matrix))->unref();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000235 }
236
237 void addColorTextureEffect(GrTexture* texture,
238 const SkMatrix& matrix,
239 const GrTextureParams& params) {
bsalomon97b9ab72014-07-08 06:52:35 -0700240 this->addColorEffect(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
bsalomon@google.com1ce49fc2012-09-18 14:14:49 +0000241 }
242
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000243 void addCoverageTextureEffect(GrTexture* texture,
244 const SkMatrix& matrix,
245 const GrTextureParams& params) {
bsalomon97b9ab72014-07-08 06:52:35 -0700246 this->addCoverageEffect(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000247 }
tomhudson@google.com676e6602012-07-10 17:21:48 +0000248
robertphillips@google.com972265d2012-06-13 18:49:30 +0000249 /**
bsalomon9b536522014-09-05 09:18:51 -0700250 * When this object is destroyed it will remove any color/coverage effects from the draw state
251 * that were added after its constructor.
252 *
253 * This class has strange behavior around geometry processor. If there is a GP on the draw state
254 * it will assert that the GP is not modified until after the destructor of the ARE. If the
255 * draw state has a NULL GP when the ARE is constructed then it will reset it to null in the
256 * destructor.
257 *
258 * TODO: We'd prefer for the ARE to just save and restore the GP. However, this would add
259 * significant complexity to the multi-ref architecture for deferred drawing. Once GrDrawState
260 * and GrOptDrawState are fully separated then GrDrawState will never be in the deferred
261 * execution state and GrOptDrawState always will be (and will be immutable and therefore
262 * unable to have an ARE). At this point we can restore sanity and have the ARE save and restore
263 * the GP.
robertphillips@google.com972265d2012-06-13 18:49:30 +0000264 */
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +0000265 class AutoRestoreEffects : public ::SkNoncopyable {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000266 public:
bsalomon9b536522014-09-05 09:18:51 -0700267 AutoRestoreEffects()
268 : fDrawState(NULL)
bsalomon52e9d632014-09-05 12:23:12 -0700269 , fOriginalGPID(SK_InvalidUniqueID)
bsalomon9b536522014-09-05 09:18:51 -0700270 , fColorEffectCnt(0)
271 , fCoverageEffectCnt(0) {}
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000272
bsalomon9b536522014-09-05 09:18:51 -0700273 AutoRestoreEffects(GrDrawState* ds)
274 : fDrawState(NULL)
bsalomon52e9d632014-09-05 12:23:12 -0700275 , fOriginalGPID(SK_InvalidUniqueID)
bsalomon9b536522014-09-05 09:18:51 -0700276 , fColorEffectCnt(0)
277 , fCoverageEffectCnt(0) {
skia.committer@gmail.com5c493d52013-06-14 07:00:49 +0000278 this->set(ds);
robertphillips@google.comf09b87d2013-06-13 20:06:44 +0000279 }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000280
281 ~AutoRestoreEffects() { this->set(NULL); }
282
bsalomon8f727332014-08-05 07:50:06 -0700283 void set(GrDrawState* ds);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000284
bsalomon49f085d2014-09-05 13:34:00 -0700285 bool isSet() const { return SkToBool(fDrawState); }
bsalomon8af05232014-06-03 06:34:58 -0700286
robertphillips@google.com972265d2012-06-13 18:49:30 +0000287 private:
bsalomon9b536522014-09-05 09:18:51 -0700288 GrDrawState* fDrawState;
bsalomon52e9d632014-09-05 12:23:12 -0700289 uint32_t fOriginalGPID;
bsalomon9b536522014-09-05 09:18:51 -0700290 int fColorEffectCnt;
291 int fCoverageEffectCnt;
robertphillips@google.com972265d2012-06-13 18:49:30 +0000292 };
293
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000294 /// @}
295
296 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000297 /// @name Blending
298 ////
299
300 /**
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000301 * Sets the blending function coefficients.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000302 *
303 * The blend function will be:
304 * D' = sat(S*srcCoef + D*dstCoef)
305 *
306 * where D is the existing destination color, S is the incoming source
307 * color, and D' is the new destination color that will be written. sat()
308 * is the saturation function.
309 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000310 * @param srcCoef coefficient applied to the src color.
311 * @param dstCoef coefficient applied to the dst color.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000312 */
313 void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
egdaniel3658f382014-09-15 07:01:59 -0700314 if (srcCoeff != fSrcBlend || dstCoeff != fDstBlend) {
315 fSrcBlend = srcCoeff;
316 fDstBlend = dstCoeff;
317 this->invalidateOptState();
318 }
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000319 #ifdef SK_DEBUG
commit-bot@chromium.org24ab3b02013-08-14 21:56:37 +0000320 if (GrBlendCoeffRefsDst(dstCoeff)) {
321 GrPrintf("Unexpected dst blend coeff. Won't work correctly with coverage stages.\n");
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000322 }
commit-bot@chromium.org24ab3b02013-08-14 21:56:37 +0000323 if (GrBlendCoeffRefsSrc(srcCoeff)) {
324 GrPrintf("Unexpected src blend coeff. Won't work correctly with coverage stages.\n");
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000325 }
326 #endif
327 }
328
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000329 /**
330 * Sets the blending function constant referenced by the following blending
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000331 * coefficients:
bsalomon@google.com47059542012-06-06 20:51:20 +0000332 * kConstC_GrBlendCoeff
333 * kIConstC_GrBlendCoeff
334 * kConstA_GrBlendCoeff
335 * kIConstA_GrBlendCoeff
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000336 *
337 * @param constant the constant to set
338 */
egdaniel9514d242014-07-18 06:15:43 -0700339 void setBlendConstant(GrColor constant) {
egdaniel3658f382014-09-15 07:01:59 -0700340 if (constant != fBlendConstant) {
341 fBlendConstant = constant;
342 this->invalidateOptState();
343 }
egdaniel9514d242014-07-18 06:15:43 -0700344 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000345
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000346 /// @}
347
348 ///////////////////////////////////////////////////////////////////////////
349 /// @name View Matrix
350 ////
351
352 /**
bsalomon@google.com137f1342013-05-29 21:27:53 +0000353 * Sets the view matrix to identity and updates any installed effects to compensate for the
354 * coord system change.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000355 */
bsalomon@google.com137f1342013-05-29 21:27:53 +0000356 bool setIdentityViewMatrix();
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000357
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000358 ////////////////////////////////////////////////////////////////////////////
359
360 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000361 * Preconcats the current view matrix and restores the previous view matrix in the destructor.
bsalomon@google.com137f1342013-05-29 21:27:53 +0000362 * Effect matrices are automatically adjusted to compensate and adjusted back in the destructor.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000363 */
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +0000364 class AutoViewMatrixRestore : public ::SkNoncopyable {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000365 public:
366 AutoViewMatrixRestore() : fDrawState(NULL) {}
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000367
bsalomon@google.comc7818882013-03-20 19:19:53 +0000368 AutoViewMatrixRestore(GrDrawState* ds, const SkMatrix& preconcatMatrix) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000369 fDrawState = NULL;
bsalomon@google.comc7818882013-03-20 19:19:53 +0000370 this->set(ds, preconcatMatrix);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000371 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000372
373 ~AutoViewMatrixRestore() { this->restore(); }
374
bsalomon@google.coma8347462012-10-08 18:59:39 +0000375 /**
376 * Can be called prior to destructor to restore the original matrix.
377 */
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000378 void restore();
skia.committer@gmail.comf467ce72012-10-09 02:01:37 +0000379
bsalomon@google.comc7818882013-03-20 19:19:53 +0000380 void set(GrDrawState* drawState, const SkMatrix& preconcatMatrix);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000381
bsalomon@google.com137f1342013-05-29 21:27:53 +0000382 /** Sets the draw state's matrix to identity. This can fail because the current view matrix
383 is not invertible. */
384 bool setIdentity(GrDrawState* drawState);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000385
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000386 private:
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000387 void doEffectCoordChanges(const SkMatrix& coordChangeMatrix);
388
389 GrDrawState* fDrawState;
390 SkMatrix fViewMatrix;
391 int fNumColorStages;
joshualittbd769d02014-09-04 08:56:46 -0700392 bool fHasGeometryProcessor;
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000393 SkAutoSTArray<8, GrEffectStage::SavedCoordChange> fSavedCoordChanges;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000394 };
395
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000396 /// @}
397
398 ///////////////////////////////////////////////////////////////////////////
399 /// @name Render Target
400 ////
401
402 /**
bsalomon@google.comca432082013-01-23 19:53:46 +0000403 * Sets the render-target used at the next drawing call
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000404 *
405 * @param target The render target to set.
406 */
bsalomon2a9ca782014-09-05 14:27:43 -0700407 void setRenderTarget(GrRenderTarget* target) {
bsalomon45725db2014-09-19 11:48:02 -0700408 fRenderTarget.set(SkSafeRef(target), GrIORef::kWrite_IOType);
egdaniel3658f382014-09-15 07:01:59 -0700409 this->invalidateOptState();
bsalomon2a9ca782014-09-05 14:27:43 -0700410 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000411
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000412 /// @}
413
414 ///////////////////////////////////////////////////////////////////////////
415 /// @name Stencil
416 ////
417
418 /**
419 * Sets the stencil settings to use for the next draw.
420 * Changing the clip has the side-effect of possibly zeroing
421 * out the client settable stencil bits. So multipass algorithms
422 * using stencil should not change the clip between passes.
423 * @param settings the stencil settings to use.
424 */
425 void setStencil(const GrStencilSettings& settings) {
egdaniel3658f382014-09-15 07:01:59 -0700426 if (settings != fStencilSettings) {
427 fStencilSettings = settings;
428 this->invalidateOptState();
429 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000430 }
431
432 /**
433 * Shortcut to disable stencil testing and ops.
434 */
435 void disableStencil() {
egdaniel3658f382014-09-15 07:01:59 -0700436 if (!fStencilSettings.isDisabled()) {
437 fStencilSettings.setDisabled();
438 this->invalidateOptState();
439 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000440 }
441
bsalomon2ed5ef82014-07-07 08:44:05 -0700442 GrStencilSettings* stencil() { return &fStencilSettings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000443
444 /// @}
445
446 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000447 /// @name State Flags
448 ////
tomhudson@google.com62b09682011-11-09 16:39:17 +0000449
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000450 void resetStateFlags() {
egdaniel3658f382014-09-15 07:01:59 -0700451 if (0 != fFlagBits) {
452 fFlagBits = 0;
453 this->invalidateOptState();
454 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000455 }
456
457 /**
458 * Enable render state settings.
459 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000460 * @param stateBits bitfield of StateBits specifying the states to enable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000461 */
462 void enableState(uint32_t stateBits) {
egdaniel3658f382014-09-15 07:01:59 -0700463 if (stateBits & ~fFlagBits) {
464 fFlagBits |= stateBits;
465 this->invalidateOptState();
466 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000467 }
468
469 /**
470 * Disable render state settings.
471 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000472 * @param stateBits bitfield of StateBits specifying the states to disable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000473 */
474 void disableState(uint32_t stateBits) {
egdaniel3658f382014-09-15 07:01:59 -0700475 if (stateBits & fFlagBits) {
476 fFlagBits &= ~(stateBits);
477 this->invalidateOptState();
478 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000479 }
480
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000481 /**
482 * Enable or disable stateBits based on a boolean.
483 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000484 * @param stateBits bitfield of StateBits to enable or disable
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000485 * @param enable if true enable stateBits, otherwise disable
486 */
487 void setState(uint32_t stateBits, bool enable) {
488 if (enable) {
489 this->enableState(stateBits);
490 } else {
491 this->disableState(stateBits);
492 }
493 }
494
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000495 /// @}
496
497 ///////////////////////////////////////////////////////////////////////////
498 /// @name Face Culling
499 ////
500
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000501 /**
502 * Controls whether clockwise, counterclockwise, or both faces are drawn.
503 * @param face the face(s) to draw.
504 */
505 void setDrawFace(DrawFace face) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000506 SkASSERT(kInvalid_DrawFace != face);
bsalomon2ed5ef82014-07-07 08:44:05 -0700507 fDrawFace = face;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000508 }
509
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000510 /// @}
511
512 ///////////////////////////////////////////////////////////////////////////
bsalomon62c447d2014-08-08 08:08:50 -0700513 /// @name Hints
514 /// Hints that when provided can enable optimizations.
515 ////
516
bsalomon62c447d2014-08-08 08:08:50 -0700517 void setHint(Hints hint, bool value) { fHints = value ? (fHints | hint) : (fHints & ~hint); }
518
519 /// @}
520
521 ///////////////////////////////////////////////////////////////////////////
tomhudson@google.com62b09682011-11-09 16:39:17 +0000522
bsalomon838f62d2014-08-05 07:15:57 -0700523 /** Return type for CombineIfPossible. */
524 enum CombinedState {
525 /** The GrDrawStates cannot be combined. */
526 kIncompatible_CombinedState,
527 /** Either draw state can be used in place of the other. */
528 kAOrB_CombinedState,
529 /** Use the first draw state. */
530 kA_CombinedState,
531 /** Use the second draw state. */
532 kB_CombinedState,
533 };
534
535 /** This function determines whether the GrDrawStates used for two draws can be combined into
536 a single GrDrawState. This is used to avoid storing redundant GrDrawStates and to determine
537 if draws can be batched. The return value indicates whether combining is possible and, if
538 so, which of the two inputs should be used. */
bsalomon62c447d2014-08-08 08:08:50 -0700539 static CombinedState CombineIfPossible(const GrDrawState& a, const GrDrawState& b,
540 const GrDrawTargetCaps& caps);
bsalomon72336ed2014-08-05 07:35:56 -0700541
bsalomon8f727332014-08-05 07:50:06 -0700542 GrDrawState& operator= (const GrDrawState& that);
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000543
egdaniel3658f382014-09-15 07:01:59 -0700544 /**
545 * Returns a snapshot of the current optimized state. If the current drawState has a valid
546 * cached optimiezed state it will simply return a pointer to it otherwise it will create a new
547 * GrOptDrawState. In all cases the GrOptDrawState is reffed and ownership is given to the
548 * caller.
549 */
550 GrOptDrawState* createOptState() const;
551
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000552private:
egdaniel170f90b2014-09-16 12:54:40 -0700553 void invalidateOptState() const;
egdaniel3658f382014-09-15 07:01:59 -0700554
bsalomon8f727332014-08-05 07:50:06 -0700555 void onReset(const SkMatrix* initialViewMatrix);
bsalomon@google.com137f1342013-05-29 21:27:53 +0000556
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000557 // Some of the auto restore objects assume that no effects are removed during their lifetime.
558 // This is used to assert that this condition holds.
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +0000559 SkDEBUGCODE(int fBlockEffectRemovalCnt;)
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000560
egdaniel7b3d5ee2014-08-28 05:41:14 -0700561 void internalSetVertexAttribs(const GrVertexAttrib attribs[], int count, size_t stride);
robertphillips@google.com42903302013-04-20 12:26:07 +0000562
egdaniel3658f382014-09-15 07:01:59 -0700563 mutable GrOptDrawState* fCachedOptState;
564
egdaniel21aed572014-08-26 12:24:06 -0700565 typedef GrRODrawState INHERITED;
tomhudson@google.com93813632011-10-27 20:21:16 +0000566};
567
568#endif