Make GrGLShaderVar objects aware of whether they are uniform, varying, or

attribute varibles. Extract GLSL generation enum and utility function into
new GrGLSL header.



git-svn-id: http://skia.googlecode.com/svn/trunk@2827 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
tomhudson@google.com 2011-12-08 14:44:10 +00:00
parent 88ca1b4102
commit 086e5354fe
7 changed files with 218 additions and 109 deletions

View File

@ -210,6 +210,8 @@
'../src/gpu/GrGLRenderTarget.cpp',
'../src/gpu/GrGLRenderTarget.h',
'../src/gpu/GrGLShaderVar.h',
'../src/gpu/GrGLSL.cpp',
'../src/gpu/GrGLSL.h',
'../src/gpu/GrGLStencilBuffer.cpp',
'../src/gpu/GrGLStencilBuffer.h',
'../src/gpu/GrGLTexture.cpp',

View File

@ -369,9 +369,9 @@ static void addColorFilter(GrStringBuilder* fsCode, const char * outputVar,
namespace {
const char* glsl_version_string(const GrGLInterface* gl,
GrGLProgram::GLSLVersion v) {
GrGLSLGeneration v) {
switch (v) {
case GrGLProgram::k110_GLSLVersion:
case k110_GLSLGeneration:
if (gl->supportsES2()) {
// ES2s shader language is based on version 1.20 but is version
// 1.00 of the ES language.
@ -379,10 +379,10 @@ const char* glsl_version_string(const GrGLInterface* gl,
} else {
return "#version 110\n";
}
case GrGLProgram::k130_GLSLVersion:
case k130_GLSLGeneration:
GrAssert(!gl->supportsES2());
return "#version 130\n";
case GrGLProgram::k150_GLSLVersion:
case k150_GLSLGeneration:
GrAssert(!gl->supportsES2());
return "#version 150\n";
default:
@ -400,6 +400,8 @@ void append_varying(GrGLShaderVar::Type type,
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();
@ -411,11 +413,15 @@ void append_varying(GrGLShaderVar::Type type,
// 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 {
@ -423,6 +429,8 @@ void append_varying(GrGLShaderVar::Type type,
}
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();
@ -450,6 +458,7 @@ void GrGLProgram::genEdgeCoverage(const GrGLInterface* gl,
ShaderCodeSegments* segments) const {
if (fProgramDesc.fEdgeAANumEdges > 0) {
segments->fFSUnis.push_back().set(GrGLShaderVar::kVec3f_Type,
GrGLShaderVar::kUniform_TypeModifier,
EDGES_UNI_NAME,
fProgramDesc.fEdgeAANumEdges);
programData->fUniLocations.fEdgesUni = kUseUniform;
@ -499,8 +508,10 @@ void GrGLProgram::genEdgeCoverage(const GrGLInterface* gl,
*coverageVar = "edgeAlpha";
} else if (layout & GrDrawTarget::kEdge_VertexLayoutBit) {
const char *vsName, *fsName;
append_varying(GrGLShaderVar::kVec4f_Type, "Edge", segments, &vsName, &fsName);
segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type, EDGE_ATTR_NAME);
append_varying(GrGLShaderVar::kVec4f_Type, "Edge", segments,
&vsName, &fsName);
segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type,
GrGLShaderVar::kAttribute_TypeModifier, EDGE_ATTR_NAME);
segments->fVSCode.appendf("\t%s = " EDGE_ATTR_NAME ";\n", vsName);
if (GrDrawState::kHairLine_EdgeType == fProgramDesc.fVertexEdgeType) {
segments->fFSCode.appendf("\tfloat edgeAlpha = abs(dot(vec3(gl_FragCoord.xy,1), %s.xyz));\n", fsName);
@ -528,18 +539,19 @@ 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(GrGLProgram::GLSLVersion v,
bool decl_and_get_fs_color_output(GrGLSLGeneration v,
VarArray* fsOutputs,
const char** name) {
switch (v) {
case GrGLProgram::k110_GLSLVersion:
case k110_GLSLGeneration:
*name = "gl_FragColor";
return false;
break;
case GrGLProgram::k130_GLSLVersion: // fallthru
case GrGLProgram::k150_GLSLVersion:
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;
@ -556,7 +568,8 @@ void genInputColor(GrGLProgram::ProgramDesc::ColorInput colorInput,
switch (colorInput) {
case GrGLProgram::ProgramDesc::kAttribute_ColorInput: {
segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type,
COL_ATTR_NAME);
GrGLShaderVar::kAttribute_TypeModifier,
COL_ATTR_NAME);
const char *vsName, *fsName;
append_varying(GrGLShaderVar::kVec4f_Type, "Color", segments, &vsName, &fsName);
segments->fVSCode.appendf("\t%s = " COL_ATTR_NAME ";\n", vsName);
@ -564,7 +577,8 @@ void genInputColor(GrGLProgram::ProgramDesc::ColorInput colorInput,
} break;
case GrGLProgram::ProgramDesc::kUniform_ColorInput:
segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
COL_UNI_NAME);
GrGLShaderVar::kUniform_TypeModifier,
COL_UNI_NAME);
programData->fUniLocations.fColorUni = kUseUniform;
*inColor = COL_UNI_NAME;
break;
@ -582,6 +596,7 @@ void genInputColor(GrGLProgram::ProgramDesc::ColorInput colorInput,
void genPerVertexCoverage(ShaderCodeSegments* segments,
GrStringBuilder* inCoverage) {
segments->fVSAttrs.push_back().set(GrGLShaderVar::kFloat_Type,
GrGLShaderVar::kAttribute_TypeModifier,
COV_ATTR_NAME);
const char *vsName, *fsName;
append_varying(GrGLShaderVar::kFloat_Type, "Coverage",
@ -599,11 +614,11 @@ void genPerVertexCoverage(ShaderCodeSegments* segments,
}
void GrGLProgram::genGeometryShader(const GrGLInterface* gl,
GLSLVersion glslVersion,
GrGLSLGeneration glslGeneration,
ShaderCodeSegments* segments) const {
#if GR_GL_EXPERIMENTAL_GS
if (fProgramDesc.fExperimentalGS) {
GrAssert(glslVersion >= k150_GLSLVersion);
GrAssert(glslGeneration >= k150_GLSLGeneration);
segments->fGSHeader.append("layout(triangles) in;\n"
"layout(triangle_strip, max_vertices = 6) out;\n");
segments->fGSCode.append("void main() {\n"
@ -628,7 +643,7 @@ void GrGLProgram::genGeometryShader(const GrGLInterface* gl,
}
bool GrGLProgram::genProgram(const GrGLInterface* gl,
GLSLVersion glslVersion,
GrGLSLGeneration glslGeneration,
GrGLProgram::CachedData* programData) const {
ShaderCodeSegments segments;
@ -676,19 +691,22 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
// 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, glslVersion));
bool isColorDeclared = decl_and_get_fs_color_output(glslVersion,
segments.fHeader.printf(glsl_version_string(gl, glslGeneration));
bool isColorDeclared = decl_and_get_fs_color_output(glslGeneration,
&segments.fFSOutputs,
&fsColorOutput);
#if GR_GL_ATTRIBUTE_MATRICES
segments.fVSAttrs.push_back().set(GrGLShaderVar::kMat33f_Type, VIEW_MATRIX_NAME);
segments.fVSAttrs.push_back().set(GrGLShaderVar::kMat33f_Type,
GrGLShaderVar::kAttribute_TypeModifier, VIEW_MATRIX_NAME);
programData->fUniLocations.fViewMatrixUni = kSetAsAttribute;
#else
segments.fVSUnis.push_back().set(GrGLShaderVar::kMat33f_Type, VIEW_MATRIX_NAME);
segments.fVSUnis.push_back().set(GrGLShaderVar::kMat33f_Type,
GrGLShaderVar::kUniform_TypeModifier, VIEW_MATRIX_NAME);
programData->fUniLocations.fViewMatrixUni = kUseUniform;
#endif
segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec2f_Type, POS_ATTR_NAME);
segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec2f_Type,
GrGLShaderVar::kAttribute_TypeModifier, POS_ATTR_NAME);
segments.fVSCode.append(
"void main() {\n"
@ -716,7 +734,8 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
if (GrDrawTarget::VertexUsesTexCoordIdx(t, layout)) {
tex_attr_name(t, texCoordAttrs + t);
segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec2f_Type,
texCoordAttrs[t].c_str());
GrGLShaderVar::kAttribute_TypeModifier,
texCoordAttrs[t].c_str());
}
}
@ -775,6 +794,7 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
}
if (needColorFilterUniform) {
segments.fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
GrGLShaderVar::kUniform_TypeModifier,
COL_FILTER_UNI_NAME);
programData->fUniLocations.fColorFilterUni = kUseUniform;
}
@ -854,7 +874,8 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
}
if (ProgramDesc::kNone_DualSrcOutput != fProgramDesc.fDualSrcOutput) {
segments.fFSOutputs.push_back().set(GrGLShaderVar::kVec4f_Type,
dual_source_output_name());
GrGLShaderVar::kOut_TypeModifier,
dual_source_output_name());
bool outputIsZero = false;
GrStringBuilder coeff;
if (ProgramDesc::kCoverage_DualSrcOutput !=
@ -908,13 +929,13 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
///////////////////////////////////////////////////////////////////////////
// insert GS
#if GR_DEBUG
this->genGeometryShader(gl, glslVersion, &segments);
this->genGeometryShader(gl, glslGeneration, &segments);
#endif
///////////////////////////////////////////////////////////////////////////
// compile and setup attribs and unis
if (!CompileShaders(gl, glslVersion, segments, programData)) {
if (!CompileShaders(gl, glslGeneration, segments, programData)) {
return false;
}
@ -934,14 +955,11 @@ namespace {
inline void expand_decls(const VarArray& vars,
const GrGLInterface* gl,
const char* prefix,
GrStringBuilder* string) {
GrStringBuilder* string,
GrGLSLGeneration gen) {
const int count = vars.count();
for (int i = 0; i < count; ++i) {
string->append(prefix);
string->append(" ");
vars[i].appendDecl(gl, string);
string->append(";\n");
vars[i].appendDecl(gl, string, gen);
}
}
@ -980,18 +998,18 @@ inline void append_string(const GrStringBuilder& str,
inline void append_decls(const VarArray& vars,
const GrGLInterface* gl,
const char* prefix,
StrArray* strings,
LengthArray* lengths,
TempArray* temp) {
expand_decls(vars, gl, prefix, &temp->push_back());
TempArray* temp,
GrGLSLGeneration gen) {
expand_decls(vars, gl, &temp->push_back(), gen);
append_string(temp->back(), strings, lengths);
}
}
bool GrGLProgram::CompileShaders(const GrGLInterface* gl,
GLSLVersion glslVersion,
GrGLSLGeneration glslGeneration,
const ShaderCodeSegments& segments,
CachedData* programData) {
enum { kPreAllocStringCnt = 8 };
@ -1004,19 +1022,12 @@ bool GrGLProgram::CompileShaders(const GrGLInterface* gl,
GrStringBuilder inputs;
GrStringBuilder outputs;
static const char* gVaryingPrefixes[2][2] = {{"varying", "varying"},
{"out", "in"}};
const char** varyingPrefixes = k110_GLSLVersion == glslVersion ?
gVaryingPrefixes[0] :
gVaryingPrefixes[1];
const char* attributePrefix = k110_GLSLVersion == glslVersion ?
"attribute" :
"in";
append_string(segments.fHeader, &strs, &lengths);
append_decls(segments.fVSUnis, gl, "uniform", &strs, &lengths, &temps);
append_decls(segments.fVSAttrs, gl, attributePrefix, &strs, &lengths, &temps);
append_decls(segments.fVSOutputs, gl, varyingPrefixes[0], &strs, &lengths, &temps);
append_decls(segments.fVSUnis, gl, &strs, &lengths, &temps, glslGeneration);
append_decls(segments.fVSAttrs, gl, &strs, &lengths,
&temps, glslGeneration);
append_decls(segments.fVSOutputs, gl, &strs, &lengths,
&temps, glslGeneration);
append_string(segments.fVSCode, &strs, &lengths);
#if PRINT_SHADERS
@ -1037,8 +1048,10 @@ bool GrGLProgram::CompileShaders(const GrGLInterface* gl,
temps.reset();
append_string(segments.fHeader, &strs, &lengths);
append_string(segments.fGSHeader, &strs, &lengths);
append_decls(segments.fGSInputs, gl, "in", &strs, &lengths, &temps);
append_decls(segments.fGSOutputs, gl, "out", &strs, &lengths, &temps);
append_decls(segments.fGSInputs, gl, &strs, &lengths,
&temps, glslGeneration);
append_decls(segments.fGSOutputs, gl, &strs, &lengths,
&temps, glslGeneration);
append_string(segments.fGSCode, &strs, &lengths);
#if PRINT_SHADERS
print_shader(strs.count(), &strs[0], &lengths[0]);
@ -1058,11 +1071,14 @@ bool GrGLProgram::CompileShaders(const GrGLInterface* gl,
append_string(segments.fHeader, &strs, &lengths);
GrStringBuilder precisionStr(GrShaderPrecision(gl));
append_string(precisionStr, &strs, &lengths);
append_decls(segments.fFSUnis, gl, "uniform", &strs, &lengths, &temps);
append_decls(segments.fFSInputs, gl, varyingPrefixes[1], &strs, &lengths, &temps);
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_GLSLVersion != glslVersion || segments.fFSOutputs.empty());
append_decls(segments.fFSOutputs, gl, "out", &strs, &lengths, &temps);
GrAssert(k110_GLSLGeneration != glslGeneration ||
segments.fFSOutputs.empty());
append_decls(segments.fFSOutputs, gl, &strs, &lengths,
&temps, glslGeneration);
append_string(segments.fFSFunctions, &strs, &lengths);
append_string(segments.fFSCode, &strs, &lengths);
@ -1334,6 +1350,7 @@ GrGLShaderVar* genRadialVS(int stageNum,
GrGLShaderVar* radial2FSParams = &segments->fFSUnis.push_back();
radial2FSParams->setType(GrGLShaderVar::kFloat_Type);
radial2FSParams->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
radial2FSParams->setArrayCount(6);
radial2_param_name(stageNum, radial2FSParams->accessName());
segments->fVSUnis.push_back(*radial2FSParams).setEmitPrecision(true);
@ -1523,9 +1540,11 @@ void genConvolutionVS(int stageNum,
//GrGLShaderVar* kernel = &segments->fFSUnis.push_back();
*kernel = &segments->fFSUnis.push_back();
(*kernel)->setType(GrGLShaderVar::kFloat_Type);
(*kernel)->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
(*kernel)->setArrayCount(desc.fKernelWidth);
GrGLShaderVar* imgInc = &segments->fFSUnis.push_back();
imgInc->setType(GrGLShaderVar::kVec2f_Type);
imgInc->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
convolve_param_names(stageNum,
(*kernel)->accessName(),
@ -1612,9 +1631,11 @@ void GrGLProgram::genStageCode(const GrGLInterface* gl,
GrGLShaderVar* mat;
#if GR_GL_ATTRIBUTE_MATRICES
mat = &segments->fVSAttrs.push_back();
mat->setTypeModifier(GrGLShaderVar::kAttribute_TypeModifier);
locations->fTextureMatrixUni = kSetAsAttribute;
#else
mat = &segments->fVSUnis.push_back();
mat->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
locations->fTextureMatrixUni = kUseUniform;
#endif
tex_matrix_name(stageNum, mat->accessName());
@ -1628,14 +1649,16 @@ void GrGLProgram::genStageCode(const GrGLInterface* gl,
}
}
segments->fFSUnis.push_back().setType(GrGLShaderVar::kSampler2D_Type);
segments->fFSUnis.push_back().set(GrGLShaderVar::kSampler2D_Type,
GrGLShaderVar::kUniform_TypeModifier, "");
sampler_name(stageNum, segments->fFSUnis.back().accessName());
locations->fSamplerUni = kUseUniform;
const char* samplerName = segments->fFSUnis.back().getName().c_str();
const char* texelSizeName = NULL;
if (StageDesc::k2x2_FetchMode == desc.fFetchMode) {
segments->fFSUnis.push_back().setType(GrGLShaderVar::kVec2f_Type);
segments->fFSUnis.push_back().set(GrGLShaderVar::kVec2f_Type,
GrGLShaderVar::kUniform_TypeModifier, "");
normalized_texel_size_name(stageNum, segments->fFSUnis.back().accessName());
texelSizeName = segments->fFSUnis.back().getName().c_str();
}
@ -1758,7 +1781,8 @@ void GrGLProgram::genStageCode(const GrGLInterface* gl,
StageDesc::kCustomTextureDomain_OptFlagBit) {
GrStringBuilder texDomainName;
tex_domain_name(stageNum, &texDomainName);
segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type, texDomainName);
segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
GrGLShaderVar::kUniform_TypeModifier, texDomainName);
GrStringBuilder coordVar("clampCoord");
segments->fFSCode.appendf("\t%s %s = clamp(%s, %s.xy, %s.zw);\n",
float_vector_type_str(coordDims),

View File

@ -12,6 +12,7 @@
#include "GrDrawState.h"
#include "GrGLInterface.h"
#include "GrGLSL.h"
#include "GrStringBuilder.h"
#include "GrGpu.h"
@ -36,22 +37,6 @@ struct ShaderCodeSegments;
*/
class GrGLProgram {
public:
// Limited set of GLSL versions we build shaders for. Caller should round
// down the GLSL version to one of these enums.
enum GLSLVersion {
/**
* Desktop GLSL 1.10 and ES2 shading lang (based on desktop GLSL 1.20)
*/
k110_GLSLVersion,
/**
* Desktop GLSL 1.30
*/
k130_GLSLVersion,
/**
* Dekstop GLSL 1.50
*/
k150_GLSLVersion,
};
class CachedData;
@ -64,7 +49,7 @@ public:
* but in a separate cacheable container.
*/
bool genProgram(const GrGLInterface* gl,
GLSLVersion glslVersion,
GrGLSLGeneration glslVersion,
CachedData* programData) const;
/**
@ -353,7 +338,7 @@ private:
StageUniLocations* locations) const;
void genGeometryShader(const GrGLInterface* gl,
GLSLVersion glslVersion,
GrGLSLGeneration glslVersion,
ShaderCodeSegments* segments) const;
// generates code to compute coverage based on edge AA.
@ -364,7 +349,7 @@ private:
ShaderCodeSegments* segments) const;
static bool CompileShaders(const GrGLInterface* gl,
GLSLVersion glslVersion,
GrGLSLGeneration glslVersion,
const ShaderCodeSegments& segments,
CachedData* programData);

32
src/gpu/GrGLSL.cpp Normal file
View File

@ -0,0 +1,32 @@
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "GrGLSL.h"
GrGLSLGeneration GetGLSLGeneration(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;
} else if (ver >= GR_GLSL_VER(1,30)) {
return k130_GLSLGeneration;
} else {
return k110_GLSLGeneration;
}
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;
default:
GrCrash("Unknown GL Binding");
return k110_GLSLGeneration; // suppress warning
}
}

34
src/gpu/GrGLSL.h Normal file
View File

@ -0,0 +1,34 @@
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrGLSL_DEFINED
#define GrGLSL_DEFINED
#include "GrGLInterface.h"
// 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,
/**
* Desktop GLSL 1.30
*/
k130_GLSLGeneration,
/**
* Dekstop GLSL 1.50
*/
k150_GLSLGeneration,
};
GrGLSLGeneration GetGLSLGeneration(GrGLBinding binding,
const GrGLInterface* gl);
#endif

View File

@ -10,6 +10,7 @@
#define GrGLShaderVar_DEFINED
#include "GrGLInterface.h"
#include "GrGLSL.h"
#include "GrStringBuilder.h"
#define USE_UNIFORM_FLOAT_ARRAYS true
@ -29,11 +30,25 @@ public:
kSampler2D_Type,
};
/**
* Early versions of GLSL have Varying and Attribute; those are later
* deprecated, but we still need to know whether a Varying variable
* should be treated as In or Out.
*/
enum TypeModifier {
kNone_TypeModifier,
kOut_TypeModifier,
kIn_TypeModifier,
kUniform_TypeModifier,
kAttribute_TypeModifier
};
/**
* Defaults to a float with no precision specifier
*/
GrGLShaderVar() {
fType = kFloat_Type;
fTypeModifier = kNone_TypeModifier;
fCount = kNonArray;
fEmitPrecision = false;
fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
@ -41,6 +56,7 @@ public:
GrGLShaderVar(const GrGLShaderVar& var)
: fType(var.fType)
, fTypeModifier(var.fTypeModifier)
, fName(var.fName)
, fCount(var.fCount)
, fEmitPrecision(var.fEmitPrecision)
@ -58,10 +74,12 @@ public:
* Sets as a non-array.
*/
void set(Type type,
TypeModifier typeModifier,
const GrStringBuilder& name,
bool emitPrecision = false,
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
fType = type;
fTypeModifier = typeModifier;
fName = name;
fCount = kNonArray;
fEmitPrecision = emitPrecision;
@ -72,10 +90,12 @@ public:
* Sets as a non-array.
*/
void set(Type type,
TypeModifier typeModifier,
const char* name,
bool specifyPrecision = false,
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
fType = type;
fTypeModifier = typeModifier;
fName = name;
fCount = kNonArray;
fEmitPrecision = specifyPrecision;
@ -86,11 +106,13 @@ public:
* Set all var options
*/
void set(Type type,
TypeModifier typeModifier,
const GrStringBuilder& name,
int count,
bool specifyPrecision = false,
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
fType = type;
fTypeModifier = typeModifier;
fName = name;
fCount = count;
fEmitPrecision = specifyPrecision;
@ -101,11 +123,13 @@ public:
* Set all var options
*/
void set(Type type,
TypeModifier typeModifier,
const char* name,
int count,
bool specifyPrecision = false,
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
fType = type;
fTypeModifier = typeModifier;
fName = name;
fCount = count;
fEmitPrecision = specifyPrecision;
@ -160,6 +184,9 @@ public:
*/
void setType(Type type) { fType = type; }
TypeModifier getTypeModifier() const { return fTypeModifier; }
void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
/**
* Must the variable declaration emit a precision specifier
*/
@ -172,7 +199,12 @@ public:
/**
* Write a declaration of this variable to out.
*/
void appendDecl(const GrGLInterface* gl, GrStringBuilder* out) const {
void appendDecl(const GrGLInterface* gl, GrStringBuilder* out,
GrGLSLGeneration gen) const {
if (this->getTypeModifier() != kNone_TypeModifier) {
out->append(TypeModifierString(this->getTypeModifier(), gen));
out->append(" ");
}
if (this->emitsPrecision()) {
out->append(PrecisionString(gl));
out->append(" ");
@ -195,6 +227,7 @@ public:
TypeString(effectiveType),
this->getName().c_str());
}
out->append(";\n");
}
static const char* TypeString(Type t) {
@ -236,7 +269,27 @@ private:
return gl->supportsDesktop() ? "" : "mediump";
}
static const char* TypeModifierString(TypeModifier t,
GrGLSLGeneration gen) {
switch (t) {
case kNone_TypeModifier:
return "";
case kOut_TypeModifier:
return k110_GLSLGeneration == gen ? "varying" : "out";
case kIn_TypeModifier:
return k110_GLSLGeneration == gen ? "varying" : "in";
case kUniform_TypeModifier:
return "uniform";
case kAttribute_TypeModifier:
return k110_GLSLGeneration == gen ? "attribute" : "in";
default:
GrCrash("Unknown shader variable type modifier.");
return ""; // suppress warning
}
}
Type fType;
TypeModifier fTypeModifier;
GrStringBuilder fName;
int fCount;
bool fEmitPrecision;

View File

@ -9,6 +9,7 @@
#include "GrBinHashKey.h"
#include "GrGLProgram.h"
#include "GrGLSL.h"
#include "GrGpuGLShaders.h"
#include "GrGpuVertex.h"
#include "GrNoncopyable.h"
@ -55,15 +56,15 @@ private:
int fCount;
unsigned int fCurrLRUStamp;
const GrGLInterface* fGL;
GrGLProgram::GLSLVersion fGLSLVersion;
GrGLSLGeneration fGLSLGeneration;
public:
ProgramCache(const GrGLInterface* gl,
GrGLProgram::GLSLVersion glslVersion)
GrGLSLGeneration glslGeneration)
: fCount(0)
, fCurrLRUStamp(0)
, fGL(gl)
, fGLSLVersion(glslVersion) {
, fGLSLGeneration(glslGeneration) {
}
~ProgramCache() {
@ -89,7 +90,8 @@ public:
Entry* entry = fHashCache.find(newEntry.fKey);
if (NULL == entry) {
if (!desc.genProgram(fGL, fGLSLVersion, &newEntry.fProgramData)) {
if (!desc.genProgram(fGL, fGLSLGeneration,
&newEntry.fProgramData)) {
return NULL;
}
if (fCount < kMaxEntries) {
@ -144,29 +146,6 @@ void GrGpuGLShaders::DeleteProgram(const GrGLInterface* gl,
namespace {
GrGLProgram::GLSLVersion get_glsl_version(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 GrGLProgram::k150_GLSLVersion;
} else if (ver >= GR_GLSL_VER(1,30)) {
return GrGLProgram::k130_GLSLVersion;
} else {
return GrGLProgram::k110_GLSLVersion;
}
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 GrGLProgram::k110_GLSLVersion;
default:
GrCrash("Unknown GL Binding");
return GrGLProgram::k110_GLSLVersion; // suppress warning
}
}
// GrRandoms nextU() values have patterns in the low bits
// So using nextU() % array_count might never take some values.
int random_int(GrRandom* r, int count) {
@ -186,8 +165,8 @@ bool random_bool(GrRandom* r) {
bool GrGpuGLShaders::programUnitTest() {
GrGLProgram::GLSLVersion glslVersion =
get_glsl_version(this->glBinding(), this->glInterface());
GrGLSLGeneration glslGeneration =
GetGLSLGeneration(this->glBinding(), this->glInterface());
static const int STAGE_OPTS[] = {
0,
StageDesc::kNoPerspective_OptFlagBit,
@ -302,7 +281,7 @@ bool GrGpuGLShaders::programUnitTest() {
}
CachedData cachedData;
if (!program.genProgram(this->glInterface(),
glslVersion,
glslGeneration,
&cachedData)) {
return false;
}
@ -325,8 +304,8 @@ GrGLBinding get_binding_in_use(const GrGLInterface* gl) {
GrGpuGLShaders::GrGpuGLShaders(const GrGLInterface* gl)
: GrGpuGL(gl, get_binding_in_use(gl)) {
GrGLProgram::GLSLVersion glslVersion =
get_glsl_version(this->glBinding(), gl);
GrGLSLGeneration glslGeneration =
GetGLSLGeneration(this->glBinding(), gl);
// Enable supported shader-releated caps
fCaps.fShaderSupport = true;
@ -339,7 +318,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) &&
glslVersion >= GrGLProgram::k150_GLSLVersion;
glslGeneration >= k150_GLSLGeneration;
} else {
fCaps.fShaderDerivativeSupport =
this->hasExtension("GL_OES_standard_derivatives");
@ -348,7 +327,7 @@ GrGpuGLShaders::GrGpuGLShaders(const GrGLInterface* gl)
GR_GL_GetIntegerv(gl, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttribs);
fProgramData = NULL;
fProgramCache = new ProgramCache(gl, glslVersion);
fProgramCache = new ProgramCache(gl, glslGeneration);
#if 0
this->programUnitTest();