blob: 1460f57320e48e3c56d87278a96941936f66b333 [file] [log] [blame]
egdaniel21aed572014-08-26 12:24:06 -07001/*
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#include "GrDrawTargetCaps.h"
10
11////////////////////////////////////////////////////////////////////////////////
12
13bool GrRODrawState::isEqual(const GrRODrawState& that) const {
14 bool usingVertexColors = this->hasColorVertexAttribute();
15 if (!usingVertexColors && this->fColor != that.fColor) {
16 return false;
17 }
18
19 if (this->fRenderTarget.get() != that.fRenderTarget.get() ||
20 this->fColorStages.count() != that.fColorStages.count() ||
21 this->fCoverageStages.count() != that.fCoverageStages.count() ||
22 !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) ||
23 this->fSrcBlend != that.fSrcBlend ||
24 this->fDstBlend != that.fDstBlend ||
25 this->fBlendConstant != that.fBlendConstant ||
26 this->fFlagBits != that.fFlagBits ||
27 this->fVACount != that.fVACount ||
28 memcmp(this->fVAPtr, that.fVAPtr, this->fVACount * sizeof(GrVertexAttrib)) ||
29 this->fStencilSettings != that.fStencilSettings ||
30 this->fDrawFace != that.fDrawFace) {
31 return false;
32 }
33
34 bool usingVertexCoverage = this->hasCoverageVertexAttribute();
35 if (!usingVertexCoverage && this->fCoverage != that.fCoverage) {
36 return false;
37 }
38
39 bool explicitLocalCoords = this->hasLocalCoordAttribute();
40 for (int i = 0; i < this->numColorStages(); i++) {
41 if (!GrEffectStage::AreCompatible(this->getColorStage(i), that.getColorStage(i),
42 explicitLocalCoords)) {
43 return false;
44 }
45 }
46 for (int i = 0; i < this->numCoverageStages(); i++) {
47 if (!GrEffectStage::AreCompatible(this->getCoverageStage(i), that.getCoverageStage(i),
48 explicitLocalCoords)) {
49 return false;
50 }
51 }
52
53 SkASSERT(this->fVertexSize == that.fVertexSize);
54 SkASSERT(0 == memcmp(this->fFixedFunctionVertexAttribIndices,
55 that.fFixedFunctionVertexAttribIndices,
56 sizeof(this->fFixedFunctionVertexAttribIndices)));
57
58 return true;
59}
60
61////////////////////////////////////////////////////////////////////////////////
62
63bool GrRODrawState::validateVertexAttribs() const {
64 // check consistency of effects and attributes
65 GrSLType slTypes[kMaxVertexAttribCnt];
66 for (int i = 0; i < kMaxVertexAttribCnt; ++i) {
67 slTypes[i] = static_cast<GrSLType>(-1);
68 }
69 int totalStages = this->numTotalStages();
70 for (int s = 0; s < totalStages; ++s) {
71 int covIdx = s - this->numColorStages();
72 const GrEffectStage& stage = covIdx < 0 ? this->getColorStage(s) :
73 this->getCoverageStage(covIdx);
74 const GrEffect* effect = stage.getEffect();
75 SkASSERT(NULL != effect);
76 // make sure that any attribute indices have the correct binding type, that the attrib
77 // type and effect's shader lang type are compatible, and that attributes shared by
78 // multiple effects use the same shader lang type.
79 const int* attributeIndices = stage.getVertexAttribIndices();
80 int numAttributes = stage.getVertexAttribIndexCount();
81 for (int i = 0; i < numAttributes; ++i) {
82 int attribIndex = attributeIndices[i];
83 if (attribIndex >= fVACount ||
84 kEffect_GrVertexAttribBinding != fVAPtr[attribIndex].fBinding) {
85 return false;
86 }
87
88 GrSLType effectSLType = effect->vertexAttribType(i);
89 GrVertexAttribType attribType = fVAPtr[attribIndex].fType;
90 int slVecCount = GrSLTypeVectorCount(effectSLType);
91 int attribVecCount = GrVertexAttribTypeVectorCount(attribType);
92 if (slVecCount != attribVecCount ||
93 (static_cast<GrSLType>(-1) != slTypes[attribIndex] &&
94 slTypes[attribIndex] != effectSLType)) {
95 return false;
96 }
97 slTypes[attribIndex] = effectSLType;
98 }
99 }
100
101 return true;
102}
103
104bool GrRODrawState::hasSolidCoverage() const {
105 // If we're drawing coverage directly then coverage is effectively treated as color.
106 if (this->isCoverageDrawing()) {
107 return true;
108 }
109
110 GrColor coverage;
111 uint32_t validComponentFlags;
112 // Initialize to an unknown starting coverage if per-vertex coverage is specified.
113 if (this->hasCoverageVertexAttribute()) {
114 validComponentFlags = 0;
115 } else {
116 coverage = fCoverage;
117 validComponentFlags = kRGBA_GrColorComponentFlags;
118 }
119
120 // Run through the coverage stages and see if the coverage will be all ones at the end.
121 for (int s = 0; s < this->numCoverageStages(); ++s) {
122 const GrEffect* effect = this->getCoverageStage(s).getEffect();
123 effect->getConstantColorComponents(&coverage, &validComponentFlags);
124 }
125 return (kRGBA_GrColorComponentFlags == validComponentFlags) && (0xffffffff == coverage);
126}
127
128////////////////////////////////////////////////////////////////////////////////
129
130bool GrRODrawState::willEffectReadDstColor() const {
131 if (!this->isColorWriteDisabled()) {
132 for (int s = 0; s < this->numColorStages(); ++s) {
133 if (this->getColorStage(s).getEffect()->willReadDstColor()) {
134 return true;
135 }
136 }
137 }
138 for (int s = 0; s < this->numCoverageStages(); ++s) {
139 if (this->getCoverageStage(s).getEffect()->willReadDstColor()) {
140 return true;
141 }
142 }
143 return false;
144}
145
146////////////////////////////////////////////////////////////////////////////////
147
148// Some blend modes allow folding a fractional coverage value into the color's alpha channel, while
149// others will blend incorrectly.
150bool GrRODrawState::canTweakAlphaForCoverage() const {
151 /*
152 The fractional coverage is f.
153 The src and dst coeffs are Cs and Cd.
154 The dst and src colors are S and D.
155 We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the source color's alpha
156 we're replacing S with S'=fS. It's obvious that that first term will always be ok. The second
157 term can be rearranged as [1-(1-Cd)f]D. By substituting in the various possibilities for Cd we
158 find that only 1, ISA, and ISC produce the correct destination when applied to S' and D.
159 Also, if we're directly rendering coverage (isCoverageDrawing) then coverage is treated as
160 color by definition.
161 */
162 return kOne_GrBlendCoeff == fDstBlend ||
163 kISA_GrBlendCoeff == fDstBlend ||
164 kISC_GrBlendCoeff == fDstBlend ||
165 this->isCoverageDrawing();
166}
167