OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 "GrGLProgram.h" | 8 #include "GrGLProgram.h" |
9 | 9 |
10 #include "GrAllocator.h" | 10 #include "GrAllocator.h" |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 builder.getShader(GrGLShaderBuilder::kVertex_ShaderType, &shader); | 382 builder.getShader(GrGLShaderBuilder::kVertex_ShaderType, &shader); |
383 if (c_PrintShaders) { | 383 if (c_PrintShaders) { |
384 GrPrintf(shader.c_str()); | 384 GrPrintf(shader.c_str()); |
385 GrPrintf("\n"); | 385 GrPrintf("\n"); |
386 } | 386 } |
387 | 387 |
388 if (!(fVShaderID = compile_shader(fContext, GR_GL_VERTEX_SHADER, shader))) { | 388 if (!(fVShaderID = compile_shader(fContext, GR_GL_VERTEX_SHADER, shader))) { |
389 return false; | 389 return false; |
390 } | 390 } |
391 | 391 |
392 if (builder.fUsesGS) { | 392 fGShaderID = 0; |
| 393 #if GR_GL_EXPERIMENTAL_GS |
| 394 if (fDesc.fExperimentalGS) { |
393 builder.getShader(GrGLShaderBuilder::kGeometry_ShaderType, &shader); | 395 builder.getShader(GrGLShaderBuilder::kGeometry_ShaderType, &shader); |
394 if (c_PrintShaders) { | 396 if (c_PrintShaders) { |
395 GrPrintf(shader.c_str()); | 397 GrPrintf(shader.c_str()); |
396 GrPrintf("\n"); | 398 GrPrintf("\n"); |
397 } | 399 } |
398 if (!(fGShaderID = compile_shader(fContext, GR_GL_GEOMETRY_SHADER, shade
r))) { | 400 if (!(fGShaderID = compile_shader(fContext, GR_GL_GEOMETRY_SHADER, shade
r))) { |
399 return false; | 401 return false; |
400 } | 402 } |
401 } else { | |
402 fGShaderID = 0; | |
403 } | 403 } |
| 404 #endif |
404 | 405 |
405 builder.getShader(GrGLShaderBuilder::kFragment_ShaderType, &shader); | 406 builder.getShader(GrGLShaderBuilder::kFragment_ShaderType, &shader); |
406 if (c_PrintShaders) { | 407 if (c_PrintShaders) { |
407 GrPrintf(shader.c_str()); | 408 GrPrintf(shader.c_str()); |
408 GrPrintf("\n"); | 409 GrPrintf("\n"); |
409 } | 410 } |
410 if (!(fFShaderID = compile_shader(fContext, GR_GL_FRAGMENT_SHADER, shader)))
{ | 411 if (!(fFShaderID = compile_shader(fContext, GR_GL_FRAGMENT_SHADER, shader)))
{ |
411 return false; | 412 return false; |
412 } | 413 } |
413 | 414 |
414 return true; | 415 return true; |
415 } | 416 } |
416 | 417 |
417 bool GrGLProgram::genProgram(const GrEffectStage* stages[]) { | 418 bool GrGLProgram::genProgram(const GrEffectStage* stages[]) { |
418 GrAssert(0 == fProgramID); | 419 GrAssert(0 == fProgramID); |
419 | 420 |
420 const GrAttribBindings& attribBindings = fDesc.fAttribBindings; | 421 GrGLShaderBuilder builder(fContext.info(), fUniformManager, fDesc); |
421 bool hasExplicitLocalCoords = | |
422 SkToBool(attribBindings & GrDrawState::kLocalCoords_AttribBindingsBit); | |
423 GrGLShaderBuilder builder(fContext.info(), fUniformManager, hasExplicitLocal
Coords); | |
424 | |
425 #if GR_GL_EXPERIMENTAL_GS | |
426 builder.fUsesGS = fDesc.fExperimentalGS; | |
427 #endif | |
428 | 422 |
429 SkXfermode::Coeff colorCoeff, uniformCoeff; | 423 SkXfermode::Coeff colorCoeff, uniformCoeff; |
430 // The rest of transfer mode color filters have not been implemented | 424 // The rest of transfer mode color filters have not been implemented |
431 if (fDesc.fColorFilterXfermode < SkXfermode::kCoeffModesCnt) { | 425 if (fDesc.fColorFilterXfermode < SkXfermode::kCoeffModesCnt) { |
432 GR_DEBUGCODE(bool success =) | 426 GR_DEBUGCODE(bool success =) |
433 SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode> | 427 SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode> |
434 (fDesc.fColorFilterXfermode), | 428 (fDesc.fColorFilterXfermode), |
435 &uniformCoeff, &colorCoeff); | 429 &uniformCoeff, &colorCoeff); |
436 GR_DEBUGASSERT(success); | 430 GR_DEBUGASSERT(success); |
437 } else { | 431 } else { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 viewMName, builder.positionAttribute().getName().c_str
()); | 483 viewMName, builder.positionAttribute().getName().c_str
()); |
490 | 484 |
491 // incoming color to current stage being processed. | 485 // incoming color to current stage being processed. |
492 SkString inColor; | 486 SkString inColor; |
493 | 487 |
494 if (needComputedColor) { | 488 if (needComputedColor) { |
495 this->genInputColor(&builder, &inColor); | 489 this->genInputColor(&builder, &inColor); |
496 } | 490 } |
497 | 491 |
498 // we output point size in the GS if present | 492 // we output point size in the GS if present |
499 if (fDesc.fEmitsPointSize && !builder.fUsesGS){ | 493 if (fDesc.fEmitsPointSize |
| 494 #if GR_GL_EXPERIMENTAL_GS |
| 495 && !fDesc.fExperimentalGS |
| 496 #endif |
| 497 ) { |
500 builder.vsCodeAppend("\tgl_PointSize = 1.0;\n"); | 498 builder.vsCodeAppend("\tgl_PointSize = 1.0;\n"); |
501 } | 499 } |
502 | 500 |
503 /////////////////////////////////////////////////////////////////////////// | 501 /////////////////////////////////////////////////////////////////////////// |
504 // compute the final color | 502 // compute the final color |
505 | 503 |
506 // if we have color stages string them together, feeding the output color | 504 // if we have color stages string them together, feeding the output color |
507 // of each to the next and generating code for each stage. | 505 // of each to the next and generating code for each stage. |
508 if (needComputedColor) { | 506 if (needComputedColor) { |
509 SkString outColor; | 507 SkString outColor; |
510 for (int s = 0; s < fDesc.fFirstCoverageStage; ++s) { | 508 for (int s = 0; s < fDesc.fFirstCoverageStage; ++s) { |
511 if (GrGLEffect::kNoEffectKey != fDesc.fEffectKeys[s]) { | 509 if (GrGLEffect::kNoEffectKey != fDesc.fEffectKeys[s]) { |
512 // create var to hold stage result | 510 // create var to hold stage result |
513 outColor = "color"; | 511 outColor = "color"; |
514 outColor.appendS32(s); | 512 outColor.appendS32(s); |
515 builder.fsCodeAppendf("\tvec4 %s;\n", outColor.c_str()); | 513 builder.fsCodeAppendf("\tvec4 %s;\n", outColor.c_str()); |
516 | 514 |
517 builder.setCurrentStage(s); | 515 builder.setCurrentStage(s); |
518 fEffects[s] = builder.createAndEmitGLEffect(*stages[s], | 516 fEffects[s] = builder.createAndEmitGLEffect(*stages[s], |
519 fDesc.fEffectKeys[s]
, | 517 fDesc.fEffectKeys[s]
, |
520 inColor.size() ? inC
olor.c_str() : NULL, | 518 inColor.size() ? inC
olor.c_str() : NULL, |
521 outColor.c_str(), | 519 outColor.c_str(), |
522 &fUniformHandles.fSa
mplerUnis[s]); | 520 &fUniformHandles.fEf
fectSamplerUnis[s]); |
523 builder.setNonStage(); | 521 builder.setNonStage(); |
524 inColor = outColor; | 522 inColor = outColor; |
525 } | 523 } |
526 } | 524 } |
527 } | 525 } |
528 | 526 |
529 // if have all ones or zeros for the "dst" input to the color filter then we | 527 // if have all ones or zeros for the "dst" input to the color filter then we |
530 // may be able to make additional optimizations. | 528 // may be able to make additional optimizations. |
531 if (needColorFilterUniform && needComputedColor && !inColor.size()) { | 529 if (needColorFilterUniform && needComputedColor && !inColor.size()) { |
532 GrAssert(GrGLProgramDesc::kSolidWhite_ColorInput == fDesc.fColorInput); | 530 GrAssert(GrGLProgramDesc::kSolidWhite_ColorInput == fDesc.fColorInput); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 outCoverage = "coverage"; | 589 outCoverage = "coverage"; |
592 outCoverage.appendS32(s); | 590 outCoverage.appendS32(s); |
593 builder.fsCodeAppendf("\tvec4 %s;\n", outCoverage.c_str()); | 591 builder.fsCodeAppendf("\tvec4 %s;\n", outCoverage.c_str()); |
594 | 592 |
595 builder.setCurrentStage(s); | 593 builder.setCurrentStage(s); |
596 fEffects[s] = builder.createAndEmitGLEffect( | 594 fEffects[s] = builder.createAndEmitGLEffect( |
597 *stages[s], | 595 *stages[s], |
598 fDesc.fEffectKeys[s], | 596 fDesc.fEffectKeys[s], |
599 inCoverage.size() ? inCovera
ge.c_str() : NULL, | 597 inCoverage.size() ? inCovera
ge.c_str() : NULL, |
600 outCoverage.c_str(), | 598 outCoverage.c_str(), |
601 &fUniformHandles.fSamplerUni
s[s]); | 599 &fUniformHandles.fEffectSamp
lerUnis[s]); |
602 builder.setNonStage(); | 600 builder.setNonStage(); |
603 inCoverage = outCoverage; | 601 inCoverage = outCoverage; |
604 } | 602 } |
605 } | 603 } |
606 | 604 |
607 // discard if coverage is zero | 605 // discard if coverage is zero |
608 if (fDesc.fDiscardIfZeroCoverage && !outCoverage.isEmpty()) { | 606 if (fDesc.fDiscardIfZeroCoverage && !outCoverage.isEmpty()) { |
609 builder.fsCodeAppendf( | 607 builder.fsCodeAppendf( |
610 "\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\t\tdiscard;\n\
t}\n", | 608 "\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\t\tdiscard;\n\
t}\n", |
611 outCoverage.c_str()); | 609 outCoverage.c_str()); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
667 return false; | 665 return false; |
668 } | 666 } |
669 | 667 |
670 if (!this->bindOutputsAttribsAndLinkProgram(builder, | 668 if (!this->bindOutputsAttribsAndLinkProgram(builder, |
671 isColorDeclared, | 669 isColorDeclared, |
672 dualSourceOutputWritten)) { | 670 dualSourceOutputWritten)) { |
673 return false; | 671 return false; |
674 } | 672 } |
675 | 673 |
676 builder.finished(fProgramID); | 674 builder.finished(fProgramID); |
| 675 fUniformHandles.fRTHeightUni = builder.getRTHeightUniform(); |
| 676 fUniformHandles.fDstCopyTopLeftUni = builder.getDstCopyTopLeftUniform(); |
| 677 fUniformHandles.fDstCopyScaleUni = builder.getDstCopyScaleUniform(); |
| 678 fUniformHandles.fDstCopySamplerUni = builder.getDstCopySamplerUniform(); |
| 679 // This must be called after we set fDstCopySamplerUni above. |
677 this->initSamplerUniforms(); | 680 this->initSamplerUniforms(); |
678 fUniformHandles.fRTHeightUni = builder.getRTHeightUniform(); | |
679 | 681 |
680 return true; | 682 return true; |
681 } | 683 } |
682 | 684 |
683 bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& buil
der, | 685 bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& buil
der, |
684 bool bindColorOut, | 686 bool bindColorOut, |
685 bool bindDualSrcOut) { | 687 bool bindDualSrcOut) { |
686 GL_CALL_RET(fProgramID, CreateProgram()); | 688 GL_CALL_RET(fProgramID, CreateProgram()); |
687 if (!fProgramID) { | 689 if (!fProgramID) { |
688 return false; | 690 return false; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 GrAssert(!"Error linking program"); | 744 GrAssert(!"Error linking program"); |
743 GL_CALL(DeleteProgram(fProgramID)); | 745 GL_CALL(DeleteProgram(fProgramID)); |
744 fProgramID = 0; | 746 fProgramID = 0; |
745 return false; | 747 return false; |
746 } | 748 } |
747 return true; | 749 return true; |
748 } | 750 } |
749 | 751 |
750 void GrGLProgram::initSamplerUniforms() { | 752 void GrGLProgram::initSamplerUniforms() { |
751 GL_CALL(UseProgram(fProgramID)); | 753 GL_CALL(UseProgram(fProgramID)); |
752 // We simply bind the uniforms to successive texture units beginning at 0. s
etData() assumes this | 754 // We simply bind the uniforms to successive texture units beginning at 0. s
etData() assumes |
753 // behavior. | 755 // this behavior. |
754 GrGLint texUnitIdx = 0; | 756 GrGLint texUnitIdx = 0; |
| 757 if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fDstCopySam
plerUni) { |
| 758 fUniformManager.setSampler(fUniformHandles.fDstCopySamplerUni, texUnitId
x); |
| 759 ++texUnitIdx; |
| 760 } |
| 761 |
755 for (int s = 0; s < GrDrawState::kNumStages; ++s) { | 762 for (int s = 0; s < GrDrawState::kNumStages; ++s) { |
756 int numSamplers = fUniformHandles.fSamplerUnis[s].count(); | 763 int numSamplers = fUniformHandles.fEffectSamplerUnis[s].count(); |
757 for (int u = 0; u < numSamplers; ++u) { | 764 for (int u = 0; u < numSamplers; ++u) { |
758 UniformHandle handle = fUniformHandles.fSamplerUnis[s][u]; | 765 UniformHandle handle = fUniformHandles.fEffectSamplerUnis[s][u]; |
759 if (GrGLUniformManager::kInvalidUniformHandle != handle) { | 766 if (GrGLUniformManager::kInvalidUniformHandle != handle) { |
760 fUniformManager.setSampler(handle, texUnitIdx); | 767 fUniformManager.setSampler(handle, texUnitIdx); |
761 ++texUnitIdx; | 768 ++texUnitIdx; |
762 } | 769 } |
763 } | 770 } |
764 } | 771 } |
765 } | 772 } |
766 | 773 |
767 /////////////////////////////////////////////////////////////////////////////// | 774 /////////////////////////////////////////////////////////////////////////////// |
768 | 775 |
769 void GrGLProgram::setData(GrGpuGL* gpu, | 776 void GrGLProgram::setData(GrGpuGL* gpu, |
770 GrColor color, | 777 GrColor color, |
771 GrColor coverage, | 778 GrColor coverage, |
| 779 const GrDeviceCoordTexture* dstCopy, |
772 SharedGLState* sharedState) { | 780 SharedGLState* sharedState) { |
773 const GrDrawState& drawState = gpu->getDrawState(); | 781 const GrDrawState& drawState = gpu->getDrawState(); |
774 | 782 |
775 this->setColor(drawState, color, sharedState); | 783 this->setColor(drawState, color, sharedState); |
776 this->setCoverage(drawState, coverage, sharedState); | 784 this->setCoverage(drawState, coverage, sharedState); |
777 this->setMatrixAndRenderTargetHeight(drawState); | 785 this->setMatrixAndRenderTargetHeight(drawState); |
778 | 786 |
779 // Setup the SkXfermode::Mode-based colorfilter uniform if necessary | 787 // Setup the SkXfermode::Mode-based colorfilter uniform if necessary |
780 if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fColorFilte
rUni && | 788 if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fColorFilte
rUni && |
781 fColorFilterColor != drawState.getColorFilterColor()) { | 789 fColorFilterColor != drawState.getColorFilterColor()) { |
782 GrGLfloat c[4]; | 790 GrGLfloat c[4]; |
783 GrColorToRGBAFloat(drawState.getColorFilterColor(), c); | 791 GrColorToRGBAFloat(drawState.getColorFilterColor(), c); |
784 fUniformManager.set4fv(fUniformHandles.fColorFilterUni, 0, 1, c); | 792 fUniformManager.set4fv(fUniformHandles.fColorFilterUni, 0, 1, c); |
785 fColorFilterColor = drawState.getColorFilterColor(); | 793 fColorFilterColor = drawState.getColorFilterColor(); |
786 } | 794 } |
787 | 795 |
788 GrGLint texUnitIdx = 0; | 796 GrGLint texUnitIdx = 0; |
| 797 if (NULL != dstCopy) { |
| 798 if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fDstCop
yTopLeftUni) { |
| 799 GrAssert(GrGLUniformManager::kInvalidUniformHandle != fUniformHandle
s.fDstCopyScaleUni); |
| 800 GrAssert(GrGLUniformManager::kInvalidUniformHandle != |
| 801 fUniformHandles.fDstCopySamplerUni); |
| 802 fUniformManager.set2f(fUniformHandles.fDstCopyTopLeftUni, |
| 803 static_cast<GrGLfloat>(dstCopy->offset().fX), |
| 804 static_cast<GrGLfloat>(dstCopy->offset().fY)); |
| 805 fUniformManager.set2f(fUniformHandles.fDstCopyScaleUni, |
| 806 1.f / dstCopy->texture()->width(), |
| 807 1.f / dstCopy->texture()->height()); |
| 808 GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture())
; |
| 809 static GrTextureParams kParams; // the default is clamp, nearest fil
tering. |
| 810 gpu->bindTexture(texUnitIdx, kParams, texture); |
| 811 ++texUnitIdx; |
| 812 } else { |
| 813 GrAssert(GrGLUniformManager::kInvalidUniformHandle == |
| 814 fUniformHandles.fDstCopyScaleUni); |
| 815 GrAssert(GrGLUniformManager::kInvalidUniformHandle == |
| 816 fUniformHandles.fDstCopySamplerUni); |
| 817 } |
| 818 } else { |
| 819 GrAssert(GrGLUniformManager::kInvalidUniformHandle == |
| 820 fUniformHandles.fDstCopyTopLeftUni); |
| 821 GrAssert(GrGLUniformManager::kInvalidUniformHandle == |
| 822 fUniformHandles.fDstCopyScaleUni); |
| 823 GrAssert(GrGLUniformManager::kInvalidUniformHandle == |
| 824 fUniformHandles.fDstCopySamplerUni); |
| 825 } |
789 for (int s = 0; s < GrDrawState::kNumStages; ++s) { | 826 for (int s = 0; s < GrDrawState::kNumStages; ++s) { |
790 if (NULL != fEffects[s]) { | 827 if (NULL != fEffects[s]) { |
791 const GrEffectStage& stage = drawState.getStage(s); | 828 const GrEffectStage& stage = drawState.getStage(s); |
792 GrAssert(NULL != stage.getEffect()); | 829 GrAssert(NULL != stage.getEffect()); |
793 | 830 |
794 bool explicitLocalCoords = | 831 bool explicitLocalCoords = |
795 (fDesc.fAttribBindings & GrDrawState::kLocalCoords_AttribBinding
sBit); | 832 (fDesc.fAttribBindings & GrDrawState::kLocalCoords_AttribBinding
sBit); |
796 GrDrawEffect drawEffect(stage, explicitLocalCoords); | 833 GrDrawEffect drawEffect(stage, explicitLocalCoords); |
797 fEffects[s]->setData(fUniformManager, drawEffect); | 834 fEffects[s]->setData(fUniformManager, drawEffect); |
798 int numSamplers = fUniformHandles.fSamplerUnis[s].count(); | 835 int numSamplers = fUniformHandles.fEffectSamplerUnis[s].count(); |
799 for (int u = 0; u < numSamplers; ++u) { | 836 for (int u = 0; u < numSamplers; ++u) { |
800 UniformHandle handle = fUniformHandles.fSamplerUnis[s][u]; | 837 UniformHandle handle = fUniformHandles.fEffectSamplerUnis[s][u]; |
801 if (GrGLUniformManager::kInvalidUniformHandle != handle) { | 838 if (GrGLUniformManager::kInvalidUniformHandle != handle) { |
802 const GrTextureAccess& access = (*stage.getEffect())->textur
eAccess(u); | 839 const GrTextureAccess& access = (*stage.getEffect())->textur
eAccess(u); |
803 GrGLTexture* texture = static_cast<GrGLTexture*>(access.getT
exture()); | 840 GrGLTexture* texture = static_cast<GrGLTexture*>(access.getT
exture()); |
804 gpu->bindTexture(texUnitIdx, access.getParams(), texture); | 841 gpu->bindTexture(texUnitIdx, access.getParams(), texture); |
805 ++texUnitIdx; | 842 ++texUnitIdx; |
806 } | 843 } |
807 } | 844 } |
808 } | 845 } |
809 } | 846 } |
810 } | 847 } |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
916 SkScalarToFloat(m[SkMatrix::kMTransX]), | 953 SkScalarToFloat(m[SkMatrix::kMTransX]), |
917 SkScalarToFloat(m[SkMatrix::kMTransY]), | 954 SkScalarToFloat(m[SkMatrix::kMTransY]), |
918 SkScalarToFloat(m[SkMatrix::kMPersp2]) | 955 SkScalarToFloat(m[SkMatrix::kMPersp2]) |
919 }; | 956 }; |
920 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt); | 957 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt); |
921 fMatrixState.fViewMatrix = drawState.getViewMatrix(); | 958 fMatrixState.fViewMatrix = drawState.getViewMatrix(); |
922 fMatrixState.fRenderTargetSize = size; | 959 fMatrixState.fRenderTargetSize = size; |
923 fMatrixState.fRenderTargetOrigin = rt->origin(); | 960 fMatrixState.fRenderTargetOrigin = rt->origin(); |
924 } | 961 } |
925 } | 962 } |
OLD | NEW |