aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl
diff options
context:
space:
mode:
authorGravatar tomhudson@google.com <tomhudson@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-11 20:38:48 +0000
committerGravatar tomhudson@google.com <tomhudson@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-11 20:38:48 +0000
commitf9ad8867f2bcd8563862b0a5a90b473ad020d465 (patch)
treed047c590718df50a6203ed41dea40c37bfde9cef /src/gpu/gl
parent420f74fa720272b1164eae55d7b6c10e07d41601 (diff)
Extract ShaderCodeSegments from GrGLProgram into a new class,
GrGLShaderBuilder. Begin populating its interface. Requires gyp changes. http://codereview.appspot.com/6197076/ git-svn-id: http://skia.googlecode.com/svn/trunk@3916 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu/gl')
-rw-r--r--src/gpu/gl/GrGLProgram.cpp157
-rw-r--r--src/gpu/gl/GrGLProgram.h11
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp80
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.h58
4 files changed, 171 insertions, 135 deletions
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 27a0b12d3b..7ffb4d4da4 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -10,6 +10,7 @@
#include "GrAllocator.h"
#include "GrCustomStage.h"
#include "GrGLProgramStage.h"
+#include "gl/GrGLShaderBuilder.h"
#include "GrGLShaderVar.h"
#include "GrProgramStageFactory.h"
#include "SkTrace.h"
@@ -27,42 +28,6 @@ enum {
#define PRINT_SHADERS 0
-typedef GrTAllocator<GrGLShaderVar> VarArray;
-
-// number of each input/output type in a single allocation block
-static const int gVarsPerBlock = 8;
-// except FS outputs where we expect 2 at most.
-static const int gMaxFSOutputs = 2;
-
-struct ShaderCodeSegments {
- ShaderCodeSegments()
- : fVSUnis(gVarsPerBlock)
- , fVSAttrs(gVarsPerBlock)
- , fVSOutputs(gVarsPerBlock)
- , fGSInputs(gVarsPerBlock)
- , fGSOutputs(gVarsPerBlock)
- , fFSInputs(gVarsPerBlock)
- , fFSUnis(gVarsPerBlock)
- , fFSOutputs(gMaxFSOutputs)
- , fUsesGS(false) {}
- GrStringBuilder fHeader; // VS+FS, GLSL version, etc
- VarArray fVSUnis;
- VarArray fVSAttrs;
- VarArray fVSOutputs;
- VarArray fGSInputs;
- VarArray fGSOutputs;
- VarArray fFSInputs;
- GrStringBuilder fGSHeader; // layout qualifiers specific to GS
- VarArray fFSUnis;
- VarArray fFSOutputs;
- GrStringBuilder fFSFunctions;
- GrStringBuilder fVSCode;
- GrStringBuilder fGSCode;
- GrStringBuilder fFSCode;
-
- bool fUsesGS;
-};
-
typedef GrGLProgram::ProgramDesc::StageDesc StageDesc;
#if GR_GL_ATTRIBUTE_MATRICES
@@ -346,77 +311,14 @@ static void addColorMatrix(GrStringBuilder* fsCode, const char * outputVar,
fsCode->appendf("\t%s.rgb *= %s.a;\n", outputVar, outputVar);
}
-namespace {
-
-// Adds a var that is computed in the VS and read in FS.
-// If there is a GS it will just pass it through.
-void append_varying(GrSLType type,
- const char* name,
- ShaderCodeSegments* segments,
- const char** vsOutName = NULL,
- const char** fsInName = NULL) {
- segments->fVSOutputs.push_back();
- segments->fVSOutputs.back().setType(type);
- segments->fVSOutputs.back().setTypeModifier(
- GrGLShaderVar::kOut_TypeModifier);
- segments->fVSOutputs.back().accessName()->printf("v%s", name);
- if (vsOutName) {
- *vsOutName = segments->fVSOutputs.back().getName().c_str();
- }
- // input to FS comes either from VS or GS
- const GrStringBuilder* fsName;
- if (segments->fUsesGS) {
- // if we have a GS take each varying in as an array
- // and output as non-array.
- segments->fGSInputs.push_back();
- segments->fGSInputs.back().setType(type);
- segments->fGSInputs.back().setTypeModifier(
- GrGLShaderVar::kIn_TypeModifier);
- segments->fGSInputs.back().setUnsizedArray();
- *segments->fGSInputs.back().accessName() =
- segments->fVSOutputs.back().getName();
- segments->fGSOutputs.push_back();
- segments->fGSOutputs.back().setType(type);
- segments->fGSOutputs.back().setTypeModifier(
- GrGLShaderVar::kOut_TypeModifier);
- segments->fGSOutputs.back().accessName()->printf("g%s", name);
- fsName = segments->fGSOutputs.back().accessName();
- } else {
- fsName = segments->fVSOutputs.back().accessName();
- }
- segments->fFSInputs.push_back();
- segments->fFSInputs.back().setType(type);
- segments->fFSInputs.back().setTypeModifier(
- GrGLShaderVar::kIn_TypeModifier);
- segments->fFSInputs.back().setName(*fsName);
- if (fsInName) {
- *fsInName = fsName->c_str();
- }
-}
-
-// version of above that adds a stage number to the
-// the var name (for uniqueness)
-void append_varying(GrSLType type,
- const char* name,
- int stageNum,
- ShaderCodeSegments* segments,
- const char** vsOutName = NULL,
- const char** fsInName = NULL) {
- GrStringBuilder nameWithStage(name);
- nameWithStage.appendS32(stageNum);
- append_varying(type, nameWithStage.c_str(), segments, vsOutName, fsInName);
-}
-}
-
void GrGLProgram::genEdgeCoverage(const GrGLContextInfo& gl,
GrVertexLayout layout,
CachedData* programData,
GrStringBuilder* coverageVar,
- ShaderCodeSegments* segments) const {
+ GrGLShaderBuilder* segments) const {
if (layout & GrDrawTarget::kEdge_VertexLayoutBit) {
const char *vsName, *fsName;
- append_varying(kVec4f_GrSLType, "Edge", segments,
- &vsName, &fsName);
+ segments->appendVarying(kVec4f_GrSLType, "Edge", &vsName, &fsName);
segments->fVSAttrs.push_back().set(kVec4f_GrSLType,
GrGLShaderVar::kAttribute_TypeModifier, EDGE_ATTR_NAME);
segments->fVSCode.appendf("\t%s = " EDGE_ATTR_NAME ";\n", vsName);
@@ -478,7 +380,7 @@ namespace {
void genInputColor(GrGLProgram::ProgramDesc::ColorInput colorInput,
GrGLProgram::CachedData* programData,
- ShaderCodeSegments* segments,
+ GrGLShaderBuilder* segments,
GrStringBuilder* inColor) {
switch (colorInput) {
case GrGLProgram::ProgramDesc::kAttribute_ColorInput: {
@@ -486,7 +388,7 @@ void genInputColor(GrGLProgram::ProgramDesc::ColorInput colorInput,
GrGLShaderVar::kAttribute_TypeModifier,
COL_ATTR_NAME);
const char *vsName, *fsName;
- append_varying(kVec4f_GrSLType, "Color", segments, &vsName, &fsName);
+ segments->appendVarying(kVec4f_GrSLType, "Color", &vsName, &fsName);
segments->fVSCode.appendf("\t%s = " COL_ATTR_NAME ";\n", vsName);
*inColor = fsName;
} break;
@@ -508,14 +410,13 @@ void genInputColor(GrGLProgram::ProgramDesc::ColorInput colorInput,
}
}
-void genAttributeCoverage(ShaderCodeSegments* segments,
+void genAttributeCoverage(GrGLShaderBuilder* segments,
GrStringBuilder* inOutCoverage) {
segments->fVSAttrs.push_back().set(kVec4f_GrSLType,
GrGLShaderVar::kAttribute_TypeModifier,
COV_ATTR_NAME);
const char *vsName, *fsName;
- append_varying(kVec4f_GrSLType, "Coverage",
- segments, &vsName, &fsName);
+ segments->appendVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName);
segments->fVSCode.appendf("\t%s = " COV_ATTR_NAME ";\n", vsName);
if (inOutCoverage->size()) {
segments->fFSCode.appendf("\tvec4 attrCoverage = %s * %s;\n",
@@ -526,7 +427,7 @@ void genAttributeCoverage(ShaderCodeSegments* segments,
}
}
-void genUniformCoverage(ShaderCodeSegments* segments,
+void genUniformCoverage(GrGLShaderBuilder* segments,
GrGLProgram::CachedData* programData,
GrStringBuilder* inOutCoverage) {
segments->fFSUnis.push_back().set(kVec4f_GrSLType,
@@ -545,7 +446,7 @@ void genUniformCoverage(ShaderCodeSegments* segments,
}
void GrGLProgram::genGeometryShader(const GrGLContextInfo& gl,
- ShaderCodeSegments* segments) const {
+ GrGLShaderBuilder* segments) const {
#if GR_GL_EXPERIMENTAL_GS
if (fProgramDesc.fExperimentalGS) {
GrAssert(gl.glslGeneration() >= k150_GrGLSLGeneration);
@@ -596,7 +497,7 @@ GrGLProgram::CachedData::~CachedData() {
bool GrGLProgram::genProgram(const GrGLContextInfo& gl,
GrCustomStage** customStages,
GrGLProgram::CachedData* programData) const {
- ShaderCodeSegments segments;
+ GrGLShaderBuilder segments;
const uint32_t& layout = fProgramDesc.fVertexLayout;
programData->fUniLocations.reset();
@@ -1035,7 +936,7 @@ inline void append_decls(const VarArray& vars,
}
bool GrGLProgram::CompileShaders(const GrGLContextInfo& gl,
- const ShaderCodeSegments& segments,
+ const GrGLShaderBuilder& segments,
CachedData* programData) {
enum { kPreAllocStringCnt = 8 };
@@ -1383,7 +1284,7 @@ bool isRadialMapping(GrGLProgram::StageDesc::CoordMapping mapping) {
}
GrGLShaderVar* genRadialVS(int stageNum,
- ShaderCodeSegments* segments,
+ GrGLShaderBuilder* segments,
GrGLProgram::StageUniLocations* locations,
const char** radial2VaryingVSName,
const char** radial2VaryingFSName,
@@ -1403,12 +1304,11 @@ GrGLShaderVar* genRadialVS(int stageNum,
// part of the quadratic as a varying.
if (varyingDims == coordDims) {
GrAssert(2 == coordDims);
- append_varying(kFloat_GrSLType,
- "Radial2BCoeff",
- stageNum,
- segments,
- radial2VaryingVSName,
- radial2VaryingFSName);
+ segments->appendVarying(kFloat_GrSLType,
+ "Radial2BCoeff",
+ stageNum,
+ radial2VaryingVSName,
+ radial2VaryingFSName);
GrStringBuilder radial2p2;
GrStringBuilder radial2p3;
@@ -1426,7 +1326,7 @@ GrGLShaderVar* genRadialVS(int stageNum,
}
bool genRadial2GradientCoordMapping(int stageNum,
- ShaderCodeSegments* segments,
+ GrGLShaderBuilder* segments,
const char* radial2VaryingFSName,
GrGLShaderVar* radial2Params,
GrStringBuilder& sampleCoords,
@@ -1494,7 +1394,7 @@ bool genRadial2GradientCoordMapping(int stageNum,
}
bool genRadial2GradientDegenerateCoordMapping(int stageNum,
- ShaderCodeSegments* segments,
+ GrGLShaderBuilder* segments,
const char* radial2VaryingFSName,
GrGLShaderVar* radial2Params,
GrStringBuilder& sampleCoords,
@@ -1540,7 +1440,7 @@ bool genRadial2GradientDegenerateCoordMapping(int stageNum,
}
void gen2x2FS(int stageNum,
- ShaderCodeSegments* segments,
+ GrGLShaderBuilder* segments,
GrGLProgram::StageUniLocations* locations,
GrStringBuilder* sampleCoords,
const char* samplerName,
@@ -1574,7 +1474,7 @@ void gen2x2FS(int stageNum,
void genMorphologyVS(int stageNum,
const StageDesc& desc,
- ShaderCodeSegments* segments,
+ GrGLShaderBuilder* segments,
GrGLProgram::StageUniLocations* locations,
const char** imageIncrementName,
const char* varyingVSName) {
@@ -1596,7 +1496,7 @@ void genMorphologyVS(int stageNum,
void genMorphologyFS(int stageNum,
const StageDesc& desc,
- ShaderCodeSegments* segments,
+ GrGLShaderBuilder* segments,
const char* samplerName,
const char* swizzle,
const char* imageIncrementName,
@@ -1642,7 +1542,7 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
const char* fsInColor, // NULL means no incoming color
const char* fsOutColor,
const char* vsInCoord,
- ShaderCodeSegments* segments,
+ GrGLShaderBuilder* segments,
StageUniLocations* locations,
GrGLProgramStage* customStage) const {
@@ -1704,12 +1604,11 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
}
const char *varyingVSName, *varyingFSName;
- append_varying(GrSLFloatVectorType(varyingDims),
- "Stage",
- stageNum,
- segments,
- &varyingVSName,
- &varyingFSName);
+ segments->appendVarying(GrSLFloatVectorType(varyingDims),
+ "Stage",
+ stageNum,
+ &varyingVSName,
+ &varyingFSName);
if (!matName) {
GrAssert(varyingDims == coordDims);
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index eecdee7575..c4aebf66ac 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -19,8 +19,7 @@
class GrBinHashKeyBuilder;
class GrGLProgramStage;
-
-struct ShaderCodeSegments;
+class GrGLShaderBuilder;
// optionally compile the experimental GS code. Set to GR_DEBUG
// so that debug build bots will execute the code.
@@ -376,22 +375,22 @@ private:
const char* fsInColor, // NULL means no incoming color
const char* fsOutColor,
const char* vsInCoord,
- ShaderCodeSegments* segments,
+ GrGLShaderBuilder* segments,
StageUniLocations* locations,
GrGLProgramStage* override) const;
void genGeometryShader(const GrGLContextInfo& gl,
- ShaderCodeSegments* segments) const;
+ GrGLShaderBuilder* segments) const;
// generates code to compute coverage based on edge AA.
void genEdgeCoverage(const GrGLContextInfo& gl,
GrVertexLayout layout,
CachedData* programData,
GrStringBuilder* coverageVar,
- ShaderCodeSegments* segments) const;
+ GrGLShaderBuilder* segments) const;
static bool CompileShaders(const GrGLContextInfo& gl,
- const ShaderCodeSegments& segments,
+ const GrGLShaderBuilder& segments,
CachedData* programData);
// Compiles a GL shader, returns shader ID or 0 if failed
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
new file mode 100644
index 0000000000..77ae42536c
--- /dev/null
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gl/GrGLShaderBuilder.h"
+
+namespace {
+
+// number of each input/output type in a single allocation block
+static const int sVarsPerBlock = 8;
+
+// except FS outputs where we expect 2 at most.
+static const int sMaxFSOutputs = 2;
+
+}
+
+GrGLShaderBuilder::GrGLShaderBuilder()
+ : fVSUnis(sVarsPerBlock)
+ , fVSAttrs(sVarsPerBlock)
+ , fVSOutputs(sVarsPerBlock)
+ , fGSInputs(sVarsPerBlock)
+ , fGSOutputs(sVarsPerBlock)
+ , fFSInputs(sVarsPerBlock)
+ , fFSUnis(sVarsPerBlock)
+ , fFSOutputs(sMaxFSOutputs)
+ , fUsesGS(false) {
+
+}
+
+void GrGLShaderBuilder::appendVarying(GrSLType type,
+ const char* name,
+ const char** vsOutName,
+ const char** fsInName) {
+ fVSOutputs.push_back();
+ fVSOutputs.back().setType(type);
+ fVSOutputs.back().setTypeModifier(GrGLShaderVar::kOut_TypeModifier);
+ fVSOutputs.back().accessName()->printf("v%s", name);
+ if (vsOutName) {
+ *vsOutName = fVSOutputs.back().getName().c_str();
+ }
+ // input to FS comes either from VS or GS
+ const GrStringBuilder* fsName;
+ if (fUsesGS) {
+ // if we have a GS take each varying in as an array
+ // and output as non-array.
+ fGSInputs.push_back();
+ fGSInputs.back().setType(type);
+ fGSInputs.back().setTypeModifier(GrGLShaderVar::kIn_TypeModifier);
+ fGSInputs.back().setUnsizedArray();
+ *fGSInputs.back().accessName() = fVSOutputs.back().getName();
+ fGSOutputs.push_back();
+ fGSOutputs.back().setType(type);
+ fGSOutputs.back().setTypeModifier(GrGLShaderVar::kOut_TypeModifier);
+ fGSOutputs.back().accessName()->printf("g%s", name);
+ fsName = fGSOutputs.back().accessName();
+ } else {
+ fsName = fVSOutputs.back().accessName();
+ }
+ fFSInputs.push_back();
+ fFSInputs.back().setType(type);
+ fFSInputs.back().setTypeModifier(GrGLShaderVar::kIn_TypeModifier);
+ fFSInputs.back().setName(*fsName);
+ if (fsInName) {
+ *fsInName = fsName->c_str();
+ }
+}
+
+
+void GrGLShaderBuilder::appendVarying(GrSLType type,
+ const char* name,
+ int stageNum,
+ const char** vsOutName,
+ const char** fsInName) {
+ GrStringBuilder nameWithStage(name);
+ nameWithStage.appendS32(stageNum);
+ this->appendVarying(type, nameWithStage.c_str(), vsOutName, fsInName);
+}
diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h
new file mode 100644
index 0000000000..1f4c41fd65
--- /dev/null
+++ b/src/gpu/gl/GrGLShaderBuilder.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLShaderBuilder_DEFINED
+#define GrGLShaderBuilder_DEFINED
+
+#include "GrAllocator.h"
+#include "gl/GrGLShaderVar.h"
+#include "gl/GrGLSL.h"
+
+typedef GrTAllocator<GrGLShaderVar> VarArray;
+
+/**
+ Containts all the incremental state of a shader as it is being built,
+ as well as helpers to manipulate that state.
+ TODO: migrate CompileShaders() here?
+*/
+
+class GrGLShaderBuilder {
+
+public:
+
+ GrGLShaderBuilder();
+
+ void appendVarying(GrSLType type,
+ const char* name,
+ const char** vsOutName = NULL,
+ const char** fsInName = NULL);
+
+ void appendVarying(GrSLType type,
+ const char* name,
+ int stageNum,
+ const char** vsOutName = NULL,
+ const char** fsInName = NULL);
+
+ GrStringBuilder fHeader; // VS+FS, GLSL version, etc
+ VarArray fVSUnis;
+ VarArray fVSAttrs;
+ VarArray fVSOutputs;
+ VarArray fGSInputs;
+ VarArray fGSOutputs;
+ VarArray fFSInputs;
+ GrStringBuilder fGSHeader; // layout qualifiers specific to GS
+ VarArray fFSUnis;
+ VarArray fFSOutputs;
+ GrStringBuilder fFSFunctions;
+ GrStringBuilder fVSCode;
+ GrStringBuilder fGSCode;
+ GrStringBuilder fFSCode;
+
+ bool fUsesGS;
+};
+
+#endif