blob: a91a43c44e5f003b874a5efe7941496c3fc90b7a [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
egdanielb1cff032014-11-13 06:19:25 -080010#include "GrBlend.h"
egdaniel3658f382014-09-15 07:01:59 -070011#include "GrOptDrawState.h"
12#include "GrPaint.h"
egdanielb6cbc382014-11-13 11:00:34 -080013#include "GrProcOptInfo.h"
egdaniel378092f2014-12-03 10:40:13 -080014#include "GrXferProcessor.h"
15#include "effects/GrPorterDuffXferProcessor.h"
egdaniel3658f382014-09-15 07:01:59 -070016
egdaniel89af44a2014-09-26 06:15:04 -070017bool GrDrawState::isEqual(const GrDrawState& that) const {
egdaniel89af44a2014-09-26 06:15:04 -070018 if (this->getRenderTarget() != that.getRenderTarget() ||
19 this->fColorStages.count() != that.fColorStages.count() ||
20 this->fCoverageStages.count() != that.fCoverageStages.count() ||
21 !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) ||
egdaniel89af44a2014-09-26 06:15:04 -070022 this->fFlagBits != that.fFlagBits ||
egdaniel89af44a2014-09-26 06:15:04 -070023 this->fStencilSettings != that.fStencilSettings ||
24 this->fDrawFace != that.fDrawFace) {
25 return false;
26 }
27
egdaniel89af44a2014-09-26 06:15:04 -070028 bool explicitLocalCoords = this->hasLocalCoordAttribute();
29 if (this->hasGeometryProcessor()) {
30 if (!that.hasGeometryProcessor()) {
31 return false;
joshualitta5305a12014-10-10 17:47:00 -070032 } else if (!this->getGeometryProcessor()->isEqual(*that.getGeometryProcessor())) {
egdaniel89af44a2014-09-26 06:15:04 -070033 return false;
34 }
35 } else if (that.hasGeometryProcessor()) {
36 return false;
37 }
38
egdaniel915187b2014-12-05 12:58:28 -080039 if (!this->getXPFactory()->isEqual(*that.getXPFactory())) {
40 return false;
41 }
42
egdaniel89af44a2014-09-26 06:15:04 -070043 for (int i = 0; i < this->numColorStages(); i++) {
joshualitta5305a12014-10-10 17:47:00 -070044 if (!GrFragmentStage::AreCompatible(this->getColorStage(i), that.getColorStage(i),
egdaniel89af44a2014-09-26 06:15:04 -070045 explicitLocalCoords)) {
46 return false;
47 }
48 }
49 for (int i = 0; i < this->numCoverageStages(); i++) {
joshualitta5305a12014-10-10 17:47:00 -070050 if (!GrFragmentStage::AreCompatible(this->getCoverageStage(i), that.getCoverageStage(i),
egdaniel89af44a2014-09-26 06:15:04 -070051 explicitLocalCoords)) {
52 return false;
53 }
54 }
55
egdaniel89af44a2014-09-26 06:15:04 -070056 return true;
57}
58
bsalomon8f727332014-08-05 07:50:06 -070059//////////////////////////////////////////////////////////////////////////////s
60
egdaniel69bb90c2014-11-11 07:32:45 -080061GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix) {
bsalomon8f727332014-08-05 07:50:06 -070062 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
63 *this = state;
64 if (!preConcatMatrix.isIdentity()) {
egdaniel776bdbd2014-08-06 11:07:02 -070065 for (int i = 0; i < this->numColorStages(); ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -070066 fColorStages[i].localCoordChange(preConcatMatrix);
bsalomon8f727332014-08-05 07:50:06 -070067 }
egdaniel776bdbd2014-08-06 11:07:02 -070068 for (int i = 0; i < this->numCoverageStages(); ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -070069 fCoverageStages[i].localCoordChange(preConcatMatrix);
bsalomon8f727332014-08-05 07:50:06 -070070 }
bsalomon8f727332014-08-05 07:50:06 -070071 }
72}
73
74GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
bsalomonae59b772014-11-19 08:23:49 -080075 fRenderTarget.reset(SkSafeRef(that.fRenderTarget.get()));
bsalomon8f727332014-08-05 07:50:06 -070076 fViewMatrix = that.fViewMatrix;
bsalomon8f727332014-08-05 07:50:06 -070077 fFlagBits = that.fFlagBits;
bsalomon8f727332014-08-05 07:50:06 -070078 fStencilSettings = that.fStencilSettings;
bsalomon8f727332014-08-05 07:50:06 -070079 fDrawFace = that.fDrawFace;
bsalomonae59b772014-11-19 08:23:49 -080080 fGeometryProcessor.reset(SkSafeRef(that.fGeometryProcessor.get()));
egdaniel378092f2014-12-03 10:40:13 -080081 fXPFactory.reset(SkRef(that.getXPFactory()));
egdaniel8cbf3d52014-08-21 06:27:22 -070082 fColorStages = that.fColorStages;
83 fCoverageStages = that.fCoverageStages;
bsalomon8f727332014-08-05 07:50:06 -070084
bsalomon62c447d2014-08-08 08:08:50 -070085 fHints = that.fHints;
egdaniel776bdbd2014-08-06 11:07:02 -070086
egdanielb6cbc382014-11-13 11:00:34 -080087 fColorProcInfoValid = that.fColorProcInfoValid;
88 fCoverageProcInfoValid = that.fCoverageProcInfoValid;
89 if (fColorProcInfoValid) {
90 fColorProcInfo = that.fColorProcInfo;
91 }
92 if (fCoverageProcInfoValid) {
93 fCoverageProcInfo = that.fCoverageProcInfo;
94 }
bsalomon8f727332014-08-05 07:50:06 -070095 return *this;
96}
97
98void GrDrawState::onReset(const SkMatrix* initialViewMatrix) {
99 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
bsalomonae59b772014-11-19 08:23:49 -0800100 fRenderTarget.reset(NULL);
bsalomon2a9ca782014-09-05 14:27:43 -0700101
joshualittbd769d02014-09-04 08:56:46 -0700102 fGeometryProcessor.reset(NULL);
egdanielc016fb82014-12-03 11:41:54 -0800103 fXPFactory.reset(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode));
egdaniel8cbf3d52014-08-21 06:27:22 -0700104 fColorStages.reset();
105 fCoverageStages.reset();
bsalomon8f727332014-08-05 07:50:06 -0700106
bsalomon8f727332014-08-05 07:50:06 -0700107 if (NULL == initialViewMatrix) {
108 fViewMatrix.reset();
109 } else {
110 fViewMatrix = *initialViewMatrix;
111 }
bsalomon8f727332014-08-05 07:50:06 -0700112 fFlagBits = 0x0;
113 fStencilSettings.setDisabled();
bsalomon8f727332014-08-05 07:50:06 -0700114 fDrawFace = kBoth_DrawFace;
115
bsalomon62c447d2014-08-08 08:08:50 -0700116 fHints = 0;
egdanielb6cbc382014-11-13 11:00:34 -0800117
118 fColorProcInfoValid = false;
119 fCoverageProcInfoValid = false;
bsalomon8f727332014-08-05 07:50:06 -0700120}
121
bsalomon@google.com137f1342013-05-29 21:27:53 +0000122bool GrDrawState::setIdentityViewMatrix() {
joshualitt4dd99882014-11-11 08:51:30 -0800123 if (this->numFragmentStages()) {
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000124 SkMatrix invVM;
bsalomon2ed5ef82014-07-07 08:44:05 -0700125 if (!fViewMatrix.invert(&invVM)) {
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000126 // sad trombone sound
127 return false;
128 }
egdaniel776bdbd2014-08-06 11:07:02 -0700129 for (int s = 0; s < this->numColorStages(); ++s) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700130 fColorStages[s].localCoordChange(invVM);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000131 }
egdaniel776bdbd2014-08-06 11:07:02 -0700132 for (int s = 0; s < this->numCoverageStages(); ++s) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700133 fCoverageStages[s].localCoordChange(invVM);
bsalomon@google.com137f1342013-05-29 21:27:53 +0000134 }
135 }
bsalomon2ed5ef82014-07-07 08:44:05 -0700136 fViewMatrix.reset();
bsalomon@google.com137f1342013-05-29 21:27:53 +0000137 return true;
138}
139
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000140void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRenderTarget* rt) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000141 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000142
joshualittbd769d02014-09-04 08:56:46 -0700143 fGeometryProcessor.reset(NULL);
egdaniel8cbf3d52014-08-21 06:27:22 -0700144 fColorStages.reset();
145 fCoverageStages.reset();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000146
commit-bot@chromium.org42dacab2013-07-13 17:24:24 +0000147 for (int i = 0; i < paint.numColorStages(); ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700148 fColorStages.push_back(paint.getColorStage(i));
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000149 }
150
commit-bot@chromium.org42dacab2013-07-13 17:24:24 +0000151 for (int i = 0; i < paint.numCoverageStages(); ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700152 fCoverageStages.push_back(paint.getCoverageStage(i));
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000153 }
154
egdaniel378092f2014-12-03 10:40:13 -0800155 fXPFactory.reset(SkRef(paint.getXPFactory()));
156
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000157 this->setRenderTarget(rt);
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000158
bsalomon2ed5ef82014-07-07 08:44:05 -0700159 fViewMatrix = vm;
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000160
161 // These have no equivalent in GrPaint, set them to defaults
bsalomon2ed5ef82014-07-07 08:44:05 -0700162 fDrawFace = kBoth_DrawFace;
163 fStencilSettings.setDisabled();
bsalomon04ddf892014-11-19 12:36:22 -0800164 fFlagBits = 0;
bsalomon62c447d2014-08-08 08:08:50 -0700165 fHints = 0;
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000166
bsalomon@google.com21c10c52013-06-13 17:44:07 +0000167 // Enable the clip bit
168 this->enableState(GrDrawState::kClip_StateBit);
169
bsalomon@google.comc7448ce2012-10-05 19:04:13 +0000170 this->setState(GrDrawState::kDither_StateBit, paint.isDither());
171 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias());
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000172
egdanielb6cbc382014-11-13 11:00:34 -0800173 fColorProcInfoValid = false;
174 fCoverageProcInfoValid = false;
joshualitt2e3b3e32014-12-09 13:31:14 -0800175
176 fColorCache = GrColor_ILLEGAL;
177 fCoverageCache = GrColor_ILLEGAL;
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000178}
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000179
180////////////////////////////////////////////////////////////////////////////////
181
joshualitt2e3b3e32014-12-09 13:31:14 -0800182bool GrDrawState::canUseFracCoveragePrimProc(GrColor color, const GrDrawTargetCaps& caps) const {
bsalomon62c447d2014-08-08 08:08:50 -0700183 if (caps.dualSourceBlendingSupport()) {
184 return true;
185 }
egdaniel95131432014-12-09 11:15:43 -0800186
joshualitt2e3b3e32014-12-09 13:31:14 -0800187 this->calcColorInvariantOutput(color);
188
189 // The coverage isn't actually white, its unknown, but this will produce the same effect
190 // TODO we want to cache the result of this call, but we can probably clean up the interface
191 // so we don't have to pass in a seemingly known coverage
192 this->calcCoverageInvariantOutput(GrColor_WHITE);
egdaniel95131432014-12-09 11:15:43 -0800193 return fXPFactory->canApplyCoverage(fColorProcInfo, fCoverageProcInfo,
194 this->isCoverageDrawing(), this->isColorWriteDisabled());
bsalomon62c447d2014-08-08 08:08:50 -0700195}
196
joshualitt2e3b3e32014-12-09 13:31:14 -0800197bool GrDrawState::hasSolidCoverage(GrColor coverage) const {
egdaniel89af44a2014-09-26 06:15:04 -0700198 // If we're drawing coverage directly then coverage is effectively treated as color.
199 if (this->isCoverageDrawing()) {
200 return true;
201 }
202
joshualitt4dd99882014-11-11 08:51:30 -0800203 if (this->numCoverageStages() > 0) {
204 return false;
205 }
206
joshualitt2e3b3e32014-12-09 13:31:14 -0800207 this->calcCoverageInvariantOutput(coverage);
egdanielb6cbc382014-11-13 11:00:34 -0800208 return fCoverageProcInfo.isSolidWhite();
egdaniel89af44a2014-09-26 06:15:04 -0700209}
210
egdaniel21aed572014-08-26 12:24:06 -0700211//////////////////////////////////////////////////////////////////////////////s
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000212
joshualitt2e3b3e32014-12-09 13:31:14 -0800213bool GrDrawState::willEffectReadDstColor(GrColor color, GrColor coverage) const {
214 this->calcColorInvariantOutput(color);
215 this->calcCoverageInvariantOutput(coverage);
egdaniel95131432014-12-09 11:15:43 -0800216 // TODO: Remove need to create the XP here.
217 // Also once all custom blends are turned into XPs we can remove the need
218 // to check other stages since only xp's will be able to read dst
219 SkAutoTUnref<GrXferProcessor> xferProcessor(fXPFactory->createXferProcessor(fColorProcInfo,
220 fCoverageProcInfo));
221 if (xferProcessor && xferProcessor->willReadDstColor()) {
222 return true;
223 }
224
egdaniel89af44a2014-09-26 06:15:04 -0700225 if (!this->isColorWriteDisabled()) {
egdanielb6cbc382014-11-13 11:00:34 -0800226 if (fColorProcInfo.readsDst()) {
egdaniel89af44a2014-09-26 06:15:04 -0700227 return true;
228 }
229 }
egdanielb6cbc382014-11-13 11:00:34 -0800230 return fCoverageProcInfo.readsDst();
egdaniel89af44a2014-09-26 06:15:04 -0700231}
232
egdaniel21aed572014-08-26 12:24:06 -0700233void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
bsalomon49f085d2014-09-05 13:34:00 -0700234 if (fDrawState) {
bsalomon9b536522014-09-05 09:18:51 -0700235 // See the big comment on the class definition about GPs.
bsalomon52e9d632014-09-05 12:23:12 -0700236 if (SK_InvalidUniqueID == fOriginalGPID) {
bsalomon9b536522014-09-05 09:18:51 -0700237 fDrawState->fGeometryProcessor.reset(NULL);
bsalomon52e9d632014-09-05 12:23:12 -0700238 } else {
joshualitta5305a12014-10-10 17:47:00 -0700239 SkASSERT(fDrawState->getGeometryProcessor()->getUniqueID() ==
bsalomon52e9d632014-09-05 12:23:12 -0700240 fOriginalGPID);
241 fOriginalGPID = SK_InvalidUniqueID;
bsalomon9b536522014-09-05 09:18:51 -0700242 }
joshualittbd769d02014-09-04 08:56:46 -0700243
egdaniel21aed572014-08-26 12:24:06 -0700244 int m = fDrawState->numColorStages() - fColorEffectCnt;
245 SkASSERT(m >= 0);
246 fDrawState->fColorStages.pop_back_n(m);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000247
egdaniel21aed572014-08-26 12:24:06 -0700248 int n = fDrawState->numCoverageStages() - fCoverageEffectCnt;
249 SkASSERT(n >= 0);
250 fDrawState->fCoverageStages.pop_back_n(n);
egdanielb6cbc382014-11-13 11:00:34 -0800251 if (m + n > 0) {
252 fDrawState->fColorProcInfoValid = false;
253 fDrawState->fCoverageProcInfoValid = false;
254 }
egdaniel21aed572014-08-26 12:24:06 -0700255 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000256 }
egdaniel21aed572014-08-26 12:24:06 -0700257 fDrawState = ds;
258 if (NULL != ds) {
bsalomon52e9d632014-09-05 12:23:12 -0700259 SkASSERT(SK_InvalidUniqueID == fOriginalGPID);
bsalomon9b536522014-09-05 09:18:51 -0700260 if (NULL != ds->getGeometryProcessor()) {
joshualitta5305a12014-10-10 17:47:00 -0700261 fOriginalGPID = ds->getGeometryProcessor()->getUniqueID();
joshualittbd769d02014-09-04 08:56:46 -0700262 }
egdaniel21aed572014-08-26 12:24:06 -0700263 fColorEffectCnt = ds->numColorStages();
264 fCoverageEffectCnt = ds->numCoverageStages();
265 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;)
266 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000267}
268
jvanverth@google.comcc782382013-01-28 20:39:48 +0000269////////////////////////////////////////////////////////////////////////////////
270
egdaniel89af44a2014-09-26 06:15:04 -0700271// Some blend modes allow folding a fractional coverage value into the color's alpha channel, while
272// others will blend incorrectly.
273bool GrDrawState::canTweakAlphaForCoverage() const {
egdaniel95131432014-12-09 11:15:43 -0800274 return fXPFactory->canTweakAlphaForCoverage(this->isCoverageDrawing());
egdaniel89af44a2014-09-26 06:15:04 -0700275}
276
277////////////////////////////////////////////////////////////////////////////////
278
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000279void GrDrawState::AutoViewMatrixRestore::restore() {
bsalomon49f085d2014-09-05 13:34:00 -0700280 if (fDrawState) {
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +0000281 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
bsalomon2ed5ef82014-07-07 08:44:05 -0700282 fDrawState->fViewMatrix = fViewMatrix;
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000283 SkASSERT(fDrawState->numColorStages() >= fNumColorStages);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000284 int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages;
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000285 SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000286
287 int i = 0;
288 for (int s = 0; s < fNumColorStages; ++s, ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700289 fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000290 }
291 for (int s = 0; s < numCoverageStages; ++s, ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700292 fDrawState->fCoverageStages[s].restoreCoordChange(fSavedCoordChanges[i]);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000293 }
bsalomon@google.com137f1342013-05-29 21:27:53 +0000294 fDrawState = NULL;
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000295 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000296}
297
298void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState,
bsalomon@google.comc7818882013-03-20 19:19:53 +0000299 const SkMatrix& preconcatMatrix) {
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000300 this->restore();
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000301
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000302 SkASSERT(NULL == fDrawState);
bsalomon@google.com137f1342013-05-29 21:27:53 +0000303 if (NULL == drawState || preconcatMatrix.isIdentity()) {
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000304 return;
305 }
bsalomon@google.com137f1342013-05-29 21:27:53 +0000306 fDrawState = drawState;
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000307
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000308 fViewMatrix = drawState->getViewMatrix();
bsalomon2ed5ef82014-07-07 08:44:05 -0700309 drawState->fViewMatrix.preConcat(preconcatMatrix);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000310
311 this->doEffectCoordChanges(preconcatMatrix);
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +0000312 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000313}
314
bsalomon@google.com137f1342013-05-29 21:27:53 +0000315bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) {
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000316 this->restore();
317
bsalomon@google.com137f1342013-05-29 21:27:53 +0000318 if (NULL == drawState) {
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000319 return false;
skia.committer@gmail.comf467ce72012-10-09 02:01:37 +0000320 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000321
bsalomon@google.com137f1342013-05-29 21:27:53 +0000322 if (drawState->getViewMatrix().isIdentity()) {
323 return true;
324 }
325
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000326 fViewMatrix = drawState->getViewMatrix();
joshualitt4dd99882014-11-11 08:51:30 -0800327 if (0 == drawState->numFragmentStages()) {
bsalomon2ed5ef82014-07-07 08:44:05 -0700328 drawState->fViewMatrix.reset();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000329 fDrawState = drawState;
330 fNumColorStages = 0;
331 fSavedCoordChanges.reset(0);
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +0000332 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000333 return true;
334 } else {
335 SkMatrix inv;
336 if (!fViewMatrix.invert(&inv)) {
337 return false;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000338 }
bsalomon2ed5ef82014-07-07 08:44:05 -0700339 drawState->fViewMatrix.reset();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000340 fDrawState = drawState;
341 this->doEffectCoordChanges(inv);
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +0000342 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000343 return true;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000344 }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000345}
346
347void GrDrawState::AutoViewMatrixRestore::doEffectCoordChanges(const SkMatrix& coordChangeMatrix) {
joshualitt4dd99882014-11-11 08:51:30 -0800348 fSavedCoordChanges.reset(fDrawState->numFragmentStages());
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000349 int i = 0;
350
351 fNumColorStages = fDrawState->numColorStages();
352 for (int s = 0; s < fNumColorStages; ++s, ++i) {
egdaniel776bdbd2014-08-06 11:07:02 -0700353 fDrawState->getColorStage(s).saveCoordChange(&fSavedCoordChanges[i]);
egdaniel8cbf3d52014-08-21 06:27:22 -0700354 fDrawState->fColorStages[s].localCoordChange(coordChangeMatrix);
bsalomon@google.com137f1342013-05-29 21:27:53 +0000355 }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000356
357 int numCoverageStages = fDrawState->numCoverageStages();
358 for (int s = 0; s < numCoverageStages; ++s, ++i) {
egdaniel776bdbd2014-08-06 11:07:02 -0700359 fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]);
egdaniel8cbf3d52014-08-21 06:27:22 -0700360 fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000361 }
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000362}
egdaniel21aed572014-08-26 12:24:06 -0700363
egdaniel170f90b2014-09-16 12:54:40 -0700364////////////////////////////////////////////////////////////////////////////////
365
egdaniel170f90b2014-09-16 12:54:40 -0700366GrDrawState::~GrDrawState() {
egdaniel170f90b2014-09-16 12:54:40 -0700367 SkASSERT(0 == fBlockEffectRemovalCnt);
368}
369
egdaniel89af44a2014-09-26 06:15:04 -0700370////////////////////////////////////////////////////////////////////////////////
371
joshualitt2e3b3e32014-12-09 13:31:14 -0800372bool GrDrawState::srcAlphaWillBeOne(GrColor color, GrColor coverage) const {
373 this->calcColorInvariantOutput(color);
egdaniel89af44a2014-09-26 06:15:04 -0700374 if (this->isCoverageDrawing()) {
joshualitt2e3b3e32014-12-09 13:31:14 -0800375 this->calcCoverageInvariantOutput(coverage);
egdanielb6cbc382014-11-13 11:00:34 -0800376 return (fColorProcInfo.isOpaque() && fCoverageProcInfo.isOpaque());
egdaniel89af44a2014-09-26 06:15:04 -0700377 }
egdanielb6cbc382014-11-13 11:00:34 -0800378 return fColorProcInfo.isOpaque();
egdaniel89af44a2014-09-26 06:15:04 -0700379}
380
joshualitt2e3b3e32014-12-09 13:31:14 -0800381bool GrDrawState::willBlendWithDst(GrColor color, GrColor coverage) const {
382 this->calcColorInvariantOutput(color);
383 this->calcCoverageInvariantOutput(coverage);
egdaniel95131432014-12-09 11:15:43 -0800384 return fXPFactory->willBlendWithDst(fColorProcInfo, fCoverageProcInfo,
385 this->isCoverageDrawing(), this->isColorWriteDisabled());
egdanielcd8b6302014-11-11 14:46:05 -0800386}
387
joshualitt2e3b3e32014-12-09 13:31:14 -0800388void GrDrawState::calcColorInvariantOutput(GrColor color) const {
389 if (!fColorProcInfoValid || color != fColorCache) {
egdanielb6cbc382014-11-13 11:00:34 -0800390 GrColorComponentFlags flags;
391 if (this->hasColorVertexAttribute()) {
392 if (fHints & kVertexColorsAreOpaque_Hint) {
393 flags = kA_GrColorComponentFlag;
394 color = 0xFF << GrColor_SHIFT_A;
395 } else {
396 flags = static_cast<GrColorComponentFlags>(0);
397 color = 0;
398 }
399 } else {
400 flags = kRGBA_GrColorComponentFlags;
egdanielb6cbc382014-11-13 11:00:34 -0800401 }
402 fColorProcInfo.calcWithInitialValues(fColorStages.begin(), this->numColorStages(),
403 color, flags, false);
404 fColorProcInfoValid = true;
joshualitt2e3b3e32014-12-09 13:31:14 -0800405 fColorCache = color;
egdanielb6cbc382014-11-13 11:00:34 -0800406 }
407}
408
joshualitt2e3b3e32014-12-09 13:31:14 -0800409void GrDrawState::calcCoverageInvariantOutput(GrColor coverage) const {
410 if (!fCoverageProcInfoValid || coverage != fCoverageCache) {
egdanielb6cbc382014-11-13 11:00:34 -0800411 GrColorComponentFlags flags;
412 // Check if per-vertex or constant color may have partial alpha
413 if (this->hasCoverageVertexAttribute()) {
414 flags = static_cast<GrColorComponentFlags>(0);
joshualitt2e3b3e32014-12-09 13:31:14 -0800415 coverage = 0;
egdanielb6cbc382014-11-13 11:00:34 -0800416 } else {
417 flags = kRGBA_GrColorComponentFlags;
egdanielb6cbc382014-11-13 11:00:34 -0800418 }
419 fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(), this->numCoverageStages(),
joshualitt2e3b3e32014-12-09 13:31:14 -0800420 coverage, flags, true, fGeometryProcessor.get());
egdanielb6cbc382014-11-13 11:00:34 -0800421 fCoverageProcInfoValid = true;
joshualitt2e3b3e32014-12-09 13:31:14 -0800422 fCoverageCache = coverage;
egdanielb6cbc382014-11-13 11:00:34 -0800423 }
424}