blob: 8d6c283f7af04ee101f3274448578cd202e8d7b5 [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
bsalomon2a9ca782014-09-05 14:27:43 -070019 if (this->getRenderTarget() != that.getRenderTarget() ||
egdaniel21aed572014-08-26 12:24:06 -070020 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 ||
egdaniel7b3d5ee2014-08-28 05:41:14 -070028 this->fVAStride != that.fVAStride ||
egdaniel21aed572014-08-26 12:24:06 -070029 memcmp(this->fVAPtr, that.fVAPtr, this->fVACount * sizeof(GrVertexAttrib)) ||
30 this->fStencilSettings != that.fStencilSettings ||
31 this->fDrawFace != that.fDrawFace) {
32 return false;
33 }
34
35 bool usingVertexCoverage = this->hasCoverageVertexAttribute();
36 if (!usingVertexCoverage && this->fCoverage != that.fCoverage) {
37 return false;
38 }
39
40 bool explicitLocalCoords = this->hasLocalCoordAttribute();
joshualittbd769d02014-09-04 08:56:46 -070041 if (this->hasGeometryProcessor()) {
42 if (!that.hasGeometryProcessor()) {
joshualitt5a80be22014-09-05 10:45:30 -070043 return false;
joshualittbd769d02014-09-04 08:56:46 -070044 } else if (!GrEffectStage::AreCompatible(*this->getGeometryProcessor(),
45 *that.getGeometryProcessor(),
46 explicitLocalCoords)) {
joshualitt5a80be22014-09-05 10:45:30 -070047 return false;
joshualittbd769d02014-09-04 08:56:46 -070048 }
49 } else if (that.hasGeometryProcessor()) {
joshualitt5a80be22014-09-05 10:45:30 -070050 return false;
joshualittbd769d02014-09-04 08:56:46 -070051 }
52
egdaniel21aed572014-08-26 12:24:06 -070053 for (int i = 0; i < this->numColorStages(); i++) {
54 if (!GrEffectStage::AreCompatible(this->getColorStage(i), that.getColorStage(i),
55 explicitLocalCoords)) {
56 return false;
57 }
58 }
59 for (int i = 0; i < this->numCoverageStages(); i++) {
60 if (!GrEffectStage::AreCompatible(this->getCoverageStage(i), that.getCoverageStage(i),
61 explicitLocalCoords)) {
62 return false;
63 }
64 }
65
egdaniel21aed572014-08-26 12:24:06 -070066 SkASSERT(0 == memcmp(this->fFixedFunctionVertexAttribIndices,
67 that.fFixedFunctionVertexAttribIndices,
68 sizeof(this->fFixedFunctionVertexAttribIndices)));
69
70 return true;
71}
72
73////////////////////////////////////////////////////////////////////////////////
74
75bool GrRODrawState::validateVertexAttribs() const {
76 // check consistency of effects and attributes
77 GrSLType slTypes[kMaxVertexAttribCnt];
78 for (int i = 0; i < kMaxVertexAttribCnt; ++i) {
79 slTypes[i] = static_cast<GrSLType>(-1);
80 }
joshualittbd769d02014-09-04 08:56:46 -070081
82 if (this->hasGeometryProcessor()) {
83 const GrEffectStage& stage = *this->getGeometryProcessor();
egdaniel21aed572014-08-26 12:24:06 -070084 const GrEffect* effect = stage.getEffect();
bsalomon49f085d2014-09-05 13:34:00 -070085 SkASSERT(effect);
egdaniel21aed572014-08-26 12:24:06 -070086 // make sure that any attribute indices have the correct binding type, that the attrib
87 // type and effect's shader lang type are compatible, and that attributes shared by
88 // multiple effects use the same shader lang type.
89 const int* attributeIndices = stage.getVertexAttribIndices();
90 int numAttributes = stage.getVertexAttribIndexCount();
91 for (int i = 0; i < numAttributes; ++i) {
92 int attribIndex = attributeIndices[i];
93 if (attribIndex >= fVACount ||
94 kEffect_GrVertexAttribBinding != fVAPtr[attribIndex].fBinding) {
95 return false;
96 }
97
98 GrSLType effectSLType = effect->vertexAttribType(i);
99 GrVertexAttribType attribType = fVAPtr[attribIndex].fType;
100 int slVecCount = GrSLTypeVectorCount(effectSLType);
101 int attribVecCount = GrVertexAttribTypeVectorCount(attribType);
102 if (slVecCount != attribVecCount ||
103 (static_cast<GrSLType>(-1) != slTypes[attribIndex] &&
104 slTypes[attribIndex] != effectSLType)) {
105 return false;
106 }
107 slTypes[attribIndex] = effectSLType;
108 }
109 }
110
111 return true;
112}
113
114bool GrRODrawState::hasSolidCoverage() const {
115 // If we're drawing coverage directly then coverage is effectively treated as color.
116 if (this->isCoverageDrawing()) {
117 return true;
118 }
119
120 GrColor coverage;
121 uint32_t validComponentFlags;
122 // Initialize to an unknown starting coverage if per-vertex coverage is specified.
123 if (this->hasCoverageVertexAttribute()) {
124 validComponentFlags = 0;
125 } else {
126 coverage = fCoverage;
127 validComponentFlags = kRGBA_GrColorComponentFlags;
128 }
129
130 // Run through the coverage stages and see if the coverage will be all ones at the end.
joshualittbd769d02014-09-04 08:56:46 -0700131 if (this->hasGeometryProcessor()) {
132 const GrEffect* effect = fGeometryProcessor->getEffect();
133 effect->getConstantColorComponents(&coverage, &validComponentFlags);
134 }
egdaniel21aed572014-08-26 12:24:06 -0700135 for (int s = 0; s < this->numCoverageStages(); ++s) {
136 const GrEffect* effect = this->getCoverageStage(s).getEffect();
137 effect->getConstantColorComponents(&coverage, &validComponentFlags);
138 }
139 return (kRGBA_GrColorComponentFlags == validComponentFlags) && (0xffffffff == coverage);
140}
141
142////////////////////////////////////////////////////////////////////////////////
143
144bool GrRODrawState::willEffectReadDstColor() const {
145 if (!this->isColorWriteDisabled()) {
146 for (int s = 0; s < this->numColorStages(); ++s) {
147 if (this->getColorStage(s).getEffect()->willReadDstColor()) {
148 return true;
149 }
150 }
151 }
152 for (int s = 0; s < this->numCoverageStages(); ++s) {
153 if (this->getCoverageStage(s).getEffect()->willReadDstColor()) {
154 return true;
155 }
156 }
joshualittbd769d02014-09-04 08:56:46 -0700157 if (this->hasGeometryProcessor()) {
158 if (fGeometryProcessor->getEffect()->willReadDstColor()) {
159 return true;
160 }
161 }
egdaniel21aed572014-08-26 12:24:06 -0700162 return false;
163}
164
165////////////////////////////////////////////////////////////////////////////////
166
167// Some blend modes allow folding a fractional coverage value into the color's alpha channel, while
168// others will blend incorrectly.
169bool GrRODrawState::canTweakAlphaForCoverage() const {
170 /*
171 The fractional coverage is f.
172 The src and dst coeffs are Cs and Cd.
173 The dst and src colors are S and D.
174 We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the source color's alpha
175 we're replacing S with S'=fS. It's obvious that that first term will always be ok. The second
176 term can be rearranged as [1-(1-Cd)f]D. By substituting in the various possibilities for Cd we
177 find that only 1, ISA, and ISC produce the correct destination when applied to S' and D.
178 Also, if we're directly rendering coverage (isCoverageDrawing) then coverage is treated as
179 color by definition.
180 */
181 return kOne_GrBlendCoeff == fDstBlend ||
182 kISA_GrBlendCoeff == fDstBlend ||
183 kISC_GrBlendCoeff == fDstBlend ||
184 this->isCoverageDrawing();
185}
186
bsalomon2a9ca782014-09-05 14:27:43 -0700187void GrRODrawState::convertToPendingExec() {
188 fRenderTarget.markPendingIO();
189 fRenderTarget.removeRef();
190 for (int i = 0; i < fColorStages.count(); ++i) {
191 fColorStages[i].convertToPendingExec();
192 }
193 if (fGeometryProcessor) {
194 fGeometryProcessor->convertToPendingExec();
195 }
196 for (int i = 0; i < fCoverageStages.count(); ++i) {
197 fCoverageStages[i].convertToPendingExec();
198 }
199}