| 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" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(args, gpu)); | 36 SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(args, gpu)); |
| 37 | 37 |
| 38 GrGLProgramBuilder* pb = builder.get(); | 38 GrGLProgramBuilder* pb = builder.get(); |
| 39 | 39 |
| 40 // 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 |
| 41 // seed correctly here | 41 // seed correctly here |
| 42 GrGLSLExpr4 inputColor; | 42 GrGLSLExpr4 inputColor; |
| 43 GrGLSLExpr4 inputCoverage; | 43 GrGLSLExpr4 inputCoverage; |
| 44 | 44 |
| 45 if (!pb->emitAndInstallProcs(&inputColor, &inputCoverage)) { | 45 if (!pb->emitAndInstallProcs(&inputColor, &inputCoverage)) { |
| 46 return NULL; | 46 return nullptr; |
| 47 } | 47 } |
| 48 | 48 |
| 49 return pb->finalize(); | 49 return pb->finalize(); |
| 50 } | 50 } |
| 51 | 51 |
| 52 GrGLProgramBuilder* GrGLProgramBuilder::CreateProgramBuilder(const DrawArgs& arg
s, | 52 GrGLProgramBuilder* GrGLProgramBuilder::CreateProgramBuilder(const DrawArgs& arg
s, |
| 53 GrGLGpu* gpu) { | 53 GrGLGpu* gpu) { |
| 54 if (args.fPrimitiveProcessor->isPathRendering()) { | 54 if (args.fPrimitiveProcessor->isPathRendering()) { |
| 55 SkASSERT(gpu->glCaps().shaderCaps()->pathRenderingSupport() && | 55 SkASSERT(gpu->glCaps().shaderCaps()->pathRenderingSupport() && |
| 56 !args.fPrimitiveProcessor->willUseGeoShader() && | 56 !args.fPrimitiveProcessor->willUseGeoShader() && |
| 57 args.fPrimitiveProcessor->numAttribs() == 0); | 57 args.fPrimitiveProcessor->numAttribs() == 0); |
| 58 return new GrGLPathProgramBuilder(gpu, args); | 58 return new GrGLPathProgramBuilder(gpu, args); |
| 59 } else { | 59 } else { |
| 60 return new GrGLProgramBuilder(gpu, args); | 60 return new GrGLProgramBuilder(gpu, args); |
| 61 } | 61 } |
| 62 } | 62 } |
| 63 | 63 |
| 64 ///////////////////////////////////////////////////////////////////////////// | 64 ///////////////////////////////////////////////////////////////////////////// |
| 65 | 65 |
| 66 GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu, const DrawArgs& args) | 66 GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu, const DrawArgs& args) |
| 67 : fVS(this) | 67 : fVS(this) |
| 68 , fGS(this) | 68 , fGS(this) |
| 69 , fFS(this, args.fDesc->header().fFragPosKey) | 69 , fFS(this, args.fDesc->header().fFragPosKey) |
| 70 , fOutOfStage(true) | 70 , fOutOfStage(true) |
| 71 , fStageIndex(-1) | 71 , fStageIndex(-1) |
| 72 , fGeometryProcessor(NULL) | 72 , fGeometryProcessor(nullptr) |
| 73 , fXferProcessor(NULL) | 73 , fXferProcessor(nullptr) |
| 74 , fArgs(args) | 74 , fArgs(args) |
| 75 , fGpu(gpu) | 75 , fGpu(gpu) |
| 76 , fUniforms(kVarsPerBlock) | 76 , fUniforms(kVarsPerBlock) |
| 77 , fSamplerUniforms(4) { | 77 , fSamplerUniforms(4) { |
| 78 } | 78 } |
| 79 | 79 |
| 80 void GrGLProgramBuilder::addVarying(const char* name, | 80 void GrGLProgramBuilder::addVarying(const char* name, |
| 81 GrGLVarying* varying, | 81 GrGLVarying* varying, |
| 82 GrSLPrecision fsPrecision) { | 82 GrSLPrecision fsPrecision) { |
| 83 SkASSERT(varying); | 83 SkASSERT(varying); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 GrGLSLExpr4* output) { | 245 GrGLSLExpr4* output) { |
| 246 // Program builders have a bit of state we need to clear with each effect | 246 // Program builders have a bit of state we need to clear with each effect |
| 247 AutoStageAdvance adv(this); | 247 AutoStageAdvance adv(this); |
| 248 this->nameExpression(output, "output"); | 248 this->nameExpression(output, "output"); |
| 249 | 249 |
| 250 // Enclose custom code in a block to avoid namespace conflicts | 250 // Enclose custom code in a block to avoid namespace conflicts |
| 251 SkString openBrace; | 251 SkString openBrace; |
| 252 openBrace.printf("{ // Stage %d, %s\n", fStageIndex, fp.name()); | 252 openBrace.printf("{ // Stage %d, %s\n", fStageIndex, fp.name()); |
| 253 fFS.codeAppend(openBrace.c_str()); | 253 fFS.codeAppend(openBrace.c_str()); |
| 254 | 254 |
| 255 this->emitAndInstallProc(fp, index, output->c_str(), input.isOnes() ? NULL :
input.c_str()); | 255 this->emitAndInstallProc(fp, index, output->c_str(), input.isOnes() ? nullpt
r : input.c_str()); |
| 256 | 256 |
| 257 fFS.codeAppend("}"); | 257 fFS.codeAppend("}"); |
| 258 } | 258 } |
| 259 | 259 |
| 260 void GrGLProgramBuilder::emitAndInstallProc(const GrPrimitiveProcessor& proc, | 260 void GrGLProgramBuilder::emitAndInstallProc(const GrPrimitiveProcessor& proc, |
| 261 GrGLSLExpr4* outputColor, | 261 GrGLSLExpr4* outputColor, |
| 262 GrGLSLExpr4* outputCoverage) { | 262 GrGLSLExpr4* outputCoverage) { |
| 263 // Program builders have a bit of state we need to clear with each effect | 263 // Program builders have a bit of state we need to clear with each effect |
| 264 AutoStageAdvance adv(this); | 264 AutoStageAdvance adv(this); |
| 265 this->nameExpression(outputColor, "outputColor"); | 265 this->nameExpression(outputColor, "outputColor"); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLProcessor::TextureSampler, | 383 SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLProcessor::TextureSampler, |
| 384 (localSamplerUniforms[t], processor.textureAccess
(t))); | 384 (localSamplerUniforms[t], processor.textureAccess
(t))); |
| 385 } | 385 } |
| 386 } | 386 } |
| 387 | 387 |
| 388 GrGLProgram* GrGLProgramBuilder::finalize() { | 388 GrGLProgram* GrGLProgramBuilder::finalize() { |
| 389 // verify we can get a program id | 389 // verify we can get a program id |
| 390 GrGLuint programID; | 390 GrGLuint programID; |
| 391 GL_CALL_RET(programID, CreateProgram()); | 391 GL_CALL_RET(programID, CreateProgram()); |
| 392 if (0 == programID) { | 392 if (0 == programID) { |
| 393 return NULL; | 393 return nullptr; |
| 394 } | 394 } |
| 395 | 395 |
| 396 // compile shaders and bind attributes / uniforms | 396 // compile shaders and bind attributes / uniforms |
| 397 SkTDArray<GrGLuint> shadersToDelete; | 397 SkTDArray<GrGLuint> shadersToDelete; |
| 398 | 398 |
| 399 if (!fVS.compileAndAttachShaders(programID, &shadersToDelete)) { | 399 if (!fVS.compileAndAttachShaders(programID, &shadersToDelete)) { |
| 400 this->cleanupProgram(programID, shadersToDelete); | 400 this->cleanupProgram(programID, shadersToDelete); |
| 401 return NULL; | 401 return nullptr; |
| 402 } | 402 } |
| 403 | 403 |
| 404 // NVPR actually requires a vertex shader to compile | 404 // NVPR actually requires a vertex shader to compile |
| 405 bool useNvpr = primitiveProcessor().isPathRendering(); | 405 bool useNvpr = primitiveProcessor().isPathRendering(); |
| 406 if (!useNvpr) { | 406 if (!useNvpr) { |
| 407 fVS.bindVertexAttributes(programID); | 407 fVS.bindVertexAttributes(programID); |
| 408 } | 408 } |
| 409 | 409 |
| 410 if (!fFS.compileAndAttachShaders(programID, &shadersToDelete)) { | 410 if (!fFS.compileAndAttachShaders(programID, &shadersToDelete)) { |
| 411 this->cleanupProgram(programID, shadersToDelete); | 411 this->cleanupProgram(programID, shadersToDelete); |
| 412 return NULL; | 412 return nullptr; |
| 413 } | 413 } |
| 414 | 414 |
| 415 this->bindProgramResourceLocations(programID); | 415 this->bindProgramResourceLocations(programID); |
| 416 | 416 |
| 417 GL_CALL(LinkProgram(programID)); | 417 GL_CALL(LinkProgram(programID)); |
| 418 | 418 |
| 419 // Calling GetProgramiv is expensive in Chromium. Assume success in release
builds. | 419 // Calling GetProgramiv is expensive in Chromium. Assume success in release
builds. |
| 420 bool checkLinked = kChromium_GrGLDriver != fGpu->ctxInfo().driver(); | 420 bool checkLinked = kChromium_GrGLDriver != fGpu->ctxInfo().driver(); |
| 421 #ifdef SK_DEBUG | 421 #ifdef SK_DEBUG |
| 422 checkLinked = true; | 422 checkLinked = true; |
| 423 #endif | 423 #endif |
| 424 if (checkLinked) { | 424 if (checkLinked) { |
| 425 checkLinkStatus(programID); | 425 checkLinkStatus(programID); |
| 426 } | 426 } |
| 427 this->resolveProgramResourceLocations(programID); | 427 this->resolveProgramResourceLocations(programID); |
| 428 | 428 |
| 429 this->cleanupShaders(shadersToDelete); | 429 this->cleanupShaders(shadersToDelete); |
| 430 | 430 |
| 431 return this->createProgram(programID); | 431 return this->createProgram(programID); |
| 432 } | 432 } |
| 433 | 433 |
| 434 void GrGLProgramBuilder::bindProgramResourceLocations(GrGLuint programID) { | 434 void GrGLProgramBuilder::bindProgramResourceLocations(GrGLuint programID) { |
| 435 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation
!= NULL; | 435 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation
!= nullptr; |
| 436 if (usingBindUniform) { | 436 if (usingBindUniform) { |
| 437 int count = fUniforms.count(); | 437 int count = fUniforms.count(); |
| 438 for (int i = 0; i < count; ++i) { | 438 for (int i = 0; i < count; ++i) { |
| 439 GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_s
tr())); | 439 GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_s
tr())); |
| 440 fUniforms[i].fLocation = i; | 440 fUniforms[i].fLocation = i; |
| 441 } | 441 } |
| 442 } | 442 } |
| 443 | 443 |
| 444 fFS.bindFragmentShaderLocations(programID); | 444 fFS.bindFragmentShaderLocations(programID); |
| 445 } | 445 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 462 SkDebugf("%s", (char*)log.get()); | 462 SkDebugf("%s", (char*)log.get()); |
| 463 } | 463 } |
| 464 SkDEBUGFAIL("Error linking program"); | 464 SkDEBUGFAIL("Error linking program"); |
| 465 GL_CALL(DeleteProgram(programID)); | 465 GL_CALL(DeleteProgram(programID)); |
| 466 programID = 0; | 466 programID = 0; |
| 467 } | 467 } |
| 468 return SkToBool(linked); | 468 return SkToBool(linked); |
| 469 } | 469 } |
| 470 | 470 |
| 471 void GrGLProgramBuilder::resolveProgramResourceLocations(GrGLuint programID) { | 471 void GrGLProgramBuilder::resolveProgramResourceLocations(GrGLuint programID) { |
| 472 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation
!= NULL; | 472 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation
!= nullptr; |
| 473 if (!usingBindUniform) { | 473 if (!usingBindUniform) { |
| 474 int count = fUniforms.count(); | 474 int count = fUniforms.count(); |
| 475 for (int i = 0; i < count; ++i) { | 475 for (int i = 0; i < count; ++i) { |
| 476 GrGLint location; | 476 GrGLint location; |
| 477 GL_CALL_RET(location, GetUniformLocation(programID, fUniforms[i].fVa
riable.c_str())); | 477 GL_CALL_RET(location, GetUniformLocation(programID, fUniforms[i].fVa
riable.c_str())); |
| 478 fUniforms[i].fLocation = location; | 478 fUniforms[i].fLocation = location; |
| 479 } | 479 } |
| 480 } | 480 } |
| 481 } | 481 } |
| 482 | 482 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 497 } | 497 } |
| 498 | 498 |
| 499 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 499 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 500 | 500 |
| 501 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { | 501 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { |
| 502 int numProcs = fProcs.count(); | 502 int numProcs = fProcs.count(); |
| 503 for (int i = 0; i < numProcs; ++i) { | 503 for (int i = 0; i < numProcs; ++i) { |
| 504 delete fProcs[i]; | 504 delete fProcs[i]; |
| 505 } | 505 } |
| 506 } | 506 } |
| OLD | NEW |