Infrastructure for new Ganesh shader pipeline: base classes for GPU

implementation of user-defined effects.

http://codereview.appspot.com/6052047/



git-svn-id: http://skia.googlecode.com/svn/trunk@3726 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
tomhudson@google.com 2012-04-18 17:49:20 +00:00
parent 95ead84e0f
commit 168e63418c
10 changed files with 390 additions and 86 deletions

View File

@ -219,6 +219,8 @@
'../src/gpu/GrBufferAllocPool.h',
'../src/gpu/GrClip.cpp',
'../src/gpu/GrContext.cpp',
'../src/gpu/GrCustomStage.cpp',
'../src/gpu/GrCustomStage.h',
'../src/gpu/GrDefaultPathRenderer.cpp',
'../src/gpu/GrDefaultPathRenderer.h',
'../src/gpu/GrDefaultTextContext.cpp',
@ -285,6 +287,8 @@
'../src/gpu/gl/GrGLIRect.h',
'../src/gpu/gl/GrGLProgram.cpp',
'../src/gpu/gl/GrGLProgram.h',
'../src/gpu/gl/GrGLProgramStage.cpp',
'../src/gpu/gl/GrGLProgramStage.h',
'../src/gpu/gl/GrGLRenderTarget.cpp',
'../src/gpu/gl/GrGLRenderTarget.h',
'../src/gpu/gl/GrGLShaderVar.h',

View File

@ -11,6 +11,7 @@
#ifndef GrAllocator_DEFINED
#define GrAllocator_DEFINED
#include "GrNoncopyable.h"
#include "GrConfig.h"
#include "SkTArray.h"

22
src/gpu/GrCustomStage.cpp Normal file
View File

@ -0,0 +1,22 @@
/*
* 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 "GrContext.h"
#include "GrCustomStage.h"
GrCustomStage::GrCustomStage() {
}
GrCustomStage::~GrCustomStage() {
}
bool GrCustomStage::isOpaque(bool inputTextureIsOpaque) const {
return false;
}

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

@ -0,0 +1,34 @@
/*
* 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 GrCustomStage_DEFINED
#define GrCustomStage_DEFINED
class GrContext;
class GrGLProgramStageFactory;
/** Provides custom vertex shader, fragment shader, uniform data for a
particular stage of the Ganesh shading pipeline.
TODO: may want to refcount these? */
class GrCustomStage {
public:
GrCustomStage();
virtual ~GrCustomStage();
/** If given an input texture that is/is not opaque, is this
stage guaranteed to produce an opaque output? */
virtual bool isOpaque(bool inputTextureIsOpaque) const;
virtual GrGLProgramStageFactory* getGLFactory() = 0;
protected:
};
#endif

View File

@ -87,29 +87,8 @@ inline void tex_attr_name(int coordIdx, GrStringBuilder* s) {
s->appendS32(coordIdx);
}
inline GrGLShaderVar::Type float_vector_type(int count) {
GR_STATIC_ASSERT(GrGLShaderVar::kFloat_Type == 0);
GR_STATIC_ASSERT(GrGLShaderVar::kVec2f_Type == 1);
GR_STATIC_ASSERT(GrGLShaderVar::kVec3f_Type == 2);
GR_STATIC_ASSERT(GrGLShaderVar::kVec4f_Type == 3);
GrAssert(count > 0 && count <= 4);
return (GrGLShaderVar::Type)(count - 1);
}
inline const char* float_vector_type_str(int count) {
return GrGLShaderVar::TypeString(float_vector_type(count));
}
inline const char* vector_homog_coord(int count) {
static const char* HOMOGS[] = {"ERROR", "", ".y", ".z", ".w"};
GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(HOMOGS));
return HOMOGS[count];
}
inline const char* vector_nonhomog_coords(int count) {
static const char* NONHOMOGS[] = {"ERROR", "", ".x", ".xy", ".xyz"};
GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(NONHOMOGS));
return NONHOMOGS[count];
return GrGLShaderVar::TypeString(GrSLFloatVectorType(count));
}
inline const char* vector_all_coords(int count) {
@ -370,7 +349,7 @@ 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(GrGLShaderVar::Type type,
void append_varying(GrSLType type,
const char* name,
ShaderCodeSegments* segments,
const char** vsOutName = NULL,
@ -416,7 +395,7 @@ void append_varying(GrGLShaderVar::Type type,
// version of above that adds a stage number to the
// the var name (for uniqueness)
void append_varying(GrGLShaderVar::Type type,
void append_varying(GrSLType type,
const char* name,
int stageNum,
ShaderCodeSegments* segments,
@ -434,7 +413,7 @@ void GrGLProgram::genEdgeCoverage(const GrGLContextInfo& gl,
GrStringBuilder* coverageVar,
ShaderCodeSegments* segments) const {
if (fProgramDesc.fEdgeAANumEdges > 0) {
segments->fFSUnis.push_back().set(GrGLShaderVar::kVec3f_Type,
segments->fFSUnis.push_back().set(kVec3f_GrSLType,
GrGLShaderVar::kUniform_TypeModifier,
EDGES_UNI_NAME,
fProgramDesc.fEdgeAANumEdges);
@ -485,9 +464,9 @@ void GrGLProgram::genEdgeCoverage(const GrGLContextInfo& gl,
*coverageVar = "edgeAlpha";
} else if (layout & GrDrawTarget::kEdge_VertexLayoutBit) {
const char *vsName, *fsName;
append_varying(GrGLShaderVar::kVec4f_Type, "Edge", segments,
append_varying(kVec4f_GrSLType, "Edge", segments,
&vsName, &fsName);
segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type,
segments->fVSAttrs.push_back().set(kVec4f_GrSLType,
GrGLShaderVar::kAttribute_TypeModifier, EDGE_ATTR_NAME);
segments->fVSCode.appendf("\t%s = " EDGE_ATTR_NAME ";\n", vsName);
if (GrDrawState::kHairLine_EdgeType == fProgramDesc.fVertexEdgeType) {
@ -539,16 +518,16 @@ void genInputColor(GrGLProgram::ProgramDesc::ColorInput colorInput,
GrStringBuilder* inColor) {
switch (colorInput) {
case GrGLProgram::ProgramDesc::kAttribute_ColorInput: {
segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type,
segments->fVSAttrs.push_back().set(kVec4f_GrSLType,
GrGLShaderVar::kAttribute_TypeModifier,
COL_ATTR_NAME);
const char *vsName, *fsName;
append_varying(GrGLShaderVar::kVec4f_Type, "Color", segments, &vsName, &fsName);
append_varying(kVec4f_GrSLType, "Color", segments, &vsName, &fsName);
segments->fVSCode.appendf("\t%s = " COL_ATTR_NAME ";\n", vsName);
*inColor = fsName;
} break;
case GrGLProgram::ProgramDesc::kUniform_ColorInput:
segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
segments->fFSUnis.push_back().set(kVec4f_GrSLType,
GrGLShaderVar::kUniform_TypeModifier,
COL_UNI_NAME);
programData->fUniLocations.fColorUni = kUseUniform;
@ -567,11 +546,11 @@ void genInputColor(GrGLProgram::ProgramDesc::ColorInput colorInput,
void genAttributeCoverage(ShaderCodeSegments* segments,
GrStringBuilder* inOutCoverage) {
segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type,
segments->fVSAttrs.push_back().set(kVec4f_GrSLType,
GrGLShaderVar::kAttribute_TypeModifier,
COV_ATTR_NAME);
const char *vsName, *fsName;
append_varying(GrGLShaderVar::kVec4f_Type, "Coverage",
append_varying(kVec4f_GrSLType, "Coverage",
segments, &vsName, &fsName);
segments->fVSCode.appendf("\t%s = " COV_ATTR_NAME ";\n", vsName);
if (inOutCoverage->size()) {
@ -586,7 +565,7 @@ void genAttributeCoverage(ShaderCodeSegments* segments,
void genUniformCoverage(ShaderCodeSegments* segments,
GrGLProgram::CachedData* programData,
GrStringBuilder* inOutCoverage) {
segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
segments->fFSUnis.push_back().set(kVec4f_GrSLType,
GrGLShaderVar::kUniform_TypeModifier,
COV_UNI_NAME);
programData->fUniLocations.fCoverageUni = kUseUniform;
@ -711,15 +690,15 @@ bool GrGLProgram::genProgram(const GrGLContextInfo& gl,
}
#if GR_GL_ATTRIBUTE_MATRICES
segments.fVSAttrs.push_back().set(GrGLShaderVar::kMat33f_Type,
segments.fVSAttrs.push_back().set(kMat33f_GrSLType,
GrGLShaderVar::kAttribute_TypeModifier, VIEW_MATRIX_NAME);
programData->fUniLocations.fViewMatrixUni = kSetAsAttribute;
#else
segments.fVSUnis.push_back().set(GrGLShaderVar::kMat33f_Type,
segments.fVSUnis.push_back().set(kMat33f_GrSLType,
GrGLShaderVar::kUniform_TypeModifier, VIEW_MATRIX_NAME);
programData->fUniLocations.fViewMatrixUni = kUseUniform;
#endif
segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec2f_Type,
segments.fVSAttrs.push_back().set(kVec2f_GrSLType,
GrGLShaderVar::kAttribute_TypeModifier, POS_ATTR_NAME);
segments.fVSCode.append(
@ -747,7 +726,7 @@ bool GrGLProgram::genProgram(const GrGLContextInfo& gl,
for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
if (GrDrawTarget::VertexUsesTexCoordIdx(t, layout)) {
tex_attr_name(t, texCoordAttrs + t);
segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec2f_Type,
segments.fVSAttrs.push_back().set(kVec2f_GrSLType,
GrGLShaderVar::kAttribute_TypeModifier,
texCoordAttrs[t].c_str());
}
@ -807,7 +786,7 @@ bool GrGLProgram::genProgram(const GrGLContextInfo& gl,
}
}
if (needColorFilterUniform) {
segments.fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
segments.fFSUnis.push_back().set(kVec4f_GrSLType,
GrGLShaderVar::kUniform_TypeModifier,
COL_FILTER_UNI_NAME);
programData->fUniLocations.fColorFilterUni = kUseUniform;
@ -828,10 +807,10 @@ bool GrGLProgram::genProgram(const GrGLContextInfo& gl,
inColor = "filteredColor";
}
if (applyColorMatrix) {
segments.fFSUnis.push_back().set(GrGLShaderVar::kMat44f_Type,
segments.fFSUnis.push_back().set(kMat44f_GrSLType,
GrGLShaderVar::kUniform_TypeModifier,
COL_MATRIX_UNI_NAME);
segments.fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
segments.fFSUnis.push_back().set(kVec4f_GrSLType,
GrGLShaderVar::kUniform_TypeModifier,
COL_MATRIX_VEC_UNI_NAME);
programData->fUniLocations.fColorMatrixUni = kUseUniform;
@ -911,7 +890,7 @@ bool GrGLProgram::genProgram(const GrGLContextInfo& gl,
}
}
if (ProgramDesc::kNone_DualSrcOutput != fProgramDesc.fDualSrcOutput) {
segments.fFSOutputs.push_back().set(GrGLShaderVar::kVec4f_Type,
segments.fFSOutputs.push_back().set(kVec4f_GrSLType,
GrGLShaderVar::kOut_TypeModifier,
dual_source_output_name());
bool outputIsZero = coverageIsZero;
@ -1411,7 +1390,7 @@ GrGLShaderVar* genRadialVS(int stageNum,
int varyingDims, int coordDims) {
GrGLShaderVar* radial2FSParams = &segments->fFSUnis.push_back();
radial2FSParams->setType(GrGLShaderVar::kFloat_Type);
radial2FSParams->setType(kFloat_GrSLType);
radial2FSParams->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
radial2FSParams->setArrayCount(6);
radial2_param_name(stageNum, radial2FSParams->accessName());
@ -1423,7 +1402,7 @@ GrGLShaderVar* genRadialVS(int stageNum,
// part of the quadratic as a varying.
if (varyingDims == coordDims) {
GrAssert(2 == coordDims);
append_varying(GrGLShaderVar::kFloat_Type,
append_varying(kFloat_GrSLType,
"Radial2BCoeff",
stageNum,
segments,
@ -1601,11 +1580,11 @@ void genConvolutionVS(int stageNum,
const char* varyingVSName) {
//GrGLShaderVar* kernel = &segments->fFSUnis.push_back();
*kernel = &segments->fFSUnis.push_back();
(*kernel)->setType(GrGLShaderVar::kFloat_Type);
(*kernel)->setType(kFloat_GrSLType);
(*kernel)->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
(*kernel)->setArrayCount(desc.fKernelWidth);
GrGLShaderVar* imgInc = &segments->fFSUnis.push_back();
imgInc->setType(GrGLShaderVar::kVec2f_Type);
imgInc->setType(kVec2f_GrSLType);
imgInc->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
convolve_param_names(stageNum,
@ -1669,7 +1648,7 @@ void genMorphologyVS(int stageNum,
const char** imageIncrementName,
const char* varyingVSName) {
GrGLShaderVar* imgInc = &segments->fFSUnis.push_back();
imgInc->setType(GrGLShaderVar::kVec2f_Type);
imgInc->setType(kVec2f_GrSLType);
imgInc->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
image_increment_param_name(stageNum, imgInc->accessName());
@ -1763,7 +1742,7 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
locations->fTextureMatrixUni = kUseUniform;
#endif
tex_matrix_name(stageNum, mat->accessName());
mat->setType(GrGLShaderVar::kMat33f_Type);
mat->setType(kMat33f_GrSLType);
matName = mat->getName().c_str();
if (desc.fOptFlags & StageDesc::kNoPerspective_OptFlagBit) {
@ -1773,7 +1752,7 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
}
}
segments->fFSUnis.push_back().set(GrGLShaderVar::kSampler2D_Type,
segments->fFSUnis.push_back().set(kSampler2D_GrSLType,
GrGLShaderVar::kUniform_TypeModifier, "");
sampler_name(stageNum, segments->fFSUnis.back().accessName());
locations->fSamplerUni = kUseUniform;
@ -1781,14 +1760,14 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
const char* texelSizeName = NULL;
if (StageDesc::k2x2_FetchMode == desc.fFetchMode) {
segments->fFSUnis.push_back().set(GrGLShaderVar::kVec2f_Type,
segments->fFSUnis.push_back().set(kVec2f_GrSLType,
GrGLShaderVar::kUniform_TypeModifier, "");
normalized_texel_size_name(stageNum, segments->fFSUnis.back().accessName());
texelSizeName = segments->fFSUnis.back().getName().c_str();
}
const char *varyingVSName, *varyingFSName;
append_varying(float_vector_type(varyingDims),
append_varying(GrSLFloatVectorType(varyingDims),
"Stage",
stageNum,
segments,
@ -1849,12 +1828,12 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
fsCoordName = "inCoord";
fsCoordName.appendS32(stageNum);
segments->fFSCode.appendf("\t%s %s = %s%s / %s%s;\n",
GrGLShaderVar::TypeString(float_vector_type(coordDims)),
fsCoordName.c_str(),
varyingFSName,
vector_nonhomog_coords(varyingDims),
varyingFSName,
vector_homog_coord(varyingDims));
GrGLShaderVar::TypeString(GrSLFloatVectorType(coordDims)),
fsCoordName.c_str(),
varyingFSName,
GrGLSLVectorNonhomogCoords(varyingDims),
varyingFSName,
GrGLSLVectorHomogCoord(varyingDims));
}
}
@ -1918,7 +1897,7 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
StageDesc::kCustomTextureDomain_OptFlagBit) {
GrStringBuilder texDomainName;
tex_domain_name(stageNum, &texDomainName);
segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
segments->fFSUnis.push_back().set(kVec4f_GrSLType,
GrGLShaderVar::kUniform_TypeModifier, texDomainName);
GrStringBuilder coordVar("clampCoord");
segments->fFSCode.appendf("\t%s %s = clamp(%s, %s.xy, %s.zw);\n",

View File

@ -0,0 +1,79 @@
/*
* 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 "GrGLSL.h"
#include "GrGLProgramStage.h"
GrGLProgramStageFactory::~GrGLProgramStageFactory(void) {
}
uint16_t GrGLProgramStageFactory::stageKey(const GrCustomStage*) {
return 0;
}
void GrGLProgramStage::setupVSUnis(VarArray& vsUnis, int stage) {
}
void GrGLProgramStage::setupFSUnis(VarArray& fsUnis, int stage) {
}
void GrGLProgramStage::initUniforms(const GrGLInterface*, int progID) {
}
void GrGLProgramStage::setData(const GrGLInterface*, GrCustomStage*) {
}
GrStringBuilder GrGLProgramStage::emitTextureSetup(GrStringBuilder* code,
const char* coordName,
int stageNum,
int coordDims,
int varyingDims) {
GrStringBuilder retval;
switch (fSamplerMode) {
case kDefault_SamplerMode:
// Fall through
case kProj_SamplerMode:
// Do nothing
retval = coordName;
break;
case kExplicitDivide_SamplerMode:
retval = "inCoord";
retval.appendS32(stageNum);
code->appendf("\t %s %s = %s%s / %s%s\n",
GrGLShaderVar::TypeString(GrSLFloatVectorType(coordDims)),
fCoordName.c_str(),
coordName,
GrGLSLVectorNonhomogCoords(varyingDims),
coordName,
GrGLSLVectorHomogCoord(varyingDims));
break;
}
return retval;
}
void GrGLProgramStage::emitTextureLookup(GrStringBuilder* code,
const char* samplerName,
const char* coordName) {
switch (fSamplerMode) {
case kDefault_SamplerMode:
// Fall through
case kExplicitDivide_SamplerMode:
code->appendf("texture2D(%s, %s)", samplerName, coordName);
break;
case kProj_SamplerMode:
code->appendf("texture2DProj(%s, %s)", samplerName, coordName);
break;
}
}

View File

@ -0,0 +1,146 @@
/*
* 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 GrGLCustomStage_DEFINED
#define GrGLCustomStage_DEFINED
#include "../GrAllocator.h"
#include "GrGLShaderVar.h"
#include "GrGLSL.h"
#include "../GrStringBuilder.h"
class GrCustomStage;
class GrGLInterface;
/** @file
This file contains specializations for OpenGL of the shader stages
declared in src/gpu/GrCustomStage.h. All the functions emit
GLSL shader code and OpenGL calls.
These objects are created by a factory function on the
GrCustomStage.
TODO: lifetime management.
*/
class GrGLProgramStage {
public:
// TODO: redundant with GrGLProgram.cpp
enum {
kUnusedUniform = -1,
kUseUniform = 2000
};
typedef GrTAllocator<GrGLShaderVar> VarArray;
/** Creates any uniform variables the vertex shader requires
and appends them to vsUnis;
must guarantee they are unique (typically done by
appending the stage number). */
virtual void setupVSUnis(VarArray& vsUnis, int stage);
/** Creates any uniform variables the fragment shader requires
and appends them to fsUnis;
must guarantee they are unique (typically done by
appending the stage number). */
virtual void setupFSUnis(VarArray& fsUnis, int stage);
/** Given an empty GrStringBuilder and the names of variables;
must write shader code into that GrStringBuilder.
Vertex shader input is a vec2 of coordinates, which may
be altered.
The code will be inside an otherwise-empty block. */
virtual void emitVS(GrStringBuilder* code,
const char* vertexCoords) = 0;
/** Given an empty GrStringBuilder and the names of variables;
must write shader code into that GrStringBuilder.
The code will be inside an otherwise-empty block.
Fragment shader inputs are a vec2 of coordinates, one texture,
and a color; output is a color. */
/* TODO: don't give them the samplerName, just a handle; then give
a function here for them to call into that'll apply any texture
domain - but do we force them to be honest about texture domain
parameters? */
virtual void emitFS(GrStringBuilder* code,
const char* outputColor,
const char* inputColor,
const char* samplerName,
const char* sampleCoords) = 0;
/** Binds uniforms; we must have already bound the program and
determined its GL program ID. */
virtual void initUniforms(const GrGLInterface*, int programID);
/** A GrGLCustomStage instance can be reused with any GrCustomStage
that produces the same stage key; this function reads data from
a stage and uploads any uniform variables required by the shaders
created in emit*().
flush() to change the GrCustomStage from which the uniforms
are to be read.
TODO: since we don't have a factory, we can't assert to enforce
this. Shouldn't we? */
virtual void setData(const GrGLInterface*, GrCustomStage*);
// TODO: needs a better name
enum SamplerMode {
kDefault_SamplerMode,
kProj_SamplerMode,
kExplicitDivide_SamplerMode // must do an explicit divide
};
void setSamplerMode(SamplerMode shaderMode) { fSamplerMode = shaderMode; }
protected:
/** Returns the *effective* coord name after any perspective divide
or other transform. */
GrStringBuilder emitTextureSetup(GrStringBuilder* code,
const char* coordName,
int stageNum,
int coordDims,
int varyingDims);
/** Convenience function for subclasses to write texture2D() or
texture2DProj(), depending on fSamplerMode. */
void emitTextureLookup(GrStringBuilder* code,
const char* samplerName,
const char* coordName);
SamplerMode fSamplerMode;
GrStringBuilder fCoordName;
};
/// Every GrGLProgramStage subclass needs a GrGLProgramStageFactory subclass
/// to manage its creation.
class GrGLProgramStageFactory {
public:
virtual ~GrGLProgramStageFactory();
/** Returns a short unique identifier for this subclass x its
parameters. If the key differs, different shader code must
be generated; if the key matches, shader code can be reused.
0 == no custom stage. */
virtual uint16_t stageKey(const GrCustomStage*);
virtual GrGLProgramStage* createGLInstance(GrCustomStage*) = 0;
protected:
/** Disable default constructor - instances should be singletons
with static factory functions: our test examples are all stateless,
but we suspect that future implementations may want to cache data? */
GrGLProgramStageFactory() { }
};
#endif

View File

@ -75,8 +75,30 @@ bool GrGLSLSetupFSColorOuput(GrGLSLGeneration gen,
const char* nameIfDeclared,
GrGLShaderVar* var) {
bool declaredOutput = k110_GrGLSLGeneration != gen;
var->set(GrGLShaderVar::kVec4f_Type,
var->set(kVec4f_GrSLType,
GrGLShaderVar::kOut_TypeModifier,
declaredOutput ? nameIfDeclared : "gl_FragColor");
return declaredOutput;
}
GrSLType GrSLFloatVectorType (int count) {
GR_STATIC_ASSERT(kFloat_GrSLType == 0);
GR_STATIC_ASSERT(kVec2f_GrSLType == 1);
GR_STATIC_ASSERT(kVec3f_GrSLType == 2);
GR_STATIC_ASSERT(kVec4f_GrSLType == 3);
GrAssert(count > 0 && count <= 4);
return (GrSLType)(count - 1);
}
const char* GrGLSLVectorHomogCoord(int count) {
static const char* HOMOGS[] = {"ERROR", "", ".y", ".z", ".w"};
GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(HOMOGS));
return HOMOGS[count];
}
const char* GrGLSLVectorNonhomogCoords(int count) {
static const char* NONHOMOGS[] = {"ERROR", "", ".x", ".xy", ".xyz"};
GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(NONHOMOGS));
return NONHOMOGS[count];
}

View File

@ -29,6 +29,21 @@ enum GrGLSLGeneration {
k150_GrGLSLGeneration,
};
/**
* Types of shader-language-specific boxed variables we can create.
* (Currently only GrGLShaderVars, but should be applicable to other shader
* langauges.)
*/
enum GrSLType {
kFloat_GrSLType,
kVec2f_GrSLType,
kVec3f_GrSLType,
kVec4f_GrSLType,
kMat33f_GrSLType,
kMat44f_GrSLType,
kSampler2D_GrSLType
};
/**
* Gets the most recent GLSL Generation compatible with the OpenGL context.
*/
@ -69,8 +84,20 @@ const char* GrGetGLSLShaderPrecisionDecl(GrGLBinding binding);
* In either case var is initialized to represent the color output in the
* shader.
*/
bool GrGLSLSetupFSColorOuput(GrGLSLGeneration gen,
bool GrGLSLSetupFSColorOuput(GrGLSLGeneration gen,
const char* nameIfDeclared,
GrGLShaderVar* var);
/** Convert a count of 1..n floats into the corresponding type enum,
e.g. 1 -> kFloat_GrSLType, 2 -> kVec2_GrSLType, ... */
GrSLType GrSLFloatVectorType(int count);
/** Return the GLSL swizzle operator for a homogenous component of a vector
with the given number of coordnates, e.g. 2 -> ".y", 3 -> ".z" */
const char* GrGLSLVectorHomogCoord(int count);
/** Return the GLSL swizzle operator for a nonhomogenous components of a vector
with the given number of coordnates, e.g. 2 -> ".x", 3 -> ".xy" */
const char* GrGLSLVectorNonhomogCoords(int count);
#endif

View File

@ -21,16 +21,6 @@
class GrGLShaderVar {
public:
enum Type {
kFloat_Type,
kVec2f_Type,
kVec3f_Type,
kVec4f_Type,
kMat33f_Type,
kMat44f_Type,
kSampler2D_Type,
};
/**
* Early versions of GLSL have Varying and Attribute; those are later
* deprecated, but we still need to know whether a Varying variable
@ -48,7 +38,7 @@ public:
* Defaults to a float with no precision specifier
*/
GrGLShaderVar() {
fType = kFloat_Type;
fType = kFloat_GrSLType;
fTypeModifier = kNone_TypeModifier;
fCount = kNonArray;
fEmitPrecision = false;
@ -74,7 +64,7 @@ public:
/**
* Sets as a non-array.
*/
void set(Type type,
void set(GrSLType type,
TypeModifier typeModifier,
const GrStringBuilder& name,
bool emitPrecision = false,
@ -90,7 +80,7 @@ public:
/**
* Sets as a non-array.
*/
void set(Type type,
void set(GrSLType type,
TypeModifier typeModifier,
const char* name,
bool specifyPrecision = false,
@ -106,7 +96,7 @@ public:
/**
* Set all var options
*/
void set(Type type,
void set(GrSLType type,
TypeModifier typeModifier,
const GrStringBuilder& name,
int count,
@ -123,7 +113,7 @@ public:
/**
* Set all var options
*/
void set(Type type,
void set(GrSLType type,
TypeModifier typeModifier,
const char* name,
int count,
@ -179,11 +169,11 @@ public:
/**
* Get the type of the var
*/
Type getType() const { return fType; }
GrSLType getType() const { return fType; }
/**
* Set the type of the var
*/
void setType(Type type) { fType = type; }
void setType(GrSLType type) { fType = type; }
TypeModifier getTypeModifier() const { return fTypeModifier; }
void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
@ -210,7 +200,7 @@ public:
out->append(GrGetGLSLVarPrecisionDeclType(gl.binding()));
out->append(" ");
}
Type effectiveType = this->getType();
GrSLType effectiveType = this->getType();
if (this->isArray()) {
if (this->isUnsizedArray()) {
out->appendf("%s %s[]",
@ -231,21 +221,21 @@ public:
out->append(";\n");
}
static const char* TypeString(Type t) {
static const char* TypeString(GrSLType t) {
switch (t) {
case kFloat_Type:
case kFloat_GrSLType:
return "float";
case kVec2f_Type:
case kVec2f_GrSLType:
return "vec2";
case kVec3f_Type:
case kVec3f_GrSLType:
return "vec3";
case kVec4f_Type:
case kVec4f_GrSLType:
return "vec4";
case kMat33f_Type:
case kMat33f_GrSLType:
return "mat3";
case kMat44f_Type:
case kMat44f_GrSLType:
return "mat4";
case kSampler2D_Type:
case kSampler2D_GrSLType:
return "sampler2D";
default:
GrCrash("Unknown shader var type.");
@ -287,7 +277,7 @@ private:
}
}
Type fType;
GrSLType fType;
TypeModifier fTypeModifier;
GrStringBuilder fName;
int fCount;