blob: 51ef6cf5d3c8302c815aacb2ba356278c35c25f5 [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 {
18 bool usingVertexColors = this->hasColorVertexAttribute();
19 if (!usingVertexColors && this->fColor != that.fColor) {
20 return false;
21 }
22
23 if (this->getRenderTarget() != that.getRenderTarget() ||
24 this->fColorStages.count() != that.fColorStages.count() ||
25 this->fCoverageStages.count() != that.fCoverageStages.count() ||
26 !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) ||
egdaniel89af44a2014-09-26 06:15:04 -070027 this->fFlagBits != that.fFlagBits ||
egdaniel89af44a2014-09-26 06:15:04 -070028 this->fStencilSettings != that.fStencilSettings ||
29 this->fDrawFace != that.fDrawFace) {
30 return false;
31 }
32
33 bool usingVertexCoverage = this->hasCoverageVertexAttribute();
34 if (!usingVertexCoverage && this->fCoverage != that.fCoverage) {
35 return false;
36 }
37
38 bool explicitLocalCoords = this->hasLocalCoordAttribute();
39 if (this->hasGeometryProcessor()) {
40 if (!that.hasGeometryProcessor()) {
41 return false;
joshualitta5305a12014-10-10 17:47:00 -070042 } else if (!this->getGeometryProcessor()->isEqual(*that.getGeometryProcessor())) {
egdaniel89af44a2014-09-26 06:15:04 -070043 return false;
44 }
45 } else if (that.hasGeometryProcessor()) {
46 return false;
47 }
48
egdaniel915187b2014-12-05 12:58:28 -080049 if (!this->getXPFactory()->isEqual(*that.getXPFactory())) {
50 return false;
51 }
52
egdaniel89af44a2014-09-26 06:15:04 -070053 for (int i = 0; i < this->numColorStages(); i++) {
joshualitta5305a12014-10-10 17:47:00 -070054 if (!GrFragmentStage::AreCompatible(this->getColorStage(i), that.getColorStage(i),
egdaniel89af44a2014-09-26 06:15:04 -070055 explicitLocalCoords)) {
56 return false;
57 }
58 }
59 for (int i = 0; i < this->numCoverageStages(); i++) {
joshualitta5305a12014-10-10 17:47:00 -070060 if (!GrFragmentStage::AreCompatible(this->getCoverageStage(i), that.getCoverageStage(i),
egdaniel89af44a2014-09-26 06:15:04 -070061 explicitLocalCoords)) {
62 return false;
63 }
64 }
65
egdaniel89af44a2014-09-26 06:15:04 -070066 return true;
67}
68
bsalomon8f727332014-08-05 07:50:06 -070069//////////////////////////////////////////////////////////////////////////////s
70
egdaniel69bb90c2014-11-11 07:32:45 -080071GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix) {
bsalomon8f727332014-08-05 07:50:06 -070072 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
73 *this = state;
74 if (!preConcatMatrix.isIdentity()) {
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 }
bsalomon8f727332014-08-05 07:50:06 -070081 }
82}
83
84GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
bsalomonae59b772014-11-19 08:23:49 -080085 fRenderTarget.reset(SkSafeRef(that.fRenderTarget.get()));
bsalomon8f727332014-08-05 07:50:06 -070086 fColor = that.fColor;
87 fViewMatrix = that.fViewMatrix;
bsalomon8f727332014-08-05 07:50:06 -070088 fFlagBits = that.fFlagBits;
bsalomon8f727332014-08-05 07:50:06 -070089 fStencilSettings = that.fStencilSettings;
90 fCoverage = that.fCoverage;
91 fDrawFace = that.fDrawFace;
bsalomonae59b772014-11-19 08:23:49 -080092 fGeometryProcessor.reset(SkSafeRef(that.fGeometryProcessor.get()));
egdaniel378092f2014-12-03 10:40:13 -080093 fXPFactory.reset(SkRef(that.getXPFactory()));
egdaniel8cbf3d52014-08-21 06:27:22 -070094 fColorStages = that.fColorStages;
95 fCoverageStages = that.fCoverageStages;
bsalomon8f727332014-08-05 07:50:06 -070096
bsalomon62c447d2014-08-08 08:08:50 -070097 fHints = that.fHints;
egdaniel776bdbd2014-08-06 11:07:02 -070098
egdanielb6cbc382014-11-13 11:00:34 -080099 fColorProcInfoValid = that.fColorProcInfoValid;
100 fCoverageProcInfoValid = that.fCoverageProcInfoValid;
101 if (fColorProcInfoValid) {
102 fColorProcInfo = that.fColorProcInfo;
103 }
104 if (fCoverageProcInfoValid) {
105 fCoverageProcInfo = that.fCoverageProcInfo;
106 }
bsalomon8f727332014-08-05 07:50:06 -0700107 return *this;
108}
109
110void GrDrawState::onReset(const SkMatrix* initialViewMatrix) {
111 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
bsalomonae59b772014-11-19 08:23:49 -0800112 fRenderTarget.reset(NULL);
bsalomon2a9ca782014-09-05 14:27:43 -0700113
joshualittbd769d02014-09-04 08:56:46 -0700114 fGeometryProcessor.reset(NULL);
egdanielc016fb82014-12-03 11:41:54 -0800115 fXPFactory.reset(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode));
egdaniel8cbf3d52014-08-21 06:27:22 -0700116 fColorStages.reset();
117 fCoverageStages.reset();
bsalomon8f727332014-08-05 07:50:06 -0700118
bsalomon8f727332014-08-05 07:50:06 -0700119 fColor = 0xffffffff;
120 if (NULL == initialViewMatrix) {
121 fViewMatrix.reset();
122 } else {
123 fViewMatrix = *initialViewMatrix;
124 }
bsalomon8f727332014-08-05 07:50:06 -0700125 fFlagBits = 0x0;
126 fStencilSettings.setDisabled();
egdaniel8cbf3d52014-08-21 06:27:22 -0700127 fCoverage = 0xff;
bsalomon8f727332014-08-05 07:50:06 -0700128 fDrawFace = kBoth_DrawFace;
129
bsalomon62c447d2014-08-08 08:08:50 -0700130 fHints = 0;
egdanielb6cbc382014-11-13 11:00:34 -0800131
132 fColorProcInfoValid = false;
133 fCoverageProcInfoValid = false;
bsalomon8f727332014-08-05 07:50:06 -0700134}
135
bsalomon@google.com137f1342013-05-29 21:27:53 +0000136bool GrDrawState::setIdentityViewMatrix() {
joshualitt4dd99882014-11-11 08:51:30 -0800137 if (this->numFragmentStages()) {
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000138 SkMatrix invVM;
bsalomon2ed5ef82014-07-07 08:44:05 -0700139 if (!fViewMatrix.invert(&invVM)) {
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000140 // sad trombone sound
141 return false;
142 }
egdaniel776bdbd2014-08-06 11:07:02 -0700143 for (int s = 0; s < this->numColorStages(); ++s) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700144 fColorStages[s].localCoordChange(invVM);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000145 }
egdaniel776bdbd2014-08-06 11:07:02 -0700146 for (int s = 0; s < this->numCoverageStages(); ++s) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700147 fCoverageStages[s].localCoordChange(invVM);
bsalomon@google.com137f1342013-05-29 21:27:53 +0000148 }
149 }
bsalomon2ed5ef82014-07-07 08:44:05 -0700150 fViewMatrix.reset();
bsalomon@google.com137f1342013-05-29 21:27:53 +0000151 return true;
152}
153
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000154void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRenderTarget* rt) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000155 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000156
joshualittbd769d02014-09-04 08:56:46 -0700157 fGeometryProcessor.reset(NULL);
egdaniel8cbf3d52014-08-21 06:27:22 -0700158 fColorStages.reset();
159 fCoverageStages.reset();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000160
commit-bot@chromium.org42dacab2013-07-13 17:24:24 +0000161 for (int i = 0; i < paint.numColorStages(); ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700162 fColorStages.push_back(paint.getColorStage(i));
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000163 }
164
commit-bot@chromium.org42dacab2013-07-13 17:24:24 +0000165 for (int i = 0; i < paint.numCoverageStages(); ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700166 fCoverageStages.push_back(paint.getCoverageStage(i));
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000167 }
168
egdaniel378092f2014-12-03 10:40:13 -0800169 fXPFactory.reset(SkRef(paint.getXPFactory()));
170
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000171 this->setRenderTarget(rt);
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000172
bsalomon2ed5ef82014-07-07 08:44:05 -0700173 fViewMatrix = vm;
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000174
175 // These have no equivalent in GrPaint, set them to defaults
bsalomon2ed5ef82014-07-07 08:44:05 -0700176 fDrawFace = kBoth_DrawFace;
177 fStencilSettings.setDisabled();
bsalomon04ddf892014-11-19 12:36:22 -0800178 fFlagBits = 0;
bsalomon62c447d2014-08-08 08:08:50 -0700179 fHints = 0;
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000180
bsalomon@google.com21c10c52013-06-13 17:44:07 +0000181 // Enable the clip bit
182 this->enableState(GrDrawState::kClip_StateBit);
183
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000184 this->setColor(paint.getColor());
bsalomon@google.comc7448ce2012-10-05 19:04:13 +0000185 this->setState(GrDrawState::kDither_StateBit, paint.isDither());
186 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias());
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000187
joshualitt4052a8e2014-11-11 13:46:30 -0800188 this->setCoverage(0xFF);
egdanielb6cbc382014-11-13 11:00:34 -0800189 fColorProcInfoValid = false;
190 fCoverageProcInfoValid = false;
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000191}
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000192
193////////////////////////////////////////////////////////////////////////////////
194
bsalomon62c447d2014-08-08 08:08:50 -0700195bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const {
196 if (caps.dualSourceBlendingSupport()) {
197 return true;
198 }
egdaniel95131432014-12-09 11:15:43 -0800199
200 this->calcColorInvariantOutput();
201 this->calcCoverageInvariantOutput();
202 return fXPFactory->canApplyCoverage(fColorProcInfo, fCoverageProcInfo,
203 this->isCoverageDrawing(), this->isColorWriteDisabled());
bsalomon62c447d2014-08-08 08:08:50 -0700204}
205
egdaniel89af44a2014-09-26 06:15:04 -0700206bool GrDrawState::hasSolidCoverage() const {
207 // If we're drawing coverage directly then coverage is effectively treated as color.
208 if (this->isCoverageDrawing()) {
209 return true;
210 }
211
joshualitt4dd99882014-11-11 08:51:30 -0800212 if (this->numCoverageStages() > 0) {
213 return false;
214 }
215
egdanielb6cbc382014-11-13 11:00:34 -0800216 this->calcCoverageInvariantOutput();
217 return fCoverageProcInfo.isSolidWhite();
egdaniel89af44a2014-09-26 06:15:04 -0700218}
219
egdaniel21aed572014-08-26 12:24:06 -0700220//////////////////////////////////////////////////////////////////////////////s
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000221
egdaniel89af44a2014-09-26 06:15:04 -0700222bool GrDrawState::willEffectReadDstColor() const {
egdaniel95131432014-12-09 11:15:43 -0800223 this->calcColorInvariantOutput();
224 this->calcCoverageInvariantOutput();
225 // TODO: Remove need to create the XP here.
226 // Also once all custom blends are turned into XPs we can remove the need
227 // to check other stages since only xp's will be able to read dst
228 SkAutoTUnref<GrXferProcessor> xferProcessor(fXPFactory->createXferProcessor(fColorProcInfo,
229 fCoverageProcInfo));
230 if (xferProcessor && xferProcessor->willReadDstColor()) {
231 return true;
232 }
233
egdaniel89af44a2014-09-26 06:15:04 -0700234 if (!this->isColorWriteDisabled()) {
egdanielb6cbc382014-11-13 11:00:34 -0800235 if (fColorProcInfo.readsDst()) {
egdaniel89af44a2014-09-26 06:15:04 -0700236 return true;
237 }
238 }
egdanielb6cbc382014-11-13 11:00:34 -0800239 return fCoverageProcInfo.readsDst();
egdaniel89af44a2014-09-26 06:15:04 -0700240}
241
egdaniel21aed572014-08-26 12:24:06 -0700242void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
bsalomon49f085d2014-09-05 13:34:00 -0700243 if (fDrawState) {
bsalomon9b536522014-09-05 09:18:51 -0700244 // See the big comment on the class definition about GPs.
bsalomon52e9d632014-09-05 12:23:12 -0700245 if (SK_InvalidUniqueID == fOriginalGPID) {
bsalomon9b536522014-09-05 09:18:51 -0700246 fDrawState->fGeometryProcessor.reset(NULL);
bsalomon52e9d632014-09-05 12:23:12 -0700247 } else {
joshualitta5305a12014-10-10 17:47:00 -0700248 SkASSERT(fDrawState->getGeometryProcessor()->getUniqueID() ==
bsalomon52e9d632014-09-05 12:23:12 -0700249 fOriginalGPID);
250 fOriginalGPID = SK_InvalidUniqueID;
bsalomon9b536522014-09-05 09:18:51 -0700251 }
joshualittbd769d02014-09-04 08:56:46 -0700252
egdaniel21aed572014-08-26 12:24:06 -0700253 int m = fDrawState->numColorStages() - fColorEffectCnt;
254 SkASSERT(m >= 0);
255 fDrawState->fColorStages.pop_back_n(m);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000256
egdaniel21aed572014-08-26 12:24:06 -0700257 int n = fDrawState->numCoverageStages() - fCoverageEffectCnt;
258 SkASSERT(n >= 0);
259 fDrawState->fCoverageStages.pop_back_n(n);
egdanielb6cbc382014-11-13 11:00:34 -0800260 if (m + n > 0) {
261 fDrawState->fColorProcInfoValid = false;
262 fDrawState->fCoverageProcInfoValid = false;
263 }
egdaniel21aed572014-08-26 12:24:06 -0700264 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000265 }
egdaniel21aed572014-08-26 12:24:06 -0700266 fDrawState = ds;
267 if (NULL != ds) {
bsalomon52e9d632014-09-05 12:23:12 -0700268 SkASSERT(SK_InvalidUniqueID == fOriginalGPID);
bsalomon9b536522014-09-05 09:18:51 -0700269 if (NULL != ds->getGeometryProcessor()) {
joshualitta5305a12014-10-10 17:47:00 -0700270 fOriginalGPID = ds->getGeometryProcessor()->getUniqueID();
joshualittbd769d02014-09-04 08:56:46 -0700271 }
egdaniel21aed572014-08-26 12:24:06 -0700272 fColorEffectCnt = ds->numColorStages();
273 fCoverageEffectCnt = ds->numCoverageStages();
274 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;)
275 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000276}
277
jvanverth@google.comcc782382013-01-28 20:39:48 +0000278////////////////////////////////////////////////////////////////////////////////
279
egdaniel89af44a2014-09-26 06:15:04 -0700280// Some blend modes allow folding a fractional coverage value into the color's alpha channel, while
281// others will blend incorrectly.
282bool GrDrawState::canTweakAlphaForCoverage() const {
egdaniel95131432014-12-09 11:15:43 -0800283 return fXPFactory->canTweakAlphaForCoverage(this->isCoverageDrawing());
egdaniel89af44a2014-09-26 06:15:04 -0700284}
285
286////////////////////////////////////////////////////////////////////////////////
287
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000288void GrDrawState::AutoViewMatrixRestore::restore() {
bsalomon49f085d2014-09-05 13:34:00 -0700289 if (fDrawState) {
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +0000290 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
bsalomon2ed5ef82014-07-07 08:44:05 -0700291 fDrawState->fViewMatrix = fViewMatrix;
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000292 SkASSERT(fDrawState->numColorStages() >= fNumColorStages);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000293 int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages;
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000294 SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000295
296 int i = 0;
297 for (int s = 0; s < fNumColorStages; ++s, ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700298 fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000299 }
300 for (int s = 0; s < numCoverageStages; ++s, ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700301 fDrawState->fCoverageStages[s].restoreCoordChange(fSavedCoordChanges[i]);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000302 }
bsalomon@google.com137f1342013-05-29 21:27:53 +0000303 fDrawState = NULL;
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000304 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000305}
306
307void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState,
bsalomon@google.comc7818882013-03-20 19:19:53 +0000308 const SkMatrix& preconcatMatrix) {
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000309 this->restore();
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000310
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000311 SkASSERT(NULL == fDrawState);
bsalomon@google.com137f1342013-05-29 21:27:53 +0000312 if (NULL == drawState || preconcatMatrix.isIdentity()) {
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000313 return;
314 }
bsalomon@google.com137f1342013-05-29 21:27:53 +0000315 fDrawState = drawState;
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000316
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000317 fViewMatrix = drawState->getViewMatrix();
bsalomon2ed5ef82014-07-07 08:44:05 -0700318 drawState->fViewMatrix.preConcat(preconcatMatrix);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000319
320 this->doEffectCoordChanges(preconcatMatrix);
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +0000321 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000322}
323
bsalomon@google.com137f1342013-05-29 21:27:53 +0000324bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) {
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000325 this->restore();
326
bsalomon@google.com137f1342013-05-29 21:27:53 +0000327 if (NULL == drawState) {
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000328 return false;
skia.committer@gmail.comf467ce72012-10-09 02:01:37 +0000329 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000330
bsalomon@google.com137f1342013-05-29 21:27:53 +0000331 if (drawState->getViewMatrix().isIdentity()) {
332 return true;
333 }
334
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000335 fViewMatrix = drawState->getViewMatrix();
joshualitt4dd99882014-11-11 08:51:30 -0800336 if (0 == drawState->numFragmentStages()) {
bsalomon2ed5ef82014-07-07 08:44:05 -0700337 drawState->fViewMatrix.reset();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000338 fDrawState = drawState;
339 fNumColorStages = 0;
340 fSavedCoordChanges.reset(0);
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +0000341 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000342 return true;
343 } else {
344 SkMatrix inv;
345 if (!fViewMatrix.invert(&inv)) {
346 return false;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000347 }
bsalomon2ed5ef82014-07-07 08:44:05 -0700348 drawState->fViewMatrix.reset();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000349 fDrawState = drawState;
350 this->doEffectCoordChanges(inv);
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +0000351 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000352 return true;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000353 }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000354}
355
356void GrDrawState::AutoViewMatrixRestore::doEffectCoordChanges(const SkMatrix& coordChangeMatrix) {
joshualitt4dd99882014-11-11 08:51:30 -0800357 fSavedCoordChanges.reset(fDrawState->numFragmentStages());
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000358 int i = 0;
359
360 fNumColorStages = fDrawState->numColorStages();
361 for (int s = 0; s < fNumColorStages; ++s, ++i) {
egdaniel776bdbd2014-08-06 11:07:02 -0700362 fDrawState->getColorStage(s).saveCoordChange(&fSavedCoordChanges[i]);
egdaniel8cbf3d52014-08-21 06:27:22 -0700363 fDrawState->fColorStages[s].localCoordChange(coordChangeMatrix);
bsalomon@google.com137f1342013-05-29 21:27:53 +0000364 }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000365
366 int numCoverageStages = fDrawState->numCoverageStages();
367 for (int s = 0; s < numCoverageStages; ++s, ++i) {
egdaniel776bdbd2014-08-06 11:07:02 -0700368 fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]);
egdaniel8cbf3d52014-08-21 06:27:22 -0700369 fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000370 }
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000371}
egdaniel21aed572014-08-26 12:24:06 -0700372
egdaniel170f90b2014-09-16 12:54:40 -0700373////////////////////////////////////////////////////////////////////////////////
374
egdaniel170f90b2014-09-16 12:54:40 -0700375GrDrawState::~GrDrawState() {
egdaniel170f90b2014-09-16 12:54:40 -0700376 SkASSERT(0 == fBlockEffectRemovalCnt);
377}
378
egdaniel89af44a2014-09-26 06:15:04 -0700379////////////////////////////////////////////////////////////////////////////////
380
egdaniel89af44a2014-09-26 06:15:04 -0700381bool GrDrawState::srcAlphaWillBeOne() const {
egdanielb6cbc382014-11-13 11:00:34 -0800382 this->calcColorInvariantOutput();
egdaniel89af44a2014-09-26 06:15:04 -0700383 if (this->isCoverageDrawing()) {
egdanielb6cbc382014-11-13 11:00:34 -0800384 this->calcCoverageInvariantOutput();
385 return (fColorProcInfo.isOpaque() && fCoverageProcInfo.isOpaque());
egdaniel89af44a2014-09-26 06:15:04 -0700386 }
egdanielb6cbc382014-11-13 11:00:34 -0800387 return fColorProcInfo.isOpaque();
egdaniel89af44a2014-09-26 06:15:04 -0700388}
389
egdanielcd8b6302014-11-11 14:46:05 -0800390bool GrDrawState::willBlendWithDst() const {
egdaniel95131432014-12-09 11:15:43 -0800391 this->calcColorInvariantOutput();
392 this->calcCoverageInvariantOutput();
393 return fXPFactory->willBlendWithDst(fColorProcInfo, fCoverageProcInfo,
394 this->isCoverageDrawing(), this->isColorWriteDisabled());
egdanielcd8b6302014-11-11 14:46:05 -0800395}
396
egdanielb6cbc382014-11-13 11:00:34 -0800397void GrDrawState::calcColorInvariantOutput() const {
398 if (!fColorProcInfoValid) {
399 GrColor color;
400 GrColorComponentFlags flags;
401 if (this->hasColorVertexAttribute()) {
402 if (fHints & kVertexColorsAreOpaque_Hint) {
403 flags = kA_GrColorComponentFlag;
404 color = 0xFF << GrColor_SHIFT_A;
405 } else {
406 flags = static_cast<GrColorComponentFlags>(0);
407 color = 0;
408 }
409 } else {
410 flags = kRGBA_GrColorComponentFlags;
411 color = this->getColor();
412 }
413 fColorProcInfo.calcWithInitialValues(fColorStages.begin(), this->numColorStages(),
414 color, flags, false);
415 fColorProcInfoValid = true;
416 }
417}
418
419void GrDrawState::calcCoverageInvariantOutput() const {
420 if (!fCoverageProcInfoValid) {
421 GrColor color;
422 GrColorComponentFlags flags;
423 // Check if per-vertex or constant color may have partial alpha
424 if (this->hasCoverageVertexAttribute()) {
425 flags = static_cast<GrColorComponentFlags>(0);
426 color = 0;
427 } else {
428 flags = kRGBA_GrColorComponentFlags;
429 color = this->getCoverageColor();
430 }
431 fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(), this->numCoverageStages(),
432 color, flags, true, fGeometryProcessor.get());
433 fCoverageProcInfoValid = true;
434 }
435}