Upstream version 11.39.266.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / GrRODrawState.cpp
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.getColorStage(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.getCoverageStage(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, that the attrib
94         // type and effect's shader lang type are compatible, and that attributes 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].fBinding) {
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 everything
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 as 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 specified.
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 request.
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 alpha 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 source 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 possibilities 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 coverage 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 tools 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 coverage computation.
322     if (this->isCoverageDrawing()) {
323         // The shader generated for coverage drawing runs the full coverage computation 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).getProcessor();
338             processor->getConstantColorComponents(&coverage, &coverageComponentFlags);
339         }
340
341         // Since the shader will multiply coverage and color, the only way the final A==1 is if
342         // coverage and color both have A==1.
343         return (kA_GrColorComponentFlag & validComponentFlags & coverageComponentFlags) &&
344                 0xFF == GrColorUnpackA(color) && 0xFF == GrColorUnpackA(coverage);
345
346     }
347
348     return (kA_GrColorComponentFlag & validComponentFlags) && 0xFF == GrColorUnpackA(color);
349 }
350