blob: 6885eb0dd80b99c05915dd28d030249baabc001e [file] [log] [blame]
bsalomon@google.comaf84e742012-10-05 13:23:24 +00001/*
egdaniel8dd688b2015-01-22 10:16:09 -08002 * Copyright 2015 Google Inc.
bsalomon@google.comaf84e742012-10-05 13:23:24 +00003 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
egdaniel8dd688b2015-01-22 10:16:09 -08008#include "GrPipelineBuilder.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 "GrPaint.h"
egdaniel8dd688b2015-01-22 10:16:09 -080012#include "GrPipeline.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
egdaniel8dd688b2015-01-22 10:16:09 -080017GrPipelineBuilder::GrPipelineBuilder()
joshualitt2fdeda02015-01-22 07:11:44 -080018 : fFlagBits(0x0)
19 , fDrawFace(kBoth_DrawFace)
20 , fColorProcInfoValid(false)
21 , fCoverageProcInfoValid(false)
22 , fColorCache(GrColor_ILLEGAL)
joshualitt4d8da812015-01-28 12:53:54 -080023 , fCoverageCache(GrColor_ILLEGAL) {
joshualitt2fdeda02015-01-22 07:11:44 -080024 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
egdaniel89af44a2014-09-26 06:15:04 -070025}
26
egdaniel8dd688b2015-01-22 10:16:09 -080027GrPipelineBuilder& GrPipelineBuilder::operator=(const GrPipelineBuilder& that) {
bsalomonae59b772014-11-19 08:23:49 -080028 fRenderTarget.reset(SkSafeRef(that.fRenderTarget.get()));
bsalomon8f727332014-08-05 07:50:06 -070029 fFlagBits = that.fFlagBits;
bsalomon8f727332014-08-05 07:50:06 -070030 fStencilSettings = that.fStencilSettings;
bsalomon8f727332014-08-05 07:50:06 -070031 fDrawFace = that.fDrawFace;
egdaniel378092f2014-12-03 10:40:13 -080032 fXPFactory.reset(SkRef(that.getXPFactory()));
egdaniel8cbf3d52014-08-21 06:27:22 -070033 fColorStages = that.fColorStages;
34 fCoverageStages = that.fCoverageStages;
bsalomon8f727332014-08-05 07:50:06 -070035
egdanielb6cbc382014-11-13 11:00:34 -080036 fColorProcInfoValid = that.fColorProcInfoValid;
37 fCoverageProcInfoValid = that.fCoverageProcInfoValid;
joshualittf364b612014-12-11 06:52:01 -080038 fColorCache = that.fColorCache;
39 fCoverageCache = that.fCoverageCache;
egdanielb6cbc382014-11-13 11:00:34 -080040 if (fColorProcInfoValid) {
41 fColorProcInfo = that.fColorProcInfo;
42 }
43 if (fCoverageProcInfoValid) {
44 fCoverageProcInfo = that.fCoverageProcInfo;
45 }
bsalomon8f727332014-08-05 07:50:06 -070046 return *this;
47}
48
egdaniel8dd688b2015-01-22 10:16:09 -080049void GrPipelineBuilder::setFromPaint(const GrPaint& paint, GrRenderTarget* rt) {
joshualitt56995b52014-12-11 15:44:02 -080050 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numFragmentStages());
bsalomon@google.comeb6879f2013-06-13 19:34:18 +000051
egdaniel8cbf3d52014-08-21 06:27:22 -070052 fColorStages.reset();
53 fCoverageStages.reset();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +000054
commit-bot@chromium.org42dacab2013-07-13 17:24:24 +000055 for (int i = 0; i < paint.numColorStages(); ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -070056 fColorStages.push_back(paint.getColorStage(i));
bsalomon@google.comaf84e742012-10-05 13:23:24 +000057 }
58
commit-bot@chromium.org42dacab2013-07-13 17:24:24 +000059 for (int i = 0; i < paint.numCoverageStages(); ++i) {
egdaniel8cbf3d52014-08-21 06:27:22 -070060 fCoverageStages.push_back(paint.getCoverageStage(i));
bsalomon@google.comaf84e742012-10-05 13:23:24 +000061 }
62
egdaniel378092f2014-12-03 10:40:13 -080063 fXPFactory.reset(SkRef(paint.getXPFactory()));
64
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +000065 this->setRenderTarget(rt);
bsalomon@google.comaf84e742012-10-05 13:23:24 +000066
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +000067 // These have no equivalent in GrPaint, set them to defaults
bsalomon2ed5ef82014-07-07 08:44:05 -070068 fDrawFace = kBoth_DrawFace;
69 fStencilSettings.setDisabled();
bsalomon04ddf892014-11-19 12:36:22 -080070 fFlagBits = 0;
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +000071
bsalomon@google.com21c10c52013-06-13 17:44:07 +000072 // Enable the clip bit
egdaniel8dd688b2015-01-22 10:16:09 -080073 this->enableState(GrPipelineBuilder::kClip_StateBit);
bsalomon@google.com21c10c52013-06-13 17:44:07 +000074
egdaniel8dd688b2015-01-22 10:16:09 -080075 this->setState(GrPipelineBuilder::kDither_StateBit, paint.isDither());
76 this->setState(GrPipelineBuilder::kHWAntialias_StateBit, paint.isAntiAlias());
bsalomon@google.comaf84e742012-10-05 13:23:24 +000077
egdanielb6cbc382014-11-13 11:00:34 -080078 fColorProcInfoValid = false;
79 fCoverageProcInfoValid = false;
joshualitt2e3b3e32014-12-09 13:31:14 -080080
81 fColorCache = GrColor_ILLEGAL;
82 fCoverageCache = GrColor_ILLEGAL;
bsalomon@google.comaf84e742012-10-05 13:23:24 +000083}
bsalomon@google.com5b3e8902012-10-05 20:13:28 +000084
85////////////////////////////////////////////////////////////////////////////////
86
egdaniel8dd688b2015-01-22 10:16:09 -080087bool GrPipelineBuilder::canUseFracCoveragePrimProc(GrColor color,
88 const GrDrawTargetCaps& caps) const {
bsalomon62c447d2014-08-08 08:08:50 -070089 if (caps.dualSourceBlendingSupport()) {
90 return true;
91 }
egdaniel95131432014-12-09 11:15:43 -080092
joshualitt2e3b3e32014-12-09 13:31:14 -080093 this->calcColorInvariantOutput(color);
94
95 // The coverage isn't actually white, its unknown, but this will produce the same effect
96 // TODO we want to cache the result of this call, but we can probably clean up the interface
97 // so we don't have to pass in a seemingly known coverage
98 this->calcCoverageInvariantOutput(GrColor_WHITE);
joshualitt2fdeda02015-01-22 07:11:44 -080099 return this->getXPFactory()->canApplyCoverage(fColorProcInfo, fCoverageProcInfo);
egdaniel89af44a2014-09-26 06:15:04 -0700100}
101
egdaniel21aed572014-08-26 12:24:06 -0700102//////////////////////////////////////////////////////////////////////////////s
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000103
egdaniele36914c2015-02-13 09:00:33 -0800104bool GrPipelineBuilder::willXPNeedDstCopy(const GrDrawTargetCaps& caps,
105 const GrProcOptInfo& colorPOI,
106 const GrProcOptInfo& coveragePOI) const {
107 return this->getXPFactory()->willNeedDstCopy(caps, colorPOI, coveragePOI);
egdaniel89af44a2014-09-26 06:15:04 -0700108}
109
egdaniel8dd688b2015-01-22 10:16:09 -0800110void GrPipelineBuilder::AutoRestoreEffects::set(GrPipelineBuilder* pipelineBuilder) {
111 if (fPipelineBuilder) {
112 int m = fPipelineBuilder->numColorStages() - fColorEffectCnt;
egdaniel21aed572014-08-26 12:24:06 -0700113 SkASSERT(m >= 0);
egdaniel8dd688b2015-01-22 10:16:09 -0800114 fPipelineBuilder->fColorStages.pop_back_n(m);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000115
egdaniel8dd688b2015-01-22 10:16:09 -0800116 int n = fPipelineBuilder->numCoverageStages() - fCoverageEffectCnt;
egdaniel21aed572014-08-26 12:24:06 -0700117 SkASSERT(n >= 0);
egdaniel8dd688b2015-01-22 10:16:09 -0800118 fPipelineBuilder->fCoverageStages.pop_back_n(n);
egdanielb6cbc382014-11-13 11:00:34 -0800119 if (m + n > 0) {
egdaniel8dd688b2015-01-22 10:16:09 -0800120 fPipelineBuilder->fColorProcInfoValid = false;
121 fPipelineBuilder->fCoverageProcInfoValid = false;
egdanielb6cbc382014-11-13 11:00:34 -0800122 }
egdaniel8dd688b2015-01-22 10:16:09 -0800123 SkDEBUGCODE(--fPipelineBuilder->fBlockEffectRemovalCnt;)
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000124 }
egdaniel8dd688b2015-01-22 10:16:09 -0800125 fPipelineBuilder = pipelineBuilder;
126 if (NULL != pipelineBuilder) {
127 fColorEffectCnt = pipelineBuilder->numColorStages();
128 fCoverageEffectCnt = pipelineBuilder->numCoverageStages();
129 SkDEBUGCODE(++pipelineBuilder->fBlockEffectRemovalCnt;)
egdaniel21aed572014-08-26 12:24:06 -0700130 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000131}
132
jvanverth@google.comcc782382013-01-28 20:39:48 +0000133////////////////////////////////////////////////////////////////////////////////
134
egdaniel89af44a2014-09-26 06:15:04 -0700135// Some blend modes allow folding a fractional coverage value into the color's alpha channel, while
136// others will blend incorrectly.
egdaniel8dd688b2015-01-22 10:16:09 -0800137bool GrPipelineBuilder::canTweakAlphaForCoverage() const {
joshualitt2fdeda02015-01-22 07:11:44 -0800138 return this->getXPFactory()->canTweakAlphaForCoverage();
egdaniel89af44a2014-09-26 06:15:04 -0700139}
140
141////////////////////////////////////////////////////////////////////////////////
142
egdaniel8dd688b2015-01-22 10:16:09 -0800143GrPipelineBuilder::~GrPipelineBuilder() {
egdaniel170f90b2014-09-16 12:54:40 -0700144 SkASSERT(0 == fBlockEffectRemovalCnt);
145}
146
egdaniel89af44a2014-09-26 06:15:04 -0700147////////////////////////////////////////////////////////////////////////////////
148
egdaniel8dd688b2015-01-22 10:16:09 -0800149bool GrPipelineBuilder::willBlendWithDst(const GrPrimitiveProcessor* pp) const {
joshualitt56995b52014-12-11 15:44:02 -0800150 this->calcColorInvariantOutput(pp);
151 this->calcCoverageInvariantOutput(pp);
egdaniel9e4ecdc2014-12-18 12:44:55 -0800152
153 GrXPFactory::InvariantOutput output;
egdaniel080e6732014-12-22 07:35:52 -0800154 fXPFactory->getInvariantOutput(fColorProcInfo, fCoverageProcInfo, &output);
egdaniel9e4ecdc2014-12-18 12:44:55 -0800155 return output.fWillBlendWithDst;
egdanielcd8b6302014-11-11 14:46:05 -0800156}
157
egdaniel8dd688b2015-01-22 10:16:09 -0800158void GrPipelineBuilder::calcColorInvariantOutput(const GrPrimitiveProcessor* pp) const {
joshualitt4d8da812015-01-28 12:53:54 -0800159 fColorProcInfo.calcColorWithPrimProc(pp, fColorStages.begin(), this->numColorStages());
160 fColorProcInfoValid = false;
161
joshualitt56995b52014-12-11 15:44:02 -0800162}
163
egdaniel8dd688b2015-01-22 10:16:09 -0800164void GrPipelineBuilder::calcCoverageInvariantOutput(const GrPrimitiveProcessor* pp) const {
joshualitt4d8da812015-01-28 12:53:54 -0800165 fCoverageProcInfo.calcCoverageWithPrimProc(pp, fCoverageStages.begin(),
166 this->numCoverageStages());
167 fCoverageProcInfoValid = false;
joshualitt56995b52014-12-11 15:44:02 -0800168}
169
joshualitt4d8da812015-01-28 12:53:54 -0800170void GrPipelineBuilder::calcColorInvariantOutput(const GrBatch* batch) const {
171 fColorProcInfo.calcColorWithBatch(batch, fColorStages.begin(), this->numColorStages());
172 fColorProcInfoValid = false;
173}
174
175void GrPipelineBuilder::calcCoverageInvariantOutput(const GrBatch* batch) const {
176 fCoverageProcInfo.calcCoverageWithBatch(batch, fCoverageStages.begin(),
177 this->numCoverageStages());
178 fCoverageProcInfoValid = false;
179}
180
181
egdaniel8dd688b2015-01-22 10:16:09 -0800182void GrPipelineBuilder::calcColorInvariantOutput(GrColor color) const {
joshualitt2e3b3e32014-12-09 13:31:14 -0800183 if (!fColorProcInfoValid || color != fColorCache) {
joshualitt56995b52014-12-11 15:44:02 -0800184 GrColorComponentFlags flags = kRGBA_GrColorComponentFlags;
185 fColorProcInfo.calcWithInitialValues(fColorStages.begin(), this->numColorStages(), color,
186 flags, false);
egdanielb6cbc382014-11-13 11:00:34 -0800187 fColorProcInfoValid = true;
joshualitt2e3b3e32014-12-09 13:31:14 -0800188 fColorCache = color;
egdanielb6cbc382014-11-13 11:00:34 -0800189 }
190}
191
egdaniel8dd688b2015-01-22 10:16:09 -0800192void GrPipelineBuilder::calcCoverageInvariantOutput(GrColor coverage) const {
joshualitt2e3b3e32014-12-09 13:31:14 -0800193 if (!fCoverageProcInfoValid || coverage != fCoverageCache) {
joshualitt56995b52014-12-11 15:44:02 -0800194 GrColorComponentFlags flags = kRGBA_GrColorComponentFlags;
195 fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(),
196 this->numCoverageStages(), coverage, flags,
197 true);
egdanielb6cbc382014-11-13 11:00:34 -0800198 fCoverageProcInfoValid = true;
joshualitt2e3b3e32014-12-09 13:31:14 -0800199 fCoverageCache = coverage;
egdanielb6cbc382014-11-13 11:00:34 -0800200 }
201}