aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-05-30 15:14:56 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-05-30 15:14:56 +0000
commitf7f9aa0e4721624395d247ffa1f0128cfac95341 (patch)
treecdbbc1370a15c3e86bf0459aac13bfa64b73f364 /src/gpu/gl
parent6175d50a252764c9ab52e67e73148a8ea74a4636 (diff)
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
Diffstat (limited to 'src/gpu/gl')
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp201
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.h36
2 files changed, 128 insertions, 109 deletions
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
index d2e49a9f6c..9af28398b2 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 42186defc2..3a93c1bf72 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<GrGLuint>* 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;
};