blob: bc108923f99bbcdc4de66022b3b638d2ed1538a7 [file] [log] [blame]
tomhudson@google.comf9ad8862012-05-11 20:38:48 +00001/*
2 * Copyright 2012 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"
twiz@google.coma5e65ec2012-08-02 15:15:16 +000012#include "GrCustomStage.h"
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000013#include "gl/GrGLShaderVar.h"
14#include "gl/GrGLSL.h"
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000015#include "gl/GrGLUniformManager.h"
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000016
bsalomon@google.comad5e9372012-07-11 18:11:27 +000017class GrGLContextInfo;
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000018
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000019/**
bsalomon@google.comeb715c82012-07-11 15:03:31 +000020 Contains all the incremental state of a shader as it is being built,as well as helpers to
21 manipulate that state.
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000022*/
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000023class GrGLShaderBuilder {
24
25public:
bsalomon@google.comeb715c82012-07-11 15:03:31 +000026 enum ShaderType {
27 kVertex_ShaderType = 0x1,
28 kGeometry_ShaderType = 0x2,
29 kFragment_ShaderType = 0x4,
30 };
31
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000032 GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&);
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000033
tomhudson@google.com52598142012-05-24 17:44:30 +000034 void computeSwizzle(uint32_t configFlags);
tomhudson@google.com52598142012-05-24 17:44:30 +000035
bsalomon@google.comeb715c82012-07-11 15:03:31 +000036 /** Determines whether we should use texture2D() or texture2Dproj(), and if an explicit divide
37 is required for the sample coordinates, creates the new variable and emits the code to
bsalomon@google.com34bcb9f2012-08-28 18:20:18 +000038 initialize it. This should only be called by GrGLProgram.*/
39 void setupTextureAccess(const char* varyingFSName, GrSLType varyingType);
tomhudson@google.com52598142012-05-24 17:44:30 +000040
bsalomon@google.comeb715c82012-07-11 15:03:31 +000041 /** texture2D(samplerName, coordName), with projection if necessary; if coordName is not
bsalomon@google.com34bcb9f2012-08-28 18:20:18 +000042 specified, uses fSampleCoords. coordType must either be Vec2f or Vec3f. The latter is
43 interpreted as projective texture coords. */
bsalomon@google.com868a8e72012-08-30 19:11:34 +000044 void appendTextureLookup(SkString* out,
45 const char* samplerName,
46 const char* coordName = NULL,
47 GrSLType coordType = kVec2f_GrSLType) const;
tomhudson@google.com52598142012-05-24 17:44:30 +000048
bsalomon@google.com868a8e72012-08-30 19:11:34 +000049 /** appends a texture lookup, with swizzle as necessary. If coordName is NULL then it as if
50 defaultTexCoordsName() was passed. coordType must be either kVec2f or kVec3f. If modulateVar
51 is not NULL or "" then the texture lookup will be modulated by it. modulation must refer to
52 be expression that evaluates to a float or vec4. */
53 void appendTextureLookupAndModulate(SkString* out,
54 const char* modulation,
55 const char* samplerName,
56 const char* coordName = NULL,
57 GrSLType varyingType = kVec2f_GrSLType) const;
bsalomon@google.com34bcb9f2012-08-28 18:20:18 +000058
59 /** Gets the name of the default texture coords which are always kVec2f */
60 const char* defaultTexCoordsName() const { return fDefaultTexCoordsName.c_str(); }
61
62 /* Returns true if the texture matrix from which the default texture coords are computed has
63 perspective. */
64 bool defaultTextureMatrixIsPerspective() const {
65 return fTexCoordVaryingType == kVec3f_GrSLType;
66 }
tomhudson@google.com52598142012-05-24 17:44:30 +000067
twiz@google.coma5e65ec2012-08-02 15:15:16 +000068 /** Emits a texture lookup to the shader code with the form:
69 texture2D{Proj}(samplerName, coordName).swizzle
70 The routine selects the type of texturing based on samplerMode.
71 The generated swizzle state is built based on the format of the texture and the requested
bsalomon@google.com34bcb9f2012-08-28 18:20:18 +000072 swizzle access pattern. coordType must either be Vec2f or Vec3f. The latter is interpreted
73 as projective texture coords.*/
74 void emitCustomTextureLookup(const GrTextureAccess& textureAccess,
twiz@google.coma5e65ec2012-08-02 15:15:16 +000075 const char* samplerName,
bsalomon@google.com34bcb9f2012-08-28 18:20:18 +000076 const char* coordName,
77 GrSLType coordType = kVec2f_GrSLType);
twiz@google.coma5e65ec2012-08-02 15:15:16 +000078
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +000079 /** Emits a helper function outside of main(). Currently ShaderType must be
80 kFragment_ShaderType. */
81 void emitFunction(ShaderType shader,
82 GrSLType returnType,
83 const char* name,
84 int argCnt,
85 const GrGLShaderVar* args,
86 const char* body,
87 SkString* outName);
88
twiz@google.coma5e65ec2012-08-02 15:15:16 +000089 /** Generates a StageKey for the shader code based on the texture access parameters and the
90 capabilities of the GL context. This is useful for keying the shader programs that may
91 have multiple representations, based on the type/format of textures used. */
92 static GrCustomStage::StageKey KeyForTextureAccess(const GrTextureAccess& access,
93 const GrGLCaps& caps);
94
bsalomon@google.comeb715c82012-07-11 15:03:31 +000095 /** Add a uniform variable to the current program, that has visibilty in one or more shaders.
bsalomon@google.com777c3aa2012-07-25 20:58:20 +000096 visibility is a bitfield of ShaderType values indicating from which shaders the uniform
97 should be accessible. At least one bit must be set. Geometry shader uniforms are not
98 supported at this time. The actual uniform name will be mangled. If outName is not NULL then
99 it will refer to the final uniform name after return. Use the addUniformArray variant to add
100 an array of uniforms.
tomhudson@google.com242ed6f2012-05-30 17:38:57 +0000101 */
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000102 GrGLUniformManager::UniformHandle addUniform(uint32_t visibility,
103 GrSLType type,
104 const char* name,
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000105 const char** outName = NULL) {
106 return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName);
107 }
108 GrGLUniformManager::UniformHandle addUniformArray(uint32_t visibility,
109 GrSLType type,
110 const char* name,
111 int arrayCount,
112 const char** outName = NULL);
bsalomon@google.com032b2212012-07-16 13:36:18 +0000113
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000114 const GrGLShaderVar& getUniformVariable(GrGLUniformManager::UniformHandle) const;
bsalomon@google.com032b2212012-07-16 13:36:18 +0000115
116 /**
117 * Shorcut for getUniformVariable(u).c_str()
118 */
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000119 const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const {
bsalomon@google.com032b2212012-07-16 13:36:18 +0000120 return this->getUniformVariable(u).c_str();
121 }
tomhudson@google.com242ed6f2012-05-30 17:38:57 +0000122
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000123 /** Add a varying variable to the current program to pass values between vertex and fragment
124 shaders. If the last two parameters are non-NULL, they are filled in with the name
125 generated. */
tomhudson@google.com23cb2292012-05-30 18:26:03 +0000126 void addVarying(GrSLType type,
127 const char* name,
128 const char** vsOutName = NULL,
129 const char** fsInName = NULL);
130
bsalomon@google.comad5e9372012-07-11 18:11:27 +0000131 /** Called after building is complete to get the final shader string. */
132 void getShader(ShaderType, SkString*) const;
133
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000134 /**
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000135 * TODO: Make this do all the compiling, linking, etc. Hide from the custom stages
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000136 */
137 void finished(GrGLuint programID);
138
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000139 /**
140 * Sets the current stage (used to make variable names unique).
141 * TODO: Hide from the custom stages
142 */
143 void setCurrentStage(int stage) { fCurrentStage = stage; }
144 void setNonStage() { fCurrentStage = kNonStageIdx; }
145
bsalomon@google.com032b2212012-07-16 13:36:18 +0000146private:
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000147
bsalomon@google.com032b2212012-07-16 13:36:18 +0000148 typedef GrTAllocator<GrGLShaderVar> VarArray;
149
bsalomon@google.com032b2212012-07-16 13:36:18 +0000150 void appendDecls(const VarArray&, SkString*) const;
151 void appendUniformDecls(ShaderType, SkString*) const;
152
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000153 typedef GrGLUniformManager::BuilderUniform BuilderUniform;
154 GrGLUniformManager::BuilderUniformArray fUniforms;
bsalomon@google.com032b2212012-07-16 13:36:18 +0000155
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000156 // TODO: Everything below here private.
bsalomon@google.com032b2212012-07-16 13:36:18 +0000157public:
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000158
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000159 SkString fHeader; // VS+FS, GLSL version, etc
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000160 VarArray fVSAttrs;
161 VarArray fVSOutputs;
162 VarArray fGSInputs;
163 VarArray fGSOutputs;
164 VarArray fFSInputs;
165 SkString fGSHeader; // layout qualifiers specific to GS
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000166 VarArray fFSOutputs;
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000167 SkString fVSCode;
168 SkString fGSCode;
169 SkString fFSCode;
170 bool fUsesGS;
tomhudson@google.com040c41a2012-05-18 14:57:40 +0000171
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000172 /// Per-stage settings - only valid while we're inside GrGLProgram::genStageCode().
tomhudson@google.com040c41a2012-05-18 14:57:40 +0000173 //@{
tomhudson@google.comf9ad8862012-05-11 20:38:48 +0000174
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000175 SkString fSwizzle;
tomhudson@google.com040c41a2012-05-18 14:57:40 +0000176
177 //@}
tomhudson@google.com9c639a42012-05-14 19:58:06 +0000178
bsalomon@google.comad5e9372012-07-11 18:11:27 +0000179private:
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000180 enum {
181 kNonStageIdx = -1,
182 };
183
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000184 const GrGLContextInfo& fContext;
185 GrGLUniformManager& fUniformManager;
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000186 int fCurrentStage;
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +0000187 SkString fFSFunctions;
bsalomon@google.com34bcb9f2012-08-28 18:20:18 +0000188
189 /// Per-stage settings - only valid while we're inside GrGLProgram::genStageCode().
190 //@{
191 GrSLType fTexCoordVaryingType; // the type, either Vec2f or Vec3f, of the coords passed
192 // as a varying from the VS to the FS.
193 SkString fDefaultTexCoordsName; // the name of the default 2D coords value.
194 //@}
195
tomhudson@google.comf9ad8862012-05-11 20:38:48 +0000196};
197
198#endif