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:
parent
95ead84e0f
commit
168e63418c
@ -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',
|
||||
|
@ -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
22
src/gpu/GrCustomStage.cpp
Normal 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
34
src/gpu/GrCustomStage.h
Normal 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
|
@ -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",
|
||||
|
79
src/gpu/gl/GrGLProgramStage.cpp
Normal file
79
src/gpu/gl/GrGLProgramStage.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
146
src/gpu/gl/GrGLProgramStage.h
Normal file
146
src/gpu/gl/GrGLProgramStage.h
Normal 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
|
@ -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];
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user