blob: 6694100cc21dae3ab6cd6ad62e76a76cd13fc81b [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
joshualitt56995b52014-12-11 15:44:02 -080017bool GrDrawState::isEqual(const GrDrawState& that, bool explicitLocalCoords) 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
egdaniel915187b2014-12-05 12:58:28 -080028 if (!this->getXPFactory()->isEqual(*that.getXPFactory())) {
29 return false;
30 }
31
egdaniel89af44a2014-09-26 06:15:04 -070032 for (int i = 0; i < this->numColorStages(); i++) {
joshualitt40d4bd82014-12-29 09:04:40 -080033 if (this->getColorStage(i) != that.getColorStage(i)) {
egdaniel89af44a2014-09-26 06:15:04 -070034 return false;
35 }
36 }
37 for (int i = 0; i < this->numCoverageStages(); i++) {
joshualitt40d4bd82014-12-29 09:04:40 -080038 if (this->getCoverageStage(i) != that.getCoverageStage(i)) {
egdaniel89af44a2014-09-26 06:15:04 -070039 return false;
40 }
41 }
42
egdaniel89af44a2014-09-26 06:15:04 -070043 return true;
44}
45
joshualitt40d4bd82014-12-29 09:04:40 -080046//////////////////////////////////////////////////////////////////////////////
bsalomon8f727332014-08-05 07:50:06 -070047
48GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
bsalomonae59b772014-11-19 08:23:49 -080049 fRenderTarget.reset(SkSafeRef(that.fRenderTarget.get()));
bsalomon8f727332014-08-05 07:50:06 -070050 fViewMatrix = that.fViewMatrix;
bsalomon8f727332014-08-05 07:50:06 -070051 fFlagBits = that.fFlagBits;
bsalomon8f727332014-08-05 07:50:06 -070052 fStencilSettings = that.fStencilSettings;
bsalomon8f727332014-08-05 07:50:06 -070053 fDrawFace = that.fDrawFace;
egdaniel378092f2014-12-03 10:40:13 -080054 fXPFactory.reset(SkRef(that.getXPFactory()));
egdaniel8cbf3d52014-08-21 06:27:22 -070055 fColorStages = that.fColorStages;
56 fCoverageStages = that.fCoverageStages;
bsalomon8f727332014-08-05 07:50:06 -070057
egdanielb6cbc382014-11-13 11:00:34 -080058 fColorProcInfoValid = that.fColorProcInfoValid;
59 fCoverageProcInfoValid = that.fCoverageProcInfoValid;
joshualittf364b612014-12-11 06:52:01 -080060 fColorCache = that.fColorCache;
61 fCoverageCache = that.fCoverageCache;
joshualitte832b952014-12-12 08:41:15 -080062 fColorPrimProc = that.fColorPrimProc;
63 fCoveragePrimProc = that.fCoveragePrimProc;
egdanielb6cbc382014-11-13 11:00:34 -080064 if (fColorProcInfoValid) {
65 fColorProcInfo = that.fColorProcInfo;
66 }
67 if (fCoverageProcInfoValid) {
68 fCoverageProcInfo = that.fCoverageProcInfo;
69 }
bsalomon8f727332014-08-05 07:50:06 -070070 return *this;
71}
72
73void GrDrawState::onReset(const SkMatrix* initialViewMatrix) {
joshualitt56995b52014-12-11 15:44:02 -080074 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numFragmentStages());
bsalomonae59b772014-11-19 08:23:49 -080075 fRenderTarget.reset(NULL);
bsalomon2a9ca782014-09-05 14:27:43 -070076
egdanielc016fb82014-12-03 11:41:54 -080077 fXPFactory.reset(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode));
egdaniel8cbf3d52014-08-21 06:27:22 -070078 fColorStages.reset();
79 fCoverageStages.reset();
bsalomon8f727332014-08-05 07:50:06 -070080
bsalomon8f727332014-08-05 07:50:06 -070081 if (NULL == initialViewMatrix) {
82 fViewMatrix.reset();
83 } else {
84 fViewMatrix = *initialViewMatrix;
85 }
bsalomon8f727332014-08-05 07:50:06 -070086 fFlagBits = 0x0;
87 fStencilSettings.setDisabled();
bsalomon8f727332014-08-05 07:50:06 -070088 fDrawFace = kBoth_DrawFace;
89
egdanielb6cbc382014-11-13 11:00:34 -080090 fColorProcInfoValid = false;
91 fCoverageProcInfoValid = false;
joshualitt9b338222014-12-10 12:28:08 -080092
93 fColorCache = GrColor_ILLEGAL;
94 fCoverageCache = GrColor_ILLEGAL;
joshualitt56995b52014-12-11 15:44:02 -080095
96 fColorPrimProc = NULL;
97 fCoveragePrimProc = NULL;
bsalomon8f727332014-08-05 07:50:06 -070098}
99
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000100void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRenderTarget* rt) {
joshualitt56995b52014-12-11 15:44:02 -0800101 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numFragmentStages());
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000102
egdaniel8cbf3d52014-08-21 06:27:22 -0700103 fColorStages.reset();
104 fCoverageStages.reset();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000105
commit-bot@chromium.org42dacab2013-07-13 17:24:24 +0000106 for (int i = 0; i < paint.numColorStages(); ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700107 fColorStages.push_back(paint.getColorStage(i));
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000108 }
109
commit-bot@chromium.org42dacab2013-07-13 17:24:24 +0000110 for (int i = 0; i < paint.numCoverageStages(); ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700111 fCoverageStages.push_back(paint.getCoverageStage(i));
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000112 }
113
egdaniel378092f2014-12-03 10:40:13 -0800114 fXPFactory.reset(SkRef(paint.getXPFactory()));
115
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000116 this->setRenderTarget(rt);
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000117
bsalomon2ed5ef82014-07-07 08:44:05 -0700118 fViewMatrix = vm;
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000119
120 // These have no equivalent in GrPaint, set them to defaults
bsalomon2ed5ef82014-07-07 08:44:05 -0700121 fDrawFace = kBoth_DrawFace;
122 fStencilSettings.setDisabled();
bsalomon04ddf892014-11-19 12:36:22 -0800123 fFlagBits = 0;
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000124
bsalomon@google.com21c10c52013-06-13 17:44:07 +0000125 // Enable the clip bit
126 this->enableState(GrDrawState::kClip_StateBit);
127
bsalomon@google.comc7448ce2012-10-05 19:04:13 +0000128 this->setState(GrDrawState::kDither_StateBit, paint.isDither());
129 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias());
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000130
egdanielb6cbc382014-11-13 11:00:34 -0800131 fColorProcInfoValid = false;
132 fCoverageProcInfoValid = false;
joshualitt2e3b3e32014-12-09 13:31:14 -0800133
134 fColorCache = GrColor_ILLEGAL;
135 fCoverageCache = GrColor_ILLEGAL;
joshualitte832b952014-12-12 08:41:15 -0800136
137 fColorPrimProc = NULL;
138 fCoveragePrimProc = NULL;
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000139}
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000140
141////////////////////////////////////////////////////////////////////////////////
142
joshualitt2e3b3e32014-12-09 13:31:14 -0800143bool GrDrawState::canUseFracCoveragePrimProc(GrColor color, const GrDrawTargetCaps& caps) const {
bsalomon62c447d2014-08-08 08:08:50 -0700144 if (caps.dualSourceBlendingSupport()) {
145 return true;
146 }
egdaniel95131432014-12-09 11:15:43 -0800147
joshualitt2e3b3e32014-12-09 13:31:14 -0800148 this->calcColorInvariantOutput(color);
149
150 // The coverage isn't actually white, its unknown, but this will produce the same effect
151 // TODO we want to cache the result of this call, but we can probably clean up the interface
152 // so we don't have to pass in a seemingly known coverage
153 this->calcCoverageInvariantOutput(GrColor_WHITE);
egdaniel080e6732014-12-22 07:35:52 -0800154 return fXPFactory->canApplyCoverage(fColorProcInfo, fCoverageProcInfo);
egdaniel89af44a2014-09-26 06:15:04 -0700155}
156
egdaniel21aed572014-08-26 12:24:06 -0700157//////////////////////////////////////////////////////////////////////////////s
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000158
joshualitt56995b52014-12-11 15:44:02 -0800159bool GrDrawState::willEffectReadDstColor(const GrPrimitiveProcessor* pp) const {
160 this->calcColorInvariantOutput(pp);
161 this->calcCoverageInvariantOutput(pp);
egdaniel95131432014-12-09 11:15:43 -0800162
egdaniel080e6732014-12-22 07:35:52 -0800163 return fXPFactory->willReadDst(fColorProcInfo, fCoverageProcInfo);
egdaniel89af44a2014-09-26 06:15:04 -0700164}
165
egdaniel21aed572014-08-26 12:24:06 -0700166void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
bsalomon49f085d2014-09-05 13:34:00 -0700167 if (fDrawState) {
egdaniel21aed572014-08-26 12:24:06 -0700168 int m = fDrawState->numColorStages() - fColorEffectCnt;
169 SkASSERT(m >= 0);
170 fDrawState->fColorStages.pop_back_n(m);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000171
egdaniel21aed572014-08-26 12:24:06 -0700172 int n = fDrawState->numCoverageStages() - fCoverageEffectCnt;
173 SkASSERT(n >= 0);
174 fDrawState->fCoverageStages.pop_back_n(n);
egdanielb6cbc382014-11-13 11:00:34 -0800175 if (m + n > 0) {
176 fDrawState->fColorProcInfoValid = false;
177 fDrawState->fCoverageProcInfoValid = false;
178 }
egdaniel21aed572014-08-26 12:24:06 -0700179 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000180 }
egdaniel21aed572014-08-26 12:24:06 -0700181 fDrawState = ds;
182 if (NULL != ds) {
183 fColorEffectCnt = ds->numColorStages();
184 fCoverageEffectCnt = ds->numCoverageStages();
185 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;)
186 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000187}
188
jvanverth@google.comcc782382013-01-28 20:39:48 +0000189////////////////////////////////////////////////////////////////////////////////
190
egdaniel89af44a2014-09-26 06:15:04 -0700191// Some blend modes allow folding a fractional coverage value into the color's alpha channel, while
192// others will blend incorrectly.
193bool GrDrawState::canTweakAlphaForCoverage() const {
egdaniel87509242014-12-17 13:37:13 -0800194 return fXPFactory->canTweakAlphaForCoverage();
egdaniel89af44a2014-09-26 06:15:04 -0700195}
196
197////////////////////////////////////////////////////////////////////////////////
198
egdaniel170f90b2014-09-16 12:54:40 -0700199GrDrawState::~GrDrawState() {
egdaniel170f90b2014-09-16 12:54:40 -0700200 SkASSERT(0 == fBlockEffectRemovalCnt);
201}
202
egdaniel89af44a2014-09-26 06:15:04 -0700203////////////////////////////////////////////////////////////////////////////////
204
joshualitt56995b52014-12-11 15:44:02 -0800205bool GrDrawState::willBlendWithDst(const GrPrimitiveProcessor* pp) const {
206 this->calcColorInvariantOutput(pp);
207 this->calcCoverageInvariantOutput(pp);
egdaniel9e4ecdc2014-12-18 12:44:55 -0800208
209 GrXPFactory::InvariantOutput output;
egdaniel080e6732014-12-22 07:35:52 -0800210 fXPFactory->getInvariantOutput(fColorProcInfo, fCoverageProcInfo, &output);
egdaniel9e4ecdc2014-12-18 12:44:55 -0800211 return output.fWillBlendWithDst;
egdanielcd8b6302014-11-11 14:46:05 -0800212}
213
joshualitt56995b52014-12-11 15:44:02 -0800214void GrDrawState::calcColorInvariantOutput(const GrPrimitiveProcessor* pp) const {
215 if (!fColorProcInfoValid || fColorPrimProc != pp) {
216 fColorProcInfo.calcColorWithPrimProc(pp, fColorStages.begin(), this->numColorStages());
217 fColorProcInfoValid = true;
218 fColorPrimProc = pp;
219 }
220}
221
222void GrDrawState::calcCoverageInvariantOutput(const GrPrimitiveProcessor* pp) const {
223 if (!fCoverageProcInfoValid || fCoveragePrimProc != pp) {
224 fCoverageProcInfo.calcCoverageWithPrimProc(pp, fCoverageStages.begin(),
225 this->numCoverageStages());
226 fCoverageProcInfoValid = true;
227 fCoveragePrimProc = pp;
228 }
229}
230
joshualitt2e3b3e32014-12-09 13:31:14 -0800231void GrDrawState::calcColorInvariantOutput(GrColor color) const {
232 if (!fColorProcInfoValid || color != fColorCache) {
joshualitt56995b52014-12-11 15:44:02 -0800233 GrColorComponentFlags flags = kRGBA_GrColorComponentFlags;
234 fColorProcInfo.calcWithInitialValues(fColorStages.begin(), this->numColorStages(), color,
235 flags, false);
egdanielb6cbc382014-11-13 11:00:34 -0800236 fColorProcInfoValid = true;
joshualitt2e3b3e32014-12-09 13:31:14 -0800237 fColorCache = color;
egdanielb6cbc382014-11-13 11:00:34 -0800238 }
239}
240
joshualitt2e3b3e32014-12-09 13:31:14 -0800241void GrDrawState::calcCoverageInvariantOutput(GrColor coverage) const {
242 if (!fCoverageProcInfoValid || coverage != fCoverageCache) {
joshualitt56995b52014-12-11 15:44:02 -0800243 GrColorComponentFlags flags = kRGBA_GrColorComponentFlags;
244 fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(),
245 this->numCoverageStages(), coverage, flags,
246 true);
egdanielb6cbc382014-11-13 11:00:34 -0800247 fCoverageProcInfoValid = true;
joshualitt2e3b3e32014-12-09 13:31:14 -0800248 fCoverageCache = coverage;
egdanielb6cbc382014-11-13 11:00:34 -0800249 }
250}