blob: 892fcbee473fc87995994884eebde1e28f19574b [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"
12#include "gl/GrGLShaderVar.h"
13#include "gl/GrGLSL.h"
14
bsalomon@google.comad5e9372012-07-11 18:11:27 +000015class GrGLContextInfo;
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000016/**
bsalomon@google.comeb715c82012-07-11 15:03:31 +000017 Contains all the incremental state of a shader as it is being built,as well as helpers to
18 manipulate that state.
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000019 TODO: migrate CompileShaders() here?
20*/
21
22class GrGLShaderBuilder {
23
24public:
bsalomon@google.com032b2212012-07-16 13:36:18 +000025
26 typedef int UniformHandle;
27 static const UniformHandle kInvalidUniformHandle = 0;
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000028
bsalomon@google.comeb715c82012-07-11 15:03:31 +000029 enum ShaderType {
30 kVertex_ShaderType = 0x1,
31 kGeometry_ShaderType = 0x2,
32 kFragment_ShaderType = 0x4,
33 };
34
bsalomon@google.comad5e9372012-07-11 18:11:27 +000035 GrGLShaderBuilder(const GrGLContextInfo&);
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000036
tomhudson@google.com52598142012-05-24 17:44:30 +000037 void computeSwizzle(uint32_t configFlags);
38 void computeModulate(const char* fsInColor);
39
tomhudson@google.com5440f062012-06-01 15:55:50 +000040 // TODO: needs a better name
41 enum SamplerMode {
42 kDefault_SamplerMode,
43 kProj_SamplerMode,
44 kExplicitDivide_SamplerMode // must do an explicit divide
45 };
46
bsalomon@google.comeb715c82012-07-11 15:03:31 +000047 /** Determines whether we should use texture2D() or texture2Dproj(), and if an explicit divide
48 is required for the sample coordinates, creates the new variable and emits the code to
49 initialize it. */
tomhudson@google.com5440f062012-06-01 15:55:50 +000050 void setupTextureAccess(SamplerMode samplerMode, int stageNum);
tomhudson@google.com52598142012-05-24 17:44:30 +000051
bsalomon@google.comeb715c82012-07-11 15:03:31 +000052 /** texture2D(samplerName, coordName), with projection if necessary; if coordName is not
53 specified, uses fSampleCoords. */
tomhudson@google.com52598142012-05-24 17:44:30 +000054 void emitTextureLookup(const char* samplerName,
55 const char* coordName = NULL);
56
bsalomon@google.comeb715c82012-07-11 15:03:31 +000057 /** sets outColor to results of texture lookup, with swizzle, and/or modulate as necessary */
tomhudson@google.com52598142012-05-24 17:44:30 +000058 void emitDefaultFetch(const char* outColor,
59 const char* samplerName);
60
bsalomon@google.comeb715c82012-07-11 15:03:31 +000061 /** Add a uniform variable to the current program, that has visibilty in one or more shaders.
62 If stageNum is specified, it is appended to the name to guarantee uniqueness; if count is
63 specified, the uniform is an array. visibility is a bitfield of ShaderType values indicating
64 from which shaders the uniform should be accessible. At least one bit must be set. Geometry
65 shader uniforms are not supported at this time.
tomhudson@google.com242ed6f2012-05-30 17:38:57 +000066 */
bsalomon@google.com032b2212012-07-16 13:36:18 +000067 UniformHandle addUniform(uint32_t visibility,
68 GrSLType type,
69 const char* name,
70 int stageNum = -1,
71 int count = GrGLShaderVar::kNonArray);
72
73 const GrGLShaderVar& getUniformVariable(UniformHandle) const;
74
75 /**
76 * Shorcut for getUniformVariable(u).c_str()
77 */
78 const char* getUniformCStr(UniformHandle u) const {
79 return this->getUniformVariable(u).c_str();
80 }
tomhudson@google.com242ed6f2012-05-30 17:38:57 +000081
bsalomon@google.comeb715c82012-07-11 15:03:31 +000082 /** Add a varying variable to the current program to pass values between vertex and fragment
83 shaders. If the last two parameters are non-NULL, they are filled in with the name
84 generated. */
tomhudson@google.com23cb2292012-05-30 18:26:03 +000085 void addVarying(GrSLType type,
86 const char* name,
87 const char** vsOutName = NULL,
88 const char** fsInName = NULL);
89
bsalomon@google.comeb715c82012-07-11 15:03:31 +000090 /** Add a varying variable to the current program to pass values between vertex and fragment
91 shaders; stageNum is appended to the name to guarantee uniqueness. If the last two
92 parameters are non-NULL, they are filled in with the name generated. */
tomhudson@google.com23cb2292012-05-30 18:26:03 +000093 void addVarying(GrSLType type,
94 const char* name,
95 int stageNum,
96 const char** vsOutName = NULL,
97 const char** fsInName = NULL);
bsalomon@google.comeb715c82012-07-11 15:03:31 +000098
bsalomon@google.comad5e9372012-07-11 18:11:27 +000099 /** Called after building is complete to get the final shader string. */
100 void getShader(ShaderType, SkString*) const;
101
bsalomon@google.com032b2212012-07-16 13:36:18 +0000102private:
103 typedef GrTAllocator<GrGLShaderVar> VarArray;
104
105 struct Uniform {
106 GrGLShaderVar fVariable;
107 uint32_t fVisibility;
108 };
109
110 typedef GrTAllocator<Uniform> UniformArray;
111 void appendDecls(const VarArray&, SkString*) const;
112 void appendUniformDecls(ShaderType, SkString*) const;
113
114 UniformArray fUniforms;
115
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000116 // TODO: Everything below here private.
bsalomon@google.com032b2212012-07-16 13:36:18 +0000117public:
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000118
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000119 SkString fHeader; // VS+FS, GLSL version, etc
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000120 VarArray fVSAttrs;
121 VarArray fVSOutputs;
122 VarArray fGSInputs;
123 VarArray fGSOutputs;
124 VarArray fFSInputs;
125 SkString fGSHeader; // layout qualifiers specific to GS
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000126 VarArray fFSOutputs;
127 SkString fFSFunctions;
128 SkString fVSCode;
129 SkString fGSCode;
130 SkString fFSCode;
131 bool fUsesGS;
tomhudson@google.com040c41a2012-05-18 14:57:40 +0000132
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000133 /// Per-stage settings - only valid while we're inside GrGLProgram::genStageCode().
tomhudson@google.com040c41a2012-05-18 14:57:40 +0000134 //@{
tomhudson@google.comf9ad8862012-05-11 20:38:48 +0000135
tomhudson@google.com52598142012-05-24 17:44:30 +0000136 int fVaryingDims;
tomhudson@google.com9c639a42012-05-14 19:58:06 +0000137 static const int fCoordDims = 2;
138
tomhudson@google.com040c41a2012-05-18 14:57:40 +0000139 /// True if fSampleCoords is an expression; false if it's a bare
140 /// variable name
tomhudson@google.com52598142012-05-24 17:44:30 +0000141 bool fComplexCoord;
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000142 SkString fSampleCoords;
tomhudson@google.com52598142012-05-24 17:44:30 +0000143
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000144 SkString fSwizzle;
145 SkString fModulate;
tomhudson@google.com040c41a2012-05-18 14:57:40 +0000146
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000147 SkString fTexFunc;
tomhudson@google.com5440f062012-06-01 15:55:50 +0000148
tomhudson@google.com040c41a2012-05-18 14:57:40 +0000149 //@}
tomhudson@google.com9c639a42012-05-14 19:58:06 +0000150
bsalomon@google.comad5e9372012-07-11 18:11:27 +0000151private:
152 const GrGLContextInfo& fContext;
tomhudson@google.comf9ad8862012-05-11 20:38:48 +0000153};
154
155#endif