OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2014 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 "GrRODrawState.h" | |
9 | |
10 #include "GrDrawTargetCaps.h" | |
11 #include "GrRenderTarget.h" | |
12 | |
13 //////////////////////////////////////////////////////////////////////////////// | |
14 | |
15 GrRODrawState::GrRODrawState(const GrRODrawState& drawState) : INHERITED() { | |
16 fRenderTarget.setResource(SkSafeRef(drawState.fRenderTarget.getResource()), | |
17 GrIORef::kWrite_IOType); | |
18 } | |
19 | |
20 bool GrRODrawState::isEqual(const GrRODrawState& that) const { | |
21 bool usingVertexColors = this->hasColorVertexAttribute(); | |
22 if (!usingVertexColors && this->fColor != that.fColor) { | |
23 return false; | |
24 } | |
25 | |
26 if (this->getRenderTarget() != that.getRenderTarget() || | |
27 this->fColorStages.count() != that.fColorStages.count() || | |
28 this->fCoverageStages.count() != that.fCoverageStages.count() || | |
29 !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) || | |
30 this->fSrcBlend != that.fSrcBlend || | |
31 this->fDstBlend != that.fDstBlend || | |
32 this->fBlendConstant != that.fBlendConstant || | |
33 this->fFlagBits != that.fFlagBits || | |
34 this->fVACount != that.fVACount || | |
35 this->fVAStride != that.fVAStride || | |
36 memcmp(this->fVAPtr, that.fVAPtr, this->fVACount * sizeof(GrVertexAttrib
)) || | |
37 this->fStencilSettings != that.fStencilSettings || | |
38 this->fDrawFace != that.fDrawFace) { | |
39 return false; | |
40 } | |
41 | |
42 bool usingVertexCoverage = this->hasCoverageVertexAttribute(); | |
43 if (!usingVertexCoverage && this->fCoverage != that.fCoverage) { | |
44 return false; | |
45 } | |
46 | |
47 bool explicitLocalCoords = this->hasLocalCoordAttribute(); | |
48 if (this->hasGeometryProcessor()) { | |
49 if (!that.hasGeometryProcessor()) { | |
50 return false; | |
51 } else if (!GrProcessorStage::AreCompatible(*this->getGeometryProcessor(
), | |
52 *that.getGeometryProcessor()
, | |
53 explicitLocalCoords)) { | |
54 return false; | |
55 } | |
56 } else if (that.hasGeometryProcessor()) { | |
57 return false; | |
58 } | |
59 | |
60 for (int i = 0; i < this->numColorStages(); i++) { | |
61 if (!GrProcessorStage::AreCompatible(this->getColorStage(i), that.getCol
orStage(i), | |
62 explicitLocalCoords)) { | |
63 return false; | |
64 } | |
65 } | |
66 for (int i = 0; i < this->numCoverageStages(); i++) { | |
67 if (!GrProcessorStage::AreCompatible(this->getCoverageStage(i), that.get
CoverageStage(i), | |
68 explicitLocalCoords)) { | |
69 return false; | |
70 } | |
71 } | |
72 | |
73 SkASSERT(0 == memcmp(this->fFixedFunctionVertexAttribIndices, | |
74 that.fFixedFunctionVertexAttribIndices, | |
75 sizeof(this->fFixedFunctionVertexAttribIndices))); | |
76 | |
77 return true; | |
78 } | |
79 | |
80 //////////////////////////////////////////////////////////////////////////////// | |
81 | |
82 bool GrRODrawState::validateVertexAttribs() const { | |
83 // check consistency of effects and attributes | |
84 GrSLType slTypes[kMaxVertexAttribCnt]; | |
85 for (int i = 0; i < kMaxVertexAttribCnt; ++i) { | |
86 slTypes[i] = static_cast<GrSLType>(-1); | |
87 } | |
88 | |
89 if (this->hasGeometryProcessor()) { | |
90 const GrGeometryStage& stage = *this->getGeometryProcessor(); | |
91 const GrGeometryProcessor* gp = stage.getGeometryProcessor(); | |
92 SkASSERT(gp); | |
93 // make sure that any attribute indices have the correct binding type, t
hat the attrib | |
94 // type and effect's shader lang type are compatible, and that attribute
s shared by | |
95 // multiple effects use the same shader lang type. | |
96 const GrGeometryProcessor::VertexAttribArray& s = gp->getVertexAttribs()
; | |
97 | |
98 int effectIndex = 0; | |
99 for (int index = 0; index < fVACount; index++) { | |
100 if (kGeometryProcessor_GrVertexAttribBinding != fVAPtr[index].fBindi
ng) { | |
101 // we only care about effect bindings | |
102 continue; | |
103 } | |
104 SkASSERT(effectIndex < s.count()); | |
105 GrSLType effectSLType = s[effectIndex].getType(); | |
106 GrVertexAttribType attribType = fVAPtr[index].fType; | |
107 int slVecCount = GrSLTypeVectorCount(effectSLType); | |
108 int attribVecCount = GrVertexAttribTypeVectorCount(attribType); | |
109 if (slVecCount != attribVecCount || | |
110 (static_cast<GrSLType>(-1) != slTypes[index] && slTypes[index] !
= effectSLType)) { | |
111 return false; | |
112 } | |
113 slTypes[index] = effectSLType; | |
114 effectIndex++; | |
115 } | |
116 // Make sure all attributes are consumed and we were able to find everyt
hing | |
117 SkASSERT(s.count() == effectIndex); | |
118 } | |
119 | |
120 return true; | |
121 } | |
122 | |
123 bool GrRODrawState::hasSolidCoverage() const { | |
124 // If we're drawing coverage directly then coverage is effectively treated a
s color. | |
125 if (this->isCoverageDrawing()) { | |
126 return true; | |
127 } | |
128 | |
129 GrColor coverage; | |
130 uint32_t validComponentFlags; | |
131 // Initialize to an unknown starting coverage if per-vertex coverage is spec
ified. | |
132 if (this->hasCoverageVertexAttribute()) { | |
133 validComponentFlags = 0; | |
134 } else { | |
135 coverage = fCoverage; | |
136 validComponentFlags = kRGBA_GrColorComponentFlags; | |
137 } | |
138 | |
139 // Run through the coverage stages and see if the coverage will be all ones
at the end. | |
140 if (this->hasGeometryProcessor()) { | |
141 const GrGeometryProcessor* gp = fGeometryProcessor->getGeometryProcessor
(); | |
142 gp->getConstantColorComponents(&coverage, &validComponentFlags); | |
143 } | |
144 for (int s = 0; s < this->numCoverageStages(); ++s) { | |
145 const GrProcessor* processor = this->getCoverageStage(s).getProcessor(); | |
146 processor->getConstantColorComponents(&coverage, &validComponentFlags); | |
147 } | |
148 return (kRGBA_GrColorComponentFlags == validComponentFlags) && (0xffffffff =
= coverage); | |
149 } | |
150 | |
151 //////////////////////////////////////////////////////////////////////////////// | |
152 | |
153 bool GrRODrawState::willEffectReadDstColor() const { | |
154 if (!this->isColorWriteDisabled()) { | |
155 for (int s = 0; s < this->numColorStages(); ++s) { | |
156 if (this->getColorStage(s).getFragmentProcessor()->willReadDstColor(
)) { | |
157 return true; | |
158 } | |
159 } | |
160 } | |
161 for (int s = 0; s < this->numCoverageStages(); ++s) { | |
162 if (this->getCoverageStage(s).getFragmentProcessor()->willReadDstColor()
) { | |
163 return true; | |
164 } | |
165 } | |
166 return false; | |
167 } | |
168 | |
169 //////////////////////////////////////////////////////////////////////////////// | |
170 | |
171 GrRODrawState::BlendOptFlags GrRODrawState::getBlendOpts(bool forceCoverage, | |
172 GrBlendCoeff* srcCoeff, | |
173 GrBlendCoeff* dstCoeff)
const { | |
174 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff; | |
175 if (NULL == srcCoeff) { | |
176 srcCoeff = &bogusSrcCoeff; | |
177 } | |
178 if (NULL == dstCoeff) { | |
179 dstCoeff = &bogusDstCoeff; | |
180 } | |
181 | |
182 *srcCoeff = this->getSrcBlendCoeff(); | |
183 *dstCoeff = this->getDstBlendCoeff(); | |
184 | |
185 if (this->isColorWriteDisabled()) { | |
186 *srcCoeff = kZero_GrBlendCoeff; | |
187 *dstCoeff = kOne_GrBlendCoeff; | |
188 } | |
189 | |
190 bool srcAIsOne = this->srcAlphaWillBeOne(); | |
191 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || | |
192 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne); | |
193 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff || | |
194 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne); | |
195 | |
196 // When coeffs are (0,1) there is no reason to draw at all, unless | |
197 // stenciling is enabled. Having color writes disabled is effectively | |
198 // (0,1). | |
199 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne)) { | |
200 if (this->getStencil().doesWrite()) { | |
201 return kEmitCoverage_BlendOptFlag; | |
202 } else { | |
203 *dstCoeff = kOne_GrBlendCoeff; | |
204 return kSkipDraw_BlendOptFlag; | |
205 } | |
206 } | |
207 | |
208 bool hasCoverage = forceCoverage || !this->hasSolidCoverage(); | |
209 | |
210 // if we don't have coverage we can check whether the dst | |
211 // has to read at all. If not, we'll disable blending. | |
212 if (!hasCoverage) { | |
213 if (dstCoeffIsZero) { | |
214 if (kOne_GrBlendCoeff == *srcCoeff) { | |
215 // if there is no coverage and coeffs are (1,0) then we | |
216 // won't need to read the dst at all, it gets replaced by src | |
217 *dstCoeff = kZero_GrBlendCoeff; | |
218 return kNone_BlendOpt; | |
219 } else if (kZero_GrBlendCoeff == *srcCoeff) { | |
220 // if the op is "clear" then we don't need to emit a color | |
221 // or blend, just write transparent black into the dst. | |
222 *srcCoeff = kOne_GrBlendCoeff; | |
223 *dstCoeff = kZero_GrBlendCoeff; | |
224 return kEmitTransBlack_BlendOptFlag; | |
225 } | |
226 } | |
227 } else if (this->isCoverageDrawing()) { | |
228 // we have coverage but we aren't distinguishing it from alpha by reques
t. | |
229 return kCoverageAsAlpha_BlendOptFlag; | |
230 } else { | |
231 // check whether coverage can be safely rolled into alpha | |
232 // of if we can skip color computation and just emit coverage | |
233 if (this->canTweakAlphaForCoverage()) { | |
234 return kCoverageAsAlpha_BlendOptFlag; | |
235 } | |
236 if (dstCoeffIsZero) { | |
237 if (kZero_GrBlendCoeff == *srcCoeff) { | |
238 // the source color is not included in the blend | |
239 // the dst coeff is effectively zero so blend works out to: | |
240 // (c)(0)D + (1-c)D = (1-c)D. | |
241 *dstCoeff = kISA_GrBlendCoeff; | |
242 return kEmitCoverage_BlendOptFlag; | |
243 } else if (srcAIsOne) { | |
244 // the dst coeff is effectively zero so blend works out to: | |
245 // cS + (c)(0)D + (1-c)D = cS + (1-c)D. | |
246 // If Sa is 1 then we can replace Sa with c | |
247 // and set dst coeff to 1-Sa. | |
248 *dstCoeff = kISA_GrBlendCoeff; | |
249 return kCoverageAsAlpha_BlendOptFlag; | |
250 } | |
251 } else if (dstCoeffIsOne) { | |
252 // the dst coeff is effectively one so blend works out to: | |
253 // cS + (c)(1)D + (1-c)D = cS + D. | |
254 *dstCoeff = kOne_GrBlendCoeff; | |
255 return kCoverageAsAlpha_BlendOptFlag; | |
256 } | |
257 } | |
258 | |
259 return kNone_BlendOpt; | |
260 } | |
261 | |
262 //////////////////////////////////////////////////////////////////////////////// | |
263 | |
264 // Some blend modes allow folding a fractional coverage value into the color's a
lpha channel, while | |
265 // others will blend incorrectly. | |
266 bool GrRODrawState::canTweakAlphaForCoverage() const { | |
267 /* | |
268 The fractional coverage is f. | |
269 The src and dst coeffs are Cs and Cd. | |
270 The dst and src colors are S and D. | |
271 We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the sou
rce color's alpha | |
272 we're replacing S with S'=fS. It's obvious that that first term will always
be ok. The second | |
273 term can be rearranged as [1-(1-Cd)f]D. By substituting in the various poss
ibilities for Cd we | |
274 find that only 1, ISA, and ISC produce the correct destination when applied
to S' and D. | |
275 Also, if we're directly rendering coverage (isCoverageDrawing) then coverag
e is treated as | |
276 color by definition. | |
277 */ | |
278 return kOne_GrBlendCoeff == fDstBlend || | |
279 kISA_GrBlendCoeff == fDstBlend || | |
280 kISC_GrBlendCoeff == fDstBlend || | |
281 this->isCoverageDrawing(); | |
282 } | |
283 | |
284 void GrRODrawState::convertToPendingExec() { | |
285 fRenderTarget.markPendingIO(); | |
286 fRenderTarget.removeRef(); | |
287 for (int i = 0; i < fColorStages.count(); ++i) { | |
288 fColorStages[i].convertToPendingExec(); | |
289 } | |
290 if (fGeometryProcessor) { | |
291 fGeometryProcessor->convertToPendingExec(); | |
292 } | |
293 for (int i = 0; i < fCoverageStages.count(); ++i) { | |
294 fCoverageStages[i].convertToPendingExec(); | |
295 } | |
296 } | |
297 | |
298 bool GrRODrawState::srcAlphaWillBeOne() const { | |
299 uint32_t validComponentFlags; | |
300 GrColor color; | |
301 // Check if per-vertex or constant color may have partial alpha | |
302 if (this->hasColorVertexAttribute()) { | |
303 if (fHints & kVertexColorsAreOpaque_Hint) { | |
304 validComponentFlags = kA_GrColorComponentFlag; | |
305 color = 0xFF << GrColor_SHIFT_A; | |
306 } else { | |
307 validComponentFlags = 0; | |
308 color = 0; // not strictly necessary but we get false alarms from to
ols about uninit. | |
309 } | |
310 } else { | |
311 validComponentFlags = kRGBA_GrColorComponentFlags; | |
312 color = this->getColor(); | |
313 } | |
314 | |
315 // Run through the color stages | |
316 for (int s = 0; s < this->numColorStages(); ++s) { | |
317 const GrProcessor* processor = this->getColorStage(s).getProcessor(); | |
318 processor->getConstantColorComponents(&color, &validComponentFlags); | |
319 } | |
320 | |
321 // Check whether coverage is treated as color. If so we run through the cove
rage computation. | |
322 if (this->isCoverageDrawing()) { | |
323 // The shader generated for coverage drawing runs the full coverage comp
utation and then | |
324 // makes the shader output be the multiplication of color and coverage.
We mirror that here. | |
325 GrColor coverage; | |
326 uint32_t coverageComponentFlags; | |
327 if (this->hasCoverageVertexAttribute()) { | |
328 coverageComponentFlags = 0; | |
329 coverage = 0; // suppresses any warnings. | |
330 } else { | |
331 coverageComponentFlags = kRGBA_GrColorComponentFlags; | |
332 coverage = this->getCoverageColor(); | |
333 } | |
334 | |
335 // Run through the coverage stages | |
336 for (int s = 0; s < this->numCoverageStages(); ++s) { | |
337 const GrProcessor* processor = this->getCoverageStage(s).getProcesso
r(); | |
338 processor->getConstantColorComponents(&coverage, &coverageComponentF
lags); | |
339 } | |
340 | |
341 // Since the shader will multiply coverage and color, the only way the f
inal A==1 is if | |
342 // coverage and color both have A==1. | |
343 return (kA_GrColorComponentFlag & validComponentFlags & coverageComponen
tFlags) && | |
344 0xFF == GrColorUnpackA(color) && 0xFF == GrColorUnpackA(coverage
); | |
345 | |
346 } | |
347 | |
348 return (kA_GrColorComponentFlag & validComponentFlags) && 0xFF == GrColorUnp
ackA(color); | |
349 } | |
350 | |
OLD | NEW |