blob: 642ec2669ff9e348f49153b400c75009587dc7cc [file] [log] [blame]
bsalomon@google.comaf84e742012-10-05 13:23:24 +00001/*
2 * Copyright 2012 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#include "GrDrawState.h"
egdaniel3658f382014-09-15 07:01:59 -07009
bsalomon62c447d2014-08-08 08:08:50 -070010#include "GrDrawTargetCaps.h"
egdaniel3658f382014-09-15 07:01:59 -070011#include "GrOptDrawState.h"
12#include "GrPaint.h"
13
14//////////////////////////////////////////////////////////////////////////////s
15
16GrOptDrawState* GrDrawState::createOptState() const {
17 if (NULL == fCachedOptState) {
egdaniel8a4c1032014-09-16 07:18:54 -070018 fCachedOptState = SkNEW_ARGS(GrOptDrawState, (*this));
egdaniel3658f382014-09-15 07:01:59 -070019 } else {
egdaniel8a4c1032014-09-16 07:18:54 -070020 SkASSERT(GrOptDrawState(*this) == *fCachedOptState);
egdaniel3658f382014-09-15 07:01:59 -070021 }
22 fCachedOptState->ref();
23 return fCachedOptState;
24}
bsalomon@google.comaf84e742012-10-05 13:23:24 +000025
bsalomon8f727332014-08-05 07:50:06 -070026//////////////////////////////////////////////////////////////////////////////s
27
28GrDrawState::CombinedState GrDrawState::CombineIfPossible(
bsalomon62c447d2014-08-08 08:08:50 -070029 const GrDrawState& a, const GrDrawState& b, const GrDrawTargetCaps& caps) {
bsalomon8f727332014-08-05 07:50:06 -070030
egdaniel21aed572014-08-26 12:24:06 -070031 if (!a.isEqual(b)) {
bsalomon8f727332014-08-05 07:50:06 -070032 return kIncompatible_CombinedState;
33 }
34
egdaniel21aed572014-08-26 12:24:06 -070035 // If the general draw states are equal (from check above) we know hasColorVertexAttribute()
36 // is equivalent for both a and b
37 if (a.hasColorVertexAttribute()) {
bsalomon62c447d2014-08-08 08:08:50 -070038 // If one is opaque and the other is not then the combined state is not opaque. Moreover,
39 // if the opaqueness affects the ability to get color/coverage blending correct then we
40 // don't combine the draw states.
41 bool aIsOpaque = (kVertexColorsAreOpaque_Hint & a.fHints);
42 bool bIsOpaque = (kVertexColorsAreOpaque_Hint & b.fHints);
43 if (aIsOpaque != bIsOpaque) {
44 const GrDrawState* opaque;
45 const GrDrawState* nonOpaque;
46 if (aIsOpaque) {
47 opaque = &a;
48 nonOpaque = &b;
49 } else {
50 opaque = &b;
51 nonOpaque = &a;
52 }
53 if (!opaque->hasSolidCoverage() && opaque->couldApplyCoverage(caps)) {
54 SkASSERT(!nonOpaque->hasSolidCoverage());
55 if (!nonOpaque->couldApplyCoverage(caps)) {
56 return kIncompatible_CombinedState;
57 }
58 }
59 return aIsOpaque ? kB_CombinedState : kA_CombinedState;
60 }
61 }
bsalomon8f727332014-08-05 07:50:06 -070062 return kAOrB_CombinedState;
63}
64
bsalomon8f727332014-08-05 07:50:06 -070065//////////////////////////////////////////////////////////////////////////////s
66
egdaniel3658f382014-09-15 07:01:59 -070067GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix)
68 : fCachedOptState(NULL) {
bsalomon8f727332014-08-05 07:50:06 -070069 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
70 *this = state;
71 if (!preConcatMatrix.isIdentity()) {
joshualittbd769d02014-09-04 08:56:46 -070072 if (this->hasGeometryProcessor()) {
73 fGeometryProcessor->localCoordChange(preConcatMatrix);
74 }
egdaniel776bdbd2014-08-06 11:07:02 -070075 for (int i = 0; i < this->numColorStages(); ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -070076 fColorStages[i].localCoordChange(preConcatMatrix);
bsalomon8f727332014-08-05 07:50:06 -070077 }
egdaniel776bdbd2014-08-06 11:07:02 -070078 for (int i = 0; i < this->numCoverageStages(); ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -070079 fCoverageStages[i].localCoordChange(preConcatMatrix);
bsalomon8f727332014-08-05 07:50:06 -070080 }
egdaniel3658f382014-09-15 07:01:59 -070081 this->invalidateOptState();
bsalomon8f727332014-08-05 07:50:06 -070082 }
83}
84
85GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
86 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
bsalomon2a9ca782014-09-05 14:27:43 -070087 SkASSERT(!that.fRenderTarget.ownsPendingIO());
88 SkASSERT(!this->fRenderTarget.ownsPendingIO());
89 this->setRenderTarget(that.getRenderTarget());
bsalomon8f727332014-08-05 07:50:06 -070090 fColor = that.fColor;
91 fViewMatrix = that.fViewMatrix;
egdaniel8cbf3d52014-08-21 06:27:22 -070092 fSrcBlend = that.fSrcBlend;
93 fDstBlend = that.fDstBlend;
bsalomon8f727332014-08-05 07:50:06 -070094 fBlendConstant = that.fBlendConstant;
95 fFlagBits = that.fFlagBits;
96 fVACount = that.fVACount;
97 fVAPtr = that.fVAPtr;
egdaniel7b3d5ee2014-08-28 05:41:14 -070098 fVAStride = that.fVAStride;
bsalomon8f727332014-08-05 07:50:06 -070099 fStencilSettings = that.fStencilSettings;
100 fCoverage = that.fCoverage;
101 fDrawFace = that.fDrawFace;
joshualittbd769d02014-09-04 08:56:46 -0700102 if (that.hasGeometryProcessor()) {
103 fGeometryProcessor.reset(SkNEW_ARGS(GrEffectStage, (*that.fGeometryProcessor.get())));
104 } else {
105 fGeometryProcessor.reset(NULL);
106 }
egdaniel8cbf3d52014-08-21 06:27:22 -0700107 fColorStages = that.fColorStages;
108 fCoverageStages = that.fCoverageStages;
egdaniel8a4c1032014-09-16 07:18:54 -0700109 fOptSrcBlend = that.fOptSrcBlend;
110 fOptDstBlend = that.fOptDstBlend;
111 fBlendOptFlags = that.fBlendOptFlags;
bsalomon8f727332014-08-05 07:50:06 -0700112
bsalomon62c447d2014-08-08 08:08:50 -0700113 fHints = that.fHints;
egdaniel776bdbd2014-08-06 11:07:02 -0700114
egdaniel3658f382014-09-15 07:01:59 -0700115 SkRefCnt_SafeAssign(fCachedOptState, that.fCachedOptState);
116
bsalomon8f727332014-08-05 07:50:06 -0700117 memcpy(fFixedFunctionVertexAttribIndices,
118 that.fFixedFunctionVertexAttribIndices,
119 sizeof(fFixedFunctionVertexAttribIndices));
120 return *this;
121}
122
123void GrDrawState::onReset(const SkMatrix* initialViewMatrix) {
124 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
bsalomon2a9ca782014-09-05 14:27:43 -0700125 SkASSERT(!fRenderTarget.ownsPendingIO());
126
joshualittbd769d02014-09-04 08:56:46 -0700127 fGeometryProcessor.reset(NULL);
egdaniel8cbf3d52014-08-21 06:27:22 -0700128 fColorStages.reset();
129 fCoverageStages.reset();
bsalomon8f727332014-08-05 07:50:06 -0700130
bsalomon2a9ca782014-09-05 14:27:43 -0700131 fRenderTarget.reset();
bsalomon8f727332014-08-05 07:50:06 -0700132
133 this->setDefaultVertexAttribs();
134
135 fColor = 0xffffffff;
136 if (NULL == initialViewMatrix) {
137 fViewMatrix.reset();
138 } else {
139 fViewMatrix = *initialViewMatrix;
140 }
egdaniel8cbf3d52014-08-21 06:27:22 -0700141 fSrcBlend = kOne_GrBlendCoeff;
142 fDstBlend = kZero_GrBlendCoeff;
bsalomon8f727332014-08-05 07:50:06 -0700143 fBlendConstant = 0x0;
144 fFlagBits = 0x0;
145 fStencilSettings.setDisabled();
egdaniel8cbf3d52014-08-21 06:27:22 -0700146 fCoverage = 0xff;
bsalomon8f727332014-08-05 07:50:06 -0700147 fDrawFace = kBoth_DrawFace;
148
bsalomon62c447d2014-08-08 08:08:50 -0700149 fHints = 0;
150
egdaniel3658f382014-09-15 07:01:59 -0700151 this->invalidateOptState();
bsalomon8f727332014-08-05 07:50:06 -0700152}
153
bsalomon@google.com137f1342013-05-29 21:27:53 +0000154bool GrDrawState::setIdentityViewMatrix() {
egdaniel776bdbd2014-08-06 11:07:02 -0700155 if (this->numTotalStages()) {
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000156 SkMatrix invVM;
bsalomon2ed5ef82014-07-07 08:44:05 -0700157 if (!fViewMatrix.invert(&invVM)) {
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000158 // sad trombone sound
159 return false;
160 }
joshualittbd769d02014-09-04 08:56:46 -0700161 if (this->hasGeometryProcessor()) {
162 fGeometryProcessor->localCoordChange(invVM);
163 }
egdaniel776bdbd2014-08-06 11:07:02 -0700164 for (int s = 0; s < this->numColorStages(); ++s) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700165 fColorStages[s].localCoordChange(invVM);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000166 }
egdaniel776bdbd2014-08-06 11:07:02 -0700167 for (int s = 0; s < this->numCoverageStages(); ++s) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700168 fCoverageStages[s].localCoordChange(invVM);
bsalomon@google.com137f1342013-05-29 21:27:53 +0000169 }
170 }
egdaniel3658f382014-09-15 07:01:59 -0700171 this->invalidateOptState();
bsalomon2ed5ef82014-07-07 08:44:05 -0700172 fViewMatrix.reset();
bsalomon@google.com137f1342013-05-29 21:27:53 +0000173 return true;
174}
175
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000176void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRenderTarget* rt) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000177 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000178
joshualittbd769d02014-09-04 08:56:46 -0700179 fGeometryProcessor.reset(NULL);
egdaniel8cbf3d52014-08-21 06:27:22 -0700180 fColorStages.reset();
181 fCoverageStages.reset();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000182
commit-bot@chromium.org42dacab2013-07-13 17:24:24 +0000183 for (int i = 0; i < paint.numColorStages(); ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700184 fColorStages.push_back(paint.getColorStage(i));
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000185 }
186
commit-bot@chromium.org42dacab2013-07-13 17:24:24 +0000187 for (int i = 0; i < paint.numCoverageStages(); ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700188 fCoverageStages.push_back(paint.getCoverageStage(i));
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000189 }
190
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000191 this->setRenderTarget(rt);
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000192
bsalomon2ed5ef82014-07-07 08:44:05 -0700193 fViewMatrix = vm;
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000194
195 // These have no equivalent in GrPaint, set them to defaults
bsalomon2ed5ef82014-07-07 08:44:05 -0700196 fBlendConstant = 0x0;
197 fDrawFace = kBoth_DrawFace;
198 fStencilSettings.setDisabled();
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000199 this->resetStateFlags();
bsalomon62c447d2014-08-08 08:08:50 -0700200 fHints = 0;
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000201
bsalomon@google.com21c10c52013-06-13 17:44:07 +0000202 // Enable the clip bit
203 this->enableState(GrDrawState::kClip_StateBit);
204
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000205 this->setColor(paint.getColor());
bsalomon@google.comc7448ce2012-10-05 19:04:13 +0000206 this->setState(GrDrawState::kDither_StateBit, paint.isDither());
207 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias());
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000208
bsalomon@google.comc7448ce2012-10-05 19:04:13 +0000209 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff());
bsalomon@google.comc7448ce2012-10-05 19:04:13 +0000210 this->setCoverage(paint.getCoverage());
egdaniel3658f382014-09-15 07:01:59 -0700211 this->invalidateOptState();
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000212}
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000213
214////////////////////////////////////////////////////////////////////////////////
215
egdaniel7b3d5ee2014-08-28 05:41:14 -0700216static void validate_vertex_attribs(const GrVertexAttrib* attribs, int count, size_t stride) {
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000217 // this works as long as we're 4 byte-aligned
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000218#ifdef SK_DEBUG
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000219 uint32_t overlapCheck = 0;
egdaniel21aed572014-08-26 12:24:06 -0700220 SkASSERT(count <= GrRODrawState::kMaxVertexAttribCnt);
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000221 for (int index = 0; index < count; ++index) {
jvanverth@google.com054ae992013-04-01 20:06:51 +0000222 size_t attribSize = GrVertexAttribTypeSize(attribs[index].fType);
egdaniel7b3d5ee2014-08-28 05:41:14 -0700223 size_t attribOffset = attribs[index].fOffset;
224 SkASSERT(attribOffset + attribSize <= stride);
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000225 size_t dwordCount = attribSize >> 2;
226 uint32_t mask = (1 << dwordCount)-1;
egdaniel7b3d5ee2014-08-28 05:41:14 -0700227 size_t offsetShift = attribOffset >> 2;
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000228 SkASSERT(!(overlapCheck & (mask << offsetShift)));
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000229 overlapCheck |= (mask << offsetShift);
djsollenea81ced2014-08-27 13:07:34 -0700230 }
egdaniel7b3d5ee2014-08-28 05:41:14 -0700231#endif
jvanverth@google.comcc782382013-01-28 20:39:48 +0000232}
233
234////////////////////////////////////////////////////////////////////////////////
235
egdaniel7b3d5ee2014-08-28 05:41:14 -0700236void GrDrawState::internalSetVertexAttribs(const GrVertexAttrib* attribs, int count,
237 size_t stride) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000238 SkASSERT(count <= kMaxVertexAttribCnt);
robertphillips@google.com42903302013-04-20 12:26:07 +0000239
bsalomon2ed5ef82014-07-07 08:44:05 -0700240 fVAPtr = attribs;
241 fVACount = count;
egdaniel7b3d5ee2014-08-28 05:41:14 -0700242 fVAStride = stride;
243 validate_vertex_attribs(fVAPtr, fVACount, fVAStride);
jvanverth@google.com054ae992013-04-01 20:06:51 +0000244
245 // Set all the indices to -1
bsalomon2ed5ef82014-07-07 08:44:05 -0700246 memset(fFixedFunctionVertexAttribIndices,
jvanverth@google.com054ae992013-04-01 20:06:51 +0000247 0xff,
bsalomon2ed5ef82014-07-07 08:44:05 -0700248 sizeof(fFixedFunctionVertexAttribIndices));
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000249#ifdef SK_DEBUG
jvanverth@google.com054ae992013-04-01 20:06:51 +0000250 uint32_t overlapCheck = 0;
251#endif
252 for (int i = 0; i < count; ++i) {
253 if (attribs[i].fBinding < kGrFixedFunctionVertexAttribBindingCnt) {
254 // The fixed function attribs can only be specified once
bsalomon2ed5ef82014-07-07 08:44:05 -0700255 SkASSERT(-1 == fFixedFunctionVertexAttribIndices[attribs[i].fBinding]);
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000256 SkASSERT(GrFixedFunctionVertexAttribVectorCount(attribs[i].fBinding) ==
jvanverth@google.com054ae992013-04-01 20:06:51 +0000257 GrVertexAttribTypeVectorCount(attribs[i].fType));
bsalomon2ed5ef82014-07-07 08:44:05 -0700258 fFixedFunctionVertexAttribIndices[attribs[i].fBinding] = i;
jvanverth@google.com054ae992013-04-01 20:06:51 +0000259 }
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000260#ifdef SK_DEBUG
jvanverth@google.com054ae992013-04-01 20:06:51 +0000261 size_t dwordCount = GrVertexAttribTypeSize(attribs[i].fType) >> 2;
262 uint32_t mask = (1 << dwordCount)-1;
263 size_t offsetShift = attribs[i].fOffset >> 2;
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000264 SkASSERT(!(overlapCheck & (mask << offsetShift)));
jvanverth@google.com054ae992013-04-01 20:06:51 +0000265 overlapCheck |= (mask << offsetShift);
266#endif
jvanverth@google.comcc782382013-01-28 20:39:48 +0000267 }
egdaniel3658f382014-09-15 07:01:59 -0700268 this->invalidateOptState();
jvanverth@google.com054ae992013-04-01 20:06:51 +0000269 // Positions must be specified.
bsalomon2ed5ef82014-07-07 08:44:05 -0700270 SkASSERT(-1 != fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding]);
jvanverth@google.comcc782382013-01-28 20:39:48 +0000271}
272
273////////////////////////////////////////////////////////////////////////////////
274
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000275void GrDrawState::setDefaultVertexAttribs() {
jvanverth@google.com054ae992013-04-01 20:06:51 +0000276 static const GrVertexAttrib kPositionAttrib =
277 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding};
robertphillips@google.com42903302013-04-20 12:26:07 +0000278
bsalomon2ed5ef82014-07-07 08:44:05 -0700279 fVAPtr = &kPositionAttrib;
280 fVACount = 1;
egdaniel7b3d5ee2014-08-28 05:41:14 -0700281 fVAStride = GrVertexAttribTypeSize(kVec2f_GrVertexAttribType);
robertphillips@google.com42903302013-04-20 12:26:07 +0000282
jvanverth@google.com054ae992013-04-01 20:06:51 +0000283 // set all the fixed function indices to -1 except position.
bsalomon2ed5ef82014-07-07 08:44:05 -0700284 memset(fFixedFunctionVertexAttribIndices,
jvanverth@google.com054ae992013-04-01 20:06:51 +0000285 0xff,
bsalomon2ed5ef82014-07-07 08:44:05 -0700286 sizeof(fFixedFunctionVertexAttribIndices));
287 fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0;
egdaniel3658f382014-09-15 07:01:59 -0700288 this->invalidateOptState();
jvanverth@google.comcc782382013-01-28 20:39:48 +0000289}
290
291////////////////////////////////////////////////////////////////////////////////
292
bsalomon62c447d2014-08-08 08:08:50 -0700293bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const {
294 if (caps.dualSourceBlendingSupport()) {
295 return true;
296 }
297 // we can correctly apply coverage if a) we have dual source blending
298 // or b) one of our blend optimizations applies
299 // or c) the src, dst blend coeffs are 1,0 and we will read Dst Color
300 GrBlendCoeff srcCoeff;
301 GrBlendCoeff dstCoeff;
egdaniel8a4c1032014-09-16 07:18:54 -0700302 GrRODrawState::BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dstCoeff);
egdaniel21aed572014-08-26 12:24:06 -0700303 return GrRODrawState::kNone_BlendOpt != flag ||
bsalomon62c447d2014-08-08 08:08:50 -0700304 (this->willEffectReadDstColor() &&
305 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff);
306}
307
egdaniel21aed572014-08-26 12:24:06 -0700308//////////////////////////////////////////////////////////////////////////////
jvanverth@google.comcc782382013-01-28 20:39:48 +0000309
egdaniel3658f382014-09-15 07:01:59 -0700310GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore(GrDrawState* drawState) {
bsalomon49f085d2014-09-05 13:34:00 -0700311 SkASSERT(drawState);
egdaniel21aed572014-08-26 12:24:06 -0700312 fDrawState = drawState;
313 fVAPtr = drawState->fVAPtr;
314 fVACount = drawState->fVACount;
egdaniel7b3d5ee2014-08-28 05:41:14 -0700315 fVAStride = drawState->fVAStride;
egdaniel21aed572014-08-26 12:24:06 -0700316 fDrawState->setDefaultVertexAttribs();
jvanverth@google.comcc782382013-01-28 20:39:48 +0000317}
318
egdaniel21aed572014-08-26 12:24:06 -0700319//////////////////////////////////////////////////////////////////////////////s
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000320
egdaniel21aed572014-08-26 12:24:06 -0700321void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
bsalomon49f085d2014-09-05 13:34:00 -0700322 if (fDrawState) {
bsalomon9b536522014-09-05 09:18:51 -0700323 // See the big comment on the class definition about GPs.
bsalomon52e9d632014-09-05 12:23:12 -0700324 if (SK_InvalidUniqueID == fOriginalGPID) {
bsalomon9b536522014-09-05 09:18:51 -0700325 fDrawState->fGeometryProcessor.reset(NULL);
bsalomon52e9d632014-09-05 12:23:12 -0700326 } else {
327 SkASSERT(fDrawState->getGeometryProcessor()->getEffect()->getUniqueID() ==
328 fOriginalGPID);
329 fOriginalGPID = SK_InvalidUniqueID;
bsalomon9b536522014-09-05 09:18:51 -0700330 }
joshualittbd769d02014-09-04 08:56:46 -0700331
egdaniel21aed572014-08-26 12:24:06 -0700332 int m = fDrawState->numColorStages() - fColorEffectCnt;
333 SkASSERT(m >= 0);
334 fDrawState->fColorStages.pop_back_n(m);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000335
egdaniel21aed572014-08-26 12:24:06 -0700336 int n = fDrawState->numCoverageStages() - fCoverageEffectCnt;
337 SkASSERT(n >= 0);
338 fDrawState->fCoverageStages.pop_back_n(n);
339 if (m + n > 0) {
egdaniel3658f382014-09-15 07:01:59 -0700340 fDrawState->invalidateOptState();
egdaniel21aed572014-08-26 12:24:06 -0700341 }
342 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000343 }
egdaniel21aed572014-08-26 12:24:06 -0700344 fDrawState = ds;
345 if (NULL != ds) {
bsalomon52e9d632014-09-05 12:23:12 -0700346 SkASSERT(SK_InvalidUniqueID == fOriginalGPID);
bsalomon9b536522014-09-05 09:18:51 -0700347 if (NULL != ds->getGeometryProcessor()) {
bsalomon52e9d632014-09-05 12:23:12 -0700348 fOriginalGPID = ds->getGeometryProcessor()->getEffect()->getUniqueID();
joshualittbd769d02014-09-04 08:56:46 -0700349 }
egdaniel21aed572014-08-26 12:24:06 -0700350 fColorEffectCnt = ds->numColorStages();
351 fCoverageEffectCnt = ds->numCoverageStages();
352 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;)
353 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000354}
355
jvanverth@google.comcc782382013-01-28 20:39:48 +0000356////////////////////////////////////////////////////////////////////////////////
357
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000358void GrDrawState::AutoViewMatrixRestore::restore() {
bsalomon49f085d2014-09-05 13:34:00 -0700359 if (fDrawState) {
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +0000360 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
bsalomon2ed5ef82014-07-07 08:44:05 -0700361 fDrawState->fViewMatrix = fViewMatrix;
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000362 SkASSERT(fDrawState->numColorStages() >= fNumColorStages);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000363 int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages;
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000364 SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000365
366 int i = 0;
joshualittbd769d02014-09-04 08:56:46 -0700367 if (fHasGeometryProcessor) {
368 SkASSERT(fDrawState->hasGeometryProcessor());
369 fDrawState->fGeometryProcessor->restoreCoordChange(fSavedCoordChanges[i++]);
370 }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000371 for (int s = 0; s < fNumColorStages; ++s, ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700372 fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000373 }
374 for (int s = 0; s < numCoverageStages; ++s, ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700375 fDrawState->fCoverageStages[s].restoreCoordChange(fSavedCoordChanges[i]);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000376 }
egdaniel3658f382014-09-15 07:01:59 -0700377 fDrawState->invalidateOptState();
bsalomon@google.com137f1342013-05-29 21:27:53 +0000378 fDrawState = NULL;
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000379 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000380}
381
382void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState,
bsalomon@google.comc7818882013-03-20 19:19:53 +0000383 const SkMatrix& preconcatMatrix) {
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000384 this->restore();
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000385
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000386 SkASSERT(NULL == fDrawState);
bsalomon@google.com137f1342013-05-29 21:27:53 +0000387 if (NULL == drawState || preconcatMatrix.isIdentity()) {
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000388 return;
389 }
bsalomon@google.com137f1342013-05-29 21:27:53 +0000390 fDrawState = drawState;
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000391
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000392 fViewMatrix = drawState->getViewMatrix();
bsalomon2ed5ef82014-07-07 08:44:05 -0700393 drawState->fViewMatrix.preConcat(preconcatMatrix);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000394
395 this->doEffectCoordChanges(preconcatMatrix);
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +0000396 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
egdaniel3658f382014-09-15 07:01:59 -0700397 drawState->invalidateOptState();
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000398}
399
bsalomon@google.com137f1342013-05-29 21:27:53 +0000400bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) {
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000401 this->restore();
402
bsalomon@google.com137f1342013-05-29 21:27:53 +0000403 if (NULL == drawState) {
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000404 return false;
skia.committer@gmail.comf467ce72012-10-09 02:01:37 +0000405 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000406
bsalomon@google.com137f1342013-05-29 21:27:53 +0000407 if (drawState->getViewMatrix().isIdentity()) {
408 return true;
409 }
410
egdaniel3658f382014-09-15 07:01:59 -0700411 drawState->invalidateOptState();
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000412 fViewMatrix = drawState->getViewMatrix();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000413 if (0 == drawState->numTotalStages()) {
bsalomon2ed5ef82014-07-07 08:44:05 -0700414 drawState->fViewMatrix.reset();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000415 fDrawState = drawState;
joshualittbd769d02014-09-04 08:56:46 -0700416 fHasGeometryProcessor = false;
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000417 fNumColorStages = 0;
418 fSavedCoordChanges.reset(0);
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +0000419 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000420 return true;
421 } else {
422 SkMatrix inv;
423 if (!fViewMatrix.invert(&inv)) {
424 return false;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000425 }
bsalomon2ed5ef82014-07-07 08:44:05 -0700426 drawState->fViewMatrix.reset();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000427 fDrawState = drawState;
428 this->doEffectCoordChanges(inv);
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +0000429 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000430 return true;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000431 }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000432}
433
434void GrDrawState::AutoViewMatrixRestore::doEffectCoordChanges(const SkMatrix& coordChangeMatrix) {
435 fSavedCoordChanges.reset(fDrawState->numTotalStages());
436 int i = 0;
437
joshualittbd769d02014-09-04 08:56:46 -0700438 fHasGeometryProcessor = false;
439 if (fDrawState->hasGeometryProcessor()) {
440 fDrawState->fGeometryProcessor->saveCoordChange(&fSavedCoordChanges[i++]);
441 fDrawState->fGeometryProcessor->localCoordChange(coordChangeMatrix);
442 fHasGeometryProcessor = true;
443 }
444
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000445 fNumColorStages = fDrawState->numColorStages();
446 for (int s = 0; s < fNumColorStages; ++s, ++i) {
egdaniel776bdbd2014-08-06 11:07:02 -0700447 fDrawState->getColorStage(s).saveCoordChange(&fSavedCoordChanges[i]);
egdaniel8cbf3d52014-08-21 06:27:22 -0700448 fDrawState->fColorStages[s].localCoordChange(coordChangeMatrix);
bsalomon@google.com137f1342013-05-29 21:27:53 +0000449 }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000450
451 int numCoverageStages = fDrawState->numCoverageStages();
452 for (int s = 0; s < numCoverageStages; ++s, ++i) {
egdaniel776bdbd2014-08-06 11:07:02 -0700453 fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]);
egdaniel8cbf3d52014-08-21 06:27:22 -0700454 fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000455 }
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000456}
egdaniel21aed572014-08-26 12:24:06 -0700457