1 /*
2 * Copyright 2015 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 "GrPipelineBuilder.h"
9
10 #include "GrBatch.h"
11 #include "GrBlend.h"
12 #include "GrPaint.h"
13 #include "GrPipeline.h"
14 #include "GrProcOptInfo.h"
15 #include "GrXferProcessor.h"
16 #include "effects/GrPorterDuffXferProcessor.h"
17
GrPipelineBuilder()18 GrPipelineBuilder::GrPipelineBuilder()
19 : fFlags(0x0)
20 , fDrawFace(kBoth_DrawFace)
21 , fColorProcInfoValid(false)
22 , fCoverageProcInfoValid(false)
23 , fColorCache(GrColor_ILLEGAL)
24 , fCoverageCache(GrColor_ILLEGAL) {
25 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
26 }
27
operator =(const GrPipelineBuilder & that)28 GrPipelineBuilder& GrPipelineBuilder::operator=(const GrPipelineBuilder& that) {
29 fRenderTarget.reset(SkSafeRef(that.fRenderTarget.get()));
30 fFlags = that.fFlags;
31 fStencilSettings = that.fStencilSettings;
32 fDrawFace = that.fDrawFace;
33 fXPFactory.reset(SkRef(that.getXPFactory()));
34 fColorStages = that.fColorStages;
35 fCoverageStages = that.fCoverageStages;
36 fClip = that.fClip;
37
38 fColorProcInfoValid = that.fColorProcInfoValid;
39 fCoverageProcInfoValid = that.fCoverageProcInfoValid;
40 fColorCache = that.fColorCache;
41 fCoverageCache = that.fCoverageCache;
42 if (fColorProcInfoValid) {
43 fColorProcInfo = that.fColorProcInfo;
44 }
45 if (fCoverageProcInfoValid) {
46 fCoverageProcInfo = that.fCoverageProcInfo;
47 }
48 return *this;
49 }
50
setFromPaint(const GrPaint & paint,GrRenderTarget * rt,const GrClip & clip)51 void GrPipelineBuilder::setFromPaint(const GrPaint& paint, GrRenderTarget* rt, const GrClip& clip) {
52 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numFragmentStages());
53
54 fColorStages.reset();
55 fCoverageStages.reset();
56
57 for (int i = 0; i < paint.numColorStages(); ++i) {
58 fColorStages.push_back(paint.getColorStage(i));
59 }
60
61 for (int i = 0; i < paint.numCoverageStages(); ++i) {
62 fCoverageStages.push_back(paint.getCoverageStage(i));
63 }
64
65 fXPFactory.reset(SkRef(paint.getXPFactory()));
66
67 this->setRenderTarget(rt);
68
69 // These have no equivalent in GrPaint, set them to defaults
70 fDrawFace = kBoth_DrawFace;
71 fStencilSettings.setDisabled();
72 fFlags = 0;
73
74 fClip = clip;
75
76 this->setState(GrPipelineBuilder::kDither_Flag, paint.isDither());
77 this->setState(GrPipelineBuilder::kHWAntialias_Flag,
78 rt->isMultisampled() && paint.isAntiAlias());
79
80 fColorProcInfoValid = false;
81 fCoverageProcInfoValid = false;
82
83 fColorCache = GrColor_ILLEGAL;
84 fCoverageCache = GrColor_ILLEGAL;
85 }
86
87 //////////////////////////////////////////////////////////////////////////////s
88
willXPNeedDstCopy(const GrDrawTargetCaps & caps,const GrProcOptInfo & colorPOI,const GrProcOptInfo & coveragePOI) const89 bool GrPipelineBuilder::willXPNeedDstCopy(const GrDrawTargetCaps& caps,
90 const GrProcOptInfo& colorPOI,
91 const GrProcOptInfo& coveragePOI) const {
92 return this->getXPFactory()->willNeedDstCopy(caps, colorPOI, coveragePOI);
93 }
94
set(GrPipelineBuilder * pipelineBuilder)95 void GrPipelineBuilder::AutoRestoreFragmentProcessors::set(GrPipelineBuilder* pipelineBuilder) {
96 if (fPipelineBuilder) {
97 int m = fPipelineBuilder->numColorFragmentStages() - fColorEffectCnt;
98 SkASSERT(m >= 0);
99 fPipelineBuilder->fColorStages.pop_back_n(m);
100
101 int n = fPipelineBuilder->numCoverageFragmentStages() - fCoverageEffectCnt;
102 SkASSERT(n >= 0);
103 fPipelineBuilder->fCoverageStages.pop_back_n(n);
104 if (m + n > 0) {
105 fPipelineBuilder->fColorProcInfoValid = false;
106 fPipelineBuilder->fCoverageProcInfoValid = false;
107 }
108 SkDEBUGCODE(--fPipelineBuilder->fBlockEffectRemovalCnt;)
109 }
110 fPipelineBuilder = pipelineBuilder;
111 if (NULL != pipelineBuilder) {
112 fColorEffectCnt = pipelineBuilder->numColorFragmentStages();
113 fCoverageEffectCnt = pipelineBuilder->numCoverageFragmentStages();
114 SkDEBUGCODE(++pipelineBuilder->fBlockEffectRemovalCnt;)
115 }
116 }
117
118 ////////////////////////////////////////////////////////////////////////////////
119
~GrPipelineBuilder()120 GrPipelineBuilder::~GrPipelineBuilder() {
121 SkASSERT(0 == fBlockEffectRemovalCnt);
122 }
123
124 ////////////////////////////////////////////////////////////////////////////////
125
willBlendWithDst(const GrPrimitiveProcessor * pp) const126 bool GrPipelineBuilder::willBlendWithDst(const GrPrimitiveProcessor* pp) const {
127 this->calcColorInvariantOutput(pp);
128 this->calcCoverageInvariantOutput(pp);
129
130 GrXPFactory::InvariantOutput output;
131 fXPFactory->getInvariantOutput(fColorProcInfo, fCoverageProcInfo, &output);
132 return output.fWillBlendWithDst;
133 }
134
calcColorInvariantOutput(const GrPrimitiveProcessor * pp) const135 void GrPipelineBuilder::calcColorInvariantOutput(const GrPrimitiveProcessor* pp) const {
136 fColorProcInfo.calcColorWithPrimProc(pp, fColorStages.begin(), this->numColorFragmentStages());
137 fColorProcInfoValid = false;
138
139 }
140
calcCoverageInvariantOutput(const GrPrimitiveProcessor * pp) const141 void GrPipelineBuilder::calcCoverageInvariantOutput(const GrPrimitiveProcessor* pp) const {
142 fCoverageProcInfo.calcCoverageWithPrimProc(pp, fCoverageStages.begin(),
143 this->numCoverageFragmentStages());
144 fCoverageProcInfoValid = false;
145 }
146
calcColorInvariantOutput(const GrBatch * batch) const147 void GrPipelineBuilder::calcColorInvariantOutput(const GrBatch* batch) const {
148 fColorProcInfo.calcColorWithBatch(batch, fColorStages.begin(), this->numColorFragmentStages());
149 fColorProcInfoValid = false;
150 }
151
calcCoverageInvariantOutput(const GrBatch * batch) const152 void GrPipelineBuilder::calcCoverageInvariantOutput(const GrBatch* batch) const {
153 fCoverageProcInfo.calcCoverageWithBatch(batch, fCoverageStages.begin(),
154 this->numCoverageFragmentStages());
155 fCoverageProcInfoValid = false;
156 }
157
158
calcColorInvariantOutput(GrColor color) const159 void GrPipelineBuilder::calcColorInvariantOutput(GrColor color) const {
160 if (!fColorProcInfoValid || color != fColorCache) {
161 GrColorComponentFlags flags = kRGBA_GrColorComponentFlags;
162 fColorProcInfo.calcWithInitialValues(fColorStages.begin(),this->numColorFragmentStages(),
163 color, flags, false);
164 fColorProcInfoValid = true;
165 fColorCache = color;
166 }
167 }
168
calcCoverageInvariantOutput(GrColor coverage) const169 void GrPipelineBuilder::calcCoverageInvariantOutput(GrColor coverage) const {
170 if (!fCoverageProcInfoValid || coverage != fCoverageCache) {
171 GrColorComponentFlags flags = kRGBA_GrColorComponentFlags;
172 fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(),
173 this->numCoverageFragmentStages(), coverage, flags,
174 true);
175 fCoverageProcInfoValid = true;
176 fCoverageCache = coverage;
177 }
178 }
179