aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-02-10 15:56:06 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-02-10 15:56:06 +0000
commite55fd0f188a2b0b137ddfd9728da58481e2309ef (patch)
treeb3dc09e6ad3fe234e9a7d1d9e40f73b705f98118 /src
parent368b4192001ccb3c14fd54f96fffe52fde545cb9 (diff)
Pull GLSL helpers out of GrGLProgram.cpp
Review URL: http://codereview.appspot.com/5652047/ git-svn-id: http://skia.googlecode.com/svn/trunk@3161 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrGLProgram.cpp100
-rw-r--r--src/gpu/GrGLSL.cpp62
-rw-r--r--src/gpu/GrGLSL.h54
-rw-r--r--src/gpu/GrGLShaderVar.h6
-rw-r--r--src/gpu/GrGpuGLShaders.cpp6
5 files changed, 131 insertions, 97 deletions
diff --git a/src/gpu/GrGLProgram.cpp b/src/gpu/GrGLProgram.cpp
index 610446d615..e77638f098 100644
--- a/src/gpu/GrGLProgram.cpp
+++ b/src/gpu/GrGLProgram.cpp
@@ -22,23 +22,6 @@ enum {
kUseUniform = 2000
};
-
-const char* GrPrecision(const GrGLInterface* gl) {
- if (gl->supportsES2()) {
- return "mediump";
- } else {
- return " ";
- }
-}
-
-const char* GrShaderPrecision(const GrGLInterface* gl) {
- if (gl->supportsES2()) {
- return "precision mediump float;\n";
- } else {
- return "";
- }
-}
-
} // namespace
#define PRINT_SHADERS 0
@@ -380,29 +363,6 @@ static void addColorMatrix(GrStringBuilder* fsCode, const char * outputVar,
namespace {
-const char* glsl_version_string(const GrGLInterface* gl,
- GrGLSLGeneration v) {
- switch (v) {
- case k110_GLSLGeneration:
- if (gl->supportsES2()) {
- // ES2s shader language is based on version 1.20 but is version
- // 1.00 of the ES language.
- return "#version 100\n";
- } else {
- return "#version 110\n";
- }
- case k130_GLSLGeneration:
- GrAssert(!gl->supportsES2());
- return "#version 130\n";
- case k150_GLSLGeneration:
- GrAssert(!gl->supportsES2());
- return "#version 150\n";
- default:
- GrCrash("Unknown GL version.");
- return ""; // suppress warning
- }
-}
-
// 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(GrGLShaderVar::Type type,
@@ -568,29 +528,6 @@ void GrGLProgram::genEdgeCoverage(const GrGLInterface* gl,
namespace {
-// returns true if the color output was explicitly declared or not.
-bool decl_and_get_fs_color_output(GrGLSLGeneration v,
- VarArray* fsOutputs,
- const char** name) {
- switch (v) {
- case k110_GLSLGeneration:
- *name = "gl_FragColor";
- return false;
- break;
- case k130_GLSLGeneration: // fallthru
- case k150_GLSLGeneration:
- *name = declared_color_output_name();
- fsOutputs->push_back().set(GrGLShaderVar::kVec4f_Type,
- GrGLShaderVar::kOut_TypeModifier,
- declared_color_output_name());
- return true;
- break;
- default:
- GrCrash("Unknown GLSL version.");
- return false; // suppress warning
- }
-}
-
void genInputColor(GrGLProgram::ProgramDesc::ColorInput colorInput,
GrGLProgram::CachedData* programData,
ShaderCodeSegments* segments,
@@ -664,7 +601,7 @@ void GrGLProgram::genGeometryShader(const GrGLInterface* gl,
ShaderCodeSegments* segments) const {
#if GR_GL_EXPERIMENTAL_GS
if (fProgramDesc.fExperimentalGS) {
- GrAssert(glslGeneration >= k150_GLSLGeneration);
+ GrAssert(glslGeneration >= k150_GrGLSLGeneration);
segments->fGSHeader.append("layout(triangles) in;\n"
"layout(triangle_strip, max_vertices = 6) out;\n");
segments->fGSCode.append("void main() {\n"
@@ -758,12 +695,17 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
// the dual source output has no canonical var name, have to
// declare an output, which is incompatible with gl_FragColor/gl_FragData.
- const char* fsColorOutput = NULL;
bool dualSourceOutputWritten = false;
- segments.fHeader.printf(glsl_version_string(gl, glslGeneration));
- bool isColorDeclared = decl_and_get_fs_color_output(glslGeneration,
- &segments.fFSOutputs,
- &fsColorOutput);
+ segments.fHeader.printf(GrGetGLSLVersionDecl(gl->fBindingsExported,
+ glslGeneration));
+
+ GrGLShaderVar colorOutput;
+ bool isColorDeclared = GrGLSLSetupFSColorOuput(glslGeneration,
+ declared_color_output_name(),
+ &colorOutput);
+ if (isColorDeclared) {
+ segments.fFSOutputs.push_back(colorOutput);
+ }
#if GR_GL_ATTRIBUTE_MATRICES
segments.fVSAttrs.push_back().set(GrGLShaderVar::kMat33f_Type,
@@ -872,7 +814,7 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
SkXfermode::kZero_Coeff == colorCoeff &&
!applyColorMatrix) {
segments.fFSCode.appendf("\t%s = %s;\n",
- fsColorOutput,
+ colorOutput.getName().c_str(),
all_zeros_vec(4));
wroteFragColorZero = true;
} else if (SkXfermode::kDst_Mode != fProgramDesc.fColorFilterXfermode) {
@@ -1005,21 +947,21 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
if (!wroteFragColorZero) {
if (coverageIsZero) {
segments.fFSCode.appendf("\t%s = %s;\n",
- fsColorOutput,
+ colorOutput.getName().c_str(),
all_zeros_vec(4));
} else {
- modulate_helper(fsColorOutput,
+ modulate_helper(colorOutput.getName().c_str(),
inColor.c_str(),
inCoverage.c_str(),
&segments.fFSCode);
}
if (ProgramDesc::kNo_OutputPM == fProgramDesc.fOutputPM) {
segments.fFSCode.appendf("\t%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(%s.rgb / %s.a, %s.a);\n",
- fsColorOutput,
- fsColorOutput,
- fsColorOutput,
- fsColorOutput,
- fsColorOutput);
+ colorOutput.getName().c_str(),
+ colorOutput.getName().c_str(),
+ colorOutput.getName().c_str(),
+ colorOutput.getName().c_str(),
+ colorOutput.getName().c_str());
}
}
@@ -1169,13 +1111,13 @@ bool GrGLProgram::CompileShaders(const GrGLInterface* gl,
temps.reset();
append_string(segments.fHeader, &strs, &lengths);
- GrStringBuilder precisionStr(GrShaderPrecision(gl));
+ GrStringBuilder precisionStr(GrGetGLSLShaderPrecisionDecl(gl->fBindingsExported));
append_string(precisionStr, &strs, &lengths);
append_decls(segments.fFSUnis, gl, &strs, &lengths, &temps, glslGeneration);
append_decls(segments.fFSInputs, gl, &strs, &lengths,
&temps, glslGeneration);
// We shouldn't have declared outputs on 1.10
- GrAssert(k110_GLSLGeneration != glslGeneration ||
+ GrAssert(k110_GrGLSLGeneration != glslGeneration ||
segments.fFSOutputs.empty());
append_decls(segments.fFSOutputs, gl, &strs, &lengths,
&temps, glslGeneration);
diff --git a/src/gpu/GrGLSL.cpp b/src/gpu/GrGLSL.cpp
index 1062c81a86..e933ee87c9 100644
--- a/src/gpu/GrGLSL.cpp
+++ b/src/gpu/GrGLSL.cpp
@@ -6,27 +6,77 @@
*/
#include "GrGLSL.h"
+#include "GrGLShaderVar.h"
-GrGLSLGeneration GetGLSLGeneration(GrGLBinding binding,
+GrGLSLGeneration GrGetGLSLGeneration(GrGLBinding binding,
const GrGLInterface* gl) {
GrGLSLVersion ver = GrGLGetGLSLVersion(gl);
switch (binding) {
case kDesktop_GrGLBinding:
GrAssert(ver >= GR_GLSL_VER(1,10));
if (ver >= GR_GLSL_VER(1,50)) {
- return k150_GLSLGeneration;
+ return k150_GrGLSLGeneration;
} else if (ver >= GR_GLSL_VER(1,30)) {
- return k130_GLSLGeneration;
+ return k130_GrGLSLGeneration;
} else {
- return k110_GLSLGeneration;
+ return k110_GrGLSLGeneration;
}
case kES2_GrGLBinding:
// version 1.00 of ES GLSL based on ver 1.20 of desktop GLSL
GrAssert(ver >= GR_GL_VER(1,00));
- return k110_GLSLGeneration;
+ return k110_GrGLSLGeneration;
default:
GrCrash("Unknown GL Binding");
- return k110_GLSLGeneration; // suppress warning
+ return k110_GrGLSLGeneration; // suppress warning
}
}
+const char* GrGetGLSLVersionDecl(GrGLBinding binding,
+ GrGLSLGeneration gen) {
+ switch (gen) {
+ case k110_GrGLSLGeneration:
+ if (kES2_GrGLBinding == binding) {
+ // ES2s shader language is based on version 1.20 but is version
+ // 1.00 of the ES language.
+ return "#version 100\n";
+ } else {
+ GrAssert(kDesktop_GrGLBinding == binding);
+ return "#version 110\n";
+ }
+ case k130_GrGLSLGeneration:
+ GrAssert(kDesktop_GrGLBinding == binding);
+ return "#version 130\n";
+ case k150_GrGLSLGeneration:
+ GrAssert(kDesktop_GrGLBinding == binding);
+ return "#version 150\n";
+ default:
+ GrCrash("Unknown GL version.");
+ return ""; // suppress warning
+ }
+}
+
+const char* GrGetGLSLVarPrecisionDeclType(GrGLBinding binding) {
+ if (kES2_GrGLBinding == binding) {
+ return "mediump";
+ } else {
+ return " ";
+ }
+}
+
+const char* GrGetGLSLShaderPrecisionDecl(GrGLBinding binding) {
+ if (kES2_GrGLBinding == binding) {
+ return "precision mediump float;\n";
+ } else {
+ return "";
+ }
+}
+
+bool GrGLSLSetupFSColorOuput(GrGLSLGeneration gen,
+ const char* nameIfDeclared,
+ GrGLShaderVar* var) {
+ bool declaredOutput = k110_GrGLSLGeneration != gen;
+ var->set(GrGLShaderVar::kVec4f_Type,
+ GrGLShaderVar::kOut_TypeModifier,
+ declaredOutput ? nameIfDeclared : "gl_FragColor");
+ return declaredOutput;
+}
diff --git a/src/gpu/GrGLSL.h b/src/gpu/GrGLSL.h
index 501d1bab7a..5b9c5b631f 100644
--- a/src/gpu/GrGLSL.h
+++ b/src/gpu/GrGLSL.h
@@ -10,25 +10,67 @@
#include "GrGLInterface.h"
+class GrGLShaderVar;
+
// Limited set of GLSL versions we build shaders for. Caller should round
// down the GLSL version to one of these enums.
enum GrGLSLGeneration {
/**
* Desktop GLSL 1.10 and ES2 shading lang (based on desktop GLSL 1.20)
*/
- k110_GLSLGeneration,
+ k110_GrGLSLGeneration,
/**
* Desktop GLSL 1.30
*/
- k130_GLSLGeneration,
+ k130_GrGLSLGeneration,
/**
* Dekstop GLSL 1.50
*/
- k150_GLSLGeneration,
+ k150_GrGLSLGeneration,
};
-GrGLSLGeneration GetGLSLGeneration(GrGLBinding binding,
- const GrGLInterface* gl);
+/**
+ * Gets the most recent GLSL Generation compatible with the OpenGL context.
+ */
+GrGLSLGeneration GrGetGLSLGeneration(GrGLBinding binding,
+ const GrGLInterface* gl);
-#endif
+/**
+ * Returns a string to include at the begining of a shader to declare the GLSL
+ * version.
+ */
+const char* GrGetGLSLVersionDecl(GrGLBinding binding,
+ GrGLSLGeneration v);
+
+/**
+ * Returns a string to include in a variable decleration to set the fp precision
+ * or an emptry string if precision is not required.
+ */
+const char* GrGetGLSLVarPrecisionDeclType(GrGLBinding binding);
+/**
+ * Returns a string to set the default fp precision for an entire shader, or
+ * an emptry string if precision is not required.
+ */
+const char* GrGetGLSLShaderPrecisionDecl(GrGLBinding binding);
+
+/**
+ * Depending on the GLSL version being emitted there may be an assumed output
+ * variable from the fragment shader for the color. Otherwise, the shader must
+ * declare an output variable for the color. If this function returns true:
+ * * Parameter var's name will be set to nameIfDeclared
+ * * The variable must be declared in the fragment shader
+ * * The variable has to be bound as the color output
+ * (using glBindFragDataLocation)
+ * If the function returns false:
+ * * Parameter var's name will be set to the GLSL built-in color output name.
+ * * Do not declare the variable in the shader.
+ * * Do not use glBindFragDataLocation to bind the variable
+ * In either case var is initialized to represent the color output in the
+ * shader.
+ */
+ bool GrGLSLSetupFSColorOuput(GrGLSLGeneration gen,
+ const char* nameIfDeclared,
+ GrGLShaderVar* var);
+
+#endif
diff --git a/src/gpu/GrGLShaderVar.h b/src/gpu/GrGLShaderVar.h
index 1d5d7cad5d..7bec9f95e5 100644
--- a/src/gpu/GrGLShaderVar.h
+++ b/src/gpu/GrGLShaderVar.h
@@ -278,13 +278,13 @@ private:
case kNone_TypeModifier:
return "";
case kOut_TypeModifier:
- return k110_GLSLGeneration == gen ? "varying" : "out";
+ return k110_GrGLSLGeneration == gen ? "varying" : "out";
case kIn_TypeModifier:
- return k110_GLSLGeneration == gen ? "varying" : "in";
+ return k110_GrGLSLGeneration == gen ? "varying" : "in";
case kUniform_TypeModifier:
return "uniform";
case kAttribute_TypeModifier:
- return k110_GLSLGeneration == gen ? "attribute" : "in";
+ return k110_GrGLSLGeneration == gen ? "attribute" : "in";
default:
GrCrash("Unknown shader variable type modifier.");
return ""; // suppress warning
diff --git a/src/gpu/GrGpuGLShaders.cpp b/src/gpu/GrGpuGLShaders.cpp
index b8e0999ab8..d03c9f224e 100644
--- a/src/gpu/GrGpuGLShaders.cpp
+++ b/src/gpu/GrGpuGLShaders.cpp
@@ -166,7 +166,7 @@ bool random_bool(GrRandom* r) {
bool GrGpuGLShaders::programUnitTest() {
GrGLSLGeneration glslGeneration =
- GetGLSLGeneration(this->glBinding(), this->glInterface());
+ GrGetGLSLGeneration(this->glBinding(), this->glInterface());
static const int STAGE_OPTS[] = {
0,
StageDesc::kNoPerspective_OptFlagBit,
@@ -306,7 +306,7 @@ GrGpuGLShaders::GrGpuGLShaders(const GrGLInterface* gl)
: GrGpuGL(gl, get_binding_in_use(gl)) {
GrGLSLGeneration glslGeneration =
- GetGLSLGeneration(this->glBinding(), gl);
+ GrGetGLSLGeneration(this->glBinding(), gl);
// Enable supported shader-related caps
if (kDesktop_GrGLBinding == this->glBinding()) {
@@ -317,7 +317,7 @@ GrGpuGLShaders::GrGpuGLShaders(const GrGLInterface* gl)
// we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
fCaps.fGeometryShaderSupport =
this->glVersion() >= GR_GL_VER(3,2) &&
- glslGeneration >= k150_GLSLGeneration;
+ glslGeneration >= k150_GrGLSLGeneration;
} else {
fCaps.fShaderDerivativeSupport =
this->hasExtension("GL_OES_standard_derivatives");