diff options
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 98 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.h | 19 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderBuilder.cpp | 114 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderBuilder.h | 46 |
4 files changed, 163 insertions, 114 deletions
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index efd6e4606b..c63914893d 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -47,19 +47,18 @@ GrGLProgram::GrGLProgram(GrGpuGL* gpu, fColor = GrColor_ILLEGAL; - if (fDesc.getHeader().fHasVertexCode || - !fGpu->shouldUseFixedFunctionTexturing()) { - GrGLFullShaderBuilder fullBuilder(fGpu, fUniformManager, fDesc); - if (this->genProgram(&fullBuilder, colorStages, coverageStages)) { - fUniformHandles.fViewMatrixUni = fullBuilder.getViewMatrixUniform(); - fUniformHandles.fRTAdjustmentUni = fullBuilder.getRTAdjustmentVecUniform(); - fHasVertexShader = true; - } - } else { - GrGLFragmentOnlyShaderBuilder fragmentOnlyBuilder(fGpu, fUniformManager, fDesc); - if (this->genProgram(&fragmentOnlyBuilder, colorStages, coverageStages)) { - fNumTexCoordSets = fragmentOnlyBuilder.getNumTexCoordSets(); - } + GrGLShaderBuilder::GenProgramOutput output; + + if (GrGLShaderBuilder::GenProgram(gpu, fUniformManager, desc, colorStages, coverageStages, + &output)) { + fProgramID = output.fProgramID; + fUniformHandles = output.fUniformHandles; + fColorEffects.reset(output.fColorEffects); + fCoverageEffects.reset(output.fCoverageEffects); + fHasVertexShader = output.fHasVS; + fNumTexCoordSets = output.fNumTexCoordSets; + fGpu = gpu; + this->initSamplerUniforms(); } } @@ -95,79 +94,6 @@ void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff, } } -bool GrGLProgram::genProgram(GrGLShaderBuilder* builder, - const GrEffectStage* colorStages[], - const GrEffectStage* coverageStages[]) { - SkASSERT(0 == fProgramID); - - const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); - - // incoming color to current stage being processed. - GrGLSLExpr4 inColor = builder->getInputColor(); - - fColorEffects.reset( - builder->createAndEmitEffects(colorStages, - fDesc.effectKeys(), - fDesc.numColorEffects(), - &inColor)); - - /////////////////////////////////////////////////////////////////////////// - // compute the partial coverage - GrGLSLExpr4 inCoverage = builder->getInputCoverage(); - - fCoverageEffects.reset( - builder->createAndEmitEffects(coverageStages, - fDesc.getEffectKeys() + fDesc.numColorEffects(), - fDesc.numCoverageEffects(), - &inCoverage)); - - if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutput)) { - const char* secondaryOutputName = builder->enableSecondaryOutput(); - - // default coeff to ones for kCoverage_DualSrcOutput - GrGLSLExpr4 coeff(1); - if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCoverageOutput) { - // Get (1-A) into coeff - coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inColor.a()); - } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == header.fCoverageOutput) { - // Get (1-RGBA) into coeff - coeff = GrGLSLExpr4(1) - inColor; - } - // Get coeff * coverage into modulate and then write that to the dual source output. - builder->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inCoverage).c_str()); - } - - /////////////////////////////////////////////////////////////////////////// - // combine color and coverage as frag color - - // Get "color * coverage" into fragColor - GrGLSLExpr4 fragColor = inColor * inCoverage; - // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do so. - if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutput) { - GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inCoverage; - - GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(builder->dstColor()); - - fragColor = fragColor + dstContribution; - } - builder->fsCodeAppendf("\t%s = %s;\n", builder->getColorOutputName(), fragColor.c_str()); - - if (!builder->finish(&fProgramID)) { - return false; - } - - fUniformHandles.fRTHeightUni = builder->getRTHeightUniform(); - fUniformHandles.fDstCopyTopLeftUni = builder->getDstCopyTopLeftUniform(); - fUniformHandles.fDstCopyScaleUni = builder->getDstCopyScaleUniform(); - fUniformHandles.fColorUni = builder->getColorUniform(); - fUniformHandles.fCoverageUni = builder->getCoverageUniform(); - fUniformHandles.fDstCopySamplerUni = builder->getDstCopySamplerUniform(); - // This must be called after we set fDstCopySamplerUni above. - this->initSamplerUniforms(); - - return true; -} - void GrGLProgram::initSamplerUniforms() { GL_CALL(UseProgram(fProgramID)); GrGLint texUnitIdx = 0; diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h index b6d9a8e085..a9a2da222e 100644 --- a/src/gpu/gl/GrGLProgram.h +++ b/src/gpu/gl/GrGLProgram.h @@ -164,23 +164,6 @@ public: private: typedef GrGLUniformManager::UniformHandle UniformHandle; - // handles for uniforms (aside from per-effect samplers) - struct UniformHandles { - UniformHandle fViewMatrixUni; - UniformHandle fRTAdjustmentUni; - UniformHandle fColorUni; - UniformHandle fCoverageUni; - - // We use the render target height to provide a y-down frag coord when specifying - // origin_upper_left is not supported. - UniformHandle fRTHeightUni; - - // Uniforms for computing texture coords to do the dst-copy lookup - UniformHandle fDstCopyTopLeftUni; - UniformHandle fDstCopyScaleUni; - UniformHandle fDstCopySamplerUni; - }; - GrGLProgram(GrGpuGL* gpu, const GrGLProgramDesc& desc, const GrEffectStage* colorStages[], @@ -226,7 +209,7 @@ private: GrGpuGL* fGpu; GrGLUniformManager fUniformManager; - UniformHandles fUniformHandles; + GrGLShaderBuilder::UniformHandles fUniformHandles; bool fHasVertexShader; int fNumTexCoordSets; diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp index 1fd1967e21..52644f82b8 100644 --- a/src/gpu/gl/GrGLShaderBuilder.cpp +++ b/src/gpu/gl/GrGLShaderBuilder.cpp @@ -89,10 +89,108 @@ static const char kDstCopyColorName[] = "_dstColor"; /////////////////////////////////////////////////////////////////////////////// +bool GrGLShaderBuilder::GenProgram(GrGpuGL* gpu, + GrGLUniformManager& uman, + const GrGLProgramDesc& desc, + const GrEffectStage* inColorStages[], + const GrEffectStage* inCoverageStages[], + GenProgramOutput* output) { + if (desc.getHeader().fHasVertexCode ||!gpu->shouldUseFixedFunctionTexturing()) { + GrGLFullShaderBuilder fullBuilder(gpu, uman, desc); + if (fullBuilder.genProgram(inColorStages, inCoverageStages, output)) { + output->fHasVS = true; + output->fUniformHandles.fViewMatrixUni = fullBuilder.getViewMatrixUniform(); + output->fUniformHandles.fRTAdjustmentUni = fullBuilder.getRTAdjustmentVecUniform(); + return true; + } + } else { + GrGLFragmentOnlyShaderBuilder fragmentOnlyBuilder(gpu, uman, desc); + if (fragmentOnlyBuilder.genProgram(inColorStages, inCoverageStages, output)) { + output->fHasVS = false; + output->fNumTexCoordSets = fragmentOnlyBuilder.getNumTexCoordSets(); + return true; + } + } + return false; +} + +bool GrGLShaderBuilder::genProgram(const GrEffectStage* colorStages[], + const GrEffectStage* coverageStages[], + GenProgramOutput* output) { + const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); + + // incoming color to current stage being processed. + GrGLSLExpr4 inColor = this->getInputColor(); + + output->fColorEffects = + this->createAndEmitEffects(colorStages, + this->desc().getEffectKeys(), + this->desc().numColorEffects(), + &inColor); + + /////////////////////////////////////////////////////////////////////////// + // compute the partial coverage + GrGLSLExpr4 inCoverage = this->getInputCoverage(); + + output->fCoverageEffects = + this->createAndEmitEffects(coverageStages, + this->desc().getEffectKeys() + this->desc().numColorEffects(), + this->desc().numCoverageEffects(), + &inCoverage); + + if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutput)) { + const char* secondaryOutputName = this->enableSecondaryOutput(); + + // default coeff to ones for kCoverage_DualSrcOutput + GrGLSLExpr4 coeff(1); + if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCoverageOutput) { + // Get (1-A) into coeff + coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inColor.a()); + } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == + header.fCoverageOutput){ + // Get (1-RGBA) into coeff + coeff = GrGLSLExpr4(1) - inColor; + } + // Get coeff * coverage into modulate and then write that to the dual source output. + this->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inCoverage).c_str()); + } + + /////////////////////////////////////////////////////////////////////////// + // combine color and coverage as frag color + + // Get "color * coverage" into fragColor + GrGLSLExpr4 fragColor = inColor * inCoverage; + // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do so. + if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutput) { + GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inCoverage; + + GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(this->dstColor()); + + fragColor = fragColor + dstContribution; + } + this->fsCodeAppendf("\t%s = %s;\n", this->getColorOutputName(), fragColor.c_str()); + + if (!this->finish(&output->fProgramID)) { + return false; + } + + output->fUniformHandles.fRTHeightUni = this->getRTHeightUniform(); + output->fUniformHandles.fDstCopyTopLeftUni = this->getDstCopyTopLeftUniform(); + output->fUniformHandles.fDstCopyScaleUni = this->getDstCopyScaleUniform(); + output->fUniformHandles.fColorUni = this->getColorUniform(); + output->fUniformHandles.fCoverageUni = this->getCoverageUniform(); + output->fUniformHandles.fDstCopySamplerUni = this->getDstCopySamplerUniform(); + + return true; +} + +////////////////////////////////////////////////////////////////////////////// + GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, GrGLUniformManager& uniformManager, const GrGLProgramDesc& desc) - : fGpu(gpu) + : fDesc(desc) + , fGpu(gpu) , fUniformManager(uniformManager) , fFSFeaturesAddedMask(0) , fFSInputs(kVarsPerBlock) @@ -735,13 +833,12 @@ GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu, GrGLUniformManager& uniformManager, const GrGLProgramDesc& desc) : INHERITED(gpu, uniformManager, desc) - , fDesc(desc) , fVSAttrs(kVarsPerBlock) , fVSOutputs(kVarsPerBlock) , fGSInputs(kVarsPerBlock) , fGSOutputs(kVarsPerBlock) { - const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); + const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); fPositionVar = &fVSAttrs.push_back(); fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition"); @@ -837,7 +934,7 @@ void GrGLFullShaderBuilder::addVarying(GrSLType type, // input to FS comes either from VS or GS const SkString* fsName; #if GR_GL_EXPERIMENTAL_GS - if (fDesc.getHeader().fExperimentalGS) { + if (this->desc().getHeader().fExperimentalGS) { // if we have a GS take each varying in as an array // and output as non-array. fGSInputs.push_back(); @@ -887,7 +984,8 @@ GrGLProgramEffects* GrGLFullShaderBuilder::createAndEmitEffects( return programEffectsBuilder.finish(); } -bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const { +bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId, + SkTDArray<GrGLuint>* shaderIds) const { const GrGLContext& glCtx = this->gpu()->glContext(); SkString vertShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); this->appendUniformDecls(kVertex_Visibility, &vertShaderSrc); @@ -903,7 +1001,7 @@ bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId, SkTDArra *shaderIds->append() = vertShaderId; #if GR_GL_EXPERIMENTAL_GS - if (fDesc.getHeader().fExperimentalGS) { + if (this->desc().getHeader().fExperimentalGS) { SkASSERT(this->ctxInfo().glslGeneration() >= k150_GrGLSLGeneration); SkString geomShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); geomShaderSrc.append("layout(triangles) in;\n" @@ -913,7 +1011,7 @@ bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId, SkTDArra geomShaderSrc.append("void main() {\n"); geomShaderSrc.append("\tfor (int i = 0; i < 3; ++i) {\n" "\t\tgl_Position = gl_in[i].gl_Position;\n"); - if (fDesc.getHeader().fEmitsPointSize) { + if (this->desc().getHeader().fEmitsPointSize) { geomShaderSrc.append("\t\tgl_PointSize = 1.0;\n"); } SkASSERT(fGSInputs.count() == fGSOutputs.count()); @@ -940,7 +1038,7 @@ bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId, SkTDArra void GrGLFullShaderBuilder::bindProgramLocations(GrGLuint programId) const { this->INHERITED::bindProgramLocations(programId); - const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); + const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); // Bind the attrib locations to same values for all shaders SkASSERT(-1 != header.fPositionAttributeIndex); diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h index 1be9a881d3..90f1a94ea3 100644 --- a/src/gpu/gl/GrGLShaderBuilder.h +++ b/src/gpu/gl/GrGLShaderBuilder.h @@ -41,7 +41,41 @@ public: kFragment_Visibility = 0x4, }; - GrGLShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&); + typedef GrGLUniformManager::UniformHandle UniformHandle; + + // Handles for program uniforms (other than per-effect uniforms) + struct UniformHandles { + UniformHandle fViewMatrixUni; + UniformHandle fRTAdjustmentUni; + UniformHandle fColorUni; + UniformHandle fCoverageUni; + + // We use the render target height to provide a y-down frag coord when specifying + // origin_upper_left is not supported. + UniformHandle fRTHeightUni; + + // Uniforms for computing texture coords to do the dst-copy lookup + UniformHandle fDstCopyTopLeftUni; + UniformHandle fDstCopyScaleUni; + UniformHandle fDstCopySamplerUni; + }; + + struct GenProgramOutput { + GrGLProgramEffects* fColorEffects; + GrGLProgramEffects* fCoverageEffects; + UniformHandles fUniformHandles; + bool fHasVS; + int fNumTexCoordSets; + GrGLuint fProgramID; + }; + + static bool GenProgram(GrGpuGL* gpu, + GrGLUniformManager& uman, + const GrGLProgramDesc& desc, + const GrEffectStage* inColorStages[], + const GrEffectStage* inCoverageStages[], + GenProgramOutput* output); + virtual ~GrGLShaderBuilder() {} /** @@ -228,8 +262,12 @@ public: }; protected: + GrGLShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&); + GrGpuGL* gpu() const { return fGpu; } + const GrGLProgramDesc& desc() const { return fDesc; } + void setInputColor(const GrGLSLExpr4& inputColor) { fInputColor = inputColor; } void setInputCoverage(const GrGLSLExpr4& inputCoverage) { fInputCoverage = inputCoverage; } @@ -306,6 +344,10 @@ private: const GrEffectStage* fEffectStage; } fCodeStage; + bool genProgram(const GrEffectStage* colorStages[], + const GrEffectStage* coverageStages[], + GenProgramOutput* output); + /** * Features that should only be enabled by GrGLShaderBuilder itself. */ @@ -334,6 +376,7 @@ private: kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to bottom-left. }; + const GrGLProgramDesc& fDesc; GrGpuGL* fGpu; GrGLUniformManager& fUniformManager; uint32_t fFSFeaturesAddedMask; @@ -433,7 +476,6 @@ protected: virtual void bindProgramLocations(GrGLuint programId) const SK_OVERRIDE; private: - const GrGLProgramDesc& fDesc; VarArray fVSAttrs; VarArray fVSOutputs; VarArray fGSInputs; |