| 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 #include "gl/GrGLProgram.h" | 9 #include "gl/GrGLProgram.h" |
| 10 #include "gl/GrGLSLPrettyPrint.h" | 10 #include "gl/GrGLSLPrettyPrint.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 | 38 |
| 39 // emit code to read the dst copy texture, if necessary | 39 // emit code to read the dst copy texture, if necessary |
| 40 if (GrGLFragmentShaderBuilder::kNoDstRead_DstReadKey != header.fDstReadKey | 40 if (GrGLFragmentShaderBuilder::kNoDstRead_DstReadKey != header.fDstReadKey |
| 41 && !gpu->glCaps().fbFetchSupport()) { | 41 && !gpu->glCaps().fbFetchSupport()) { |
| 42 pb->fFS.emitCodeToReadDstTexture(); | 42 pb->fFS.emitCodeToReadDstTexture(); |
| 43 } | 43 } |
| 44 | 44 |
| 45 // get the initial color and coverage to feed into the first effect in each
effect chain | 45 // get the initial color and coverage to feed into the first effect in each
effect chain |
| 46 GrGLSLExpr4 inputColor; | 46 GrGLSLExpr4 inputColor; |
| 47 GrGLSLExpr1 inputCoverage; | 47 GrGLSLExpr1 inputCoverage; |
| 48 pb->setupUniformColorAndCoverageIfNeeded(&inputColor, &inputCoverage); | 48 |
| 49 // TODO do this in the path processor |
| 50 if (header.fUseNvpr) { |
| 51 pb->setupUniformColorAndCoverageIfNeeded(&inputColor, &inputCoverage); |
| 52 } |
| 49 | 53 |
| 50 // TODO: Once all stages can handle taking a float or vec4 and correctly han
dling them we can | 54 // TODO: Once all stages can handle taking a float or vec4 and correctly han
dling them we can |
| 51 // remove this cast to a vec4. | 55 // remove this cast to a vec4. |
| 52 GrGLSLExpr4 inputCoverageVec4; | 56 GrGLSLExpr4 inputCoverageVec4; |
| 53 if (inputCoverage.isValid()) { | 57 if (inputCoverage.isValid()) { |
| 54 inputCoverageVec4 = GrGLSLExpr4::VectorCast(inputCoverage); | 58 inputCoverageVec4 = GrGLSLExpr4::VectorCast(inputCoverage); |
| 55 } | 59 } |
| 56 | 60 |
| 57 pb->emitAndInstallProcs(&inputColor, &inputCoverageVec4); | 61 pb->emitAndInstallProcs(&inputColor, &inputCoverageVec4); |
| 58 | 62 |
| 59 return pb->finalize(); | 63 return pb->finalize(); |
| 60 } | 64 } |
| 61 | 65 |
| 62 GrGLProgramBuilder* GrGLProgramBuilder::CreateProgramBuilder(const GrOptDrawStat
e& optState, | 66 GrGLProgramBuilder* GrGLProgramBuilder::CreateProgramBuilder(const GrOptDrawStat
e& optState, |
| 63 bool hasGeometryPro
cessor, | 67 bool hasGeometryPro
cessor, |
| 64 GrGpuGL* gpu) { | 68 GrGpuGL* gpu) { |
| 65 const GrProgramDesc& desc = optState.programDesc(); | 69 const GrProgramDesc& desc = optState.programDesc(); |
| 66 if (GrGLProgramDescBuilder::GetHeader(desc).fUseNvpr) { | 70 if (GrGLProgramDescBuilder::GetHeader(desc).fUseNvpr) { |
| 67 SkASSERT(gpu->glCaps().pathRenderingSupport()); | 71 SkASSERT(gpu->glCaps().pathRenderingSupport()); |
| 68 SkASSERT(GrProgramDesc::kAttribute_ColorInput != desc.header().fColorInp
ut); | |
| 69 SkASSERT(GrProgramDesc::kAttribute_ColorInput != desc.header().fCoverage
Input); | |
| 70 SkASSERT(!hasGeometryProcessor); | 72 SkASSERT(!hasGeometryProcessor); |
| 71 if (gpu->glPathRendering()->texturingMode() == | 73 if (gpu->glPathRendering()->texturingMode() == |
| 72 GrGLPathRendering::FixedFunction_TexturingMode) { | 74 GrGLPathRendering::FixedFunction_TexturingMode) { |
| 73 return SkNEW_ARGS(GrGLLegacyNvprProgramBuilder, (gpu, optState)); | 75 return SkNEW_ARGS(GrGLLegacyNvprProgramBuilder, (gpu, optState)); |
| 74 } else { | 76 } else { |
| 75 return SkNEW_ARGS(GrGLNvprProgramBuilder, (gpu, optState)); | 77 return SkNEW_ARGS(GrGLNvprProgramBuilder, (gpu, optState)); |
| 76 } | 78 } |
| 77 } else { | 79 } else { |
| 78 return SkNEW_ARGS(GrGLProgramBuilder, (gpu, optState)); | 80 return SkNEW_ARGS(GrGLProgramBuilder, (gpu, optState)); |
| 79 } | 81 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 } | 182 } |
| 181 } | 183 } |
| 182 } | 184 } |
| 183 | 185 |
| 184 const GrGLContextInfo& GrGLProgramBuilder::ctxInfo() const { | 186 const GrGLContextInfo& GrGLProgramBuilder::ctxInfo() const { |
| 185 return fGpu->ctxInfo(); | 187 return fGpu->ctxInfo(); |
| 186 } | 188 } |
| 187 | 189 |
| 188 void GrGLProgramBuilder::setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* input
Color, | 190 void GrGLProgramBuilder::setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* input
Color, |
| 189 GrGLSLExpr1* input
Coverage) { | 191 GrGLSLExpr1* input
Coverage) { |
| 190 const GrProgramDesc::KeyHeader& header = this->header(); | 192 const char* name; |
| 191 if (GrProgramDesc::kUniform_ColorInput == header.fColorInput) { | 193 fUniformHandles.fColorUni = |
| 192 const char* name; | 194 this->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
| 193 fUniformHandles.fColorUni = | 195 kVec4f_GrSLType, kDefault_GrSLPrecision, |
| 194 this->addUniform(GrGLProgramBuilder::kFragment_Visibility, | 196 "Color", &name); |
| 195 kVec4f_GrSLType, kDefault_GrSLPrecision, | 197 *inputColor = GrGLSLExpr4(name); |
| 196 "Color", &name); | 198 *inputCoverage = GrGLSLExpr1(1); |
| 197 *inputColor = GrGLSLExpr4(name); | |
| 198 } else if (GrProgramDesc::kAllOnes_ColorInput == header.fColorInput) { | |
| 199 *inputColor = GrGLSLExpr4(1); | |
| 200 } | |
| 201 if (GrProgramDesc::kUniform_ColorInput == header.fCoverageInput) { | |
| 202 const char* name; | |
| 203 fUniformHandles.fCoverageUni = | |
| 204 this->addUniform(GrGLProgramBuilder::kFragment_Visibility, | |
| 205 kFloat_GrSLType, kDefault_GrSLPrecision, | |
| 206 "Coverage",&name); | |
| 207 *inputCoverage = GrGLSLExpr1(name); | |
| 208 } else if (GrProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) { | |
| 209 *inputCoverage = GrGLSLExpr1(1); | |
| 210 } | |
| 211 } | 199 } |
| 212 | 200 |
| 213 void GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr
4* inputCoverage) { | 201 void GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr
4* inputCoverage) { |
| 214 if (fOptState.hasGeometryProcessor()) { | 202 if (fOptState.hasGeometryProcessor()) { |
| 215 fVS.setupUniformViewMatrix(); | 203 fVS.setupUniformViewMatrix(); |
| 216 | 204 |
| 217 const GrProgramDesc::KeyHeader& header = this->header(); | |
| 218 fVS.codeAppend("gl_PointSize = 1.0;"); | 205 fVS.codeAppend("gl_PointSize = 1.0;"); |
| 219 | 206 |
| 220 // Setup position | 207 // Setup position |
| 221 // TODO it'd be possible to remove these from the vertexshader builder a
nd have them | 208 // TODO it'd be possible to remove these from the vertexshader builder a
nd have them |
| 222 // be outputs from the emit call. We don't do this because emitargs is
constant. It would | 209 // be outputs from the emit call. We don't do this because emitargs is
constant. It would |
| 223 // be easy to change this though | 210 // be easy to change this though |
| 224 fVS.codeAppendf("vec3 %s;", fVS.glPosition()); | 211 fVS.codeAppendf("vec3 %s;", fVS.glPosition()); |
| 225 fVS.codeAppendf("vec2 %s;", fVS.positionCoords()); | 212 fVS.codeAppendf("vec2 %s;", fVS.positionCoords()); |
| 226 fVS.codeAppendf("vec2 %s;", fVS.localCoords()); | 213 fVS.codeAppendf("vec2 %s;", fVS.localCoords()); |
| 227 | 214 |
| 228 const GrGeometryProcessor& gp = *fOptState.getGeometryProcessor(); | 215 const GrGeometryProcessor& gp = *fOptState.getGeometryProcessor(); |
| 229 fVS.emitAttributes(gp); | 216 fVS.emitAttributes(gp); |
| 230 GrGLSLExpr4 outputColor; | 217 this->emitAndInstallProc(gp, inputColor, inputCoverage); |
| 231 GrGLSLExpr4 outputCoverage; | |
| 232 this->emitAndInstallProc(gp, &outputColor, &outputCoverage); | |
| 233 | |
| 234 // We may override color and coverage here if we have unform color or co
verage. This is | |
| 235 // obviously not ideal. | |
| 236 // TODO lets the GP itself do the override | |
| 237 if (GrProgramDesc::kAttribute_ColorInput == header.fColorInput) { | |
| 238 *inputColor = outputColor; | |
| 239 } | |
| 240 | |
| 241 // We may have uniform coverage, if so we need to multiply the GPs outpu
t by the uniform | |
| 242 // coverage | |
| 243 if (GrProgramDesc::kUniform_ColorInput == header.fCoverageInput) { | |
| 244 fFS.codeAppendf("%s *= %s;", outputCoverage.c_str(), inputCoverage->
c_str()); | |
| 245 } | |
| 246 *inputCoverage = outputCoverage; | |
| 247 } | 218 } |
| 248 | 219 |
| 249 fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs)); | 220 fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs)); |
| 250 int numProcs = fOptState.numFragmentStages(); | 221 int numProcs = fOptState.numFragmentStages(); |
| 251 this->emitAndInstallFragProcs(0, fOptState.numColorStages(), inputColor); | 222 this->emitAndInstallFragProcs(0, fOptState.numColorStages(), inputColor); |
| 252 this->emitAndInstallFragProcs(fOptState.numColorStages(), numProcs, inputCo
verage); | 223 this->emitAndInstallFragProcs(fOptState.numColorStages(), numProcs, inputCo
verage); |
| 253 | 224 |
| 254 if (fOptState.hasGeometryProcessor()) { | 225 if (fOptState.hasGeometryProcessor()) { |
| 255 fVS.transformToNormalizedDeviceSpace(); | 226 fVS.transformToNormalizedDeviceSpace(); |
| 256 } | 227 } |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 GrGLProgram* GrGLProgramBuilder::finalize() { | 453 GrGLProgram* GrGLProgramBuilder::finalize() { |
| 483 // verify we can get a program id | 454 // verify we can get a program id |
| 484 GrGLuint programID; | 455 GrGLuint programID; |
| 485 GL_CALL_RET(programID, CreateProgram()); | 456 GL_CALL_RET(programID, CreateProgram()); |
| 486 if (0 == programID) { | 457 if (0 == programID) { |
| 487 return NULL; | 458 return NULL; |
| 488 } | 459 } |
| 489 | 460 |
| 490 // compile shaders and bind attributes / uniforms | 461 // compile shaders and bind attributes / uniforms |
| 491 SkTDArray<GrGLuint> shadersToDelete; | 462 SkTDArray<GrGLuint> shadersToDelete; |
| 492 if (!fFS.compileAndAttachShaders(programID, &shadersToDelete)) { | |
| 493 this->cleanupProgram(programID, shadersToDelete); | |
| 494 return NULL; | |
| 495 } | |
| 496 | |
| 497 if (!(GrGLProgramDescBuilder::GetHeader(fDesc).fUseNvpr && | 463 if (!(GrGLProgramDescBuilder::GetHeader(fDesc).fUseNvpr && |
| 498 fGpu->glPathRendering()->texturingMode() == | 464 fGpu->glPathRendering()->texturingMode() == |
| 499 GrGLPathRendering::FixedFunction_TexturingMode)) { | 465 GrGLPathRendering::FixedFunction_TexturingMode)) { |
| 500 if (!fVS.compileAndAttachShaders(programID, &shadersToDelete)) { | 466 if (!fVS.compileAndAttachShaders(programID, &shadersToDelete)) { |
| 501 this->cleanupProgram(programID, shadersToDelete); | 467 this->cleanupProgram(programID, shadersToDelete); |
| 502 return NULL; | 468 return NULL; |
| 503 } | 469 } |
| 504 | 470 |
| 505 // Non fixed function NVPR actually requires a vertex shader to compile | 471 // Non fixed function NVPR actually requires a vertex shader to compile |
| 506 if (fOptState.hasGeometryProcessor()) { | 472 if (fOptState.hasGeometryProcessor()) { |
| 507 fVS.bindVertexAttributes(programID); | 473 fVS.bindVertexAttributes(programID); |
| 508 } | 474 } |
| 509 } | 475 } |
| 476 |
| 477 if (!fFS.compileAndAttachShaders(programID, &shadersToDelete)) { |
| 478 this->cleanupProgram(programID, shadersToDelete); |
| 479 return NULL; |
| 480 } |
| 481 |
| 510 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation
!= NULL; | 482 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation
!= NULL; |
| 511 if (usingBindUniform) { | 483 if (usingBindUniform) { |
| 512 this->bindUniformLocations(programID); | 484 this->bindUniformLocations(programID); |
| 513 } | 485 } |
| 514 fFS.bindFragmentShaderLocations(programID); | 486 fFS.bindFragmentShaderLocations(programID); |
| 515 GL_CALL(LinkProgram(programID)); | 487 GL_CALL(LinkProgram(programID)); |
| 516 | 488 |
| 517 // Calling GetProgramiv is expensive in Chromium. Assume success in release
builds. | 489 // Calling GetProgramiv is expensive in Chromium. Assume success in release
builds. |
| 518 bool checkLinked = !fGpu->ctxInfo().isChromium(); | 490 bool checkLinked = !fGpu->ctxInfo().isChromium(); |
| 519 #ifdef SK_DEBUG | 491 #ifdef SK_DEBUG |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 } | 560 } |
| 589 | 561 |
| 590 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 562 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 591 | 563 |
| 592 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { | 564 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { |
| 593 int numProcs = fProcs.count(); | 565 int numProcs = fProcs.count(); |
| 594 for (int e = 0; e < numProcs; ++e) { | 566 for (int e = 0; e < numProcs; ++e) { |
| 595 SkDELETE(fProcs[e]); | 567 SkDELETE(fProcs[e]); |
| 596 } | 568 } |
| 597 } | 569 } |
| OLD | NEW |