aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gyp/gpu.gyp4
-rwxr-xr-xsrc/gpu/GrAllocator.h1
-rw-r--r--src/gpu/GrCustomStage.cpp22
-rw-r--r--src/gpu/GrCustomStage.h34
-rw-r--r--src/gpu/gl/GrGLProgram.cpp93
-rw-r--r--src/gpu/gl/GrGLProgramStage.cpp79
-rw-r--r--src/gpu/gl/GrGLProgramStage.h146
-rw-r--r--src/gpu/gl/GrGLSL.cpp24
-rw-r--r--src/gpu/gl/GrGLSL.h29
-rw-r--r--src/gpu/gl/GrGLShaderVar.h44
10 files changed, 390 insertions, 86 deletions
diff --git a/gyp/gpu.gyp b/gyp/gpu.gyp
index fc2277e0b3..0ffaa283bd 100644
--- a/gyp/gpu.gyp
+++ b/gyp/gpu.gyp
@@ -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',
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;