OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrGLProgram.h" | 8 #include "GrGLProgram.h" |
9 | 9 |
10 #include "GrAllocator.h" | 10 #include "GrAllocator.h" |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 } else if (covIsSolidWhite) { | 110 } else if (covIsSolidWhite) { |
111 desc->fCoverageInput = Desc::kSolidWhite_ColorInput; | 111 desc->fCoverageInput = Desc::kSolidWhite_ColorInput; |
112 } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeCoverage) { | 112 } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeCoverage) { |
113 desc->fCoverageInput = Desc::kUniform_ColorInput; | 113 desc->fCoverageInput = Desc::kUniform_ColorInput; |
114 } else { | 114 } else { |
115 desc->fCoverageInput = Desc::kAttribute_ColorInput; | 115 desc->fCoverageInput = Desc::kAttribute_ColorInput; |
116 } | 116 } |
117 | 117 |
118 int lastEnabledStage = -1; | 118 int lastEnabledStage = -1; |
119 | 119 |
120 if (!skipCoverage) { | |
121 desc->fDiscardIfOutsideEdge = drawState.getStencil().doesWrite(); | |
122 } else { | |
123 // Use canonical values when edge-aa is not enabled to avoid program cac
he misses. | |
124 desc->fDiscardIfOutsideEdge = false; | |
125 } | |
126 | |
127 for (int s = 0; s < GrDrawState::kNumStages; ++s) { | 120 for (int s = 0; s < GrDrawState::kNumStages; ++s) { |
128 | 121 |
129 bool skip = s < drawState.getFirstCoverageStage() ? skipColor : skipCove
rage; | 122 bool skip = s < drawState.getFirstCoverageStage() ? skipColor : skipCove
rage; |
130 if (!skip && drawState.isStageEnabled(s)) { | 123 if (!skip && drawState.isStageEnabled(s)) { |
131 lastEnabledStage = s; | 124 lastEnabledStage = s; |
132 const GrEffectRef& effect = *drawState.getStage(s).getEffect(); | 125 const GrEffectRef& effect = *drawState.getStage(s).getEffect(); |
133 const GrBackendEffectFactory& factory = effect->getFactory(); | 126 const GrBackendEffectFactory& factory = effect->getFactory(); |
134 bool explicitLocalCoords = (drawState.getAttribBindings() & | 127 bool explicitLocalCoords = (drawState.getAttribBindings() & |
135 GrDrawState::kLocalCoords_AttribBindings
Bit); | 128 GrDrawState::kLocalCoords_AttribBindings
Bit); |
136 GrDrawEffect drawEffect(drawState.getStage(s), explicitLocalCoords); | 129 GrDrawEffect drawEffect(drawState.getStage(s), explicitLocalCoords); |
137 desc->fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps()
); | 130 desc->fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps()
); |
138 } else { | 131 } else { |
139 desc->fEffectKeys[s] = 0; | 132 desc->fEffectKeys[s] = 0; |
140 } | 133 } |
141 } | 134 } |
142 | 135 |
143 desc->fDualSrcOutput = Desc::kNone_DualSrcOutput; | 136 desc->fDualSrcOutput = Desc::kNone_DualSrcOutput; |
144 | 137 |
145 // Currently the experimental GS will only work with triangle prims (and it
doesn't do anything | 138 // Currently the experimental GS will only work with triangle prims (and it
doesn't do anything |
146 // other than pass through values from the VS to the FS anyway). | 139 // other than pass through values from the VS to the FS anyway). |
147 #if GR_GL_EXPERIMENTAL_GS | 140 #if GR_GL_EXPERIMENTAL_GS |
148 #if 0 | 141 #if 0 |
149 desc->fExperimentalGS = gpu->caps().geometryShaderSupport(); | 142 desc->fExperimentalGS = gpu->caps().geometryShaderSupport(); |
150 #else | 143 #else |
151 desc->fExperimentalGS = false; | 144 desc->fExperimentalGS = false; |
152 #endif | 145 #endif |
153 #endif | 146 #endif |
154 | 147 |
155 // We want to avoid generating programs with different "first cov stage" val
ues when they would | 148 // We leave this set to kNumStages until we discover that the coverage/color
distinction is |
156 // compute the same result. We set field in the desc to kNumStages when eith
er there are no | 149 // material to the generated program. We do this to avoid distinct keys that
generate equivalent |
157 // coverage stages or the distinction between coverage and color is immateri
al. | 150 // programs. |
| 151 desc->fFirstCoverageStage = GrDrawState::kNumStages; |
| 152 // This tracks the actual first coverage stage. |
158 int firstCoverageStage = GrDrawState::kNumStages; | 153 int firstCoverageStage = GrDrawState::kNumStages; |
159 desc->fFirstCoverageStage = GrDrawState::kNumStages; | 154 desc->fDiscardIfZeroCoverage = false; // Enabled below if stenciling and the
re is coverage. |
160 bool hasCoverage = drawState.getFirstCoverageStage() <= lastEnabledStage; | 155 bool hasCoverage = false; |
161 if (hasCoverage) { | 156 // If we're rendering coverage-as-color then its as though there are no cove
rage stages. |
162 firstCoverageStage = drawState.getFirstCoverageStage(); | 157 if (!drawState.isCoverageDrawing()) { |
| 158 // We can have coverage either through a stage or coverage vertex attrib
utes. |
| 159 if (drawState.getFirstCoverageStage() <= lastEnabledStage) { |
| 160 firstCoverageStage = drawState.getFirstCoverageStage(); |
| 161 hasCoverage = true; |
| 162 } else { |
| 163 hasCoverage = requiresAttributeCoverage; |
| 164 } |
163 } | 165 } |
164 | 166 |
165 // other coverage inputs | |
166 if (!hasCoverage) { | |
167 hasCoverage = requiresAttributeCoverage; | |
168 } | |
169 | |
170 if (hasCoverage) { | 167 if (hasCoverage) { |
171 // color filter is applied between color/coverage computation | 168 // color filter is applied between color/coverage computation |
172 if (SkXfermode::kDst_Mode != desc->fColorFilterXfermode) { | 169 if (SkXfermode::kDst_Mode != desc->fColorFilterXfermode) { |
173 desc->fFirstCoverageStage = firstCoverageStage; | 170 desc->fFirstCoverageStage = firstCoverageStage; |
174 } | 171 } |
| 172 |
| 173 // If we're stenciling then we want to discard samples that have zero co
verage |
| 174 if (drawState.getStencil().doesWrite()) { |
| 175 desc->fDiscardIfZeroCoverage = true; |
| 176 desc->fFirstCoverageStage = firstCoverageStage; |
| 177 } |
175 | 178 |
176 if (gpu->caps()->dualSourceBlendingSupport() && | 179 if (gpu->caps()->dualSourceBlendingSupport() && |
177 !(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag | | 180 !(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag | |
178 GrDrawState::kCoverageAsAlpha_BlendOptFlag))) { | 181 GrDrawState::kCoverageAsAlpha_BlendOptFlag))) { |
179 if (kZero_GrBlendCoeff == dstCoeff) { | 182 if (kZero_GrBlendCoeff == dstCoeff) { |
180 // write the coverage value to second color | 183 // write the coverage value to second color |
181 desc->fDualSrcOutput = Desc::kCoverage_DualSrcOutput; | 184 desc->fDualSrcOutput = Desc::kCoverage_DualSrcOutput; |
182 desc->fFirstCoverageStage = firstCoverageStage; | 185 desc->fFirstCoverageStage = firstCoverageStage; |
183 } else if (kSA_GrBlendCoeff == dstCoeff) { | 186 } else if (kSA_GrBlendCoeff == dstCoeff) { |
184 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
covered. | 187 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
covered. |
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 fDesc.fEffectKeys[s], | 793 fDesc.fEffectKeys[s], |
791 inCoverage.size() ? inCovera
ge.c_str() : NULL, | 794 inCoverage.size() ? inCovera
ge.c_str() : NULL, |
792 outCoverage.c_str(), | 795 outCoverage.c_str(), |
793 &fUniformHandles.fSamplerUni
s[s]); | 796 &fUniformHandles.fSamplerUni
s[s]); |
794 builder.setNonStage(); | 797 builder.setNonStage(); |
795 inCoverage = outCoverage; | 798 inCoverage = outCoverage; |
796 } | 799 } |
797 } | 800 } |
798 | 801 |
799 // discard if coverage is zero | 802 // discard if coverage is zero |
800 if (fDesc.fDiscardIfOutsideEdge && !outCoverage.isEmpty()) { | 803 if (fDesc.fDiscardIfZeroCoverage && !outCoverage.isEmpty()) { |
801 builder.fsCodeAppendf( | 804 builder.fsCodeAppendf( |
802 "\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\t\tdiscard;\n\
t}\n", | 805 "\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\t\tdiscard;\n\
t}\n", |
803 outCoverage.c_str()); | 806 outCoverage.c_str()); |
804 } | 807 } |
805 } | 808 } |
806 | 809 |
807 if (Desc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) { | 810 if (Desc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) { |
808 builder.fFSOutputs.push_back().set(kVec4f_GrSLType, | 811 builder.fFSOutputs.push_back().set(kVec4f_GrSLType, |
809 GrGLShaderVar::kOut_TypeModifier, | 812 GrGLShaderVar::kOut_TypeModifier, |
810 dual_source_output_name()); | 813 dual_source_output_name()); |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1108 SkScalarToFloat(m[SkMatrix::kMTransX]), | 1111 SkScalarToFloat(m[SkMatrix::kMTransX]), |
1109 SkScalarToFloat(m[SkMatrix::kMTransY]), | 1112 SkScalarToFloat(m[SkMatrix::kMTransY]), |
1110 SkScalarToFloat(m[SkMatrix::kMPersp2]) | 1113 SkScalarToFloat(m[SkMatrix::kMPersp2]) |
1111 }; | 1114 }; |
1112 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt); | 1115 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt); |
1113 fMatrixState.fViewMatrix = drawState.getViewMatrix(); | 1116 fMatrixState.fViewMatrix = drawState.getViewMatrix(); |
1114 fMatrixState.fRenderTargetSize = size; | 1117 fMatrixState.fRenderTargetSize = size; |
1115 fMatrixState.fRenderTargetOrigin = rt->origin(); | 1118 fMatrixState.fRenderTargetOrigin = rt->origin(); |
1116 } | 1119 } |
1117 } | 1120 } |
OLD | NEW |