Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1021)

Unified Diff: src/gpu/gl/GrGLProgram.cpp

Issue 13895006: Expand modulate, add, subtract, extract component glsl helpers. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/gl/GrGLProgram.h ('k') | src/gpu/gl/GrGLSL.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/gl/GrGLProgram.cpp
===================================================================
--- src/gpu/gl/GrGLProgram.cpp (revision 8735)
+++ src/gpu/gl/GrGLProgram.cpp (working copy)
@@ -13,6 +13,7 @@
#include "GrGLEffect.h"
#include "GrGpuGL.h"
#include "GrGLShaderVar.h"
+#include "GrGLSL.h"
#include "SkTrace.h"
#include "SkXfermode.h"
@@ -112,7 +113,6 @@
}
namespace {
-
// given two blend coeffecients determine whether the src
// and/or dst computation can be omitted.
inline void need_blend_inputs(SkXfermode::Coeff srcCoeff,
@@ -211,12 +211,12 @@
blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor);
SkString sum;
- GrGLSLAdd4f(&sum, colorStr.c_str(), constStr.c_str());
+ GrGLSLAddf<4>(&sum, colorStr.c_str(), constStr.c_str());
builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str());
}
}
-void GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* inColor) {
+GrSLConstantVec GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* inColor) {
switch (fDesc.fColorInput) {
case GrGLProgramDesc::kAttribute_ColorInput: {
builder->addAttribute(kVec4f_GrSLType, COL_ATTR_NAME);
@@ -224,54 +224,57 @@
builder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName);
builder->vsCodeAppendf("\t%s = " COL_ATTR_NAME ";\n", vsName);
*inColor = fsName;
- } break;
+ return kNone_GrSLConstantVec;
+ }
case GrGLProgramDesc::kUniform_ColorInput: {
const char* name;
fUniformHandles.fColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
kVec4f_GrSLType, "Color", &name);
*inColor = name;
- break;
+ return kNone_GrSLConstantVec;
}
case GrGLProgramDesc::kTransBlack_ColorInput:
- GrAssert(!"needComputedColor should be false.");
- break;
+ inColor->reset();
+ return kZeros_GrSLConstantVec;
case GrGLProgramDesc::kSolidWhite_ColorInput:
- break;
+ inColor->reset();
+ return kOnes_GrSLConstantVec;
default:
GrCrash("Unknown color type.");
- break;
+ return kNone_GrSLConstantVec;
}
}
-void GrGLProgram::genUniformCoverage(GrGLShaderBuilder* builder, SkString* inOutCoverage) {
- const char* covUniName;
- fUniformHandles.fCoverageUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kVec4f_GrSLType, "Coverage", &covUniName);
- if (inOutCoverage->size()) {
- builder->fsCodeAppendf("\tvec4 uniCoverage = %s * %s;\n",
- covUniName, inOutCoverage->c_str());
- *inOutCoverage = "uniCoverage";
- } else {
- *inOutCoverage = covUniName;
+GrSLConstantVec GrGLProgram::genInputCoverage(GrGLShaderBuilder* builder, SkString* inCoverage) {
+ switch (fDesc.fCoverageInput) {
+ case GrGLProgramDesc::kAttribute_ColorInput: {
+ builder->addAttribute(kVec4f_GrSLType, COV_ATTR_NAME);
+ const char *vsName, *fsName;
+ builder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName);
+ builder->vsCodeAppendf("\t%s = " COV_ATTR_NAME ";\n", vsName);
+ *inCoverage = fsName;
+ return kNone_GrSLConstantVec;
+ }
+ case GrGLProgramDesc::kUniform_ColorInput: {
+ const char* name;
+ fUniformHandles.fCoverageUni =
+ builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kVec4f_GrSLType, "Coverage", &name);
+ *inCoverage = name;
+ return kNone_GrSLConstantVec;
+ }
+ case GrGLProgramDesc::kTransBlack_ColorInput:
+ inCoverage->reset();
+ return kZeros_GrSLConstantVec;
+ case GrGLProgramDesc::kSolidWhite_ColorInput:
+ inCoverage->reset();
+ return kOnes_GrSLConstantVec;
+ default:
+ GrCrash("Unknown color type.");
+ return kNone_GrSLConstantVec;
}
}
-namespace {
-void gen_attribute_coverage(GrGLShaderBuilder* builder,
- SkString* inOutCoverage) {
- builder->addAttribute(kVec4f_GrSLType, COV_ATTR_NAME);
- const char *vsName, *fsName;
- builder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName);
- builder->vsCodeAppendf("\t%s = " COV_ATTR_NAME ";\n", vsName);
- if (inOutCoverage->size()) {
- builder->fsCodeAppendf("\tvec4 attrCoverage = %s * %s;\n", fsName, inOutCoverage->c_str());
- *inOutCoverage = "attrCoverage";
- } else {
- *inOutCoverage = fsName;
- }
-}
-}
-
void GrGLProgram::genGeometryShader(GrGLShaderBuilder* builder) const {
#if GR_GL_EXPERIMENTAL_GS
// TODO: The builder should add all this glue code.
@@ -420,45 +423,6 @@
GrGLShaderBuilder builder(fContext.info(), fUniformManager, fDesc);
- SkXfermode::Coeff colorCoeff, uniformCoeff;
- // The rest of transfer mode color filters have not been implemented
- if (fDesc.fColorFilterXfermode < SkXfermode::kCoeffModesCnt) {
- GR_DEBUGCODE(bool success =)
- SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode>
- (fDesc.fColorFilterXfermode),
- &uniformCoeff, &colorCoeff);
- GR_DEBUGASSERT(success);
- } else {
- colorCoeff = SkXfermode::kOne_Coeff;
- uniformCoeff = SkXfermode::kZero_Coeff;
- }
-
- // no need to do the color filter if coverage is 0. The output color is scaled by the coverage.
- // All the dual source outputs are scaled by the coverage as well.
- if (GrGLProgramDesc::kTransBlack_ColorInput == fDesc.fCoverageInput) {
- colorCoeff = SkXfermode::kZero_Coeff;
- uniformCoeff = SkXfermode::kZero_Coeff;
- }
-
- // If we know the final color is going to be all zeros then we can
- // simplify the color filter coefficients. needComputedColor will then
- // come out false below.
- if (GrGLProgramDesc::kTransBlack_ColorInput == fDesc.fColorInput) {
- colorCoeff = SkXfermode::kZero_Coeff;
- if (SkXfermode::kDC_Coeff == uniformCoeff ||
- SkXfermode::kDA_Coeff == uniformCoeff) {
- uniformCoeff = SkXfermode::kZero_Coeff;
- } else if (SkXfermode::kIDC_Coeff == uniformCoeff ||
- SkXfermode::kIDA_Coeff == uniformCoeff) {
- uniformCoeff = SkXfermode::kOne_Coeff;
- }
- }
-
- bool needColorFilterUniform;
- bool needComputedColor;
- need_blend_inputs(uniformCoeff, colorCoeff,
- &needColorFilterUniform, &needComputedColor);
-
// the dual source output has no canonical var name, have to
// declare an output, which is incompatible with gl_FragColor/gl_FragData.
bool dualSourceOutputWritten = false;
@@ -482,11 +446,8 @@
// incoming color to current stage being processed.
SkString inColor;
+ GrSLConstantVec knownColorValue = this->genInputColor(&builder, &inColor);
- if (needComputedColor) {
- this->genInputColor(&builder, &inColor);
- }
-
// we output point size in the GS if present
if (fDesc.fEmitsPointSize
#if GR_GL_EXPERIMENTAL_GS
@@ -496,15 +457,29 @@
builder.vsCodeAppend("\tgl_PointSize = 1.0;\n");
}
- ///////////////////////////////////////////////////////////////////////////
- // compute the final color
+ // Get the coeffs for the Mode-based color filter, determine if color is needed.
+ SkXfermode::Coeff colorCoeff;
+ SkXfermode::Coeff filterColorCoeff;
+ SkAssertResult(
+ SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode>(fDesc.fColorFilterXfermode),
+ &filterColorCoeff,
+ &colorCoeff));
+ bool needColor, needFilterColor;
+ need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor);
- // if we have color stages string them together, feeding the output color
- // of each to the next and generating code for each stage.
- if (needComputedColor) {
+ if (needColor) {
+ ///////////////////////////////////////////////////////////////////////////
+ // compute the color
+ // if we have color stages string them together, feeding the output color
+ // of each to the next and generating code for each stage.
SkString outColor;
for (int s = 0; s < fDesc.fFirstCoverageStage; ++s) {
if (GrGLEffect::kNoEffectKey != fDesc.fEffectKeys[s]) {
+ if (kZeros_GrSLConstantVec == knownColorValue) {
+ // Effects have no way to communicate zeros, they treat an empty string as ones.
+ inColor = "initialColor";
+ builder.fsCodeAppendf("\tvec4 %s = %s;\n", inColor.c_str(), GrGLSLZerosVecf(4));
+ }
// create var to hold stage result
outColor = "color";
outColor.appendS32(s);
@@ -518,137 +493,132 @@
&fUniformHandles.fEffectSamplerUnis[s]);
builder.setNonStage();
inColor = outColor;
+ knownColorValue = kNone_GrSLConstantVec;
}
}
}
- // if have all ones or zeros for the "dst" input to the color filter then we
- // may be able to make additional optimizations.
- if (needColorFilterUniform && needComputedColor && !inColor.size()) {
- GrAssert(GrGLProgramDesc::kSolidWhite_ColorInput == fDesc.fColorInput);
- bool uniformCoeffIsZero = SkXfermode::kIDC_Coeff == uniformCoeff ||
- SkXfermode::kIDA_Coeff == uniformCoeff;
- if (uniformCoeffIsZero) {
- uniformCoeff = SkXfermode::kZero_Coeff;
- bool bogus;
- need_blend_inputs(SkXfermode::kZero_Coeff, colorCoeff,
- &needColorFilterUniform, &bogus);
- }
- }
- const char* colorFilterColorUniName = NULL;
- if (needColorFilterUniform) {
- fUniformHandles.fColorFilterUni = builder.addUniform(
- GrGLShaderBuilder::kFragment_ShaderType,
- kVec4f_GrSLType, "FilterColor",
- &colorFilterColorUniName);
- }
- bool wroteFragColorZero = false;
- if (SkXfermode::kZero_Coeff == uniformCoeff &&
- SkXfermode::kZero_Coeff == colorCoeff) {
- builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), GrGLSLZerosVecf(4));
- wroteFragColorZero = true;
- } else if (SkXfermode::kDst_Mode != fDesc.fColorFilterXfermode) {
+ // Insert the color filter. This will soon be replaced by a color effect.
+ if (SkXfermode::kDst_Mode != fDesc.fColorFilterXfermode) {
+ const char* colorFilterColorUniName = NULL;
+ fUniformHandles.fColorFilterUni = builder.addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kVec4f_GrSLType, "FilterColor",
+ &colorFilterColorUniName);
+
builder.fsCodeAppend("\tvec4 filteredColor;\n");
- const char* color = adjustInColor(inColor);
- add_color_filter(&builder, "filteredColor", uniformCoeff,
+ const char* color;
+ // add_color_filter requires a real input string.
+ if (knownColorValue == kOnes_GrSLConstantVec) {
+ color = GrGLSLOnesVecf(4);
+ } else if (knownColorValue == kZeros_GrSLConstantVec) {
+ color = GrGLSLZerosVecf(4);
+ } else {
+ color = inColor.c_str();
+ }
+ add_color_filter(&builder, "filteredColor", filterColorCoeff,
colorCoeff, colorFilterColorUniName, color);
inColor = "filteredColor";
}
///////////////////////////////////////////////////////////////////////////
- // compute the partial coverage (coverage stages and edge aa)
+ // compute the partial coverage
+ // incoming coverage to current stage being processed.
SkString inCoverage;
- bool coverageIsZero = GrGLProgramDesc::kTransBlack_ColorInput == fDesc.fCoverageInput;
- // we don't need to compute coverage at all if we know the final shader
- // output will be zero and we don't have a dual src blend output.
- if (!wroteFragColorZero || GrGLProgramDesc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) {
-
- if (!coverageIsZero) {
- switch (fDesc.fCoverageInput) {
- case GrGLProgramDesc::kSolidWhite_ColorInput:
- // empty string implies solid white
- break;
- case GrGLProgramDesc::kAttribute_ColorInput:
- gen_attribute_coverage(&builder, &inCoverage);
- break;
- case GrGLProgramDesc::kUniform_ColorInput:
- this->genUniformCoverage(&builder, &inCoverage);
- break;
- default:
- GrCrash("Unexpected input coverage.");
+ GrSLConstantVec knownCoverageValue = this->genInputCoverage(&builder, &inCoverage);
+
+ SkString outCoverage;
+ const int& startStage = fDesc.fFirstCoverageStage;
+ for (int s = startStage; s < GrDrawState::kNumStages; ++s) {
+ if (fDesc.fEffectKeys[s]) {
+ if (kZeros_GrSLConstantVec == knownCoverageValue) {
+ // Effects have no way to communicate zeros, they treat an empty string as ones.
+ inCoverage = "initialCoverage";
+ builder.fsCodeAppendf("\tvec4 %s = %s;\n", inCoverage.c_str(), GrGLSLZerosVecf(4));
}
+ // create var to hold stage output
+ outCoverage = "coverage";
+ outCoverage.appendS32(s);
+ builder.fsCodeAppendf("\tvec4 %s;\n", outCoverage.c_str());
- SkString outCoverage;
- const int& startStage = fDesc.fFirstCoverageStage;
- for (int s = startStage; s < GrDrawState::kNumStages; ++s) {
- if (fDesc.fEffectKeys[s]) {
- // create var to hold stage output
- outCoverage = "coverage";
- outCoverage.appendS32(s);
- builder.fsCodeAppendf("\tvec4 %s;\n", outCoverage.c_str());
+ builder.setCurrentStage(s);
+ fEffects[s] = builder.createAndEmitGLEffect(
+ *stages[s],
+ fDesc.fEffectKeys[s],
+ inCoverage.size() ? inCoverage.c_str() : NULL,
+ outCoverage.c_str(),
+ &fUniformHandles.fEffectSamplerUnis[s]);
+ builder.setNonStage();
+ inCoverage = outCoverage;
+ knownCoverageValue = kNone_GrSLConstantVec;
+ }
+ }
- builder.setCurrentStage(s);
- fEffects[s] = builder.createAndEmitGLEffect(
- *stages[s],
- fDesc.fEffectKeys[s],
- inCoverage.size() ? inCoverage.c_str() : NULL,
- outCoverage.c_str(),
- &fUniformHandles.fEffectSamplerUnis[s]);
- builder.setNonStage();
- inCoverage = outCoverage;
- }
- }
-
- // discard if coverage is zero
- if (fDesc.fDiscardIfZeroCoverage && !outCoverage.isEmpty()) {
- builder.fsCodeAppendf(
- "\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\t\tdiscard;\n\t}\n",
- outCoverage.c_str());
- }
+ // discard if coverage is zero
+ if (fDesc.fDiscardIfZeroCoverage && knownCoverageValue != kOnes_GrSLConstantVec) {
+ if (kZeros_GrSLConstantVec == knownCoverageValue) {
+ // This is unfortunate.
+ builder.fsCodeAppend("\tdiscard;\n");
+ } else {
+ builder.fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\t\tdiscard;\n\t}\n",
+ inCoverage.c_str());
}
+ }
- if (GrGLProgramDesc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) {
- builder.fFSOutputs.push_back().set(kVec4f_GrSLType,
- GrGLShaderVar::kOut_TypeModifier,
- dual_source_output_name());
- bool outputIsZero = coverageIsZero;
- SkString coeff;
- if (!outputIsZero &&
- GrGLProgramDesc::kCoverage_DualSrcOutput != fDesc.fDualSrcOutput && !wroteFragColorZero) {
- if (!inColor.size()) {
- outputIsZero = true;
- } else {
- if (GrGLProgramDesc::kCoverageISA_DualSrcOutput == fDesc.fDualSrcOutput) {
- coeff.printf("(1 - %s.a)", inColor.c_str());
- } else {
- coeff.printf("(vec4(1,1,1,1) - %s)", inColor.c_str());
- }
- }
- }
- if (outputIsZero) {
- builder.fsCodeAppendf("\t%s = %s;\n", dual_source_output_name(), GrGLSLZerosVecf(4));
- } else {
- SkString modulate;
- GrGLSLModulate4f(&modulate, coeff.c_str(), inCoverage.c_str());
- builder.fsCodeAppendf("\t%s = %s;\n", dual_source_output_name(), modulate.c_str());
- }
- dualSourceOutputWritten = true;
+ if (GrGLProgramDesc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) {
+ builder.fFSOutputs.push_back().set(kVec4f_GrSLType,
+ GrGLShaderVar::kOut_TypeModifier,
+ dual_source_output_name());
+ // default coeff to ones for kCoverage_DualSrcOutput
+ SkString coeff;
+ GrSLConstantVec knownCoeffValue = kOnes_GrSLConstantVec;
+ if (GrGLProgramDesc::kCoverageISA_DualSrcOutput == fDesc.fDualSrcOutput) {
+ // Get (1-A) into coeff
+ SkString inColorAlpha;
+ GrGLSLGetComponent4f(&inColorAlpha,
+ inColor.c_str(),
+ kA_GrColorComponentFlag,
+ knownColorValue,
+ true);
+ knownCoeffValue = GrGLSLSubtractf<1>(&coeff,
+ NULL,
+ inColorAlpha.c_str(),
+ kOnes_GrSLConstantVec,
+ knownColorValue,
+ true);
+ } else if (GrGLProgramDesc::kCoverageISC_DualSrcOutput == fDesc.fDualSrcOutput) {
+ // Get (1-RGBA) into coeff
+ knownCoeffValue = GrGLSLSubtractf<4>(&coeff,
+ NULL,
+ inColor.c_str(),
+ kOnes_GrSLConstantVec,
+ knownColorValue,
+ true);
}
+ // Get coeff * coverage into modulate and then write that to the dual source output.
+ SkString modulate;
+ GrGLSLModulatef<4>(&modulate,
+ coeff.c_str(),
+ inCoverage.c_str(),
+ knownCoeffValue,
+ knownCoverageValue,
+ false);
+ builder.fsCodeAppendf("\t%s = %s;\n", dual_source_output_name(), modulate.c_str());
+ dualSourceOutputWritten = true;
}
///////////////////////////////////////////////////////////////////////////
// combine color and coverage as frag color
- if (!wroteFragColorZero) {
- if (coverageIsZero) {
- builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), GrGLSLZerosVecf(4));
- } else {
- SkString modulate;
- GrGLSLModulate4f(&modulate, inColor.c_str(), inCoverage.c_str());
- builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), modulate.c_str());
- }
- }
+ // Get color * coverage into modulate and write that to frag shader's output.
+ SkString modulate;
+ GrGLSLModulatef<4>(&modulate,
+ inColor.c_str(),
+ inCoverage.c_str(),
+ knownColorValue,
+ knownCoverageValue,
+ false);
+ builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), modulate.c_str());
///////////////////////////////////////////////////////////////////////////
// insert GS
@@ -698,7 +668,7 @@
GL_CALL(BindFragDataLocation(fProgramID, 0, declared_color_output_name()));
}
if (bindDualSrcOut) {
- GL_CALL(BindFragDataLocationIndexed(fProgramID, 0, 1, dual_source_output_name()));
+ //GL_CALL(BindFragDataLocationIndexed(fProgramID, 0, 1, dual_source_output_name()));
}
// Bind the attrib locations to same values for all shaders
« no previous file with comments | « src/gpu/gl/GrGLProgram.h ('k') | src/gpu/gl/GrGLSL.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698