egdaniel | 0eafe79 | 2015-11-20 14:01:22 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2015 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
| 8 | #ifndef GrGLSLVarying_DEFINED |
| 9 | #define GrGLSLVarying_DEFINED |
| 10 | |
| 11 | #include "GrAllocator.h" |
| 12 | #include "GrGeometryProcessor.h" |
| 13 | #include "GrTypesPriv.h" |
| 14 | #include "glsl/GrGLSLProgramDataManager.h" |
| 15 | #include "glsl/GrGLSLShaderVar.h" |
| 16 | |
| 17 | class GrGLSLProgramBuilder; |
| 18 | |
| 19 | class GrGLSLVarying { |
| 20 | public: |
| 21 | bool vsVarying() const { return kVertToFrag_Varying == fVarying || |
| 22 | kVertToGeo_Varying == fVarying; } |
| 23 | bool fsVarying() const { return kVertToFrag_Varying == fVarying || |
| 24 | kGeoToFrag_Varying == fVarying; } |
| 25 | const char* vsOut() const { return fVsOut; } |
| 26 | const char* gsIn() const { return fGsIn; } |
| 27 | const char* gsOut() const { return fGsOut; } |
| 28 | const char* fsIn() const { return fFsIn; } |
| 29 | GrSLType type() const { return fType; } |
| 30 | |
| 31 | protected: |
| 32 | enum Varying { |
| 33 | kVertToFrag_Varying, |
| 34 | kVertToGeo_Varying, |
| 35 | kGeoToFrag_Varying, |
| 36 | }; |
| 37 | |
| 38 | GrGLSLVarying(GrSLType type, Varying varying) |
| 39 | : fVarying(varying), fType(type), fVsOut(nullptr), fGsIn(nullptr), fGsOut(nullptr), |
| 40 | fFsIn(nullptr) {} |
| 41 | |
| 42 | Varying fVarying; |
| 43 | |
| 44 | private: |
| 45 | GrSLType fType; |
| 46 | const char* fVsOut; |
| 47 | const char* fGsIn; |
| 48 | const char* fGsOut; |
| 49 | const char* fFsIn; |
| 50 | |
| 51 | friend class GrGLSLVaryingHandler; |
| 52 | }; |
| 53 | |
| 54 | struct GrGLSLVertToFrag : public GrGLSLVarying { |
| 55 | GrGLSLVertToFrag(GrSLType type) |
| 56 | : GrGLSLVarying(type, kVertToFrag_Varying) {} |
| 57 | }; |
| 58 | |
| 59 | struct GrGLSLVertToGeo : public GrGLSLVarying { |
| 60 | GrGLSLVertToGeo(GrSLType type) |
| 61 | : GrGLSLVarying(type, kVertToGeo_Varying) {} |
| 62 | }; |
| 63 | |
| 64 | struct GrGLSLGeoToFrag : public GrGLSLVarying { |
| 65 | GrGLSLGeoToFrag(GrSLType type) |
| 66 | : GrGLSLVarying(type, kGeoToFrag_Varying) {} |
| 67 | }; |
| 68 | |
| 69 | static const int kVaryingsPerBlock = 8; |
| 70 | |
| 71 | class GrGLSLVaryingHandler { |
| 72 | public: |
| 73 | explicit GrGLSLVaryingHandler(GrGLSLProgramBuilder* program) |
| 74 | : fVertexInputs(kVaryingsPerBlock) |
| 75 | , fVertexOutputs(kVaryingsPerBlock) |
| 76 | , fGeomInputs(kVaryingsPerBlock) |
| 77 | , fGeomOutputs(kVaryingsPerBlock) |
| 78 | , fFragInputs(kVaryingsPerBlock) |
| 79 | , fFragOutputs(kVaryingsPerBlock) |
| 80 | , fProgramBuilder(program) {} |
| 81 | |
| 82 | typedef GrTAllocator<GrGLSLShaderVar> VarArray; |
| 83 | typedef GrGLSLProgramDataManager::VaryingHandle VaryingHandle; |
| 84 | |
| 85 | /* |
| 86 | * addVarying allows fine grained control for setting up varyings between stages. Calling this |
| 87 | * functions will make sure all necessary decls are setup for the client. The client however is |
| 88 | * responsible for setting up all shader code (e.g "vOut = vIn;") If you just need to take an |
| 89 | * attribute and pass it through to an output value in a fragment shader, use |
| 90 | * addPassThroughAttribute. |
| 91 | * TODO convert most uses of addVarying to addPassThroughAttribute |
| 92 | */ |
| 93 | void addVarying(const char* name, |
| 94 | GrGLSLVarying*, |
| 95 | GrSLPrecision precision = kDefault_GrSLPrecision); |
| 96 | |
| 97 | /* |
| 98 | * This call can be used by GP to pass an attribute through all shaders directly to 'output' in |
| 99 | * the fragment shader. Though this call effects both the vertex shader and fragment shader, |
| 100 | * it expects 'output' to be defined in the fragment shader before this call is made. If there |
| 101 | * is a geometry shader, we will simply take the value of the varying from the first vertex and |
| 102 | * that will be set as the output varying for all emitted vertices. |
| 103 | * TODO it might be nicer behavior to have a flag to declare output inside this call |
| 104 | */ |
| 105 | void addPassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output); |
| 106 | |
| 107 | void emitAttributes(const GrGeometryProcessor& gp); |
| 108 | |
| 109 | void getVertexDecls(SkString* inputDecls, SkString* outputDecls) const; |
| 110 | void getGeomDecls(SkString* inputDecls, SkString* outputDecls) const; |
| 111 | void getFragDecls(SkString* inputDecls, SkString* outputDecls) const; |
| 112 | protected: |
| 113 | VarArray fVertexInputs; |
| 114 | VarArray fVertexOutputs; |
| 115 | VarArray fGeomInputs; |
| 116 | VarArray fGeomOutputs; |
| 117 | VarArray fFragInputs; |
| 118 | VarArray fFragOutputs; |
| 119 | |
| 120 | // This is not owned by the class |
| 121 | GrGLSLProgramBuilder* fProgramBuilder; |
| 122 | |
| 123 | private: |
| 124 | void addVertexVarying(const char* name, GrSLPrecision precision, GrGLSLVarying* v); |
| 125 | void addGeomVarying(const char* name, GrSLPrecision precision, GrGLSLVarying* v); |
| 126 | void addFragVarying(GrSLPrecision precision, GrGLSLVarying* v); |
| 127 | |
| 128 | void addAttribute(const GrShaderVar& var); |
| 129 | |
| 130 | // helper function for get*Decls |
| 131 | void appendDecls(const VarArray& vars, SkString* out) const; |
| 132 | |
| 133 | friend class GrGLSLProgramBuilder; |
| 134 | }; |
| 135 | |
| 136 | #endif |