Index: src/gpu/gl/GrGLShaderBuilder.cpp |
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp |
index d2e49a9f6c719814b4ed7716563c074fb4687fc4..9af28398b2795758909155f82d6069d76f5ee90d 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); |