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" |
11 #include "GrEffect.h" | 11 #include "GrEffect.h" |
12 #include "GrDrawEffect.h" | 12 #include "GrDrawEffect.h" |
13 #include "GrGLEffect.h" | 13 #include "GrGLEffect.h" |
14 #include "GrGpuGL.h" | 14 #include "GrGpuGL.h" |
15 #include "GrGLShaderVar.h" | 15 #include "GrGLShaderVar.h" |
16 #include "GrBackendEffectFactory.h" | |
17 #include "SkTrace.h" | 16 #include "SkTrace.h" |
18 #include "SkXfermode.h" | 17 #include "SkXfermode.h" |
19 | 18 |
20 #include "SkRTConf.h" | 19 #include "SkRTConf.h" |
21 | 20 |
22 SK_DEFINE_INST_COUNT(GrGLProgram) | 21 SK_DEFINE_INST_COUNT(GrGLProgram) |
23 | 22 |
24 #define GL_CALL(X) GR_GL_CALL(fContext.interface(), X) | 23 #define GL_CALL(X) GR_GL_CALL(fContext.interface(), X) |
25 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fContext.interface(), R, X) | 24 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fContext.interface(), R, X) |
26 | 25 |
27 SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false, | 26 SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false, |
28 "Print the source code for all shaders generated."); | 27 "Print the source code for all shaders generated."); |
29 | 28 |
30 #define COL_ATTR_NAME "aColor" | 29 #define COL_ATTR_NAME "aColor" |
31 #define COV_ATTR_NAME "aCoverage" | 30 #define COV_ATTR_NAME "aCoverage" |
32 #define EDGE_ATTR_NAME "aEdge" | 31 #define EDGE_ATTR_NAME "aEdge" |
33 | 32 |
34 namespace { | 33 namespace { |
35 inline const char* declared_color_output_name() { return "fsColorOut"; } | 34 inline const char* declared_color_output_name() { return "fsColorOut"; } |
36 inline const char* dual_source_output_name() { return "dualSourceOut"; } | 35 inline const char* dual_source_output_name() { return "dualSourceOut"; } |
37 } | 36 } |
38 | 37 |
39 void GrGLProgramDesc::Build(const GrDrawState& drawState, | |
40 bool isPoints, | |
41 GrDrawState::BlendOptFlags blendOpts, | |
42 GrBlendCoeff srcCoeff, | |
43 GrBlendCoeff dstCoeff, | |
44 const GrGpuGL* gpu, | |
45 GrGLProgramDesc* desc) { | |
46 | |
47 // This should already have been caught | |
48 GrAssert(!(GrDrawState::kSkipDraw_BlendOptFlag & blendOpts)); | |
49 | |
50 bool skipCoverage = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendO
ptFlag); | |
51 | |
52 bool skipColor = SkToBool(blendOpts & (GrDrawState::kEmitTransBlack_BlendOpt
Flag | | |
53 GrDrawState::kEmitCoverage_BlendOptFl
ag)); | |
54 | |
55 // The descriptor is used as a cache key. Thus when a field of the | |
56 // descriptor will not affect program generation (because of the attribute | |
57 // bindings in use or other descriptor field settings) it should be set | |
58 // to a canonical value to avoid duplicate programs with different keys. | |
59 | |
60 // Must initialize all fields or cache will have false negatives! | |
61 desc->fAttribBindings = drawState.getAttribBindings(); | |
62 | |
63 desc->fEmitsPointSize = isPoints; | |
64 | |
65 bool requiresAttributeColors = | |
66 !skipColor && SkToBool(desc->fAttribBindings & GrDrawState::kColor_Attri
bBindingsBit); | |
67 bool requiresAttributeCoverage = | |
68 !skipCoverage && SkToBool(desc->fAttribBindings & GrDrawState::kCoverage
_AttribBindingsBit); | |
69 | |
70 // fColorInput/fCoverageInput records how colors are specified for the progr
am So we strip the | |
71 // bits from the bindings to avoid false negatives when searching for an exi
sting program in the | |
72 // cache. | |
73 desc->fAttribBindings &= | |
74 ~(GrDrawState::kColor_AttribBindingsBit | GrDrawState::kCoverage_AttribB
indingsBit); | |
75 | |
76 desc->fColorFilterXfermode = skipColor ? | |
77 SkXfermode::kDst_Mode : | |
78 drawState.getColorFilterMode(); | |
79 | |
80 // no reason to do edge aa or look at per-vertex coverage if coverage is ign
ored | |
81 if (skipCoverage) { | |
82 desc->fAttribBindings &= ~(GrDrawState::kCoverage_AttribBindingsBit); | |
83 } | |
84 | |
85 bool colorIsTransBlack = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_B
lendOptFlag); | |
86 bool colorIsSolidWhite = (blendOpts & GrDrawState::kEmitCoverage_BlendOptFla
g) || | |
87 (!requiresAttributeColors && 0xffffffff == drawStat
e.getColor()); | |
88 if (colorIsTransBlack) { | |
89 desc->fColorInput = kTransBlack_ColorInput; | |
90 } else if (colorIsSolidWhite) { | |
91 desc->fColorInput = kSolidWhite_ColorInput; | |
92 } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeColors) { | |
93 desc->fColorInput = kUniform_ColorInput; | |
94 } else { | |
95 desc->fColorInput = kAttribute_ColorInput; | |
96 } | |
97 | |
98 bool covIsSolidWhite = !requiresAttributeCoverage && 0xffffffff == drawState
.getCoverage(); | |
99 | |
100 if (skipCoverage) { | |
101 desc->fCoverageInput = kTransBlack_ColorInput; | |
102 } else if (covIsSolidWhite) { | |
103 desc->fCoverageInput = kSolidWhite_ColorInput; | |
104 } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeCoverage) { | |
105 desc->fCoverageInput = kUniform_ColorInput; | |
106 } else { | |
107 desc->fCoverageInput = kAttribute_ColorInput; | |
108 } | |
109 | |
110 int lastEnabledStage = -1; | |
111 | |
112 for (int s = 0; s < GrDrawState::kNumStages; ++s) { | |
113 | |
114 bool skip = s < drawState.getFirstCoverageStage() ? skipColor : skipCove
rage; | |
115 if (!skip && drawState.isStageEnabled(s)) { | |
116 lastEnabledStage = s; | |
117 const GrEffectRef& effect = *drawState.getStage(s).getEffect(); | |
118 const GrBackendEffectFactory& factory = effect->getFactory(); | |
119 bool explicitLocalCoords = (drawState.getAttribBindings() & | |
120 GrDrawState::kLocalCoords_AttribBindings
Bit); | |
121 GrDrawEffect drawEffect(drawState.getStage(s), explicitLocalCoords); | |
122 desc->fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps()
); | |
123 } else { | |
124 desc->fEffectKeys[s] = 0; | |
125 } | |
126 } | |
127 | |
128 desc->fDualSrcOutput = kNone_DualSrcOutput; | |
129 | |
130 // Currently the experimental GS will only work with triangle prims (and it
doesn't do anything | |
131 // other than pass through values from the VS to the FS anyway). | |
132 #if GR_GL_EXPERIMENTAL_GS | |
133 #if 0 | |
134 desc->fExperimentalGS = gpu->caps().geometryShaderSupport(); | |
135 #else | |
136 desc->fExperimentalGS = false; | |
137 #endif | |
138 #endif | |
139 | |
140 // We leave this set to kNumStages until we discover that the coverage/color
distinction is | |
141 // material to the generated program. We do this to avoid distinct keys that
generate equivalent | |
142 // programs. | |
143 desc->fFirstCoverageStage = GrDrawState::kNumStages; | |
144 // This tracks the actual first coverage stage. | |
145 int firstCoverageStage = GrDrawState::kNumStages; | |
146 desc->fDiscardIfZeroCoverage = false; // Enabled below if stenciling and the
re is coverage. | |
147 bool hasCoverage = false; | |
148 // If we're rendering coverage-as-color then its as though there are no cove
rage stages. | |
149 if (!drawState.isCoverageDrawing()) { | |
150 // We can have coverage either through a stage or coverage vertex attrib
utes. | |
151 if (drawState.getFirstCoverageStage() <= lastEnabledStage) { | |
152 firstCoverageStage = drawState.getFirstCoverageStage(); | |
153 hasCoverage = true; | |
154 } else { | |
155 hasCoverage = requiresAttributeCoverage; | |
156 } | |
157 } | |
158 | |
159 if (hasCoverage) { | |
160 // color filter is applied between color/coverage computation | |
161 if (SkXfermode::kDst_Mode != desc->fColorFilterXfermode) { | |
162 desc->fFirstCoverageStage = firstCoverageStage; | |
163 } | |
164 | |
165 // If we're stenciling then we want to discard samples that have zero co
verage | |
166 if (drawState.getStencil().doesWrite()) { | |
167 desc->fDiscardIfZeroCoverage = true; | |
168 desc->fFirstCoverageStage = firstCoverageStage; | |
169 } | |
170 | |
171 if (gpu->caps()->dualSourceBlendingSupport() && | |
172 !(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag | | |
173 GrDrawState::kCoverageAsAlpha_BlendOptFlag))) { | |
174 if (kZero_GrBlendCoeff == dstCoeff) { | |
175 // write the coverage value to second color | |
176 desc->fDualSrcOutput = kCoverage_DualSrcOutput; | |
177 desc->fFirstCoverageStage = firstCoverageStage; | |
178 } else if (kSA_GrBlendCoeff == dstCoeff) { | |
179 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
covered. | |
180 desc->fDualSrcOutput = kCoverageISA_DualSrcOutput; | |
181 desc->fFirstCoverageStage = firstCoverageStage; | |
182 } else if (kSC_GrBlendCoeff == dstCoeff) { | |
183 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
covered. | |
184 desc->fDualSrcOutput = kCoverageISC_DualSrcOutput; | |
185 desc->fFirstCoverageStage = firstCoverageStage; | |
186 } | |
187 } | |
188 } | |
189 | |
190 desc->fPositionAttributeIndex = drawState.getAttribIndex(GrDrawState::kPosit
ion_AttribIndex); | |
191 if (requiresAttributeColors) { | |
192 desc->fColorAttributeIndex = drawState.getAttribIndex(GrDrawState::kColo
r_AttribIndex); | |
193 } else { | |
194 desc->fColorAttributeIndex = GrDrawState::kColorOverrideAttribIndexValue
; | |
195 } | |
196 if (requiresAttributeCoverage) { | |
197 desc->fCoverageAttributeIndex = drawState.getAttribIndex(GrDrawState::kC
overage_AttribIndex); | |
198 } else { | |
199 desc->fCoverageAttributeIndex = GrDrawState::kCoverageOverrideAttribInde
xValue; | |
200 } | |
201 if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) { | |
202 desc->fLocalCoordsAttributeIndex = drawState.getAttribIndex(GrDrawState:
:kLocalCoords_AttribIndex); | |
203 } | |
204 | |
205 #if GR_DEBUG | |
206 // Verify valid vertex attribute state. These assertions should probably be
done somewhere | |
207 // higher up the callstack | |
208 const GrVertexAttrib* vertexAttribs = drawState.getVertexAttribs(); | |
209 GrAssert(desc->fPositionAttributeIndex < GrDrawState::kVertexAttribCnt); | |
210 GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fPositionAttributeIndex]
.fType).fCount == 2); | |
211 if (requiresAttributeColors) { | |
212 GrAssert(desc->fColorAttributeIndex < GrDrawState::kVertexAttribCnt); | |
213 GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fColorAttributeIndex
].fType).fCount == 4); | |
214 } | |
215 if (requiresAttributeCoverage) { | |
216 GrAssert(desc->fCoverageAttributeIndex < GrDrawState::kVertexAttribCnt); | |
217 GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fCoverageAttributeIn
dex].fType).fCount == 4); | |
218 } | |
219 if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) { | |
220 GrAssert(desc->fLocalCoordsAttributeIndex < GrDrawState::kVertexAttribCn
t); | |
221 GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fLocalCoordsAttribut
eIndex].fType).fCount == 2); | |
222 } | |
223 #endif | |
224 } | |
225 | |
226 GrGLProgram* GrGLProgram::Create(const GrGLContext& gl, | 38 GrGLProgram* GrGLProgram::Create(const GrGLContext& gl, |
227 const GrGLProgramDesc& desc, | 39 const GrGLProgramDesc& desc, |
228 const GrEffectStage* stages[]) { | 40 const GrEffectStage* stages[]) { |
229 GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gl, desc, stages)); | 41 GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gl, desc, stages)); |
230 if (!program->succeeded()) { | 42 if (!program->succeeded()) { |
231 delete program; | 43 delete program; |
232 program = NULL; | 44 program = NULL; |
233 } | 45 } |
234 return program; | 46 return program; |
235 } | 47 } |
(...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1104 SkScalarToFloat(m[SkMatrix::kMTransX]), | 916 SkScalarToFloat(m[SkMatrix::kMTransX]), |
1105 SkScalarToFloat(m[SkMatrix::kMTransY]), | 917 SkScalarToFloat(m[SkMatrix::kMTransY]), |
1106 SkScalarToFloat(m[SkMatrix::kMPersp2]) | 918 SkScalarToFloat(m[SkMatrix::kMPersp2]) |
1107 }; | 919 }; |
1108 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt); | 920 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt); |
1109 fMatrixState.fViewMatrix = drawState.getViewMatrix(); | 921 fMatrixState.fViewMatrix = drawState.getViewMatrix(); |
1110 fMatrixState.fRenderTargetSize = size; | 922 fMatrixState.fRenderTargetSize = size; |
1111 fMatrixState.fRenderTargetOrigin = rt->origin(); | 923 fMatrixState.fRenderTargetOrigin = rt->origin(); |
1112 } | 924 } |
1113 } | 925 } |
OLD | NEW |