blob: 16a11e29a0ee51bd143d3bd303e68b450c1b60d2 [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.com5440f062012-06-01 15:55:50 +000048 void setupTextureAccess(SamplerMode samplerMode, 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
69 /** Generates a StageKey for the shader code based on the texture access parameters and the
70 capabilities of the GL context. This is useful for keying the shader programs that may
71 have multiple representations, based on the type/format of textures used. */
72 static GrCustomStage::StageKey KeyForTextureAccess(const GrTextureAccess& access,
73 const GrGLCaps& caps);
74
bsalomon@google.comeb715c82012-07-11 15:03:31 +000075 /** Add a uniform variable to the current program, that has visibilty in one or more shaders.
bsalomon@google.com777c3aa2012-07-25 20:58:20 +000076 visibility is a bitfield of ShaderType values indicating from which shaders the uniform
77 should be accessible. At least one bit must be set. Geometry shader uniforms are not
78 supported at this time. The actual uniform name will be mangled. If outName is not NULL then
79 it will refer to the final uniform name after return. Use the addUniformArray variant to add
80 an array of uniforms.
tomhudson@google.com242ed6f2012-05-30 17:38:57 +000081 */
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000082 GrGLUniformManager::UniformHandle addUniform(uint32_t visibility,
83 GrSLType type,
84 const char* name,
bsalomon@google.com777c3aa2012-07-25 20:58:20 +000085 const char** outName = NULL) {
86 return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName);
87 }
88 GrGLUniformManager::UniformHandle addUniformArray(uint32_t visibility,
89 GrSLType type,
90 const char* name,
91 int arrayCount,
92 const char** outName = NULL);
bsalomon@google.com032b2212012-07-16 13:36:18 +000093
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000094 const GrGLShaderVar& getUniformVariable(GrGLUniformManager::UniformHandle) const;
bsalomon@google.com032b2212012-07-16 13:36:18 +000095
96 /**
97 * Shorcut for getUniformVariable(u).c_str()
98 */
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000099 const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const {
bsalomon@google.com032b2212012-07-16 13:36:18 +0000100 return this->getUniformVariable(u).c_str();
101 }
tomhudson@google.com242ed6f2012-05-30 17:38:57 +0000102
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000103 /** Add a varying variable to the current program to pass values between vertex and fragment
104 shaders. If the last two parameters are non-NULL, they are filled in with the name
105 generated. */
tomhudson@google.com23cb2292012-05-30 18:26:03 +0000106 void addVarying(GrSLType type,
107 const char* name,
108 const char** vsOutName = NULL,
109 const char** fsInName = NULL);
110
bsalomon@google.comad5e9372012-07-11 18:11:27 +0000111 /** Called after building is complete to get the final shader string. */
112 void getShader(ShaderType, SkString*) const;
113
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000114 /**
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000115 * TODO: Make this do all the compiling, linking, etc. Hide from the custom stages
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000116 */
117 void finished(GrGLuint programID);
118
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000119 /**
120 * Sets the current stage (used to make variable names unique).
121 * TODO: Hide from the custom stages
122 */
123 void setCurrentStage(int stage) { fCurrentStage = stage; }
124 void setNonStage() { fCurrentStage = kNonStageIdx; }
125
bsalomon@google.com032b2212012-07-16 13:36:18 +0000126private:
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000127
bsalomon@google.com032b2212012-07-16 13:36:18 +0000128 typedef GrTAllocator<GrGLShaderVar> VarArray;
129
bsalomon@google.com032b2212012-07-16 13:36:18 +0000130 void appendDecls(const VarArray&, SkString*) const;
131 void appendUniformDecls(ShaderType, SkString*) const;
132
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000133 typedef GrGLUniformManager::BuilderUniform BuilderUniform;
134 GrGLUniformManager::BuilderUniformArray fUniforms;
bsalomon@google.com032b2212012-07-16 13:36:18 +0000135
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000136 // TODO: Everything below here private.
bsalomon@google.com032b2212012-07-16 13:36:18 +0000137public:
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000138
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000139 SkString fHeader; // VS+FS, GLSL version, etc
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000140 VarArray fVSAttrs;
141 VarArray fVSOutputs;
142 VarArray fGSInputs;
143 VarArray fGSOutputs;
144 VarArray fFSInputs;
145 SkString fGSHeader; // layout qualifiers specific to GS
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000146 VarArray fFSOutputs;
147 SkString fFSFunctions;
148 SkString fVSCode;
149 SkString fGSCode;
150 SkString fFSCode;
151 bool fUsesGS;
tomhudson@google.com040c41a2012-05-18 14:57:40 +0000152
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000153 /// Per-stage settings - only valid while we're inside GrGLProgram::genStageCode().
tomhudson@google.com040c41a2012-05-18 14:57:40 +0000154 //@{
tomhudson@google.comf9ad8862012-05-11 20:38:48 +0000155
tomhudson@google.com52598142012-05-24 17:44:30 +0000156 int fVaryingDims;
tomhudson@google.com9c639a42012-05-14 19:58:06 +0000157 static const int fCoordDims = 2;
158
tomhudson@google.com040c41a2012-05-18 14:57:40 +0000159 /// True if fSampleCoords is an expression; false if it's a bare
160 /// variable name
tomhudson@google.com52598142012-05-24 17:44:30 +0000161 bool fComplexCoord;
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000162 SkString fSampleCoords;
tomhudson@google.com52598142012-05-24 17:44:30 +0000163
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000164 SkString fSwizzle;
165 SkString fModulate;
tomhudson@google.com040c41a2012-05-18 14:57:40 +0000166
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000167 SkString fTexFunc;
tomhudson@google.com5440f062012-06-01 15:55:50 +0000168
tomhudson@google.com040c41a2012-05-18 14:57:40 +0000169 //@}
tomhudson@google.com9c639a42012-05-14 19:58:06 +0000170
bsalomon@google.comad5e9372012-07-11 18:11:27 +0000171private:
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000172 enum {
173 kNonStageIdx = -1,
174 };
175
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000176 const GrGLContextInfo& fContext;
177 GrGLUniformManager& fUniformManager;
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000178 int fCurrentStage;
tomhudson@google.comf9ad8862012-05-11 20:38:48 +0000179};
180
181#endif