From f7f9aa0e4721624395d247ffa1f0128cfac95341 Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Fri, 30 May 2014 15:14:56 +0000 Subject: [PATCH] move all code generation under genProgram() in GrGLShaderBuilder. R=robertphillips@google.com, jvanverth@google.com Author: bsalomon@google.com Review URL: https://codereview.chromium.org/306063002 git-svn-id: http://skia.googlecode.com/svn/trunk@14996 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/gpu/gl/GrGLShaderBuilder.cpp | 201 +++++++++++++++++++++------------------ src/gpu/gl/GrGLShaderBuilder.h | 36 ++++--- 2 files changed, 128 insertions(+), 109 deletions(-) diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp index d2e49a9..9af2839 100644 --- a/src/gpu/gl/GrGLShaderBuilder.cpp +++ b/src/gpu/gl/GrGLShaderBuilder.cpp @@ -112,84 +112,8 @@ bool GrGLShaderBuilder::genProgram(const GrEffectStage* colorStages[], const GrEffectStage* coverageStages[]) { const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); - // incoming color to current stage being processed. - GrGLSLExpr4 inColor = this->getInputColor(); - - fOutput.fColorEffects = - this->createAndEmitEffects(colorStages, - this->desc().getEffectKeys(), - this->desc().numColorEffects(), - &inColor); - /////////////////////////////////////////////////////////////////////////// - // compute the partial coverage - GrGLSLExpr4 inCoverage = this->getInputCoverage(); - - fOutput.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()) { - return false; - } - - return true; -} - -////////////////////////////////////////////////////////////////////////////// - -GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, - GrGLUniformManager* uniformManager, - const GrGLProgramDesc& desc) - : fDesc(desc) - , fGpu(gpu) - , fUniformManager(SkRef(uniformManager)) - , fFSFeaturesAddedMask(0) - , fFSInputs(kVarsPerBlock) - , fFSOutputs(kMaxFSOutputs) - , fUniforms(kVarsPerBlock) - , fSetupFragPosition(false) - , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey) - , fHasCustomColorOutput(false) - , fHasSecondaryOutput(false) { - - const GrGLProgramDesc::KeyHeader& header = desc.getHeader(); - - // Emit code to read the dst copy textue if necessary. + // emit code to read the dst copy texture, if necessary if (kNoDstRead_DstReadKey != header.fDstReadKey && GrGLCaps::kNone_FBFetchType == fGpu->glCaps().fbFetchType()) { bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKey); @@ -228,16 +152,22 @@ GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, this->fsCodeAppend(";\n\n"); } + /////////////////////////////////////////////////////////////////////////// + // get the initial color and coverage to feed into the first effect in each effect chain + + GrGLSLExpr4 inputColor; + GrGLSLExpr4 inputCoverage; + if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) { const char* name; fOutput.fUniformHandles.fColorUni = this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "Color", &name); - fInputColor = GrGLSLExpr4(name); + inputColor = GrGLSLExpr4(name); } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fColorInput) { - fInputColor = GrGLSLExpr4(1); + inputColor = GrGLSLExpr4(1); } else if (GrGLProgramDesc::kTransBlack_ColorInput == header.fColorInput) { - fInputColor = GrGLSLExpr4(0); + inputColor = GrGLSLExpr4(0); } if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) { @@ -245,11 +175,11 @@ GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, fOutput.fUniformHandles.fCoverageUni = this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "Coverage", &name); - fInputCoverage = GrGLSLExpr4(name); + inputCoverage = GrGLSLExpr4(name); } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fCoverageInput) { - fInputCoverage = GrGLSLExpr4(1); + inputCoverage = GrGLSLExpr4(1); } else if (GrGLProgramDesc::kTransBlack_ColorInput == header.fCoverageInput) { - fInputCoverage = GrGLSLExpr4(0); + inputCoverage = GrGLSLExpr4(0); } if (k110_GrGLSLGeneration != fGpu->glslGeneration()) { @@ -258,6 +188,83 @@ GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, declared_color_output_name()); fHasCustomColorOutput = true; } + + this->emitCodeBeforeEffects(&inputColor, &inputCoverage); + + /////////////////////////////////////////////////////////////////////////// + // emit the per-effect code for both color and coverage effects + + fOutput.fColorEffects = + this->createAndEmitEffects(colorStages, + this->desc().getEffectKeys(), + this->desc().numColorEffects(), + &inputColor); + + fOutput.fCoverageEffects = + this->createAndEmitEffects(coverageStages, + this->desc().getEffectKeys() + this->desc().numColorEffects(), + this->desc().numCoverageEffects(), + &inputCoverage); + + this->emitCodeAfterEffects(); + + /////////////////////////////////////////////////////////////////////////// + // write the secondary color output if necessary + 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) - inputColor.a()); + } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == + header.fCoverageOutput){ + // Get (1-RGBA) into coeff + coeff = GrGLSLExpr4(1) - inputColor; + } + // Get coeff * coverage into modulate and then write that to the dual source output. + this->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inputCoverage).c_str()); + } + + /////////////////////////////////////////////////////////////////////////// + // combine color and coverage as frag color + + // Get "color * coverage" into fragColor + GrGLSLExpr4 fragColor = inputColor * inputCoverage; + // 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) - inputCoverage; + + GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(this->dstColor()); + + fragColor = fragColor + dstContribution; + } + this->fsCodeAppendf("\t%s = %s;\n", this->getColorOutputName(), fragColor.c_str()); + + if (!this->finish()) { + return false; + } + + return true; +} + +////////////////////////////////////////////////////////////////////////////// + +GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, + GrGLUniformManager* uniformManager, + const GrGLProgramDesc& desc) + : fDesc(desc) + , fGpu(gpu) + , fUniformManager(SkRef(uniformManager)) + , fFSFeaturesAddedMask(0) + , fFSInputs(kVarsPerBlock) + , fFSOutputs(kMaxFSOutputs) + , fUniforms(kVarsPerBlock) + , fSetupFragPosition(false) + , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey) + , fHasCustomColorOutput(false) + , fHasSecondaryOutput(false) { } bool GrGLShaderBuilder::enableFeature(GLSLFeature feature) { @@ -822,7 +829,9 @@ GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu, , fVSOutputs(kVarsPerBlock) , fGSInputs(kVarsPerBlock) , fGSOutputs(kVarsPerBlock) { +} +void GrGLFullShaderBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) { const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); fOutput.fHasVertexShader = true; @@ -842,20 +851,11 @@ GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu, fOutput.fUniformHandles.fViewMatrixUni = this->addUniform(GrGLShaderBuilder::kVertex_Visibility, kMat33f_GrSLType, "ViewM", &viewMName); - const char* rtAdjustName; - fOutput.fUniformHandles.fRTAdjustmentUni = - this->addUniform(GrGLShaderBuilder::kVertex_Visibility, kVec4f_GrSLType, "rtAdjustment", - &rtAdjustName); // Transform the position into Skia's device coords. this->vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n", viewMName, fPositionVar->c_str()); - // Transform from Skia's device coords to GL's normalized device coords. - this->vsCodeAppendf( - "\tgl_Position = vec4(dot(pos3.xz, %s.xy), dot(pos3.yz, %s.zw), 0, pos3.z);\n", - rtAdjustName, rtAdjustName); - // we output point size in the GS if present if (header.fEmitsPointSize #if GR_GL_EXPERIMENTAL_GS @@ -870,7 +870,7 @@ GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu, const char *vsName, *fsName; this->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName); this->vsCodeAppendf("\t%s = %s;\n", vsName, color_attribute_name()); - this->setInputColor(fsName); + *color = fsName; } if (GrGLProgramDesc::kAttribute_ColorInput == header.fCoverageInput) { @@ -878,10 +878,22 @@ GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu, const char *vsName, *fsName; this->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); this->vsCodeAppendf("\t%s = %s;\n", vsName, coverage_attribute_name()); - this->setInputCoverage(fsName); + *coverage = fsName; } } +void GrGLFullShaderBuilder::emitCodeAfterEffects() { + const char* rtAdjustName; + fOutput.fUniformHandles.fRTAdjustmentUni = + this->addUniform(GrGLShaderBuilder::kVertex_Visibility, kVec4f_GrSLType, "rtAdjustment", + &rtAdjustName); + + // Transform from Skia's device coords to GL's normalized device coords. + this->vsCodeAppendf( + "\tgl_Position = vec4(dot(pos3.xz, %s.xy), dot(pos3.yz, %s.zw), 0, pos3.z);\n", + rtAdjustName, rtAdjustName); +} + bool GrGLFullShaderBuilder::addAttribute(GrSLType type, const char* name) { for (int i = 0; i < fVSAttrs.count(); ++i) { const GrGLShaderVar& attr = fVSAttrs[i]; @@ -1062,7 +1074,6 @@ GrGLFragmentOnlyShaderBuilder::GrGLFragmentOnlyShaderBuilder(GrGpuGL* gpu, GrGLUniformManager* uniformManager, const GrGLProgramDesc& desc) : INHERITED(gpu, uniformManager, desc) { - SkASSERT(!desc.getHeader().fHasVertexCode); SkASSERT(gpu->glCaps().pathRenderingSupport()); SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fColorInput); diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h index 42186de..3a93c1b 100644 --- a/src/gpu/gl/GrGLShaderBuilder.h +++ b/src/gpu/gl/GrGLShaderBuilder.h @@ -233,9 +233,6 @@ protected: const GrGLProgramDesc& desc() const { return fDesc; } - void setInputColor(const GrGLSLExpr4& inputColor) { fInputColor = inputColor; } - void setInputCoverage(const GrGLSLExpr4& inputCoverage) { fInputCoverage = inputCoverage; } - /** Add input/output variable declarations (i.e. 'varying') to the fragment shader. */ GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); } @@ -317,6 +314,15 @@ private: bool genProgram(const GrEffectStage* colorStages[], const GrEffectStage* coverageStages[]); /** + * The base class will emit the fragment code that precedes the per-effect code and then call + * this function. The subclass can use it to insert additional fragment code that should + * execute before the effects' code and/or emit other shaders (e.g. geometry, vertex). + * + * The subclass can modify the initial color or coverage + */ + virtual void emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) = 0; + + /** * Adds code for effects and returns a GrGLProgramEffects* object. The caller is responsible for * deleting it when finished. effectStages contains the effects to add. effectKeys[i] is the key * generated from effectStages[i]. inOutFSColor specifies the input color to the first stage and @@ -329,6 +335,11 @@ private: int effectCnt, GrGLSLExpr4* inOutFSColor) = 0; + /** + * Similar to emitCodeBeforeEffects() but called after per-effect code is emitted. + */ + virtual void emitCodeAfterEffects() = 0; + /** Enables using the secondary color output and returns the name of the var in which it is to be stored */ const char* enableSecondaryOutput(); @@ -341,14 +352,6 @@ private: **/ bool finish(); - const GrGLSLExpr4& getInputColor() const { - return fInputColor; - } - - const GrGLSLExpr4& getInputCoverage() const { - return fInputCoverage; - } - /** * Features that should only be enabled by GrGLShaderBuilder itself. */ @@ -392,9 +395,6 @@ private: bool fSetupFragPosition; bool fTopLeftFragPosRead; - GrGLSLExpr4 fInputColor; - GrGLSLExpr4 fInputCoverage; - bool fHasCustomColorOutput; bool fHasSecondaryOutput; }; @@ -448,10 +448,15 @@ public: const SkString* getEffectAttributeName(int attributeIndex) const; private: + virtual void emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) SK_OVERRIDE; + virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[], const EffectKey effectKeys[], int effectCnt, GrGLSLExpr4* inOutFSColor) SK_OVERRIDE; + + virtual void emitCodeAfterEffects() SK_OVERRIDE; + virtual bool compileAndAttachShaders(GrGLuint programId, SkTDArray* shaderIds) const SK_OVERRIDE; @@ -488,12 +493,15 @@ public: int addTexCoordSets(int count); private: + virtual void emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) SK_OVERRIDE {} virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[], const EffectKey effectKeys[], int effectCnt, GrGLSLExpr4* inOutFSColor) SK_OVERRIDE; + virtual void emitCodeAfterEffects() SK_OVERRIDE {} + typedef GrGLShaderBuilder INHERITED; }; -- 2.7.4