aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/gpu/gl/GrGLProgram.cpp98
-rw-r--r--src/gpu/gl/GrGLProgram.h19
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp114
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.h46
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;