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