Index: src/gpu/glsl/GrGLSLVarying.h |
diff --git a/src/gpu/glsl/GrGLSLVarying.h b/src/gpu/glsl/GrGLSLVarying.h |
index 22431978c859666d57d33dcc0619c51694420c0e..5867361ce4a48648e54fa7d317d3548c0671f729 100644 |
--- a/src/gpu/glsl/GrGLSLVarying.h |
+++ b/src/gpu/glsl/GrGLSLVarying.h |
@@ -71,18 +71,25 @@ static const int kVaryingsPerBlock = 8; |
class GrGLSLVaryingHandler { |
public: |
explicit GrGLSLVaryingHandler(GrGLSLProgramBuilder* program) |
- : fVertexInputs(kVaryingsPerBlock) |
+ : fVaryings(kVaryingsPerBlock) |
+ , fVertexInputs(kVaryingsPerBlock) |
, fVertexOutputs(kVaryingsPerBlock) |
, fGeomInputs(kVaryingsPerBlock) |
, fGeomOutputs(kVaryingsPerBlock) |
, fFragInputs(kVaryingsPerBlock) |
, fFragOutputs(kVaryingsPerBlock) |
- , fProgramBuilder(program) {} |
+ , fProgramBuilder(program) |
+ , fDefaultInterpolationModifier(nullptr) {} |
virtual ~GrGLSLVaryingHandler() {} |
- typedef GrTAllocator<GrGLSLShaderVar> VarArray; |
- typedef GrGLSLProgramDataManager::VaryingHandle VaryingHandle; |
+ /* |
+ * Notifies the varying handler that this shader will never emit geometry in perspective and |
+ * therefore does not require perspective-correct interpolation. When supported, this allows |
+ * varyings to use the "noperspective" keyword, which means the GPU can use cheaper math for |
+ * interpolation. |
+ */ |
+ void setNoPerspective(); |
/* |
* addVarying allows fine grained control for setting up varyings between stages. Calling this |
@@ -93,18 +100,36 @@ public: |
* TODO convert most uses of addVarying to addPassThroughAttribute |
*/ |
void addVarying(const char* name, |
- GrGLSLVarying*, |
- GrSLPrecision precision = kDefault_GrSLPrecision); |
+ GrGLSLVarying* varying, |
+ GrSLPrecision precision = kDefault_GrSLPrecision) { |
+ SkASSERT(GrSLTypeIsFloatType(varying->type())); // Integers must use addFlatVarying. |
+ this->internalAddVarying(name, varying, precision, false /*flat*/); |
+ } |
+ |
+ /* |
+ * addFlatVarying sets up a varying whose value is constant across every fragment. The graphics |
+ * pipeline will pull its value from the final vertex of the draw primitive (provoking vertex). |
+ * Flat interpolation is not always supported and the user must check the caps before using. |
+ * TODO: Some platforms can change the provoking vertex. Should we be resetting this knob? |
+ */ |
+ void addFlatVarying(const char* name, |
+ GrGLSLVarying* varying, |
+ GrSLPrecision precision = kDefault_GrSLPrecision) { |
+ this->internalAddVarying(name, varying, precision, true /*flat*/); |
+ } |
/* |
- * This call can be used by GP to pass an attribute through all shaders directly to 'output' in |
- * the fragment shader. Though this call effects both the vertex shader and fragment shader, |
- * it expects 'output' to be defined in the fragment shader before this call is made. If there |
+ * The GP can use these calls to pass an attribute through all shaders directly to 'output' in |
+ * the fragment shader. Though these calls affect both the vertex shader and fragment shader, |
+ * they expect 'output' to be defined in the fragment shader before the call is made. If there |
* is a geometry shader, we will simply take the value of the varying from the first vertex and |
* that will be set as the output varying for all emitted vertices. |
- * TODO it might be nicer behavior to have a flag to declare output inside this call |
+ * TODO it might be nicer behavior to have a flag to declare output inside these calls |
*/ |
- void addPassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output); |
+ void addPassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output, |
+ GrSLPrecision = kDefault_GrSLPrecision); |
+ void addFlatPassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output, |
+ GrSLPrecision = kDefault_GrSLPrecision); |
void emitAttributes(const GrGeometryProcessor& gp); |
@@ -115,21 +140,36 @@ public: |
void getVertexDecls(SkString* inputDecls, SkString* outputDecls) const; |
void getGeomDecls(SkString* inputDecls, SkString* outputDecls) const; |
void getFragDecls(SkString* inputDecls, SkString* outputDecls) const; |
+ |
protected: |
- VarArray fVertexInputs; |
- VarArray fVertexOutputs; |
- VarArray fGeomInputs; |
- VarArray fGeomOutputs; |
- VarArray fFragInputs; |
- VarArray fFragOutputs; |
+ struct VaryingInfo { |
+ GrSLType fType; |
+ GrSLPrecision fPrecision; |
+ bool fIsFlat; |
+ SkString fVsOut; |
+ SkString fGsOut; |
+ GrShaderFlags fVisibility; |
+ }; |
+ |
+ typedef GrTAllocator<VaryingInfo> VaryingList; |
+ typedef GrTAllocator<GrGLSLShaderVar> VarArray; |
+ typedef GrGLSLProgramDataManager::VaryingHandle VaryingHandle; |
+ |
+ VaryingList fVaryings; |
+ VarArray fVertexInputs; |
+ VarArray fVertexOutputs; |
+ VarArray fGeomInputs; |
+ VarArray fGeomOutputs; |
+ VarArray fFragInputs; |
+ VarArray fFragOutputs; |
// This is not owned by the class |
GrGLSLProgramBuilder* fProgramBuilder; |
private: |
- void addVertexVarying(const char* name, GrSLPrecision precision, GrGLSLVarying* v); |
- void addGeomVarying(const char* name, GrSLPrecision precision, GrGLSLVarying* v); |
- void addFragVarying(GrSLPrecision precision, GrGLSLVarying* v); |
+ void internalAddVarying(const char* name, GrGLSLVarying*, GrSLPrecision, bool flat); |
+ void writePassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output, |
+ const GrGLSLVarying&); |
void addAttribute(const GrShaderVar& var); |
@@ -138,6 +178,8 @@ private: |
// helper function for get*Decls |
void appendDecls(const VarArray& vars, SkString* out) const; |
+ const char* fDefaultInterpolationModifier; |
+ |
friend class GrGLSLProgramBuilder; |
}; |