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
15GrRODrawState::GrRODrawState(const GrRODrawState& drawState) : INHERITED() {
16    fRenderTarget.setResource(SkSafeRef(drawState.fRenderTarget.getResource()),
17                              GrIORef::kWrite_IOType);
18}
19
20bool 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
82bool 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
123bool 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
153bool 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
171GrRODrawState::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.
266bool 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
284void 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
298bool 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
351