Chromium Code Reviews| Index: src/gpu/glsl/GrGLSLVarying.h |
| diff --git a/src/gpu/glsl/GrGLSLVarying.h b/src/gpu/glsl/GrGLSLVarying.h |
| index 22431978c859666d57d33dcc0619c51694420c0e..8697ebb129e7ded8ba709d1ff45f92e79520585c 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 fName; |
|
egdaniel
2016/02/12 18:53:06
I think using fName is kind of confusing since it
Chris Dalton
2016/02/12 19:35:03
Done.
|
| + 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; |
| }; |