blob: 31d603a8d2ad6177a3cfd1d6797800f62fdc89ae [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.com032b2212012-07-16 13:36:18 +000026
bsalomon@google.comeb715c82012-07-11 15:03:31 +000027 enum ShaderType {
28 kVertex_ShaderType = 0x1,
29 kGeometry_ShaderType = 0x2,
30 kFragment_ShaderType = 0x4,
31 };
32
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000033 GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&);
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000034
tomhudson@google.com52598142012-05-24 17:44:30 +000035 void computeSwizzle(uint32_t configFlags);
36 void computeModulate(const char* fsInColor);
37
tomhudson@google.com5440f062012-06-01 15:55:50 +000038 // TODO: needs a better name
39 enum SamplerMode {
40 kDefault_SamplerMode,
41 kProj_SamplerMode,
42 kExplicitDivide_SamplerMode // must do an explicit divide
43 };
44
bsalomon@google.comeb715c82012-07-11 15:03:31 +000045 /** Determines whether we should use texture2D() or texture2Dproj(), and if an explicit divide
46 is required for the sample coordinates, creates the new variable and emits the code to
47 initialize it. */
tomhudson@google.comde788232012-08-02 20:13:12 +000048 void setupTextureAccess(int stageNum);
tomhudson@google.com52598142012-05-24 17:44:30 +000049
bsalomon@google.comeb715c82012-07-11 15:03:31 +000050 /** texture2D(samplerName, coordName), with projection if necessary; if coordName is not
51 specified, uses fSampleCoords. */
tomhudson@google.com52598142012-05-24 17:44:30 +000052 void emitTextureLookup(const char* samplerName,
53 const char* coordName = NULL);
54
bsalomon@google.comeb715c82012-07-11 15:03:31 +000055 /** sets outColor to results of texture lookup, with swizzle, and/or modulate as necessary */
tomhudson@google.com52598142012-05-24 17:44:30 +000056 void emitDefaultFetch(const char* outColor,
57 const char* samplerName);
58
twiz@google.coma5e65ec2012-08-02 15:15:16 +000059 /** Emits a texture lookup to the shader code with the form:
60 texture2D{Proj}(samplerName, coordName).swizzle
61 The routine selects the type of texturing based on samplerMode.
62 The generated swizzle state is built based on the format of the texture and the requested
63 swizzle access pattern. */
64 void emitCustomTextureLookup(SamplerMode samplerMode,
65 const GrTextureAccess& textureAccess,
66 const char* samplerName,
67 const char* coordName);
68
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +000069 /** Emits a helper function outside of main(). Currently ShaderType must be
70 kFragment_ShaderType. */
71 void emitFunction(ShaderType shader,
72 GrSLType returnType,
73 const char* name,
74 int argCnt,
75 const GrGLShaderVar* args,
76 const char* body,
77 SkString* outName);
78
twiz@google.coma5e65ec2012-08-02 15:15:16 +000079 /** Generates a StageKey for the shader code based on the texture access parameters and the
80 capabilities of the GL context. This is useful for keying the shader programs that may
81 have multiple representations, based on the type/format of textures used. */
82 static GrCustomStage::StageKey KeyForTextureAccess(const GrTextureAccess& access,
83 const GrGLCaps& caps);
84
bsalomon@google.comeb715c82012-07-11 15:03:31 +000085 /** Add a uniform variable to the current program, that has visibilty in one or more shaders.
bsalomon@google.com777c3aa2012-07-25 20:58:20 +000086 visibility is a bitfield of ShaderType values indicating from which shaders the uniform
87 should be accessible. At least one bit must be set. Geometry shader uniforms are not
88 supported at this time. The actual uniform name will be mangled. If outName is not NULL then
89 it will refer to the final uniform name after return. Use the addUniformArray variant to add
90 an array of uniforms.
tomhudson@google.com242ed6f2012-05-30 17:38:57 +000091 */
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000092 GrGLUniformManager::UniformHandle addUniform(uint32_t visibility,
93 GrSLType type,
94 const char* name,
bsalomon@google.com777c3aa2012-07-25 20:58:20 +000095 const char** outName = NULL) {
96 return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName);
97 }
98 GrGLUniformManager::UniformHandle addUniformArray(uint32_t visibility,
99 GrSLType type,
100 const char* name,
101 int arrayCount,
102 const char** outName = NULL);
bsalomon@google.com032b2212012-07-16 13:36:18 +0000103
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000104 const GrGLShaderVar& getUniformVariable(GrGLUniformManager::UniformHandle) const;
bsalomon@google.com032b2212012-07-16 13:36:18 +0000105
106 /**
107 * Shorcut for getUniformVariable(u).c_str()
108 */
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000109 const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const {
bsalomon@google.com032b2212012-07-16 13:36:18 +0000110 return this->getUniformVariable(u).c_str();
111 }
tomhudson@google.com242ed6f2012-05-30 17:38:57 +0000112
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000113 /** Add a varying variable to the current program to pass values between vertex and fragment
114 shaders. If the last two parameters are non-NULL, they are filled in with the name
115 generated. */
tomhudson@google.com23cb2292012-05-30 18:26:03 +0000116 void addVarying(GrSLType type,
117 const char* name,
118 const char** vsOutName = NULL,
119 const char** fsInName = NULL);
120
bsalomon@google.comad5e9372012-07-11 18:11:27 +0000121 /** Called after building is complete to get the final shader string. */
122 void getShader(ShaderType, SkString*) const;
123
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000124 /**
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000125 * TODO: Make this do all the compiling, linking, etc. Hide from the custom stages
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000126 */
127 void finished(GrGLuint programID);
128
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000129 /**
130 * Sets the current stage (used to make variable names unique).
131 * TODO: Hide from the custom stages
132 */
133 void setCurrentStage(int stage) { fCurrentStage = stage; }
134 void setNonStage() { fCurrentStage = kNonStageIdx; }
135
bsalomon@google.com032b2212012-07-16 13:36:18 +0000136private:
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000137
bsalomon@google.com032b2212012-07-16 13:36:18 +0000138 typedef GrTAllocator<GrGLShaderVar> VarArray;
139
bsalomon@google.com032b2212012-07-16 13:36:18 +0000140 void appendDecls(const VarArray&, SkString*) const;
141 void appendUniformDecls(ShaderType, SkString*) const;
142
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000143 typedef GrGLUniformManager::BuilderUniform BuilderUniform;
144 GrGLUniformManager::BuilderUniformArray fUniforms;
bsalomon@google.com032b2212012-07-16 13:36:18 +0000145
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000146 // TODO: Everything below here private.
bsalomon@google.com032b2212012-07-16 13:36:18 +0000147public:
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000148
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000149 SkString fHeader; // VS+FS, GLSL version, etc
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000150 VarArray fVSAttrs;
151 VarArray fVSOutputs;
152 VarArray fGSInputs;
153 VarArray fGSOutputs;
154 VarArray fFSInputs;
155 SkString fGSHeader; // layout qualifiers specific to GS
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000156 VarArray fFSOutputs;
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000157 SkString fVSCode;
158 SkString fGSCode;
159 SkString fFSCode;
160 bool fUsesGS;
tomhudson@google.com040c41a2012-05-18 14:57:40 +0000161
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000162 /// Per-stage settings - only valid while we're inside GrGLProgram::genStageCode().
tomhudson@google.com040c41a2012-05-18 14:57:40 +0000163 //@{
tomhudson@google.comf9ad8862012-05-11 20:38:48 +0000164
tomhudson@google.com52598142012-05-24 17:44:30 +0000165 int fVaryingDims;
tomhudson@google.com9c639a42012-05-14 19:58:06 +0000166 static const int fCoordDims = 2;
167
tomhudson@google.com040c41a2012-05-18 14:57:40 +0000168 /// True if fSampleCoords is an expression; false if it's a bare
169 /// variable name
tomhudson@google.com52598142012-05-24 17:44:30 +0000170 bool fComplexCoord;
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000171 SkString fSampleCoords;
tomhudson@google.com52598142012-05-24 17:44:30 +0000172
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000173 SkString fSwizzle;
174 SkString fModulate;
tomhudson@google.com040c41a2012-05-18 14:57:40 +0000175
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000176 SkString fTexFunc;
tomhudson@google.com5440f062012-06-01 15:55:50 +0000177
tomhudson@google.com040c41a2012-05-18 14:57:40 +0000178 //@}
tomhudson@google.com9c639a42012-05-14 19:58:06 +0000179
bsalomon@google.comad5e9372012-07-11 18:11:27 +0000180private:
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000181 enum {
182 kNonStageIdx = -1,
183 };
184
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000185 const GrGLContextInfo& fContext;
186 GrGLUniformManager& fUniformManager;
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000187 int fCurrentStage;
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +0000188 SkString fFSFunctions;
tomhudson@google.comf9ad8862012-05-11 20:38:48 +0000189};
190
191#endif