OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 "GrGLProgramBuilder.h" | 8 #include "GrGLProgramBuilder.h" |
9 | 9 |
10 #include "gl/GrGLGeometryProcessor.h" | 10 #include "gl/GrGLGeometryProcessor.h" |
11 #include "gl/GrGLGpu.h" | 11 #include "gl/GrGLGpu.h" |
12 #include "gl/GrGLPathProcessor.h" | 12 #include "gl/GrGLPathProcessor.h" |
13 #include "gl/GrGLProgram.h" | 13 #include "gl/GrGLProgram.h" |
14 #include "gl/GrGLSLPrettyPrint.h" | 14 #include "gl/GrGLSLPrettyPrint.h" |
15 #include "gl/GrGLUniformHandle.h" | 15 #include "gl/GrGLUniformHandle.h" |
16 #include "gl/GrGLXferProcessor.h" | 16 #include "gl/GrGLXferProcessor.h" |
17 #include "GrAutoLocaleSetter.h" | 17 #include "GrAutoLocaleSetter.h" |
18 #include "GrCoordTransform.h" | 18 #include "GrCoordTransform.h" |
19 #include "GrGLPathProgramBuilder.h" | |
19 #include "GrGLProgramBuilder.h" | 20 #include "GrGLProgramBuilder.h" |
20 #include "GrTexture.h" | 21 #include "GrTexture.h" |
21 #include "SkRTConf.h" | 22 #include "SkRTConf.h" |
22 #include "SkTraceEvent.h" | 23 #include "SkTraceEvent.h" |
23 | 24 |
24 #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X) | 25 #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X) |
25 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X) | 26 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X) |
26 | 27 |
27 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
28 | |
29 class GrGLNvprProgramBuilder : public GrGLProgramBuilder { | |
30 public: | |
31 GrGLNvprProgramBuilder(GrGLGpu* gpu, const DrawArgs& args) | |
32 : INHERITED(gpu, args) {} | |
33 | |
34 GrGLProgram* createProgram(GrGLuint programID) override { | |
35 // this is just for nvpr es, which has separable varyings that are plugg ed in after | |
36 // building | |
37 GrGLPathProcessor* pathProc = | |
38 static_cast<GrGLPathProcessor*>(fGeometryProcessor->fGLProc.get( )); | |
39 pathProc->resolveSeparableVaryings(fGpu, programID); | |
40 return SkNEW_ARGS(GrGLNvprProgram, (fGpu, this->desc(), fUniformHandles, programID, | |
41 fUniforms, | |
42 fGeometryProcessor, | |
43 fXferProcessor, fFragmentProcessors. get())); | |
44 } | |
45 | |
46 private: | |
47 typedef GrGLProgramBuilder INHERITED; | |
48 }; | |
49 | |
50 | |
51 | |
52 ////////////////////////////////////////////////////////////////////////////// | |
53 | |
54 const int GrGLProgramBuilder::kVarsPerBlock = 8; | 28 const int GrGLProgramBuilder::kVarsPerBlock = 8; |
55 | 29 |
56 GrGLProgram* GrGLProgramBuilder::CreateProgram(const DrawArgs& args, GrGLGpu* gp u) { | 30 GrGLProgram* GrGLProgramBuilder::CreateProgram(const DrawArgs& args, GrGLGpu* gp u) { |
57 GrAutoLocaleSetter als("C"); | 31 GrAutoLocaleSetter als("C"); |
58 | 32 |
59 // create a builder. This will be handed off to effects so they can use it to add | 33 // create a builder. This will be handed off to effects so they can use it to add |
60 // uniforms, varyings, textures, etc | 34 // uniforms, varyings, textures, etc |
61 SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(args, gpu)); | 35 SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(args, gpu)); |
62 | 36 |
63 GrGLProgramBuilder* pb = builder.get(); | 37 GrGLProgramBuilder* pb = builder.get(); |
64 | 38 |
65 // TODO: Once all stages can handle taking a float or vec4 and correctly han dling them we can | 39 // TODO: Once all stages can handle taking a float or vec4 and correctly han dling them we can |
66 // seed correctly here | 40 // seed correctly here |
67 GrGLSLExpr4 inputColor; | 41 GrGLSLExpr4 inputColor; |
68 GrGLSLExpr4 inputCoverage; | 42 GrGLSLExpr4 inputCoverage; |
69 | 43 |
70 if (!pb->emitAndInstallProcs(&inputColor, &inputCoverage)) { | 44 if (!pb->emitAndInstallProcs(&inputColor, &inputCoverage)) { |
71 return NULL; | 45 return NULL; |
72 } | 46 } |
73 | 47 |
74 return pb->finalize(); | 48 return pb->finalize(); |
75 } | 49 } |
76 | 50 |
77 GrGLProgramBuilder* GrGLProgramBuilder::CreateProgramBuilder(const DrawArgs& arg s, | 51 GrGLProgramBuilder* GrGLProgramBuilder::CreateProgramBuilder(const DrawArgs& arg s, |
78 GrGLGpu* gpu) { | 52 GrGLGpu* gpu) { |
79 if (args.fPrimitiveProcessor->isPathRendering()) { | 53 if (args.fPrimitiveProcessor->isPathRendering()) { |
80 SkASSERT(gpu->glCaps().shaderCaps()->pathRenderingSupport() && | 54 SkASSERT(gpu->glCaps().shaderCaps()->pathRenderingSupport() && |
81 !args.fPrimitiveProcessor->willUseGeoShader() && | 55 !args.fPrimitiveProcessor->willUseGeoShader() && |
82 args.fPrimitiveProcessor->numAttribs() == 0); | 56 args.fPrimitiveProcessor->numAttribs() == 0); |
83 return SkNEW_ARGS(GrGLNvprProgramBuilder, (gpu, args)); | 57 return SkNEW_ARGS(GrGLPathProgramBuilder, (gpu, args)); |
84 } else { | 58 } else { |
85 return SkNEW_ARGS(GrGLProgramBuilder, (gpu, args)); | 59 return SkNEW_ARGS(GrGLProgramBuilder, (gpu, args)); |
86 } | 60 } |
87 } | 61 } |
88 | 62 |
89 ///////////////////////////////////////////////////////////////////////////// | 63 ///////////////////////////////////////////////////////////////////////////// |
90 | 64 |
91 GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu, const DrawArgs& args) | 65 GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu, const DrawArgs& args) |
92 : fVS(this) | 66 : fVS(this) |
93 , fGS(this) | 67 , fGS(this) |
94 , fFS(this, args.fDesc->header().fFragPosKey) | 68 , fFS(this, args.fDesc->header().fFragPosKey) |
95 , fOutOfStage(true) | 69 , fOutOfStage(true) |
96 , fStageIndex(-1) | 70 , fStageIndex(-1) |
97 , fGeometryProcessor(NULL) | 71 , fGeometryProcessor(NULL) |
98 , fXferProcessor(NULL) | 72 , fXferProcessor(NULL) |
99 , fArgs(args) | 73 , fArgs(args) |
100 , fGpu(gpu) | 74 , fGpu(gpu) |
101 , fUniforms(kVarsPerBlock) { | 75 , fUniforms(kVarsPerBlock) { |
76 | |
joshualitt
2015/06/23 14:07:24
extra newline
Kimmo Kinnunen
2015/06/25 12:38:11
Done.
| |
102 } | 77 } |
103 | 78 |
104 void GrGLProgramBuilder::addVarying(const char* name, | 79 void GrGLProgramBuilder::addVarying(const char* name, |
105 GrGLVarying* varying, | 80 GrGLVarying* varying, |
106 GrSLPrecision fsPrecision) { | 81 GrSLPrecision fsPrecision) { |
107 SkASSERT(varying); | 82 SkASSERT(varying); |
108 if (varying->vsVarying()) { | 83 if (varying->vsVarying()) { |
109 fVS.addVarying(name, varying); | 84 fVS.addVarying(name, varying); |
110 } | 85 } |
111 if (this->primitiveProcessor().willUseGeoShader()) { | 86 if (this->primitiveProcessor().willUseGeoShader()) { |
112 fGS.addVarying(name, varying); | 87 fGS.addVarying(name, varying); |
113 } | 88 } |
114 if (varying->fsVarying()) { | 89 if (varying->fsVarying()) { |
115 fFS.addVarying(varying, fsPrecision); | 90 fFS.addVarying(varying, fsPrecision); |
116 } | 91 } |
117 } | 92 } |
118 | 93 |
119 void GrGLProgramBuilder::addPassThroughAttribute(const GrPrimitiveProcessor::Att ribute* input, | 94 void GrGLProgramBuilder::addPassThroughAttribute(const GrPrimitiveProcessor::Att ribute* input, |
120 const char* output) { | 95 const char* output) { |
121 GrSLType type = GrVertexAttribTypeToSLType(input->fType); | 96 GrSLType type = GrVertexAttribTypeToSLType(input->fType); |
122 GrGLVertToFrag v(type); | 97 GrGLVertToFrag v(type); |
123 this->addVarying(input->fName, &v); | 98 this->addVarying(input->fName, &v); |
124 fVS.codeAppendf("%s = %s;", v.vsOut(), input->fName); | 99 fVS.codeAppendf("%s = %s;", v.vsOut(), input->fName); |
125 fFS.codeAppendf("%s = %s;", output, v.fsIn()); | 100 fFS.codeAppendf("%s = %s;", output, v.fsIn()); |
126 } | 101 } |
127 | 102 |
103 GrGLProgramBuilder::SeparableVaryingHandle GrGLProgramBuilder::addSeparableVaryi ng(const char*, | |
104 GrGLVertToFrag*, | |
105 GrSLPrecision) { | |
106 // This call is not used for non-NVPR backends. However, the polymorphism be tween | |
107 // GrPrimitiveProcessor, GrGLPrimitiveProcessor and GrGLProgramBuilder does not allow for | |
108 // a system where GrGLPathProcessor would be able to refer to a primitive-sp ecific builder | |
109 // that would understand separable varyings. Thus separable varyings need to be present | |
110 // early in the inheritance chain of builders. | |
111 SkASSERT(false); | |
112 return SeparableVaryingHandle(); | |
113 } | |
114 | |
128 void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* na me) { | 115 void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* na me) { |
129 if ('\0' == prefix) { | 116 if ('\0' == prefix) { |
130 *out = name; | 117 *out = name; |
131 } else { | 118 } else { |
132 out->printf("%c%s", prefix, name); | 119 out->printf("%c%s", prefix, name); |
133 } | 120 } |
134 if (!fOutOfStage) { | 121 if (!fOutOfStage) { |
135 if (out->endsWith('_')) { | 122 if (out->endsWith('_')) { |
136 // Names containing "__" are reserved. | 123 // Names containing "__" are reserved. |
137 out->append("x"); | 124 out->append("x"); |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
414 bool useNvpr = primitiveProcessor().isPathRendering(); | 401 bool useNvpr = primitiveProcessor().isPathRendering(); |
415 if (!useNvpr) { | 402 if (!useNvpr) { |
416 fVS.bindVertexAttributes(programID); | 403 fVS.bindVertexAttributes(programID); |
417 } | 404 } |
418 | 405 |
419 if (!fFS.compileAndAttachShaders(programID, &shadersToDelete)) { | 406 if (!fFS.compileAndAttachShaders(programID, &shadersToDelete)) { |
420 this->cleanupProgram(programID, shadersToDelete); | 407 this->cleanupProgram(programID, shadersToDelete); |
421 return NULL; | 408 return NULL; |
422 } | 409 } |
423 | 410 |
424 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL; | 411 this->bindProgramResourceLocations(programID); |
425 if (usingBindUniform) { | 412 |
426 this->bindUniformLocations(programID); | |
427 } | |
428 fFS.bindFragmentShaderLocations(programID); | |
429 GL_CALL(LinkProgram(programID)); | 413 GL_CALL(LinkProgram(programID)); |
430 | 414 |
431 // Calling GetProgramiv is expensive in Chromium. Assume success in release builds. | 415 // Calling GetProgramiv is expensive in Chromium. Assume success in release builds. |
432 bool checkLinked = kChromium_GrGLDriver != fGpu->ctxInfo().driver(); | 416 bool checkLinked = kChromium_GrGLDriver != fGpu->ctxInfo().driver(); |
433 #ifdef SK_DEBUG | 417 #ifdef SK_DEBUG |
434 checkLinked = true; | 418 checkLinked = true; |
435 #endif | 419 #endif |
436 if (checkLinked) { | 420 if (checkLinked) { |
437 checkLinkStatus(programID); | 421 checkLinkStatus(programID); |
438 } | 422 } |
439 if (!usingBindUniform) { | 423 this->resolveProgramResourceLocations(programID); |
440 this->resolveUniformLocations(programID); | |
441 } | |
442 | 424 |
443 this->cleanupShaders(shadersToDelete); | 425 this->cleanupShaders(shadersToDelete); |
444 | 426 |
445 return this->createProgram(programID); | 427 return this->createProgram(programID); |
446 } | 428 } |
447 | 429 |
448 void GrGLProgramBuilder::bindUniformLocations(GrGLuint programID) { | 430 void GrGLProgramBuilder::bindProgramResourceLocations(GrGLuint programID) { |
449 int count = fUniforms.count(); | 431 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL; |
450 for (int i = 0; i < count; ++i) { | 432 if (usingBindUniform) { |
451 GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_str() )); | 433 int count = fUniforms.count(); |
452 fUniforms[i].fLocation = i; | 434 for (int i = 0; i < count; ++i) { |
435 GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_s tr())); | |
436 fUniforms[i].fLocation = i; | |
437 } | |
453 } | 438 } |
439 | |
440 fFS.bindFragmentShaderLocations(programID); | |
454 } | 441 } |
455 | 442 |
456 bool GrGLProgramBuilder::checkLinkStatus(GrGLuint programID) { | 443 bool GrGLProgramBuilder::checkLinkStatus(GrGLuint programID) { |
457 GrGLint linked = GR_GL_INIT_ZERO; | 444 GrGLint linked = GR_GL_INIT_ZERO; |
458 GL_CALL(GetProgramiv(programID, GR_GL_LINK_STATUS, &linked)); | 445 GL_CALL(GetProgramiv(programID, GR_GL_LINK_STATUS, &linked)); |
459 if (!linked) { | 446 if (!linked) { |
460 GrGLint infoLen = GR_GL_INIT_ZERO; | 447 GrGLint infoLen = GR_GL_INIT_ZERO; |
461 GL_CALL(GetProgramiv(programID, GR_GL_INFO_LOG_LENGTH, &infoLen)); | 448 GL_CALL(GetProgramiv(programID, GR_GL_INFO_LOG_LENGTH, &infoLen)); |
462 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger | 449 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger |
463 if (infoLen > 0) { | 450 if (infoLen > 0) { |
464 // retrieve length even though we don't need it to workaround | 451 // retrieve length even though we don't need it to workaround |
465 // bug in chrome cmd buffer param validation. | 452 // bug in chrome cmd buffer param validation. |
466 GrGLsizei length = GR_GL_INIT_ZERO; | 453 GrGLsizei length = GR_GL_INIT_ZERO; |
467 GL_CALL(GetProgramInfoLog(programID, | 454 GL_CALL(GetProgramInfoLog(programID, |
468 infoLen+1, | 455 infoLen+1, |
469 &length, | 456 &length, |
470 (char*)log.get())); | 457 (char*)log.get())); |
471 SkDebugf("%s", (char*)log.get()); | 458 SkDebugf("%s", (char*)log.get()); |
472 } | 459 } |
473 SkDEBUGFAIL("Error linking program"); | 460 SkDEBUGFAIL("Error linking program"); |
474 GL_CALL(DeleteProgram(programID)); | 461 GL_CALL(DeleteProgram(programID)); |
475 programID = 0; | 462 programID = 0; |
476 } | 463 } |
477 return SkToBool(linked); | 464 return SkToBool(linked); |
478 } | 465 } |
479 | 466 |
480 void GrGLProgramBuilder::resolveUniformLocations(GrGLuint programID) { | 467 void GrGLProgramBuilder::resolveProgramResourceLocations(GrGLuint programID) { |
481 int count = fUniforms.count(); | 468 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL; |
482 for (int i = 0; i < count; ++i) { | 469 if (!usingBindUniform) { |
483 GrGLint location; | 470 int count = fUniforms.count(); |
484 GL_CALL_RET(location, GetUniformLocation(programID, fUniforms[i].fVariab le.c_str())); | 471 for (int i = 0; i < count; ++i) { |
485 fUniforms[i].fLocation = location; | 472 GrGLint location; |
473 GL_CALL_RET(location, GetUniformLocation(programID, fUniforms[i].fVa riable.c_str())); | |
474 fUniforms[i].fLocation = location; | |
475 } | |
486 } | 476 } |
487 } | 477 } |
488 | 478 |
489 void GrGLProgramBuilder::cleanupProgram(GrGLuint programID, const SkTDArray<GrGL uint>& shaderIDs) { | 479 void GrGLProgramBuilder::cleanupProgram(GrGLuint programID, const SkTDArray<GrGL uint>& shaderIDs) { |
490 GL_CALL(DeleteProgram(programID)); | 480 GL_CALL(DeleteProgram(programID)); |
491 cleanupShaders(shaderIDs); | 481 cleanupShaders(shaderIDs); |
492 } | 482 } |
493 void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) { | 483 void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) { |
494 for (int i = 0; i < shaderIDs.count(); ++i) { | 484 for (int i = 0; i < shaderIDs.count(); ++i) { |
495 GL_CALL(DeleteShader(shaderIDs[i])); | 485 GL_CALL(DeleteShader(shaderIDs[i])); |
496 } | 486 } |
497 } | 487 } |
498 | 488 |
499 GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) { | 489 GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) { |
500 return SkNEW_ARGS(GrGLProgram, (fGpu, this->desc(), fUniformHandles, program ID, fUniforms, | 490 return SkNEW_ARGS(GrGLProgram, (fGpu, this->desc(), fUniformHandles, program ID, fUniforms, |
501 fGeometryProcessor, fXferProcessor, fFragmen tProcessors.get())); | 491 fGeometryProcessor, fXferProcessor, fFragmen tProcessors.get())); |
502 } | 492 } |
503 | 493 |
504 //////////////////////////////////////////////////////////////////////////////// /////////////////// | 494 //////////////////////////////////////////////////////////////////////////////// /////////////////// |
505 | 495 |
506 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { | 496 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { |
507 int numProcs = fProcs.count(); | 497 int numProcs = fProcs.count(); |
508 for (int e = 0; e < numProcs; ++e) { | 498 for (int e = 0; e < numProcs; ++e) { |
509 SkDELETE(fProcs[e]); | 499 SkDELETE(fProcs[e]); |
510 } | 500 } |
511 } | 501 } |
OLD | NEW |