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

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

Issue 23533066: Move the GL shader compilation step into GrGLShaderBuilder (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 3 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/GrGLShaderBuilder.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/gl/GrGLShaderBuilder.cpp
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
index d11394a7b39371608b1ce113cbc7b8d1a49a4e78..f4ffb4dd2ce2f071743c9c3d08b3edb7abaa4d56 100644
--- a/src/gpu/gl/GrGLShaderBuilder.cpp
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -9,7 +9,13 @@
#include "gl/GrGLProgram.h"
#include "gl/GrGLUniformHandle.h"
#include "GrDrawEffect.h"
+#include "GrGpuGL.h"
#include "GrTexture.h"
+#include "SkRTConf.h"
+#include "SkTrace.h"
+
+#define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X)
+#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X)
// number of each input/output type in a single allocation block
static const int kVarsPerBlock = 8;
@@ -21,10 +27,18 @@ static const int kMaxFSOutputs = 2;
static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar::kMedium_Precision;
typedef GrGLUniformManager::UniformHandle UniformHandle;
+
+SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false,
+ "Print the source code for all shaders generated.");
+
///////////////////////////////////////////////////////////////////////////////
namespace {
+inline const char* color_attribute_name() { return "aColor"; }
+inline const char* coverage_attribute_name() { return "aCoverage"; }
+inline const char* declared_color_output_name() { return "fsColorOut"; }
+inline const char* dual_source_output_name() { return "dualSourceOut"; }
inline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen) {
if (kVec2f_GrSLType == type) {
return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D";
@@ -91,28 +105,32 @@ static const char kDstCopyColorName[] = "_dstColor";
///////////////////////////////////////////////////////////////////////////////
-GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo,
+GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu,
GrGLUniformManager& uniformManager,
const GrGLProgramDesc& desc,
bool needsVertexShader)
: fUniforms(kVarsPerBlock)
- , fCtxInfo(ctxInfo)
+ , fGpu(gpu)
, fUniformManager(uniformManager)
, fFSFeaturesAddedMask(0)
, fFSInputs(kVarsPerBlock)
, fFSOutputs(kMaxFSOutputs)
, fSetupFragPosition(false)
+ , fKnownColorValue(kNone_GrSLConstantVec)
+ , fKnownCoverageValue(kNone_GrSLConstantVec)
+ , fHasCustomColorOutput(false)
+ , fHasSecondaryOutput(false)
, fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey) {
const GrGLProgramDesc::KeyHeader& header = desc.getHeader();
if (needsVertexShader) {
- fVertexBuilder.reset(SkNEW_ARGS(VertexBuilder, (this, desc)));
+ fVertexBuilder.reset(SkNEW_ARGS(VertexBuilder, (this, fGpu, desc)));
}
// Emit code to read the dst copy textue if necessary.
if (kNoDstRead_DstReadKey != header.fDstReadKey &&
- GrGLCaps::kNone_FBFetchType == ctxInfo.caps()->fbFetchType()) {
+ GrGLCaps::kNone_FBFetchType == fGpu->glCaps().fbFetchType()) {
bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKey);
const char* dstCopyTopLeftName;
const char* dstCopyCoordScaleName;
@@ -143,15 +161,76 @@ GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo,
this->fsAppendTextureLookup(fDstCopySampler, "_dstTexCoord");
this->fsCodeAppend(";\n\n");
}
+
+ switch (header.fColorInput) {
+ case GrGLProgramDesc::kAttribute_ColorInput: {
+ SkASSERT(NULL != fVertexBuilder.get());
+ fVertexBuilder->addAttribute(kVec4f_GrSLType, color_attribute_name());
+ const char *vsName, *fsName;
+ fVertexBuilder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName);
+ fVertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsName, color_attribute_name());
+ fInputColor = fsName;
+ break;
+ }
+ case GrGLProgramDesc::kUniform_ColorInput: {
+ const char* name;
+ fColorUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ kVec4f_GrSLType, "Color", &name);
+ fInputColor = name;
+ break;
+ }
+ case GrGLProgramDesc::kTransBlack_ColorInput:
+ fKnownColorValue = kZeros_GrSLConstantVec;
+ break;
+ case GrGLProgramDesc::kSolidWhite_ColorInput:
+ fKnownColorValue = kOnes_GrSLConstantVec;
+ break;
+ default:
+ GrCrash("Unknown color type.");
+ }
+
+ switch (header.fCoverageInput) {
+ case GrGLProgramDesc::kAttribute_ColorInput: {
+ SkASSERT(NULL != fVertexBuilder.get());
+ fVertexBuilder->addAttribute(kVec4f_GrSLType, coverage_attribute_name());
+ const char *vsName, *fsName;
+ fVertexBuilder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName);
+ fVertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsName, coverage_attribute_name());
+ fInputCoverage = fsName;
+ break;
+ }
+ case GrGLProgramDesc::kUniform_ColorInput: {
+ const char* name;
+ fCoverageUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ kVec4f_GrSLType, "Coverage", &name);
+ fInputCoverage = name;
+ break;
+ }
+ case GrGLProgramDesc::kTransBlack_ColorInput:
+ fKnownCoverageValue = kZeros_GrSLConstantVec;
+ break;
+ case GrGLProgramDesc::kSolidWhite_ColorInput:
+ fKnownCoverageValue = kOnes_GrSLConstantVec;
+ break;
+ default:
+ GrCrash("Unknown coverage type.");
+ }
+
+ if (k110_GrGLSLGeneration != fGpu->glslGeneration()) {
+ fFSOutputs.push_back().set(kVec4f_GrSLType,
+ GrGLShaderVar::kOut_TypeModifier,
+ declared_color_output_name());
+ fHasCustomColorOutput = true;
+ }
}
bool GrGLShaderBuilder::enableFeature(GLSLFeature feature) {
switch (feature) {
case kStandardDerivatives_GLSLFeature:
- if (!fCtxInfo.caps()->shaderDerivativeSupport()) {
+ if (!fGpu->glCaps().shaderDerivativeSupport()) {
return false;
}
- if (kES_GrGLBinding == fCtxInfo.binding()) {
+ if (kES_GrGLBinding == fGpu->glBinding()) {
this->addFSFeature(1 << kStandardDerivatives_GLSLFeature,
"GL_OES_standard_derivatives");
}
@@ -165,23 +244,23 @@ bool GrGLShaderBuilder::enableFeature(GLSLFeature feature) {
bool GrGLShaderBuilder::enablePrivateFeature(GLSLPrivateFeature feature) {
switch (feature) {
case kFragCoordConventions_GLSLPrivateFeature:
- if (!fCtxInfo.caps()->fragCoordConventionsSupport()) {
+ if (!fGpu->glCaps().fragCoordConventionsSupport()) {
return false;
}
- if (fCtxInfo.glslGeneration() < k150_GrGLSLGeneration) {
+ if (fGpu->glslGeneration() < k150_GrGLSLGeneration) {
this->addFSFeature(1 << kFragCoordConventions_GLSLPrivateFeature,
"GL_ARB_fragment_coord_conventions");
}
return true;
case kEXTShaderFramebufferFetch_GLSLPrivateFeature:
- if (GrGLCaps::kEXT_FBFetchType != fCtxInfo.caps()->fbFetchType()) {
+ if (GrGLCaps::kEXT_FBFetchType != fGpu->glCaps().fbFetchType()) {
return false;
}
this->addFSFeature(1 << kEXTShaderFramebufferFetch_GLSLPrivateFeature,
"GL_EXT_shader_framebuffer_fetch");
return true;
case kNVShaderFramebufferFetch_GLSLPrivateFeature:
- if (GrGLCaps::kNV_FBFetchType != fCtxInfo.caps()->fbFetchType()) {
+ if (GrGLCaps::kNV_FBFetchType != fGpu->glCaps().fbFetchType()) {
return false;
}
this->addFSFeature(1 << kNVShaderFramebufferFetch_GLSLPrivateFeature,
@@ -225,7 +304,7 @@ const char* GrGLShaderBuilder::dstColor() {
}
}
static const char kFBFetchColorName[] = "gl_LastFragData[0]";
- GrGLCaps::FBFetchType fetchType = fCtxInfo.caps()->fbFetchType();
+ GrGLCaps::FBFetchType fetchType = fGpu->glCaps().fbFetchType();
if (GrGLCaps::kEXT_FBFetchType == fetchType) {
SkAssertResult(this->enablePrivateFeature(kEXTShaderFramebufferFetch_GLSLPrivateFeature));
return kFBFetchColorName;
@@ -246,10 +325,10 @@ void GrGLShaderBuilder::appendTextureLookup(SkString* out,
SkASSERT(NULL != coordName);
out->appendf("%s(%s, %s)",
- sample_function_name(varyingType, fCtxInfo.glslGeneration()),
+ sample_function_name(varyingType, fGpu->glslGeneration()),
this->getUniformCStr(sampler.fSamplerUniform),
coordName);
- append_swizzle(out, sampler, *fCtxInfo.caps());
+ append_swizzle(out, sampler, fGpu->glCaps());
}
void GrGLShaderBuilder::fsAppendTextureLookup(const GrGLShaderBuilder::TextureSampler& sampler,
@@ -379,7 +458,7 @@ const char* GrGLShaderBuilder::fragmentPosition() {
fSetupFragPosition = true;
}
return "gl_FragCoord";
- } else if (fCtxInfo.caps()->fragCoordConventionsSupport()) {
+ } else if (fGpu->glCaps().fragCoordConventionsSupport()) {
if (!fSetupFragPosition) {
SkAssertResult(this->enablePrivateFeature(kFragCoordConventions_GLSLPrivateFeature));
fFSInputs.push_back().set(kVec4f_GrSLType,
@@ -425,7 +504,7 @@ void GrGLShaderBuilder::fsEmitFunction(GrSLType returnType,
fFSFunctions.appendf(" %s", outName->c_str());
fFSFunctions.append("(");
for (int i = 0; i < argCnt; ++i) {
- args[i].appendDecl(fCtxInfo, &fFSFunctions);
+ args[i].appendDecl(this->ctxInfo(), &fFSFunctions);
if (i < argCnt - 1) {
fFSFunctions.append(", ");
}
@@ -463,7 +542,7 @@ inline void append_default_precision_qualifier(GrGLShaderVar::Precision p,
void GrGLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const {
for (int i = 0; i < vars.count(); ++i) {
- vars[i].appendDecl(fCtxInfo, out);
+ vars[i].appendDecl(this->ctxInfo(), out);
out->append(";\n");
}
}
@@ -472,33 +551,12 @@ void GrGLShaderBuilder::appendUniformDecls(ShaderVisibility visibility,
SkString* out) const {
for (int i = 0; i < fUniforms.count(); ++i) {
if (fUniforms[i].fVisibility & visibility) {
- fUniforms[i].fVariable.appendDecl(fCtxInfo, out);
+ fUniforms[i].fVariable.appendDecl(this->ctxInfo(), out);
out->append(";\n");
}
}
}
-void GrGLShaderBuilder::fsGetShader(SkString* shaderStr) const {
- *shaderStr = GrGetGLSLVersionDecl(fCtxInfo);
- shaderStr->append(fFSExtensions);
- append_default_precision_qualifier(kDefaultFragmentPrecision,
- fCtxInfo.binding(),
- shaderStr);
- this->appendUniformDecls(kFragment_Visibility, shaderStr);
- this->appendDecls(fFSInputs, shaderStr);
- // We shouldn't have declared outputs on 1.10
- SkASSERT(k110_GrGLSLGeneration != fCtxInfo.glslGeneration() || fFSOutputs.empty());
- this->appendDecls(fFSOutputs, shaderStr);
- shaderStr->append(fFSFunctions);
- shaderStr->append("void main() {\n");
- shaderStr->append(fFSCode);
- shaderStr->append("}\n");
-}
-
-void GrGLShaderBuilder::finished(GrGLuint programID) {
- fUniformManager.getUniformLocations(programID, fUniforms);
-}
-
void GrGLShaderBuilder::emitEffects(
const GrEffectStage* effectStages[],
const GrBackendEffectFactory::EffectKey effectKeys[],
@@ -526,7 +584,7 @@ void GrGLShaderBuilder::emitEffects(
textureSamplers[t].init(this, &effect->textureAccess(t), t);
effectSamplerHandles[e]->push_back(textureSamplers[t].fSamplerUniform);
}
- GrDrawEffect drawEffect(stage, fVertexBuilder.get()
+ GrDrawEffect drawEffect(stage, NULL != fVertexBuilder.get()
&& fVertexBuilder->hasExplicitLocalCoords());
int numAttributes = stage.getVertexAttribIndexCount();
@@ -534,7 +592,7 @@ void GrGLShaderBuilder::emitEffects(
SkSTArray<GrEffect::kMaxVertexAttribs, SkString> attributeNames;
for (int a = 0; a < numAttributes; ++a) {
// TODO: Make addAttribute mangle the name.
- SkASSERT(fVertexBuilder.get());
+ SkASSERT(NULL != fVertexBuilder.get());
SkString attributeName("aAttr");
attributeName.appendS32(attributeIndices[a]);
fVertexBuilder->addEffectAttribute(attributeIndices[a],
@@ -557,7 +615,7 @@ void GrGLShaderBuilder::emitEffects(
// Enclose custom code in a block to avoid namespace conflicts
SkString openBrace;
openBrace.printf("\t{ // Stage %d: %s\n", fCodeStage.stageIndex(), glEffects[e]->name());
- if (fVertexBuilder.get()) {
+ if (NULL != fVertexBuilder.get()) {
fVertexBuilder->vsCodeAppend(openBrace.c_str());
}
this->fsCodeAppend(openBrace.c_str());
@@ -569,7 +627,7 @@ void GrGLShaderBuilder::emitEffects(
inColor.isEmpty() ? NULL : inColor.c_str(),
textureSamplers);
- if (fVertexBuilder.get()) {
+ if (NULL != fVertexBuilder.get()) {
fVertexBuilder->vsCodeAppend("\t}\n");
}
this->fsCodeAppend("\t}\n");
@@ -584,22 +642,170 @@ void GrGLShaderBuilder::emitEffects(
}
}
+const char* GrGLShaderBuilder::getColorOutputName() const {
+ return fHasCustomColorOutput ? declared_color_output_name() : "gl_FragColor";
+}
+
+const char* GrGLShaderBuilder::enableSecondaryOutput() {
+ if (!fHasSecondaryOutput) {
+ fFSOutputs.push_back().set(kVec4f_GrSLType,
+ GrGLShaderVar::kOut_TypeModifier,
+ dual_source_output_name());
+ fHasSecondaryOutput = true;
+ }
+ return dual_source_output_name();
+}
+
+
+bool GrGLShaderBuilder::finish(GrGLuint* outProgramId) {
+ SK_TRACE_EVENT0("GrGLShaderBuilder::finish");
+
+ GrGLuint programId = 0;
+ GL_CALL_RET(programId, CreateProgram());
+ if (!programId) {
+ return false;
+ }
+
+ if (!this->compileAndAttachShaders(programId)) {
+ GL_CALL(DeleteProgram(programId));
+ return false;
+ }
+
+ this->bindProgramLocations(programId);
+
+ GL_CALL(LinkProgram(programId));
+ GrGLint linked = GR_GL_INIT_ZERO;
+ GL_CALL(GetProgramiv(programId, GR_GL_LINK_STATUS, &linked));
+ if (!linked) {
+ GrGLint infoLen = GR_GL_INIT_ZERO;
+ GL_CALL(GetProgramiv(programId, GR_GL_INFO_LOG_LENGTH, &infoLen));
+ SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
+ if (infoLen > 0) {
+ // retrieve length even though we don't need it to workaround
+ // bug in chrome cmd buffer param validation.
+ GrGLsizei length = GR_GL_INIT_ZERO;
+ GL_CALL(GetProgramInfoLog(programId,
+ infoLen+1,
+ &length,
+ (char*)log.get()));
+ GrPrintf((char*)log.get());
+ }
+ SkDEBUGFAIL("Error linking program");
+ GL_CALL(DeleteProgram(programId));
+ return false;
+ }
+
+ fUniformManager.getUniformLocations(programId, fUniforms);
+ *outProgramId = programId;
+ return true;
+}
+
+namespace {
+// Compiles a GL shader, attaches it to a program, and releases the shader's reference.
+// (That way there's no need to hang on to the GL shader id and delete it later.)
+bool attach_shader(const GrGLInterface* gli,
+ GrGLuint programId,
+ GrGLenum type,
+ const SkString& shaderSrc) {
+ GrGLuint shaderId;
+ GR_GL_CALL_RET(gli, shaderId, CreateShader(type));
+ if (0 == shaderId) {
+ return false;
+ }
+
+ const GrGLchar* sourceStr = shaderSrc.c_str();
+ int sourceLength = shaderSrc.size();
+ GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength));
+
+ GrGLint compiled = GR_GL_INIT_ZERO;
+ GR_GL_CALL(gli, CompileShader(shaderId));
+ GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled));
+
+ if (!compiled) {
+ GrGLint infoLen = GR_GL_INIT_ZERO;
+ GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLen));
+ SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
+ if (infoLen > 0) {
+ // retrieve length even though we don't need it to workaround bug in chrome cmd buffer
+ // param validation.
+ GrGLsizei length = GR_GL_INIT_ZERO;
+ GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1,
+ &length, (char*)log.get()));
+ GrPrintf(shaderSrc.c_str());
+ GrPrintf("\n%s", log.get());
+ }
+ SkDEBUGFAIL("Shader compilation failed!");
+ GR_GL_CALL(gli, DeleteShader(shaderId));
+ return false;
+ } else if (c_PrintShaders) {
+ GrPrintf(shaderSrc.c_str());
+ GrPrintf("\n");
+ }
+
+ GR_GL_CALL(gli, AttachShader(programId, shaderId));
+ GR_GL_CALL(gli, DeleteShader(shaderId));
+ return true;
+}
+
+}
+
+bool GrGLShaderBuilder::compileAndAttachShaders(GrGLuint programId) const {
+ if (NULL != fVertexBuilder.get() && !fVertexBuilder->compileAndAttachShaders(programId)) {
+ return false;
+ }
+
+ SkString fragShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo()));
+ fragShaderSrc.append(fFSExtensions);
+ append_default_precision_qualifier(kDefaultFragmentPrecision,
+ fGpu->glBinding(),
+ &fragShaderSrc);
+ this->appendUniformDecls(kFragment_Visibility, &fragShaderSrc);
+ this->appendDecls(fFSInputs, &fragShaderSrc);
+ // We shouldn't have declared outputs on 1.10
+ SkASSERT(k110_GrGLSLGeneration != fGpu->glslGeneration() || fFSOutputs.empty());
+ this->appendDecls(fFSOutputs, &fragShaderSrc);
+ fragShaderSrc.append(fFSFunctions);
+ fragShaderSrc.append("void main() {\n");
+ fragShaderSrc.append(fFSCode);
+ fragShaderSrc.append("}\n");
+ if (!attach_shader(fGpu->glInterface(), programId, GR_GL_FRAGMENT_SHADER, fragShaderSrc)) {
+ return false;
+ }
+
+ return true;
+}
+
+void GrGLShaderBuilder::bindProgramLocations(GrGLuint programId) const {
+ if (NULL != fVertexBuilder.get()) {
+ fVertexBuilder->bindProgramLocations(programId);
+ }
+
+ if (fHasCustomColorOutput) {
+ GL_CALL(BindFragDataLocation(programId, 0, declared_color_output_name()));
+ }
+ if (fHasSecondaryOutput) {
+ GL_CALL(BindFragDataLocationIndexed(programId, 0, 1, dual_source_output_name()));
+ }
+}
+
+const GrGLContextInfo& GrGLShaderBuilder::ctxInfo() const {
+ return fGpu->ctxInfo();
+}
+
////////////////////////////////////////////////////////////////////////////
GrGLShaderBuilder::VertexBuilder::VertexBuilder(GrGLShaderBuilder* parent,
+ GrGpuGL* gpu,
const GrGLProgramDesc& desc)
- : fVSAttrs(kVarsPerBlock)
+ : fParent(parent)
+ , fGpu(gpu)
+ , fDesc(desc)
+ , fVSAttrs(kVarsPerBlock)
, fVSOutputs(kVarsPerBlock)
, fGSInputs(kVarsPerBlock)
- , fGSOutputs(kVarsPerBlock)
- , fParent(parent)
-#if GR_GL_EXPERIMENTAL_GS
- , fUsesGS(SkToBool(desc.getHeader().fExperimentalGS))
-#else
- , fUsesGS(false)
-#endif
-{
- const GrGLProgramDesc::KeyHeader& header = desc.getHeader();
+ , fGSOutputs(kVarsPerBlock) {
+
+ const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
fPositionVar = &fVSAttrs.push_back();
fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition");
@@ -611,6 +817,23 @@ GrGLShaderBuilder::VertexBuilder::VertexBuilder(GrGLShaderBuilder* parent,
} else {
fLocalCoordsVar = fPositionVar;
}
+
+ const char* viewMName;
+ fViewMatrixUniform = fParent->addUniform(GrGLShaderBuilder::kVertex_Visibility,
+ kMat33f_GrSLType, "ViewM", &viewMName);
+
+ this->vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n"
+ "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n",
+ viewMName, fPositionVar->c_str());
+
+ // we output point size in the GS if present
+ if (header.fEmitsPointSize
+#if GR_GL_EXPERIMENTAL_GS
+ && !header.fExperimentalGS
+#endif
+ ) {
+ this->vsCodeAppend("\tgl_PointSize = 1.0;\n");
+ }
}
bool GrGLShaderBuilder::VertexBuilder::addAttribute(GrSLType type,
@@ -654,7 +877,8 @@ void GrGLShaderBuilder::VertexBuilder::addVarying(GrSLType type,
}
// input to FS comes either from VS or GS
const SkString* fsName;
- if (fUsesGS) {
+#if GR_GL_EXPERIMENTAL_GS
+ if (fDesc.getHeader().fExperimentalGS) {
// if we have a GS take each varying in as an array
// and output as non-array.
fGSInputs.push_back();
@@ -667,7 +891,9 @@ void GrGLShaderBuilder::VertexBuilder::addVarying(GrSLType type,
fGSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
fParent->nameVariable(fGSOutputs.back().accessName(), 'g', name);
fsName = fGSOutputs.back().accessName();
- } else {
+ } else
+#endif
+ {
fsName = fVSOutputs.back().accessName();
}
fParent->fsInputAppend().set(type,
@@ -678,41 +904,88 @@ void GrGLShaderBuilder::VertexBuilder::addVarying(GrSLType type,
}
}
-void GrGLShaderBuilder::VertexBuilder::vsGetShader(SkString* shaderStr) const {
- *shaderStr = GrGetGLSLVersionDecl(fParent->ctxInfo());
- fParent->appendUniformDecls(kVertex_Visibility, shaderStr);
- fParent->appendDecls(fVSAttrs, shaderStr);
- fParent->appendDecls(fVSOutputs, shaderStr);
- shaderStr->append("void main() {\n");
- shaderStr->append(fVSCode);
- shaderStr->append("}\n");
+const SkString* GrGLShaderBuilder::VertexBuilder::getEffectAttributeName(int attributeIndex) const {
+ const AttributePair* attribEnd = fEffectAttributes.end();
+ for (const AttributePair* attrib = fEffectAttributes.begin(); attrib != attribEnd; ++attrib) {
+ if (attrib->fIndex == attributeIndex) {
+ return &attrib->fName;
+ }
+ }
+
+ return NULL;
}
-void GrGLShaderBuilder::VertexBuilder::gsGetShader(SkString* shaderStr) const {
- if (!fUsesGS) {
- shaderStr->reset();
- return;
+bool GrGLShaderBuilder::VertexBuilder::compileAndAttachShaders(GrGLuint programId) const {
+ SkString vertShaderSrc(GrGetGLSLVersionDecl(fParent->ctxInfo()));
+ fParent->appendUniformDecls(kVertex_Visibility, &vertShaderSrc);
+ fParent->appendDecls(fVSAttrs, &vertShaderSrc);
+ fParent->appendDecls(fVSOutputs, &vertShaderSrc);
+ vertShaderSrc.append("void main() {\n");
+ vertShaderSrc.append(fVSCode);
+ vertShaderSrc.append("}\n");
+ if (!attach_shader(fGpu->glInterface(), programId, GR_GL_VERTEX_SHADER, vertShaderSrc)) {
+ return false;
}
- *shaderStr = GrGetGLSLVersionDecl(fParent->ctxInfo());
- shaderStr->append(fGSHeader);
- fParent->appendDecls(fGSInputs, shaderStr);
- fParent->appendDecls(fGSOutputs, shaderStr);
- shaderStr->append("void main() {\n");
- shaderStr->append(fGSCode);
- shaderStr->append("}\n");
+#if GR_GL_EXPERIMENTAL_GS
+ if (fDesc.getHeader().fExperimentalGS) {
+ SkASSERT(fGpu->glslGeneration() >= k150_GrGLSLGeneration);
+ SkString geomShaderSrc(GrGetGLSLVersionDecl(fParent->ctxInfo()));
+ geomShaderSrc.append("layout(triangles) in;\n"
+ "layout(triangle_strip, max_vertices = 6) out;\n");
+ fParent->appendDecls(fGSInputs, &geomShaderSrc);
+ fParent->appendDecls(fGSOutputs, &geomShaderSrc);
+ 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) {
+ geomShaderSrc.append("\t\tgl_PointSize = 1.0;\n");
+ }
+ SkASSERT(fGSInputs.count() == fGSOutputs.count());
+ for (int i = 0; i < fGSInputs.count(); ++i) {
+ geomShaderSrc.appendf("\t\t%s = %s[i];\n",
+ fGSOutputs[i].getName().c_str(),
+ fGSInputs[i].getName().c_str());
+ }
+ geomShaderSrc.append("\t\tEmitVertex();\n"
+ "\t}\n"
+ "\tEndPrimitive();\n");
+ geomShaderSrc.append("}\n");
+ if (!attach_shader(fGpu->glInterface(), programId, GR_GL_GEOMETRY_SHADER, geomShaderSrc)) {
+ return false;
+ }
+ }
+#endif
+
+ return true;
}
+void GrGLShaderBuilder::VertexBuilder::bindProgramLocations(GrGLuint programId) const {
+ const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
-const SkString* GrGLShaderBuilder::VertexBuilder::getEffectAttributeName(int attributeIndex) const {
- const AttributePair* attribEnd = this->getEffectAttributes().end();
- for (const AttributePair* attrib = this->getEffectAttributes().begin();
- attrib != attribEnd;
- ++attrib) {
- if (attrib->fIndex == attributeIndex) {
- return &attrib->fName;
- }
+ // Bind the attrib locations to same values for all shaders
+ SkASSERT(-1 != header.fPositionAttributeIndex);
+ GL_CALL(BindAttribLocation(programId,
+ header.fPositionAttributeIndex,
+ fPositionVar->c_str()));
+ if (-1 != header.fLocalCoordAttributeIndex) {
+ GL_CALL(BindAttribLocation(programId,
+ header.fLocalCoordAttributeIndex,
+ fLocalCoordsVar->c_str()));
+ }
+ if (-1 != header.fColorAttributeIndex) {
+ GL_CALL(BindAttribLocation(programId,
+ header.fColorAttributeIndex,
+ color_attribute_name()));
+ }
+ if (-1 != header.fCoverageAttributeIndex) {
+ GL_CALL(BindAttribLocation(programId,
+ header.fCoverageAttributeIndex,
+ coverage_attribute_name()));
}
- return NULL;
+ const AttributePair* attribEnd = fEffectAttributes.end();
+ for (const AttributePair* attrib = fEffectAttributes.begin(); attrib != attribEnd; ++attrib) {
+ GL_CALL(BindAttribLocation(programId, attrib->fIndex, attrib->fName.c_str()));
+ }
}
« no previous file with comments | « src/gpu/gl/GrGLShaderBuilder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698