Chromium Code Reviews| Index: src/gpu/glsl/GrGLSLVarying.h |
| diff --git a/src/gpu/glsl/GrGLSLVarying.h b/src/gpu/glsl/GrGLSLVarying.h |
| index 116ba09b99bd9d2b797a328494bd49b903d5ca81..899d1e30e8bddb7d4e6d6b988fb08dc561b2781a 100644 |
| --- a/src/gpu/glsl/GrGLSLVarying.h |
| +++ b/src/gpu/glsl/GrGLSLVarying.h |
| @@ -72,15 +72,17 @@ class GrGLSLVaryingHandler { |
| public: |
| explicit GrGLSLVaryingHandler(GrGLSLProgramBuilder* program) |
| : fVertexInputs(kVaryingsPerBlock) |
| - , fVertexOutputs(kVaryingsPerBlock) |
| - , fGeomInputs(kVaryingsPerBlock) |
| - , fGeomOutputs(kVaryingsPerBlock) |
| - , fFragInputs(kVaryingsPerBlock) |
| + , fVaryingShaderVars(kVaryingsPerBlock) |
| , fFragOutputs(kVaryingsPerBlock) |
| - , fProgramBuilder(program) {} |
| - |
| - typedef GrTAllocator<GrGLSLShaderVar> VarArray; |
| - typedef GrGLSLProgramDataManager::VaryingHandle VaryingHandle; |
| + , fProgramBuilder(program) |
| + , fNoPerspective(false) {} |
| + /* |
| + * 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 |
| @@ -91,44 +93,81 @@ 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*/); |
| + } |
| /* |
| - * 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 |
| + * 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, |
|
egdaniel
2016/02/10 14:23:44
instead of adding a new call here, does it make mo
Chris Dalton
2016/02/10 15:29:30
I thought this over quite a bit myself and my pref
|
| + GrGLSLVarying* varying, |
| + GrSLPrecision precision = kDefault_GrSLPrecision) { |
| + this->internalAddVarying(name, varying, precision, true /*flat*/); |
| + } |
| + |
| + /* |
| + * 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); |
| 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 VaryingShaderVars { |
| + GrGLSLShaderVar fVertexOutput; |
| + GrGLSLShaderVar fGeomInput; |
| + GrGLSLShaderVar fGeomOutput; |
| + GrGLSLShaderVar fFragInput; |
| + bool fIsFlat; |
| + |
| + void addModifier(const char* modifier) { |
| + fVertexOutput.addModifier(modifier); |
| + fGeomInput.addModifier(modifier); |
| + fGeomOutput.addModifier(modifier); |
| + fFragInput.addModifier(modifier); |
| + } |
| + }; |
| + |
| + typedef GrTAllocator<GrGLSLShaderVar> ShaderVarList; |
| + typedef GrTAllocator<VaryingShaderVars> VaryingShaderVarsList; |
| + typedef GrGLSLProgramDataManager::VaryingHandle VaryingHandle; |
| + |
| + ShaderVarList fVertexInputs; |
| + VaryingShaderVarsList fVaryingShaderVars; |
| + ShaderVarList 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 addAttribute(const GrShaderVar& var); |
| + void internalAddVarying(const char* name, GrGLSLVarying*, GrSLPrecision, bool flat); |
| + void writePassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output, |
| + const GrGLSLVarying&); |
| + |
| // helper function for get*Decls |
| - void appendDecls(const VarArray& vars, SkString* out) const; |
| + void appendDecls(const ShaderVarList& vars, SkString* out) const; |
| + |
| + bool fNoPerspective; |
| friend class GrGLSLProgramBuilder; |
| }; |