Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/gpu/gl/builders/GrGLProgramBuilder.cpp

Issue 1186113007: Refactor separable varying location info to be stored in GrGLProgram subclass (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698