diff options
author | 2012-04-18 17:49:20 +0000 | |
---|---|---|
committer | 2012-04-18 17:49:20 +0000 | |
commit | 168e63418cadba4018aadf95c091d40d9deb13b9 (patch) | |
tree | e99bf7049023ed0c763ab19fd0ce9944a972f2b1 /src/gpu | |
parent | 95ead84e0fe4a81b5a3343204a348ce600b47bb5 (diff) |
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
Diffstat (limited to 'src/gpu')
-rwxr-xr-x | src/gpu/GrAllocator.h | 1 | ||||
-rw-r--r-- | src/gpu/GrCustomStage.cpp | 22 | ||||
-rw-r--r-- | src/gpu/GrCustomStage.h | 34 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 93 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramStage.cpp | 79 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramStage.h | 146 | ||||
-rw-r--r-- | src/gpu/gl/GrGLSL.cpp | 24 | ||||
-rw-r--r-- | src/gpu/gl/GrGLSL.h | 29 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderVar.h | 44 |
9 files changed, 386 insertions, 86 deletions
diff --git a/src/gpu/GrAllocator.h b/src/gpu/GrAllocator.h index 555e56ffc1..f333d42e37 100755 --- a/src/gpu/GrAllocator.h +++ b/src/gpu/GrAllocator.h @@ -11,6 +11,7 @@ #ifndef GrAllocator_DEFINED #define GrAllocator_DEFINED +#include "GrNoncopyable.h" #include "GrConfig.h" #include "SkTArray.h" diff --git a/src/gpu/GrCustomStage.cpp b/src/gpu/GrCustomStage.cpp new file mode 100644 index 0000000000..f63c79ad3b --- /dev/null +++ b/src/gpu/GrCustomStage.cpp @@ -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; +} + diff --git a/src/gpu/GrCustomStage.h b/src/gpu/GrCustomStage.h new file mode 100644 index 0000000000..a5b8133c7f --- /dev/null +++ b/src/gpu/GrCustomStage.h @@ -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 diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index f2776474af..16a60cee91 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -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", diff --git a/src/gpu/gl/GrGLProgramStage.cpp b/src/gpu/gl/GrGLProgramStage.cpp new file mode 100644 index 0000000000..0ba0399554 --- /dev/null +++ b/src/gpu/gl/GrGLProgramStage.cpp @@ -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; + } + +} + diff --git a/src/gpu/gl/GrGLProgramStage.h b/src/gpu/gl/GrGLProgramStage.h new file mode 100644 index 0000000000..c9c4100c1a --- /dev/null +++ b/src/gpu/gl/GrGLProgramStage.h @@ -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 diff --git a/src/gpu/gl/GrGLSL.cpp b/src/gpu/gl/GrGLSL.cpp index e933ee87c9..21dd940c66 100644 --- a/src/gpu/gl/GrGLSL.cpp +++ b/src/gpu/gl/GrGLSL.cpp @@ -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]; +} + diff --git a/src/gpu/gl/GrGLSL.h b/src/gpu/gl/GrGLSL.h index a3d3921bfc..587d6f27b4 100644 --- a/src/gpu/gl/GrGLSL.h +++ b/src/gpu/gl/GrGLSL.h @@ -30,6 +30,21 @@ enum 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. */ GrGLSLGeneration GrGetGLSLGeneration(GrGLBinding binding, @@ -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 diff --git a/src/gpu/gl/GrGLShaderVar.h b/src/gpu/gl/GrGLShaderVar.h index dc7d52b3a7..149214e33f 100644 --- a/src/gpu/gl/GrGLShaderVar.h +++ b/src/gpu/gl/GrGLShaderVar.h @@ -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; |