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 "GrGLSL.h" | 16 #include "GrGLSL.h" |
17 #include "SkTrace.h" | |
18 #include "SkXfermode.h" | 17 #include "SkXfermode.h" |
19 | 18 |
20 #include "SkRTConf.h" | |
21 | |
22 SK_DEFINE_INST_COUNT(GrGLProgram) | 19 SK_DEFINE_INST_COUNT(GrGLProgram) |
23 | 20 |
24 #define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X) | 21 #define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X) |
25 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X) | 22 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X) |
26 | 23 |
27 SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false, | |
28 "Print the source code for all shaders generated."); | |
29 | |
30 #define COL_ATTR_NAME "aColor" | |
31 #define COV_ATTR_NAME "aCoverage" | |
32 #define EDGE_ATTR_NAME "aEdge" | |
33 | |
34 namespace { | |
35 inline const char* declared_color_output_name() { return "fsColorOut"; } | |
36 inline const char* dual_source_output_name() { return "dualSourceOut"; } | |
37 } | |
38 | |
39 GrGLProgram* GrGLProgram::Create(GrGpuGL* gpu, | 24 GrGLProgram* GrGLProgram::Create(GrGpuGL* gpu, |
40 const GrGLProgramDesc& desc, | 25 const GrGLProgramDesc& desc, |
41 const GrEffectStage* colorStages[], | 26 const GrEffectStage* colorStages[], |
42 const GrEffectStage* coverageStages[]) { | 27 const GrEffectStage* coverageStages[]) { |
43 GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gpu, desc, colorStages, cove
rageStages)); | 28 GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gpu, desc, colorStages, cove
rageStages)); |
44 if (!program->succeeded()) { | 29 if (!program->succeeded()) { |
45 delete program; | 30 delete program; |
46 program = NULL; | 31 program = NULL; |
47 } | 32 } |
48 return program; | 33 return program; |
49 } | 34 } |
50 | 35 |
51 GrGLProgram::GrGLProgram(GrGpuGL* gpu, | 36 GrGLProgram::GrGLProgram(GrGpuGL* gpu, |
52 const GrGLProgramDesc& desc, | 37 const GrGLProgramDesc& desc, |
53 const GrEffectStage* colorStages[], | 38 const GrEffectStage* colorStages[], |
54 const GrEffectStage* coverageStages[]) | 39 const GrEffectStage* coverageStages[]) |
55 : fGpu(gpu) | 40 : fGpu(gpu) |
56 , fUniformManager(gpu) { | 41 , fUniformManager(gpu) { |
57 fDesc = desc; | 42 fDesc = desc; |
58 fVShaderID = 0; | |
59 fGShaderID = 0; | |
60 fFShaderID = 0; | |
61 fProgramID = 0; | 43 fProgramID = 0; |
62 | 44 |
63 fDstCopyTexUnit = -1; | 45 fDstCopyTexUnit = -1; |
64 | 46 |
65 fColor = GrColor_ILLEGAL; | 47 fColor = GrColor_ILLEGAL; |
66 fColorFilterColor = GrColor_ILLEGAL; | 48 fColorFilterColor = GrColor_ILLEGAL; |
67 | 49 |
68 fColorEffects.reset(desc.numColorEffects()); | 50 fColorEffects.reset(desc.numColorEffects()); |
69 fCoverageEffects.reset(desc.numCoverageEffects()); | 51 fCoverageEffects.reset(desc.numCoverageEffects()); |
70 | 52 |
71 this->genProgram(colorStages, coverageStages); | 53 this->genProgram(colorStages, coverageStages); |
72 } | 54 } |
73 | 55 |
74 GrGLProgram::~GrGLProgram() { | 56 GrGLProgram::~GrGLProgram() { |
75 if (fVShaderID) { | |
76 GL_CALL(DeleteShader(fVShaderID)); | |
77 } | |
78 if (fGShaderID) { | |
79 GL_CALL(DeleteShader(fGShaderID)); | |
80 } | |
81 if (fFShaderID) { | |
82 GL_CALL(DeleteShader(fFShaderID)); | |
83 } | |
84 if (fProgramID) { | 57 if (fProgramID) { |
85 GL_CALL(DeleteProgram(fProgramID)); | 58 GL_CALL(DeleteProgram(fProgramID)); |
86 } | 59 } |
87 } | 60 } |
88 | 61 |
89 void GrGLProgram::abandon() { | 62 void GrGLProgram::abandon() { |
90 fVShaderID = 0; | |
91 fGShaderID = 0; | |
92 fFShaderID = 0; | |
93 fProgramID = 0; | 63 fProgramID = 0; |
94 } | 64 } |
95 | 65 |
96 void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff, | 66 void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff, |
97 GrBlendCoeff* dstCoeff) const { | 67 GrBlendCoeff* dstCoeff) const { |
98 switch (fDesc.getHeader().fCoverageOutput) { | 68 switch (fDesc.getHeader().fCoverageOutput) { |
99 case GrGLProgramDesc::kModulate_CoverageOutput: | 69 case GrGLProgramDesc::kModulate_CoverageOutput: |
100 break; | 70 break; |
101 // The prog will write a coverage value to the secondary | 71 // The prog will write a coverage value to the secondary |
102 // output and the dst is blended by one minus that value. | 72 // output and the dst is blended by one minus that value. |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 SkString colorStr, constStr; | 182 SkString colorStr, constStr; |
213 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); | 183 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); |
214 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor
); | 184 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor
); |
215 | 185 |
216 SkString sum; | 186 SkString sum; |
217 GrGLSLAddf<4>(&sum, colorStr.c_str(), constStr.c_str()); | 187 GrGLSLAddf<4>(&sum, colorStr.c_str(), constStr.c_str()); |
218 builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str()); | 188 builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str()); |
219 } | 189 } |
220 } | 190 } |
221 | 191 |
222 GrSLConstantVec GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString*
inColor) { | |
223 switch (fDesc.getHeader().fColorInput) { | |
224 case GrGLProgramDesc::kAttribute_ColorInput: { | |
225 GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertex
Builder(); | |
226 SkASSERT(NULL != vertexBuilder); | |
227 vertexBuilder->addAttribute(kVec4f_GrSLType, COL_ATTR_NAME); | |
228 const char *vsName, *fsName; | |
229 vertexBuilder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName
); | |
230 vertexBuilder->vsCodeAppendf("\t%s = " COL_ATTR_NAME ";\n", vsName); | |
231 *inColor = fsName; | |
232 return kNone_GrSLConstantVec; | |
233 } | |
234 case GrGLProgramDesc::kUniform_ColorInput: { | |
235 const char* name; | |
236 fUniformHandles.fColorUni = builder->addUniform(GrGLShaderBuilder::k
Fragment_Visibility, | |
237 kVec4f_GrSLType, "Co
lor", &name); | |
238 *inColor = name; | |
239 return kNone_GrSLConstantVec; | |
240 } | |
241 case GrGLProgramDesc::kTransBlack_ColorInput: | |
242 inColor->reset(); | |
243 return kZeros_GrSLConstantVec; | |
244 case GrGLProgramDesc::kSolidWhite_ColorInput: | |
245 inColor->reset(); | |
246 return kOnes_GrSLConstantVec; | |
247 default: | |
248 GrCrash("Unknown color type."); | |
249 return kNone_GrSLConstantVec; | |
250 } | |
251 } | |
252 | |
253 GrSLConstantVec GrGLProgram::genInputCoverage(GrGLShaderBuilder* builder, SkStri
ng* inCoverage) { | |
254 switch (fDesc.getHeader().fCoverageInput) { | |
255 case GrGLProgramDesc::kAttribute_ColorInput: { | |
256 GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertex
Builder(); | |
257 SkASSERT(NULL != vertexBuilder); | |
258 vertexBuilder->addAttribute(kVec4f_GrSLType, COV_ATTR_NAME); | |
259 const char *vsName, *fsName; | |
260 vertexBuilder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsN
ame); | |
261 vertexBuilder->vsCodeAppendf("\t%s = " COV_ATTR_NAME ";\n", vsName); | |
262 *inCoverage = fsName; | |
263 return kNone_GrSLConstantVec; | |
264 } | |
265 case GrGLProgramDesc::kUniform_ColorInput: { | |
266 const char* name; | |
267 fUniformHandles.fCoverageUni = | |
268 builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, | |
269 kVec4f_GrSLType, "Coverage", &name); | |
270 *inCoverage = name; | |
271 return kNone_GrSLConstantVec; | |
272 } | |
273 case GrGLProgramDesc::kTransBlack_ColorInput: | |
274 inCoverage->reset(); | |
275 return kZeros_GrSLConstantVec; | |
276 case GrGLProgramDesc::kSolidWhite_ColorInput: | |
277 inCoverage->reset(); | |
278 return kOnes_GrSLConstantVec; | |
279 default: | |
280 GrCrash("Unknown color type."); | |
281 return kNone_GrSLConstantVec; | |
282 } | |
283 } | |
284 | |
285 void GrGLProgram::genGeometryShader(GrGLShaderBuilder::VertexBuilder* vertexBuil
der) const { | |
286 #if GR_GL_EXPERIMENTAL_GS | |
287 // TODO: The builder should add all this glue code. | |
288 if (fDesc.getHeader().fExperimentalGS) { | |
289 SkASSERT(fGpu->glslGeneration() >= k150_GrGLSLGeneration); | |
290 vertexBuilder->fGSHeader.append("layout(triangles) in;\n" | |
291 "layout(triangle_strip, max_vertices = 6
) out;\n"); | |
292 vertexBuilder->gsCodeAppend("\tfor (int i = 0; i < 3; ++i) {\n" | |
293 "\t\tgl_Position = gl_in[i].gl_Position;\n")
; | |
294 if (fDesc.getHeader().fEmitsPointSize) { | |
295 vertexBuilder->gsCodeAppend("\t\tgl_PointSize = 1.0;\n"); | |
296 } | |
297 SkASSERT(vertexBuilder->fGSInputs.count() == vertexBuilder->fGSOutputs.c
ount()); | |
298 int count = vertexBuilder->fGSInputs.count(); | |
299 for (int i = 0; i < count; ++i) { | |
300 vertexBuilder->gsCodeAppendf("\t\t%s = %s[i];\n", | |
301 vertexBuilder->fGSOutputs[i].getName().
c_str(), | |
302 vertexBuilder->fGSInputs[i].getName().c
_str()); | |
303 } | |
304 vertexBuilder->gsCodeAppend("\t\tEmitVertex();\n" | |
305 "\t}\n" | |
306 "\tEndPrimitive();\n"); | |
307 } | |
308 #endif | |
309 } | |
310 | |
311 const char* GrGLProgram::adjustInColor(const SkString& inColor) const { | |
312 if (inColor.size()) { | |
313 return inColor.c_str(); | |
314 } else { | |
315 if (GrGLProgramDesc::kSolidWhite_ColorInput == fDesc.getHeader().fColorI
nput) { | |
316 return GrGLSLOnesVecf(4); | |
317 } else { | |
318 return GrGLSLZerosVecf(4); | |
319 } | |
320 } | |
321 } | |
322 | |
323 namespace { | 192 namespace { |
324 // prints a shader using params similar to glShaderSource | |
325 void print_shader(GrGLint stringCnt, | |
326 const GrGLchar** strings, | |
327 GrGLint* stringLengths) { | |
328 for (int i = 0; i < stringCnt; ++i) { | |
329 if (NULL == stringLengths || stringLengths[i] < 0) { | |
330 GrPrintf(strings[i]); | |
331 } else { | |
332 GrPrintf("%.*s", stringLengths[i], strings[i]); | |
333 } | |
334 } | |
335 } | |
336 | |
337 // Compiles a GL shader, returns shader ID or 0 if failed params have same meani
ng as glShaderSource | |
338 GrGLuint compile_shader(const GrGLInterface* gli, | |
339 GrGLenum type, | |
340 int stringCnt, | |
341 const char** strings, | |
342 int* stringLengths) { | |
343 SK_TRACE_EVENT1("GrGLProgram::CompileShader", | |
344 "stringCount", SkStringPrintf("%i", stringCnt).c_str()); | |
345 | |
346 GrGLuint shader; | |
347 GR_GL_CALL_RET(gli, shader, CreateShader(type)); | |
348 if (0 == shader) { | |
349 return 0; | |
350 } | |
351 | |
352 GrGLint compiled = GR_GL_INIT_ZERO; | |
353 GR_GL_CALL(gli, ShaderSource(shader, stringCnt, strings, stringLengths)); | |
354 GR_GL_CALL(gli, CompileShader(shader)); | |
355 GR_GL_CALL(gli, GetShaderiv(shader, GR_GL_COMPILE_STATUS, &compiled)); | |
356 | |
357 if (!compiled) { | |
358 GrGLint infoLen = GR_GL_INIT_ZERO; | |
359 GR_GL_CALL(gli, GetShaderiv(shader, GR_GL_INFO_LOG_LENGTH, &infoLen)); | |
360 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger | |
361 if (infoLen > 0) { | |
362 // retrieve length even though we don't need it to workaround bug in
chrome cmd buffer | |
363 // param validation. | |
364 GrGLsizei length = GR_GL_INIT_ZERO; | |
365 GR_GL_CALL(gli, GetShaderInfoLog(shader, infoLen+1, | |
366 &length, (char*)log.get())); | |
367 print_shader(stringCnt, strings, stringLengths); | |
368 GrPrintf("\n%s", log.get()); | |
369 } | |
370 SkDEBUGFAIL("Shader compilation failed!"); | |
371 GR_GL_CALL(gli, DeleteShader(shader)); | |
372 return 0; | |
373 } | |
374 return shader; | |
375 } | |
376 | |
377 // helper version of above for when shader is already flattened into a single Sk
String | |
378 GrGLuint compile_shader(const GrGLInterface* gli, GrGLenum type, const SkString&
shader) { | |
379 const GrGLchar* str = shader.c_str(); | |
380 int length = shader.size(); | |
381 return compile_shader(gli, type, 1, &str, &length); | |
382 } | |
383 | 193 |
384 void expand_known_value4f(SkString* string, GrSLConstantVec vec) { | 194 void expand_known_value4f(SkString* string, GrSLConstantVec vec) { |
385 SkASSERT(string->isEmpty() == (vec != kNone_GrSLConstantVec)); | 195 SkASSERT(string->isEmpty() == (vec != kNone_GrSLConstantVec)); |
386 switch (vec) { | 196 switch (vec) { |
387 case kNone_GrSLConstantVec: | 197 case kNone_GrSLConstantVec: |
388 break; | 198 break; |
389 case kZeros_GrSLConstantVec: | 199 case kZeros_GrSLConstantVec: |
390 *string = GrGLSLZerosVecf(4); | 200 *string = GrGLSLZerosVecf(4); |
391 break; | 201 break; |
392 case kOnes_GrSLConstantVec: | 202 case kOnes_GrSLConstantVec: |
393 *string = GrGLSLOnesVecf(4); | 203 *string = GrGLSLOnesVecf(4); |
394 break; | 204 break; |
395 } | 205 } |
396 } | 206 } |
397 | 207 |
398 } | 208 } |
399 | 209 |
400 // compiles all the shaders from builder and stores the shader IDs | |
401 bool GrGLProgram::compileShaders(const GrGLShaderBuilder& builder) { | |
402 | |
403 SkASSERT(!fVShaderID); | |
404 SkASSERT(!fGShaderID); | |
405 SkASSERT(!fFShaderID); | |
406 | |
407 SkString shader; | |
408 if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuild
er()) { | |
409 vertexBuilder->vsGetShader(&shader); | |
410 if (c_PrintShaders) { | |
411 GrPrintf(shader.c_str()); | |
412 GrPrintf("\n"); | |
413 } | |
414 if (!(fVShaderID = compile_shader(fGpu->glInterface(), GR_GL_VERTEX_SHAD
ER, shader))) { | |
415 return false; | |
416 } | |
417 | |
418 #if GR_GL_EXPERIMENTAL_GS | |
419 if (fDesc.getHeader().fExperimentalGS) { | |
420 vertexBuilder->gsGetShader(&shader); | |
421 if (c_PrintShaders) { | |
422 GrPrintf(shader.c_str()); | |
423 GrPrintf("\n"); | |
424 } | |
425 if (!(fGShaderID = compile_shader(fGpu->glInterface(), GR_GL_GEOMETR
Y_SHADER, shader))) { | |
426 return false; | |
427 } | |
428 } | |
429 #endif | |
430 } | |
431 | |
432 builder.fsGetShader(&shader); | |
433 if (c_PrintShaders) { | |
434 GrPrintf(shader.c_str()); | |
435 GrPrintf("\n"); | |
436 } | |
437 if (!(fFShaderID = compile_shader(fGpu->glInterface(), GR_GL_FRAGMENT_SHADER
, shader))) { | |
438 return false; | |
439 } | |
440 | |
441 return true; | |
442 } | |
443 | |
444 bool GrGLProgram::genProgram(const GrEffectStage* colorStages[], | 210 bool GrGLProgram::genProgram(const GrEffectStage* colorStages[], |
445 const GrEffectStage* coverageStages[]) { | 211 const GrEffectStage* coverageStages[]) { |
446 SkASSERT(0 == fProgramID); | 212 SkASSERT(0 == fProgramID); |
447 | 213 |
448 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); | 214 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); |
449 | 215 |
450 bool needsVertexShader = true; | 216 bool needsVertexShader = true; |
451 | 217 |
452 GrGLShaderBuilder builder(fGpu->ctxInfo(), fUniformManager, fDesc, needsVert
exShader); | 218 GrGLShaderBuilder builder(fGpu, fUniformManager, fDesc, needsVertexShader); |
453 | |
454 if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuild
er()) { | 219 if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuild
er()) { |
455 const char* viewMName; | 220 fUniformHandles.fViewMatrixUni = vertexBuilder->getViewMatrixUniform(); |
456 fUniformHandles.fViewMatrixUni = builder.addUniform(GrGLShaderBuilder::k
Vertex_Visibility, | |
457 kMat33f_GrSLType, "V
iewM", &viewMName); | |
458 | |
459 vertexBuilder->vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n" | |
460 "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\
n", | |
461 viewMName, vertexBuilder->positionAttribute
().c_str()); | |
462 | |
463 // we output point size in the GS if present | |
464 if (header.fEmitsPointSize | |
465 #if GR_GL_EXPERIMENTAL_GS | |
466 && !header.fExperimentalGS | |
467 #endif | |
468 ) { | |
469 vertexBuilder->vsCodeAppend("\tgl_PointSize = 1.0;\n"); | |
470 } | |
471 } | |
472 | |
473 // the dual source output has no canonical var name, have to | |
474 // declare an output, which is incompatible with gl_FragColor/gl_FragData. | |
475 bool dualSourceOutputWritten = false; | |
476 | |
477 GrGLShaderVar colorOutput; | |
478 bool isColorDeclared = GrGLSLSetupFSColorOuput(fGpu->glslGeneration(), | |
479 declared_color_output_name(), | |
480 &colorOutput); | |
481 if (isColorDeclared) { | |
482 builder.fsOutputAppend(colorOutput); | |
483 } | 221 } |
484 | 222 |
485 // incoming color to current stage being processed. | 223 // incoming color to current stage being processed. |
486 SkString inColor; | 224 SkString inColor = builder.getInputColor(); |
487 GrSLConstantVec knownColorValue = this->genInputColor(&builder, &inColor); | 225 GrSLConstantVec knownColorValue = builder.getKnownColorValue(); |
488 | 226 |
489 // Get the coeffs for the Mode-based color filter, determine if color is nee
ded. | 227 // Get the coeffs for the Mode-based color filter, determine if color is nee
ded. |
490 SkXfermode::Coeff colorCoeff; | 228 SkXfermode::Coeff colorCoeff; |
491 SkXfermode::Coeff filterColorCoeff; | 229 SkXfermode::Coeff filterColorCoeff; |
492 SkAssertResult( | 230 SkAssertResult( |
493 SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode>(header.fColorFilte
rXfermode), | 231 SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode>(header.fColorFilte
rXfermode), |
494 &filterColorCoeff, | 232 &filterColorCoeff, |
495 &colorCoeff)); | 233 &colorCoeff)); |
496 bool needColor, needFilterColor; | 234 bool needColor, needFilterColor; |
497 need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor
); | 235 need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor
); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 } else { | 275 } else { |
538 color = inColor.c_str(); | 276 color = inColor.c_str(); |
539 } | 277 } |
540 add_color_filter(&builder, "filteredColor", filterColorCoeff, | 278 add_color_filter(&builder, "filteredColor", filterColorCoeff, |
541 colorCoeff, colorFilterColorUniName, color); | 279 colorCoeff, colorFilterColorUniName, color); |
542 inColor = "filteredColor"; | 280 inColor = "filteredColor"; |
543 } | 281 } |
544 | 282 |
545 /////////////////////////////////////////////////////////////////////////// | 283 /////////////////////////////////////////////////////////////////////////// |
546 // compute the partial coverage | 284 // compute the partial coverage |
547 SkString inCoverage; | 285 SkString inCoverage = builder.getInputCoverage(); |
548 GrSLConstantVec knownCoverageValue = this->genInputCoverage(&builder, &inCov
erage); | 286 GrSLConstantVec knownCoverageValue = builder.getKnownCoverageValue(); |
549 | 287 |
550 for (int e = 0; e < fDesc.numCoverageEffects(); ++e) { | 288 for (int e = 0; e < fDesc.numCoverageEffects(); ++e) { |
551 effectUniformArrays[e] = &fCoverageEffects[e].fSamplerUnis; | 289 effectUniformArrays[e] = &fCoverageEffects[e].fSamplerUnis; |
552 } | 290 } |
553 | 291 |
554 builder.emitEffects(coverageStages, | 292 builder.emitEffects(coverageStages, |
555 fDesc.getEffectKeys() + fDesc.numColorEffects(), | 293 fDesc.getEffectKeys() + fDesc.numColorEffects(), |
556 fDesc.numCoverageEffects(), | 294 fDesc.numCoverageEffects(), |
557 &inCoverage, | 295 &inCoverage, |
558 &knownCoverageValue, | 296 &knownCoverageValue, |
(...skipping 10 matching lines...) Expand all Loading... |
569 builder.fsCodeAppend("\tdiscard;\n"); | 307 builder.fsCodeAppend("\tdiscard;\n"); |
570 } else { | 308 } else { |
571 builder.fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\
t\tdiscard;\n\t}\n", | 309 builder.fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\
t\tdiscard;\n\t}\n", |
572 inCoverage.c_str()); | 310 inCoverage.c_str()); |
573 } | 311 } |
574 } | 312 } |
575 | 313 |
576 GrGLProgramDesc::CoverageOutput coverageOutput = | 314 GrGLProgramDesc::CoverageOutput coverageOutput = |
577 static_cast<GrGLProgramDesc::CoverageOutput>(header.fCoverageOutput); | 315 static_cast<GrGLProgramDesc::CoverageOutput>(header.fCoverageOutput); |
578 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(coverageOutput)) { | 316 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(coverageOutput)) { |
579 builder.fsOutputAppend().set(kVec4f_GrSLType, | 317 const char* secondaryOutputName = builder.enableSecondaryOutput(); |
580 GrGLShaderVar::kOut_TypeModifier, | 318 |
581 dual_source_output_name()); | |
582 // default coeff to ones for kCoverage_DualSrcOutput | 319 // default coeff to ones for kCoverage_DualSrcOutput |
583 SkString coeff; | 320 SkString coeff; |
584 GrSLConstantVec knownCoeffValue = kOnes_GrSLConstantVec; | 321 GrSLConstantVec knownCoeffValue = kOnes_GrSLConstantVec; |
585 if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCov
erageOutput) { | 322 if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCov
erageOutput) { |
586 // Get (1-A) into coeff | 323 // Get (1-A) into coeff |
587 SkString inColorAlpha; | 324 SkString inColorAlpha; |
588 GrGLSLGetComponent4f(&inColorAlpha, | 325 GrGLSLGetComponent4f(&inColorAlpha, |
589 inColor.c_str(), | 326 inColor.c_str(), |
590 kA_GrColorComponentFlag, | 327 kA_GrColorComponentFlag, |
591 knownColorValue, | 328 knownColorValue, |
(...skipping 14 matching lines...) Expand all Loading... |
606 true); | 343 true); |
607 } | 344 } |
608 // Get coeff * coverage into modulate and then write that to the dual so
urce output. | 345 // Get coeff * coverage into modulate and then write that to the dual so
urce output. |
609 SkString modulate; | 346 SkString modulate; |
610 GrGLSLModulatef<4>(&modulate, | 347 GrGLSLModulatef<4>(&modulate, |
611 coeff.c_str(), | 348 coeff.c_str(), |
612 inCoverage.c_str(), | 349 inCoverage.c_str(), |
613 knownCoeffValue, | 350 knownCoeffValue, |
614 knownCoverageValue, | 351 knownCoverageValue, |
615 false); | 352 false); |
616 builder.fsCodeAppendf("\t%s = %s;\n", dual_source_output_name(), modulat
e.c_str()); | 353 builder.fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, modulate.c_st
r()); |
617 dualSourceOutputWritten = true; | |
618 } | 354 } |
619 | 355 |
620 /////////////////////////////////////////////////////////////////////////// | 356 /////////////////////////////////////////////////////////////////////////// |
621 // combine color and coverage as frag color | 357 // combine color and coverage as frag color |
622 | 358 |
623 // Get "color * coverage" into fragColor | 359 // Get "color * coverage" into fragColor |
624 SkString fragColor; | 360 SkString fragColor; |
625 GrSLConstantVec knownFragColorValue = GrGLSLModulatef<4>(&fragColor, | 361 GrSLConstantVec knownFragColorValue = GrGLSLModulatef<4>(&fragColor, |
626 inColor.c_str(), | 362 inColor.c_str(), |
627 inCoverage.c_str(), | 363 inCoverage.c_str(), |
(...skipping 20 matching lines...) Expand all Loading... |
648 fragColor.reset(); | 384 fragColor.reset(); |
649 GrGLSLAddf<4>(&fragColor, | 385 GrGLSLAddf<4>(&fragColor, |
650 oldFragColor.c_str(), | 386 oldFragColor.c_str(), |
651 dstContribution.c_str(), | 387 dstContribution.c_str(), |
652 knownFragColorValue, | 388 knownFragColorValue, |
653 knownDstContributionValue, | 389 knownDstContributionValue, |
654 false); | 390 false); |
655 } else { | 391 } else { |
656 expand_known_value4f(&fragColor, knownFragColorValue); | 392 expand_known_value4f(&fragColor, knownFragColorValue); |
657 } | 393 } |
658 builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), fragCol
or.c_str()); | 394 builder.fsCodeAppendf("\t%s = %s;\n", builder.getColorOutputName(), fragColo
r.c_str()); |
659 | 395 |
660 /////////////////////////////////////////////////////////////////////////// | 396 if (!builder.finish(&fProgramID)) { |
661 // insert GS | |
662 #ifdef SK_DEBUG | |
663 if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuild
er()) { | |
664 this->genGeometryShader(vertexBuilder); | |
665 } | |
666 #endif | |
667 | |
668 /////////////////////////////////////////////////////////////////////////// | |
669 // compile and setup attribs and unis | |
670 | |
671 if (!this->compileShaders(builder)) { | |
672 return false; | 397 return false; |
673 } | 398 } |
674 | 399 |
675 if (!this->bindOutputsAttribsAndLinkProgram(builder, | |
676 isColorDeclared, | |
677 dualSourceOutputWritten)) { | |
678 return false; | |
679 } | |
680 | |
681 builder.finished(fProgramID); | |
682 fUniformHandles.fRTHeightUni = builder.getRTHeightUniform(); | 400 fUniformHandles.fRTHeightUni = builder.getRTHeightUniform(); |
683 fUniformHandles.fDstCopyTopLeftUni = builder.getDstCopyTopLeftUniform(); | 401 fUniformHandles.fDstCopyTopLeftUni = builder.getDstCopyTopLeftUniform(); |
684 fUniformHandles.fDstCopyScaleUni = builder.getDstCopyScaleUniform(); | 402 fUniformHandles.fDstCopyScaleUni = builder.getDstCopyScaleUniform(); |
| 403 fUniformHandles.fColorUni = builder.getColorUniform(); |
| 404 fUniformHandles.fCoverageUni = builder.getCoverageUniform(); |
685 fUniformHandles.fDstCopySamplerUni = builder.getDstCopySamplerUniform(); | 405 fUniformHandles.fDstCopySamplerUni = builder.getDstCopySamplerUniform(); |
686 // This must be called after we set fDstCopySamplerUni above. | 406 // This must be called after we set fDstCopySamplerUni above. |
687 this->initSamplerUniforms(); | 407 this->initSamplerUniforms(); |
688 | 408 |
689 return true; | 409 return true; |
690 } | 410 } |
691 | 411 |
692 bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& buil
der, | |
693 bool bindColorOut, | |
694 bool bindDualSrcOut) { | |
695 GL_CALL_RET(fProgramID, CreateProgram()); | |
696 if (!fProgramID) { | |
697 return false; | |
698 } | |
699 | |
700 if (fVShaderID) { | |
701 GL_CALL(AttachShader(fProgramID, fVShaderID)); | |
702 } | |
703 if (fGShaderID) { | |
704 GL_CALL(AttachShader(fProgramID, fGShaderID)); | |
705 } | |
706 GL_CALL(AttachShader(fProgramID, fFShaderID)); | |
707 | |
708 if (bindColorOut) { | |
709 GL_CALL(BindFragDataLocation(fProgramID, 0, declared_color_output_name()
)); | |
710 } | |
711 if (bindDualSrcOut) { | |
712 GL_CALL(BindFragDataLocationIndexed(fProgramID, 0, 1, dual_source_output
_name())); | |
713 } | |
714 | |
715 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); | |
716 | |
717 // Bind the attrib locations to same values for all shaders | |
718 if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuild
er()) { | |
719 GL_CALL(BindAttribLocation(fProgramID, | |
720 header.fPositionAttributeIndex, | |
721 vertexBuilder->positionAttribute().c_str())); | |
722 if (-1 != header.fLocalCoordAttributeIndex) { | |
723 GL_CALL(BindAttribLocation(fProgramID, | |
724 header.fLocalCoordAttributeIndex, | |
725 vertexBuilder->localCoordsAttribute().c_s
tr())); | |
726 } | |
727 if (-1 != header.fColorAttributeIndex) { | |
728 GL_CALL(BindAttribLocation(fProgramID, header.fColorAttributeIndex,
COL_ATTR_NAME)); | |
729 } | |
730 if (-1 != header.fCoverageAttributeIndex) { | |
731 GL_CALL(BindAttribLocation(fProgramID, header.fCoverageAttributeInde
x, COV_ATTR_NAME)); | |
732 } | |
733 | |
734 const GrGLShaderBuilder::VertexBuilder::AttributePair* attribEnd = verte
xBuilder->getEffectAttributes().end(); | |
735 for (const GrGLShaderBuilder::VertexBuilder::AttributePair* attrib = ver
texBuilder->getEffectAttributes().begin(); | |
736 attrib != attribEnd; | |
737 ++attrib) { | |
738 GL_CALL(BindAttribLocation(fProgramID, attrib->fIndex, attrib->fNam
e.c_str())); | |
739 } | |
740 } | |
741 | |
742 GL_CALL(LinkProgram(fProgramID)); | |
743 | |
744 GrGLint linked = GR_GL_INIT_ZERO; | |
745 GL_CALL(GetProgramiv(fProgramID, GR_GL_LINK_STATUS, &linked)); | |
746 if (!linked) { | |
747 GrGLint infoLen = GR_GL_INIT_ZERO; | |
748 GL_CALL(GetProgramiv(fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen)); | |
749 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger | |
750 if (infoLen > 0) { | |
751 // retrieve length even though we don't need it to workaround | |
752 // bug in chrome cmd buffer param validation. | |
753 GrGLsizei length = GR_GL_INIT_ZERO; | |
754 GL_CALL(GetProgramInfoLog(fProgramID, | |
755 infoLen+1, | |
756 &length, | |
757 (char*)log.get())); | |
758 GrPrintf((char*)log.get()); | |
759 } | |
760 SkDEBUGFAIL("Error linking program"); | |
761 GL_CALL(DeleteProgram(fProgramID)); | |
762 fProgramID = 0; | |
763 return false; | |
764 } | |
765 return true; | |
766 } | |
767 | |
768 void GrGLProgram::initSamplerUniforms() { | 412 void GrGLProgram::initSamplerUniforms() { |
769 GL_CALL(UseProgram(fProgramID)); | 413 GL_CALL(UseProgram(fProgramID)); |
770 GrGLint texUnitIdx = 0; | 414 GrGLint texUnitIdx = 0; |
771 if (fUniformHandles.fDstCopySamplerUni.isValid()) { | 415 if (fUniformHandles.fDstCopySamplerUni.isValid()) { |
772 fUniformManager.setSampler(fUniformHandles.fDstCopySamplerUni, texUnitId
x); | 416 fUniformManager.setSampler(fUniformHandles.fDstCopySamplerUni, texUnitId
x); |
773 fDstCopyTexUnit = texUnitIdx++; | 417 fDstCopyTexUnit = texUnitIdx++; |
774 } | 418 } |
775 | 419 |
776 for (int e = 0; e < fColorEffects.count(); ++e) { | 420 for (int e = 0; e < fColorEffects.count(); ++e) { |
777 this->initEffectSamplerUniforms(&fColorEffects[e], &texUnitIdx); | 421 this->initEffectSamplerUniforms(&fColorEffects[e], &texUnitIdx); |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
983 | 627 |
984 fMatrixState.fViewMatrix = drawState.getViewMatrix(); | 628 fMatrixState.fViewMatrix = drawState.getViewMatrix(); |
985 fMatrixState.fRenderTargetSize = size; | 629 fMatrixState.fRenderTargetSize = size; |
986 fMatrixState.fRenderTargetOrigin = rt->origin(); | 630 fMatrixState.fRenderTargetOrigin = rt->origin(); |
987 | 631 |
988 GrGLfloat viewMatrix[3 * 3]; | 632 GrGLfloat viewMatrix[3 * 3]; |
989 fMatrixState.getGLMatrix<3>(viewMatrix); | 633 fMatrixState.getGLMatrix<3>(viewMatrix); |
990 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); | 634 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); |
991 } | 635 } |
992 } | 636 } |
OLD | NEW |