initial import
[vuplus_webkit] / Source / ThirdParty / ANGLE / src / compiler / ShaderLang.cpp
1 //
2 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 //
8 // Implement the top-level of interface to the compiler,
9 // as defined in ShaderLang.h
10 //
11
12 #include "GLSLANG/ShaderLang.h"
13
14 #include "compiler/InitializeDll.h"
15 #include "compiler/ShHandle.h"
16
17 //
18 // This is the platform independent interface between an OGL driver
19 // and the shading language compiler.
20 //
21
22 static int getVariableMaxLength(const TVariableInfoList& varList)
23 {
24     TString::size_type maxLen = 0;
25     for (TVariableInfoList::const_iterator i = varList.begin();
26          i != varList.end(); ++i)
27     {
28         maxLen = std::max(maxLen, i->name.size());
29     }
30     // Add 1 to include null-termination character.
31     return static_cast<int>(maxLen) + 1;
32 }
33
34 static void getVariableInfo(ShShaderInfo varType,
35                             const ShHandle handle,
36                             int index,
37                             int* length,
38                             int* size,
39                             ShDataType* type,
40                             char* name,
41                             char* mappedName)
42 {
43     if (!handle || !size || !type || !name)
44         return;
45     ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
46            (varType == SH_ACTIVE_UNIFORMS));
47
48     TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
49     TCompiler* compiler = base->getAsCompiler();
50     if (compiler == 0)
51         return;
52
53     const TVariableInfoList& varList = varType == SH_ACTIVE_ATTRIBUTES ?
54         compiler->getAttribs() : compiler->getUniforms();
55     if (index < 0 || index >= static_cast<int>(varList.size()))
56         return;
57
58     const TVariableInfo& varInfo = varList[index];
59     if (length) *length = varInfo.name.size();
60     *size = varInfo.size;
61     *type = varInfo.type;
62     strcpy(name, varInfo.name.c_str());
63     if (mappedName)
64         strcpy(mappedName, varInfo.mappedName.c_str());
65 }
66
67 //
68 // Driver must call this first, once, before doing any other
69 // compiler operations.
70 //
71 int ShInitialize()
72 {
73     if (!InitProcess())
74         return 0;
75
76     return 1;
77 }
78
79 //
80 // Cleanup symbol tables
81 //
82 int ShFinalize()
83 {
84     if (!DetachProcess())
85         return 0;
86
87     return 1;
88 }
89
90 //
91 // Initialize built-in resources with minimum expected values.
92 //
93 void ShInitBuiltInResources(ShBuiltInResources* resources)
94 {
95     // Constants.
96     resources->MaxVertexAttribs = 8;
97     resources->MaxVertexUniformVectors = 128;
98     resources->MaxVaryingVectors = 8;
99     resources->MaxVertexTextureImageUnits = 0;
100     resources->MaxCombinedTextureImageUnits = 8;
101     resources->MaxTextureImageUnits = 8;
102     resources->MaxFragmentUniformVectors = 16;
103     resources->MaxDrawBuffers = 1;
104
105     // Extensions.
106     resources->OES_standard_derivatives = 0;
107 }
108
109 //
110 // Driver calls these to create and destroy compiler objects.
111 //
112 ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
113                              ShShaderOutput output,
114                              const ShBuiltInResources* resources)
115 {
116     if (!InitThread())
117         return 0;
118
119     TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec, output));
120     TCompiler* compiler = base->getAsCompiler();
121     if (compiler == 0)
122         return 0;
123
124     // Generate built-in symbol table.
125     if (!compiler->Init(*resources)) {
126         ShDestruct(base);
127         return 0;
128     }
129
130     return reinterpret_cast<void*>(base);
131 }
132
133 void ShDestruct(ShHandle handle)
134 {
135     if (handle == 0)
136         return;
137
138     TShHandleBase* base = static_cast<TShHandleBase*>(handle);
139
140     if (base->getAsCompiler())
141         DeleteCompiler(base->getAsCompiler());
142 }
143
144 //
145 // Do an actual compile on the given strings.  The result is left 
146 // in the given compile object.
147 //
148 // Return:  The return value of ShCompile is really boolean, indicating
149 // success or failure.
150 //
151 int ShCompile(
152     const ShHandle handle,
153     const char* const shaderStrings[],
154     const int numStrings,
155     int compileOptions)
156 {
157     if (!InitThread())
158         return 0;
159
160     if (handle == 0)
161         return 0;
162
163     TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
164     TCompiler* compiler = base->getAsCompiler();
165     if (compiler == 0)
166         return 0;
167
168     bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
169     return success ? 1 : 0;
170 }
171
172 void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params)
173 {
174     if (!handle || !params)
175         return;
176
177     TShHandleBase* base = static_cast<TShHandleBase*>(handle);
178     TCompiler* compiler = base->getAsCompiler();
179     if (!compiler) return;
180
181     switch(pname)
182     {
183     case SH_INFO_LOG_LENGTH:
184         *params = compiler->getInfoSink().info.size() + 1;
185         break;
186     case SH_OBJECT_CODE_LENGTH:
187         *params = compiler->getInfoSink().obj.size() + 1;
188         break;
189     case SH_ACTIVE_UNIFORMS:
190         *params = compiler->getUniforms().size();
191         break;
192     case SH_ACTIVE_UNIFORM_MAX_LENGTH:
193         *params = getVariableMaxLength(compiler->getUniforms());
194         break;
195     case SH_ACTIVE_ATTRIBUTES:
196         *params = compiler->getAttribs().size();
197         break;
198     case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
199         *params = getVariableMaxLength(compiler->getAttribs());
200         break;
201     case SH_MAPPED_NAME_MAX_LENGTH:
202         *params = compiler->getMappedNameMaxLength();
203         break;
204     default: UNREACHABLE();
205     }
206 }
207
208 //
209 // Return any compiler log of messages for the application.
210 //
211 void ShGetInfoLog(const ShHandle handle, char* infoLog)
212 {
213     if (!handle || !infoLog)
214         return;
215
216     TShHandleBase* base = static_cast<TShHandleBase*>(handle);
217     TCompiler* compiler = base->getAsCompiler();
218     if (!compiler) return;
219
220     TInfoSink& infoSink = compiler->getInfoSink();
221     strcpy(infoLog, infoSink.info.c_str());
222 }
223
224 //
225 // Return any object code.
226 //
227 void ShGetObjectCode(const ShHandle handle, char* objCode)
228 {
229     if (!handle || !objCode)
230         return;
231
232     TShHandleBase* base = static_cast<TShHandleBase*>(handle);
233     TCompiler* compiler = base->getAsCompiler();
234     if (!compiler) return;
235
236     TInfoSink& infoSink = compiler->getInfoSink();
237     strcpy(objCode, infoSink.obj.c_str());
238 }
239
240 void ShGetActiveAttrib(const ShHandle handle,
241                        int index,
242                        int* length,
243                        int* size,
244                        ShDataType* type,
245                        char* name,
246                        char* mappedName)
247 {
248     getVariableInfo(SH_ACTIVE_ATTRIBUTES,
249                     handle, index, length, size, type, name, mappedName);
250 }
251
252 void ShGetActiveUniform(const ShHandle handle,
253                         int index,
254                         int* length,
255                         int* size,
256                         ShDataType* type,
257                         char* name,
258                         char* mappedName)
259 {
260     getVariableInfo(SH_ACTIVE_UNIFORMS,
261                     handle, index, length, size, type, name, mappedName);
262 }