| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright 2014 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 GrGLShaderBuilder_DEFINED | |
| 9 #define GrGLShaderBuilder_DEFINED | |
| 10 | |
| 11 #include "GrAllocator.h" | |
| 12 #include "glsl/GrGLSLShaderVar.h" | |
| 13 #include "SkTDArray.h" | |
| 14 | |
| 15 #include <stdarg.h> | |
| 16 | |
| 17 class GrGLSLProgramBuilder; | |
| 18 class GrGLSLTextureSampler; | |
| 19 | |
| 20 /** | |
| 21 base class for all shaders builders | |
| 22 */ | |
| 23 class GrGLShaderBuilder { | |
| 24 public: | |
| 25 GrGLShaderBuilder(GrGLSLProgramBuilder* program); | |
| 26 virtual ~GrGLShaderBuilder() {} | |
| 27 | |
| 28 void addInput(const GrGLSLShaderVar& input) { fInputs.push_back(input); } | |
| 29 void addOutput(const GrGLSLShaderVar& output) { fOutputs.push_back(output);
} | |
| 30 | |
| 31 /* | |
| 32 * We put texture lookups in the base class because it is TECHNICALLY possib
le to do texture | |
| 33 * lookups in any kind of shader. However, for the time being using these c
alls on non-fragment | |
| 34 * shaders will result in a shader compilation error as texture sampler unif
orms are only | |
| 35 * visible to the fragment shader. It would not be hard to change this beha
vior, if someone | |
| 36 * actually wants to do texture lookups in a non-fragment shader | |
| 37 * | |
| 38 * TODO if append texture lookup is used on a non-fragment shader, sampler u
niforms should be | |
| 39 * made visible to that shaders | |
| 40 */ | |
| 41 /** Appends a 2D texture sample with projection if necessary. coordType must
either be Vec2f or | |
| 42 Vec3f. The latter is interpreted as projective texture coords. The vec l
ength and swizzle | |
| 43 order of the result depends on the GrTextureAccess associated with the G
rGLSLTextureSampler. | |
| 44 */ | |
| 45 void appendTextureLookup(SkString* out, | |
| 46 const GrGLSLTextureSampler&, | |
| 47 const char* coordName, | |
| 48 GrSLType coordType = kVec2f_GrSLType) const; | |
| 49 | |
| 50 /** Version of above that appends the result to the fragment shader code ins
tead.*/ | |
| 51 void appendTextureLookup(const GrGLSLTextureSampler&, | |
| 52 const char* coordName, | |
| 53 GrSLType coordType = kVec2f_GrSLType); | |
| 54 | |
| 55 | |
| 56 /** Does the work of appendTextureLookup and modulates the result by modulat
ion. The result is | |
| 57 always a vec4. modulation and the swizzle specified by GrGLSLTextureSamp
ler must both be | |
| 58 vec4 or float. If modulation is "" or nullptr it this function acts as t
hough | |
| 59 appendTextureLookup were called. */ | |
| 60 void appendTextureLookupAndModulate(const char* modulation, | |
| 61 const GrGLSLTextureSampler&, | |
| 62 const char* coordName, | |
| 63 GrSLType coordType = kVec2f_GrSLType); | |
| 64 | |
| 65 /** | |
| 66 * Called by GrGLProcessors to add code to one of the shaders. | |
| 67 */ | |
| 68 void codeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { | |
| 69 va_list args; | |
| 70 va_start(args, format); | |
| 71 this->code().appendVAList(format, args); | |
| 72 va_end(args); | |
| 73 } | |
| 74 | |
| 75 void codeAppend(const char* str) { this->code().append(str); } | |
| 76 | |
| 77 void codePrependf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { | |
| 78 va_list args; | |
| 79 va_start(args, format); | |
| 80 this->code().prependVAList(format, args); | |
| 81 va_end(args); | |
| 82 } | |
| 83 | |
| 84 /** | |
| 85 * Appends a variable declaration to one of the shaders | |
| 86 */ | |
| 87 void declAppend(const GrGLSLShaderVar& var); | |
| 88 | |
| 89 /** Emits a helper function outside of main() in the fragment shader. */ | |
| 90 void emitFunction(GrSLType returnType, | |
| 91 const char* name, | |
| 92 int argCnt, | |
| 93 const GrGLSLShaderVar* args, | |
| 94 const char* body, | |
| 95 SkString* outName); | |
| 96 | |
| 97 /* | |
| 98 * Combines the various parts of the shader to create a single finalized sha
der string. | |
| 99 */ | |
| 100 void finalize(uint32_t visibility); | |
| 101 | |
| 102 /* | |
| 103 * Get parent builder for adding uniforms | |
| 104 */ | |
| 105 GrGLSLProgramBuilder* getProgramBuilder() { return fProgramBuilder; } | |
| 106 | |
| 107 /** | |
| 108 * Helper for begining and ending a block in the shader code. | |
| 109 */ | |
| 110 class ShaderBlock { | |
| 111 public: | |
| 112 ShaderBlock(GrGLShaderBuilder* builder) : fBuilder(builder) { | |
| 113 SkASSERT(builder); | |
| 114 fBuilder->codeAppend("{"); | |
| 115 } | |
| 116 | |
| 117 ~ShaderBlock() { | |
| 118 fBuilder->codeAppend("}"); | |
| 119 } | |
| 120 private: | |
| 121 GrGLShaderBuilder* fBuilder; | |
| 122 }; | |
| 123 | |
| 124 protected: | |
| 125 typedef GrTAllocator<GrGLSLShaderVar> VarArray; | |
| 126 void appendDecls(const VarArray& vars, SkString* out) const; | |
| 127 | |
| 128 /* | |
| 129 * A general function which enables an extension in a shader if the feature
bit is not present | |
| 130 */ | |
| 131 void addFeature(uint32_t featureBit, const char* extensionName); | |
| 132 | |
| 133 enum InterfaceQualifier { | |
| 134 kOut_InterfaceQualifier, | |
| 135 kLastInterfaceQualifier = kOut_InterfaceQualifier | |
| 136 }; | |
| 137 | |
| 138 /* | |
| 139 * A low level function to build default layout qualifiers. | |
| 140 * | |
| 141 * e.g. layout(param1, param2, ...) out; | |
| 142 * | |
| 143 * GLSL allows default layout qualifiers for in, out, and uniform. | |
| 144 */ | |
| 145 void addLayoutQualifier(const char* param, InterfaceQualifier); | |
| 146 | |
| 147 void compileAndAppendLayoutQualifiers(); | |
| 148 | |
| 149 void nextStage() { | |
| 150 fShaderStrings.push_back(); | |
| 151 fCompilerStrings.push_back(this->code().c_str()); | |
| 152 fCompilerStringLengths.push_back((int)this->code().size()); | |
| 153 fCodeIndex++; | |
| 154 } | |
| 155 | |
| 156 SkString& versionDecl() { return fShaderStrings[kVersionDecl]; } | |
| 157 SkString& extensions() { return fShaderStrings[kExtensions]; } | |
| 158 SkString& precisionQualifier() { return fShaderStrings[kPrecisionQualifier];
} | |
| 159 SkString& layoutQualifiers() { return fShaderStrings[kLayoutQualifiers]; } | |
| 160 SkString& uniforms() { return fShaderStrings[kUniforms]; } | |
| 161 SkString& inputs() { return fShaderStrings[kInputs]; } | |
| 162 SkString& outputs() { return fShaderStrings[kOutputs]; } | |
| 163 SkString& functions() { return fShaderStrings[kFunctions]; } | |
| 164 SkString& main() { return fShaderStrings[kMain]; } | |
| 165 SkString& code() { return fShaderStrings[fCodeIndex]; } | |
| 166 | |
| 167 virtual void onFinalize() = 0; | |
| 168 | |
| 169 enum { | |
| 170 kVersionDecl, | |
| 171 kExtensions, | |
| 172 kPrecisionQualifier, | |
| 173 kLayoutQualifiers, | |
| 174 kUniforms, | |
| 175 kInputs, | |
| 176 kOutputs, | |
| 177 kFunctions, | |
| 178 kMain, | |
| 179 kCode, | |
| 180 }; | |
| 181 | |
| 182 GrGLSLProgramBuilder* fProgramBuilder; | |
| 183 SkSTArray<kCode, const char*, true> fCompilerStrings; | |
| 184 SkSTArray<kCode, int, true> fCompilerStringLengths; | |
| 185 SkSTArray<kCode, SkString> fShaderStrings; | |
| 186 SkString fCode; | |
| 187 SkString fFunctions; | |
| 188 SkString fExtensions; | |
| 189 | |
| 190 VarArray fInputs; | |
| 191 VarArray fOutputs; | |
| 192 uint32_t fFeaturesAddedMask; | |
| 193 SkSTArray<1, SkString> fLayoutParams[kLastInterfaceQualifier + 1]; | |
| 194 int fCodeIndex; | |
| 195 bool fFinalized; | |
| 196 | |
| 197 friend class GrGLProgramBuilder; | |
| 198 friend class GrGLPathProgramBuilder; // to access fInputs. | |
| 199 }; | |
| 200 #endif | |
| OLD | NEW |