blob: 36042e19ab21fb1b224406481ee41635ffdecc02 [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() ||
egdaniel89af44a2014-09-26 06:15:04 -070021 this->fFlagBits != that.fFlagBits ||
egdaniel89af44a2014-09-26 06:15:04 -070022 this->fStencilSettings != that.fStencilSettings ||
23 this->fDrawFace != that.fDrawFace) {
24 return false;
25 }
26
egdaniel915187b2014-12-05 12:58:28 -080027 if (!this->getXPFactory()->isEqual(*that.getXPFactory())) {
28 return false;
29 }
30
egdaniel89af44a2014-09-26 06:15:04 -070031 for (int i = 0; i < this->numColorStages(); i++) {
joshualitt40d4bd82014-12-29 09:04:40 -080032 if (this->getColorStage(i) != that.getColorStage(i)) {
egdaniel89af44a2014-09-26 06:15:04 -070033 return false;
34 }
35 }
36 for (int i = 0; i < this->numCoverageStages(); i++) {
joshualitt40d4bd82014-12-29 09:04:40 -080037 if (this->getCoverageStage(i) != that.getCoverageStage(i)) {
egdaniel89af44a2014-09-26 06:15:04 -070038 return false;
39 }
40 }
41
egdaniel89af44a2014-09-26 06:15:04 -070042 return true;
43}
44
joshualitt40d4bd82014-12-29 09:04:40 -080045//////////////////////////////////////////////////////////////////////////////
bsalomon8f727332014-08-05 07:50:06 -070046
47GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
bsalomonae59b772014-11-19 08:23:49 -080048 fRenderTarget.reset(SkSafeRef(that.fRenderTarget.get()));
bsalomon8f727332014-08-05 07:50:06 -070049 fFlagBits = that.fFlagBits;
bsalomon8f727332014-08-05 07:50:06 -070050 fStencilSettings = that.fStencilSettings;
bsalomon8f727332014-08-05 07:50:06 -070051 fDrawFace = that.fDrawFace;
egdaniel378092f2014-12-03 10:40:13 -080052 fXPFactory.reset(SkRef(that.getXPFactory()));
egdaniel8cbf3d52014-08-21 06:27:22 -070053 fColorStages = that.fColorStages;
54 fCoverageStages = that.fCoverageStages;
bsalomon8f727332014-08-05 07:50:06 -070055
egdanielb6cbc382014-11-13 11:00:34 -080056 fColorProcInfoValid = that.fColorProcInfoValid;
57 fCoverageProcInfoValid = that.fCoverageProcInfoValid;
joshualittf364b612014-12-11 06:52:01 -080058 fColorCache = that.fColorCache;
59 fCoverageCache = that.fCoverageCache;
joshualitte832b952014-12-12 08:41:15 -080060 fColorPrimProc = that.fColorPrimProc;
61 fCoveragePrimProc = that.fCoveragePrimProc;
egdanielb6cbc382014-11-13 11:00:34 -080062 if (fColorProcInfoValid) {
63 fColorProcInfo = that.fColorProcInfo;
64 }
65 if (fCoverageProcInfoValid) {
66 fCoverageProcInfo = that.fCoverageProcInfo;
67 }
bsalomon8f727332014-08-05 07:50:06 -070068 return *this;
69}
70
joshualitt8059eb92014-12-29 15:10:07 -080071void GrDrawState::onReset() {
joshualitt56995b52014-12-11 15:44:02 -080072 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numFragmentStages());
bsalomonae59b772014-11-19 08:23:49 -080073 fRenderTarget.reset(NULL);
bsalomon2a9ca782014-09-05 14:27:43 -070074
egdanielc016fb82014-12-03 11:41:54 -080075 fXPFactory.reset(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode));
egdaniel8cbf3d52014-08-21 06:27:22 -070076 fColorStages.reset();
77 fCoverageStages.reset();
bsalomon8f727332014-08-05 07:50:06 -070078
bsalomon8f727332014-08-05 07:50:06 -070079 fFlagBits = 0x0;
80 fStencilSettings.setDisabled();
bsalomon8f727332014-08-05 07:50:06 -070081 fDrawFace = kBoth_DrawFace;
82
egdanielb6cbc382014-11-13 11:00:34 -080083 fColorProcInfoValid = false;
84 fCoverageProcInfoValid = false;
joshualitt9b338222014-12-10 12:28:08 -080085
86 fColorCache = GrColor_ILLEGAL;
87 fCoverageCache = GrColor_ILLEGAL;
joshualitt56995b52014-12-11 15:44:02 -080088
89 fColorPrimProc = NULL;
90 fCoveragePrimProc = NULL;
bsalomon8f727332014-08-05 07:50:06 -070091}
92
joshualitt8059eb92014-12-29 15:10:07 -080093void GrDrawState::setFromPaint(const GrPaint& paint, GrRenderTarget* rt) {
joshualitt56995b52014-12-11 15:44:02 -080094 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numFragmentStages());
bsalomon@google.comeb6879f2013-06-13 19:34:18 +000095
egdaniel8cbf3d52014-08-21 06:27:22 -070096 fColorStages.reset();
97 fCoverageStages.reset();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +000098
commit-bot@chromium.org42dacab2013-07-13 17:24:24 +000099 for (int i = 0; i < paint.numColorStages(); ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700100 fColorStages.push_back(paint.getColorStage(i));
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000101 }
102
commit-bot@chromium.org42dacab2013-07-13 17:24:24 +0000103 for (int i = 0; i < paint.numCoverageStages(); ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -0700104 fCoverageStages.push_back(paint.getCoverageStage(i));
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000105 }
106
egdaniel378092f2014-12-03 10:40:13 -0800107 fXPFactory.reset(SkRef(paint.getXPFactory()));
108
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000109 this->setRenderTarget(rt);
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000110
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000111 // These have no equivalent in GrPaint, set them to defaults
bsalomon2ed5ef82014-07-07 08:44:05 -0700112 fDrawFace = kBoth_DrawFace;
113 fStencilSettings.setDisabled();
bsalomon04ddf892014-11-19 12:36:22 -0800114 fFlagBits = 0;
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +0000115
bsalomon@google.com21c10c52013-06-13 17:44:07 +0000116 // Enable the clip bit
117 this->enableState(GrDrawState::kClip_StateBit);
118
bsalomon@google.comc7448ce2012-10-05 19:04:13 +0000119 this->setState(GrDrawState::kDither_StateBit, paint.isDither());
120 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias());
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000121
egdanielb6cbc382014-11-13 11:00:34 -0800122 fColorProcInfoValid = false;
123 fCoverageProcInfoValid = false;
joshualitt2e3b3e32014-12-09 13:31:14 -0800124
125 fColorCache = GrColor_ILLEGAL;
126 fCoverageCache = GrColor_ILLEGAL;
joshualitte832b952014-12-12 08:41:15 -0800127
128 fColorPrimProc = NULL;
129 fCoveragePrimProc = NULL;
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000130}
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000131
132////////////////////////////////////////////////////////////////////////////////
133
joshualitt2e3b3e32014-12-09 13:31:14 -0800134bool GrDrawState::canUseFracCoveragePrimProc(GrColor color, const GrDrawTargetCaps& caps) const {
bsalomon62c447d2014-08-08 08:08:50 -0700135 if (caps.dualSourceBlendingSupport()) {
136 return true;
137 }
egdaniel95131432014-12-09 11:15:43 -0800138
joshualitt2e3b3e32014-12-09 13:31:14 -0800139 this->calcColorInvariantOutput(color);
140
141 // The coverage isn't actually white, its unknown, but this will produce the same effect
142 // TODO we want to cache the result of this call, but we can probably clean up the interface
143 // so we don't have to pass in a seemingly known coverage
144 this->calcCoverageInvariantOutput(GrColor_WHITE);
egdaniel080e6732014-12-22 07:35:52 -0800145 return fXPFactory->canApplyCoverage(fColorProcInfo, fCoverageProcInfo);
egdaniel89af44a2014-09-26 06:15:04 -0700146}
147
egdaniel21aed572014-08-26 12:24:06 -0700148//////////////////////////////////////////////////////////////////////////////s
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000149
joshualitt56995b52014-12-11 15:44:02 -0800150bool GrDrawState::willEffectReadDstColor(const GrPrimitiveProcessor* pp) const {
151 this->calcColorInvariantOutput(pp);
152 this->calcCoverageInvariantOutput(pp);
egdaniel95131432014-12-09 11:15:43 -0800153
egdaniel080e6732014-12-22 07:35:52 -0800154 return fXPFactory->willReadDst(fColorProcInfo, fCoverageProcInfo);
egdaniel89af44a2014-09-26 06:15:04 -0700155}
156
egdaniel21aed572014-08-26 12:24:06 -0700157void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
bsalomon49f085d2014-09-05 13:34:00 -0700158 if (fDrawState) {
egdaniel21aed572014-08-26 12:24:06 -0700159 int m = fDrawState->numColorStages() - fColorEffectCnt;
160 SkASSERT(m >= 0);
161 fDrawState->fColorStages.pop_back_n(m);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000162
egdaniel21aed572014-08-26 12:24:06 -0700163 int n = fDrawState->numCoverageStages() - fCoverageEffectCnt;
164 SkASSERT(n >= 0);
165 fDrawState->fCoverageStages.pop_back_n(n);
egdanielb6cbc382014-11-13 11:00:34 -0800166 if (m + n > 0) {
167 fDrawState->fColorProcInfoValid = false;
168 fDrawState->fCoverageProcInfoValid = false;
169 }
egdaniel21aed572014-08-26 12:24:06 -0700170 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000171 }
egdaniel21aed572014-08-26 12:24:06 -0700172 fDrawState = ds;
173 if (NULL != ds) {
174 fColorEffectCnt = ds->numColorStages();
175 fCoverageEffectCnt = ds->numCoverageStages();
176 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;)
177 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000178}
179
jvanverth@google.comcc782382013-01-28 20:39:48 +0000180////////////////////////////////////////////////////////////////////////////////
181
egdaniel89af44a2014-09-26 06:15:04 -0700182// Some blend modes allow folding a fractional coverage value into the color's alpha channel, while
183// others will blend incorrectly.
184bool GrDrawState::canTweakAlphaForCoverage() const {
egdaniel87509242014-12-17 13:37:13 -0800185 return fXPFactory->canTweakAlphaForCoverage();
egdaniel89af44a2014-09-26 06:15:04 -0700186}
187
188////////////////////////////////////////////////////////////////////////////////
189
egdaniel170f90b2014-09-16 12:54:40 -0700190GrDrawState::~GrDrawState() {
egdaniel170f90b2014-09-16 12:54:40 -0700191 SkASSERT(0 == fBlockEffectRemovalCnt);
192}
193
egdaniel89af44a2014-09-26 06:15:04 -0700194////////////////////////////////////////////////////////////////////////////////
195
joshualitt56995b52014-12-11 15:44:02 -0800196bool GrDrawState::willBlendWithDst(const GrPrimitiveProcessor* pp) const {
197 this->calcColorInvariantOutput(pp);
198 this->calcCoverageInvariantOutput(pp);
egdaniel9e4ecdc2014-12-18 12:44:55 -0800199
200 GrXPFactory::InvariantOutput output;
egdaniel080e6732014-12-22 07:35:52 -0800201 fXPFactory->getInvariantOutput(fColorProcInfo, fCoverageProcInfo, &output);
egdaniel9e4ecdc2014-12-18 12:44:55 -0800202 return output.fWillBlendWithDst;
egdanielcd8b6302014-11-11 14:46:05 -0800203}
204
joshualitt56995b52014-12-11 15:44:02 -0800205void GrDrawState::calcColorInvariantOutput(const GrPrimitiveProcessor* pp) const {
206 if (!fColorProcInfoValid || fColorPrimProc != pp) {
207 fColorProcInfo.calcColorWithPrimProc(pp, fColorStages.begin(), this->numColorStages());
208 fColorProcInfoValid = true;
209 fColorPrimProc = pp;
210 }
211}
212
213void GrDrawState::calcCoverageInvariantOutput(const GrPrimitiveProcessor* pp) const {
214 if (!fCoverageProcInfoValid || fCoveragePrimProc != pp) {
215 fCoverageProcInfo.calcCoverageWithPrimProc(pp, fCoverageStages.begin(),
216 this->numCoverageStages());
217 fCoverageProcInfoValid = true;
218 fCoveragePrimProc = pp;
219 }
220}
221
joshualitt2e3b3e32014-12-09 13:31:14 -0800222void GrDrawState::calcColorInvariantOutput(GrColor color) const {
223 if (!fColorProcInfoValid || color != fColorCache) {
joshualitt56995b52014-12-11 15:44:02 -0800224 GrColorComponentFlags flags = kRGBA_GrColorComponentFlags;
225 fColorProcInfo.calcWithInitialValues(fColorStages.begin(), this->numColorStages(), color,
226 flags, false);
egdanielb6cbc382014-11-13 11:00:34 -0800227 fColorProcInfoValid = true;
joshualitt2e3b3e32014-12-09 13:31:14 -0800228 fColorCache = color;
egdanielb6cbc382014-11-13 11:00:34 -0800229 }
230}
231
joshualitt2e3b3e32014-12-09 13:31:14 -0800232void GrDrawState::calcCoverageInvariantOutput(GrColor coverage) const {
233 if (!fCoverageProcInfoValid || coverage != fCoverageCache) {
joshualitt56995b52014-12-11 15:44:02 -0800234 GrColorComponentFlags flags = kRGBA_GrColorComponentFlags;
235 fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(),
236 this->numCoverageStages(), coverage, flags,
237 true);
egdanielb6cbc382014-11-13 11:00:34 -0800238 fCoverageProcInfoValid = true;
joshualitt2e3b3e32014-12-09 13:31:14 -0800239 fCoverageCache = coverage;
egdanielb6cbc382014-11-13 11:00:34 -0800240 }
241}