Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / ui / gl / generate_bindings.py
1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium 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 """code generator for GL/GLES extension wrangler."""
7
8 import optparse
9 import os
10 import collections
11 import re
12 import sys
13
14 """In case there are multiple versions of the same function, one that's listed
15 first takes priority if its conditions are met. If the function is an extension
16 function, finding the extension from the extension string is a condition for
17 binding it. The last version of the function is treated as a fallback option in
18 case no other versions were bound, so a non-null function pointer in the
19 bindings does not guarantee that the function is supported.
20
21 Function binding conditions can be specified manually by supplying a versions
22 array instead of the names array. Each version has the following keys:
23    name: Mandatory. Name of the function. Multiple versions can have the same
24          name but different conditions.
25    gl_versions: List of GL versions where the function is found.
26    extensions: Extensions where the function is found. If not specified, the
27                extensions are determined based on GL header files.
28                If the function exists in an extension header, you may specify
29                an empty array to prevent making that a condition for binding.
30
31 By default, the function gets its name from the first name in its names or
32 versions array. This can be overridden by supplying a 'known_as' key.
33 """
34 GL_FUNCTIONS = [
35 { 'return_type': 'void',
36   'names': ['glActiveTexture'],
37   'arguments': 'GLenum texture', },
38 { 'return_type': 'void',
39   'names': ['glAttachShader'],
40   'arguments': 'GLuint program, GLuint shader', },
41 { 'return_type': 'void',
42   'names': ['glBeginQuery'],
43   'arguments': 'GLenum target, GLuint id', },
44 { 'return_type': 'void',
45   'names': ['glBeginQueryARB', 'glBeginQueryEXT'],
46   'arguments': 'GLenum target, GLuint id', },
47 { 'return_type': 'void',
48   'names': ['glBindAttribLocation'],
49   'arguments': 'GLuint program, GLuint index, const char* name', },
50 { 'return_type': 'void',
51   'names': ['glBindBuffer'],
52   'arguments': 'GLenum target, GLuint buffer', },
53 { 'return_type': 'void',
54   'names': ['glBindFragDataLocation'],
55   'arguments': 'GLuint program, GLuint colorNumber, const char* name', },
56 { 'return_type': 'void',
57   'names': ['glBindFragDataLocationIndexed'],
58   'arguments':
59       'GLuint program, GLuint colorNumber, GLuint index, const char* name', },
60 { 'return_type': 'void',
61   'names': ['glBindFramebufferEXT', 'glBindFramebuffer'],
62   'arguments': 'GLenum target, GLuint framebuffer', },
63 { 'return_type': 'void',
64   'names': ['glBindRenderbufferEXT', 'glBindRenderbuffer'],
65   'arguments': 'GLenum target, GLuint renderbuffer', },
66 { 'return_type': 'void',
67   'names': ['glBindTexture'],
68   'arguments': 'GLenum target, GLuint texture', },
69 { 'return_type': 'void',
70   'names': ['glBlendColor'],
71   'arguments': 'GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha', },
72 { 'return_type': 'void',
73   'names': ['glBlendEquation'],
74   'arguments': ' GLenum mode ', },
75 { 'return_type': 'void',
76   'names': ['glBlendEquationSeparate'],
77   'arguments': 'GLenum modeRGB, GLenum modeAlpha', },
78 { 'return_type': 'void',
79   'names': ['glBlendFunc'],
80   'arguments': 'GLenum sfactor, GLenum dfactor', },
81 { 'return_type': 'void',
82   'names': ['glBlendFuncSeparate'],
83   'arguments':
84       'GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha', },
85 { 'return_type': 'void',
86   'names': ['glBlitFramebuffer'],
87   'arguments': 'GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, '
88                'GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, '
89                'GLbitfield mask, GLenum filter', },
90 { 'return_type': 'void',
91   'names': ['glBlitFramebufferEXT', 'glBlitFramebuffer'],
92   'arguments': 'GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, '
93                'GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, '
94                'GLbitfield mask, GLenum filter', },
95 { 'return_type': 'void',
96   'names': ['glBlitFramebufferANGLE', 'glBlitFramebuffer'],
97   'arguments': 'GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, '
98                'GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, '
99                'GLbitfield mask, GLenum filter', },
100 { 'return_type': 'void',
101   'names': ['glBufferData'],
102   'arguments': 'GLenum target, GLsizei size, const void* data, GLenum usage', },
103 { 'return_type': 'void',
104   'names': ['glBufferSubData'],
105   'arguments': 'GLenum target, GLint offset, GLsizei size, const void* data', },
106 { 'return_type': 'GLenum',
107   'names': ['glCheckFramebufferStatusEXT',
108             'glCheckFramebufferStatus'],
109   'arguments': 'GLenum target',
110   'logging_code': """
111   GL_SERVICE_LOG("GL_RESULT: " << GLES2Util::GetStringEnum(result));
112 """, },
113 { 'return_type': 'void',
114   'names': ['glClear'],
115   'arguments': 'GLbitfield mask', },
116 { 'return_type': 'void',
117   'names': ['glClearColor'],
118   'arguments': 'GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha', },
119 { 'return_type': 'void',
120   'names': ['glClearDepth'],
121   'arguments': 'GLclampd depth', },
122 { 'return_type': 'void',
123   'names': ['glClearDepthf'],
124   'arguments': 'GLclampf depth', },
125 { 'return_type': 'void',
126   'names': ['glClearStencil'],
127   'arguments': 'GLint s', },
128 { 'return_type': 'void',
129   'names': ['glColorMask'],
130   'arguments':
131       'GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha', },
132 { 'return_type': 'void',
133   'names': ['glCompileShader'],
134   'arguments': 'GLuint shader', },
135 { 'return_type': 'void',
136   'names': ['glCompressedTexImage2D'],
137   'arguments':
138       'GLenum target, GLint level, GLenum internalformat, GLsizei width, '
139       'GLsizei height, GLint border, GLsizei imageSize, const void* data', },
140 { 'return_type': 'void',
141   'names': ['glCompressedTexSubImage2D'],
142   'arguments':
143      'GLenum target, GLint level, GLint xoffset, GLint yoffset, '
144      'GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, '
145      'const void* data', },
146 { 'return_type': 'void',
147   'names': ['glCopyTexImage2D'],
148   'arguments':
149       'GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, '
150       'GLsizei width, GLsizei height, GLint border', },
151 { 'return_type': 'void',
152   'names': ['glCopyTexSubImage2D'],
153   'arguments':
154       'GLenum target, GLint level, GLint xoffset, '
155       'GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height', },
156 { 'return_type': 'GLuint',
157   'names': ['glCreateProgram'],
158   'arguments': 'void', },
159 { 'return_type': 'GLuint',
160   'names': ['glCreateShader'],
161   'arguments': 'GLenum type', },
162 { 'return_type': 'void',
163   'names': ['glCullFace'],
164   'arguments': 'GLenum mode', },
165 { 'return_type': 'void',
166   'names': ['glDeleteBuffersARB', 'glDeleteBuffers'],
167   'arguments': 'GLsizei n, const GLuint* buffers', },
168 { 'return_type': 'void',
169   'names': ['glDeleteFramebuffersEXT', 'glDeleteFramebuffers'],
170   'arguments': 'GLsizei n, const GLuint* framebuffers', },
171 { 'return_type': 'void',
172   'names': ['glDeleteProgram'],
173   'arguments': 'GLuint program', },
174 { 'return_type': 'void',
175   'names': ['glDeleteQueries'],
176   'arguments': 'GLsizei n, const GLuint* ids', },
177 { 'return_type': 'void',
178   'names': ['glDeleteQueriesARB', 'glDeleteQueriesEXT'],
179   'arguments': 'GLsizei n, const GLuint* ids', },
180 { 'return_type': 'void',
181   'names': ['glDeleteRenderbuffersEXT', 'glDeleteRenderbuffers'],
182   'arguments': 'GLsizei n, const GLuint* renderbuffers', },
183 { 'return_type': 'void',
184   'names': ['glDeleteShader'],
185   'arguments': 'GLuint shader', },
186 { 'return_type': 'void',
187   'names': ['glDeleteTextures'],
188   'arguments': 'GLsizei n, const GLuint* textures', },
189 { 'return_type': 'void',
190   'names': ['glDepthFunc'],
191   'arguments': 'GLenum func', },
192 { 'return_type': 'void',
193   'names': ['glDepthMask'],
194   'arguments': 'GLboolean flag', },
195 { 'return_type': 'void',
196   'names': ['glDepthRange'],
197   'arguments': 'GLclampd zNear, GLclampd zFar', },
198 { 'return_type': 'void',
199   'names': ['glDepthRangef'],
200   'arguments': 'GLclampf zNear, GLclampf zFar', },
201 { 'return_type': 'void',
202   'names': ['glDetachShader'],
203   'arguments': 'GLuint program, GLuint shader', },
204 { 'return_type': 'void',
205   'names': ['glDisable'],
206   'arguments': 'GLenum cap', },
207 { 'return_type': 'void',
208   'names': ['glDisableVertexAttribArray'],
209   'arguments': 'GLuint index', },
210 { 'return_type': 'void',
211   'names': ['glDrawArrays'],
212   'arguments': 'GLenum mode, GLint first, GLsizei count', },
213 { 'return_type': 'void',
214   'names': ['glDrawBuffer'],
215   'arguments': 'GLenum mode', },
216 { 'return_type': 'void',
217   'names': ['glDrawBuffersARB', 'glDrawBuffersEXT'],
218   'arguments': 'GLsizei n, const GLenum* bufs', },
219 { 'return_type': 'void',
220   'names': ['glDrawElements'],
221   'arguments':
222       'GLenum mode, GLsizei count, GLenum type, const void* indices', },
223 { 'return_type': 'void',
224   'names': ['glEGLImageTargetTexture2DOES'],
225   'arguments': 'GLenum target, GLeglImageOES image', },
226 { 'return_type': 'void',
227   'names': ['glEGLImageTargetRenderbufferStorageOES'],
228   'arguments': 'GLenum target, GLeglImageOES image', },
229 { 'return_type': 'void',
230   'names': ['glEnable'],
231   'arguments': 'GLenum cap', },
232 { 'return_type': 'void',
233   'names': ['glEnableVertexAttribArray'],
234   'arguments': 'GLuint index', },
235 { 'return_type': 'void',
236   'names': ['glEndQuery'],
237   'arguments': 'GLenum target', },
238 { 'return_type': 'void',
239   'names': ['glEndQueryARB', 'glEndQueryEXT'],
240   'arguments': 'GLenum target', },
241 { 'return_type': 'void',
242   'names': ['glFinish'],
243   'arguments': 'void', },
244 { 'return_type': 'void',
245   'names': ['glFlush'],
246   'arguments': 'void', },
247 { 'return_type': 'void',
248   'names': ['glFramebufferRenderbufferEXT', 'glFramebufferRenderbuffer'],
249   'arguments': \
250       'GLenum target, GLenum attachment, GLenum renderbuffertarget, '
251       'GLuint renderbuffer', },
252 { 'return_type': 'void',
253   'names': ['glFramebufferTexture2DEXT', 'glFramebufferTexture2D'],
254   'arguments':
255       'GLenum target, GLenum attachment, GLenum textarget, GLuint texture, '
256       'GLint level', },
257 { 'return_type': 'void',
258   'names': ['glFramebufferTexture2DMultisampleEXT'],
259   'arguments':
260       'GLenum target, GLenum attachment, GLenum textarget, GLuint texture, '
261       'GLint level, GLsizei samples', },
262 { 'return_type': 'void',
263   'names': ['glFramebufferTexture2DMultisampleIMG'],
264   'arguments':
265       'GLenum target, GLenum attachment, GLenum textarget, GLuint texture, '
266       'GLint level, GLsizei samples', },
267 { 'return_type': 'void',
268   'names': ['glFrontFace'],
269   'arguments': 'GLenum mode', },
270 { 'return_type': 'void',
271   'names': ['glGenBuffersARB', 'glGenBuffers'],
272   'arguments': 'GLsizei n, GLuint* buffers', },
273 { 'return_type': 'void',
274   'names': ['glGenQueries'],
275   'arguments': 'GLsizei n, GLuint* ids', },
276 { 'return_type': 'void',
277   'names': ['glGenQueriesARB', 'glGenQueriesEXT'],
278   'arguments': 'GLsizei n, GLuint* ids', },
279 { 'return_type': 'void',
280   'names': ['glGenerateMipmapEXT', 'glGenerateMipmap'],
281   'arguments': 'GLenum target', },
282 { 'return_type': 'void',
283   'names': ['glGenFramebuffersEXT', 'glGenFramebuffers'],
284   'arguments': 'GLsizei n, GLuint* framebuffers', },
285 { 'return_type': 'void',
286   'names': ['glGenRenderbuffersEXT', 'glGenRenderbuffers'],
287   'arguments': 'GLsizei n, GLuint* renderbuffers', },
288 { 'return_type': 'void',
289   'names': ['glGenTextures'],
290   'arguments': 'GLsizei n, GLuint* textures', },
291 { 'return_type': 'void',
292   'names': ['glGetActiveAttrib'],
293   'arguments':
294       'GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, '
295       'GLint* size, GLenum* type, char* name', },
296 { 'return_type': 'void',
297   'names': ['glGetActiveUniform'],
298   'arguments':
299       'GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, '
300       'GLint* size, GLenum* type, char* name', },
301 { 'return_type': 'void',
302   'names': ['glGetAttachedShaders'],
303   'arguments':
304       'GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders', },
305 { 'return_type': 'GLint',
306   'names': ['glGetAttribLocation'],
307   'arguments': 'GLuint program, const char* name', },
308 { 'return_type': 'void',
309   'names': ['glGetBooleanv'],
310   'arguments': 'GLenum pname, GLboolean* params', },
311 { 'return_type': 'void',
312   'names': ['glGetBufferParameteriv'],
313   'arguments': 'GLenum target, GLenum pname, GLint* params', },
314 { 'return_type': 'GLenum',
315   'names': ['glGetError'],
316   'arguments': 'void',
317   'logging_code': """
318   GL_SERVICE_LOG("GL_RESULT: " << GLES2Util::GetStringError(result));
319 """, },
320 { 'return_type': 'void',
321   'names': ['glGetFloatv'],
322   'arguments': 'GLenum pname, GLfloat* params', },
323 { 'return_type': 'void',
324   'names': ['glGetFramebufferAttachmentParameterivEXT',
325             'glGetFramebufferAttachmentParameteriv'],
326   'arguments': 'GLenum target, '
327                'GLenum attachment, GLenum pname, GLint* params', },
328 { 'return_type': 'GLenum',
329   'names': ['glGetGraphicsResetStatusARB',
330             'glGetGraphicsResetStatusEXT'],
331   'arguments': 'void', },
332 { 'return_type': 'void',
333   'names': ['glGetIntegerv'],
334   'arguments': 'GLenum pname, GLint* params', },
335 { 'return_type': 'void',
336   'known_as': 'glGetProgramBinary',
337   'versions': [{ 'name': 'glGetProgramBinaryOES' },
338                { 'name': 'glGetProgramBinary',
339                  'extensions': ['GL_ARB_get_program_binary'] },
340                { 'name': 'glGetProgramBinary' }],
341   'arguments': 'GLuint program, GLsizei bufSize, GLsizei* length, '
342                'GLenum* binaryFormat, GLvoid* binary' },
343 { 'return_type': 'void',
344   'names': ['glGetProgramiv'],
345   'arguments': 'GLuint program, GLenum pname, GLint* params', },
346 { 'return_type': 'void',
347   'names': ['glGetProgramInfoLog'],
348   'arguments':
349       'GLuint program, GLsizei bufsize, GLsizei* length, char* infolog', },
350 { 'return_type': 'void',
351   'names': ['glGetQueryiv'],
352   'arguments': 'GLenum target, GLenum pname, GLint* params', },
353 { 'return_type': 'void',
354   'names': ['glGetQueryivARB', 'glGetQueryivEXT'],
355   'arguments': 'GLenum target, GLenum pname, GLint* params', },
356 { 'return_type': 'void',
357   'names': ['glGetQueryObjecti64v'],
358   'arguments': 'GLuint id, GLenum pname, GLint64* params', },
359 { 'return_type': 'void',
360   'names': ['glGetQueryObjectiv'],
361   'arguments': 'GLuint id, GLenum pname, GLint* params', },
362 { 'return_type': 'void',
363   'names': ['glGetQueryObjectui64v'],
364   'arguments': 'GLuint id, GLenum pname, GLuint64* params', },
365 { 'return_type': 'void',
366   'names': ['glGetQueryObjectuiv'],
367   'arguments': 'GLuint id, GLenum pname, GLuint* params', },
368 { 'return_type': 'void',
369   'names': ['glGetQueryObjectuivARB', 'glGetQueryObjectuivEXT'],
370   'arguments': 'GLuint id, GLenum pname, GLuint* params', },
371 { 'return_type': 'void',
372   'names': ['glGetRenderbufferParameterivEXT', 'glGetRenderbufferParameteriv'],
373   'arguments': 'GLenum target, GLenum pname, GLint* params', },
374 { 'return_type': 'void',
375   'names': ['glGetShaderiv'],
376   'arguments': 'GLuint shader, GLenum pname, GLint* params', },
377 { 'return_type': 'void',
378   'names': ['glGetShaderInfoLog'],
379   'arguments':
380       'GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog', },
381 { 'return_type': 'void',
382   'names': ['glGetShaderPrecisionFormat'],
383   'arguments': 'GLenum shadertype, GLenum precisiontype, '
384                'GLint* range, GLint* precision', },
385 { 'return_type': 'void',
386   'names': ['glGetShaderSource'],
387   'arguments':
388       'GLuint shader, GLsizei bufsize, GLsizei* length, char* source', },
389 { 'return_type': 'const GLubyte*',
390   'names': ['glGetString'],
391   'arguments': 'GLenum name', },
392 { 'return_type': 'void',
393   'names': ['glGetTexLevelParameterfv'],
394   'arguments': 'GLenum target, GLint level, GLenum pname, GLfloat* params', },
395 { 'return_type': 'void',
396   'names': ['glGetTexLevelParameteriv'],
397   'arguments': 'GLenum target, GLint level, GLenum pname, GLint* params', },
398 { 'return_type': 'void',
399   'names': ['glGetTexParameterfv'],
400   'arguments': 'GLenum target, GLenum pname, GLfloat* params', },
401 { 'return_type': 'void',
402   'names': ['glGetTexParameteriv'],
403   'arguments': 'GLenum target, GLenum pname, GLint* params', },
404 { 'return_type': 'void',
405   'names': ['glGetTranslatedShaderSourceANGLE'],
406   'arguments':
407       'GLuint shader, GLsizei bufsize, GLsizei* length, char* source', },
408 { 'return_type': 'void',
409   'names': ['glGetUniformfv'],
410   'arguments': 'GLuint program, GLint location, GLfloat* params', },
411 { 'return_type': 'void',
412   'names': ['glGetUniformiv'],
413   'arguments': 'GLuint program, GLint location, GLint* params', },
414 { 'return_type': 'GLint',
415   'names': ['glGetUniformLocation'],
416   'arguments': 'GLuint program, const char* name', },
417 { 'return_type': 'void',
418   'names': ['glGetVertexAttribfv'],
419   'arguments': 'GLuint index, GLenum pname, GLfloat* params', },
420 { 'return_type': 'void',
421   'names': ['glGetVertexAttribiv'],
422   'arguments': 'GLuint index, GLenum pname, GLint* params', },
423 { 'return_type': 'void',
424   'names': ['glGetVertexAttribPointerv'],
425   'arguments': 'GLuint index, GLenum pname, void** pointer', },
426 { 'return_type': 'void',
427   'names': ['glHint'],
428   'arguments': 'GLenum target, GLenum mode', },
429 { 'return_type': 'GLboolean',
430   'names': ['glIsBuffer'],
431   'arguments': 'GLuint buffer', },
432 { 'return_type': 'GLboolean',
433   'names': ['glIsEnabled'],
434   'arguments': 'GLenum cap', },
435 { 'return_type': 'GLboolean',
436   'names': ['glIsFramebufferEXT', 'glIsFramebuffer'],
437   'arguments': 'GLuint framebuffer', },
438 { 'return_type': 'GLboolean',
439   'names': ['glIsProgram'],
440   'arguments': 'GLuint program', },
441 { 'return_type': 'GLboolean',
442   'names': ['glIsQueryARB', 'glIsQueryEXT'],
443   'arguments': 'GLuint query', },
444 { 'return_type': 'GLboolean',
445   'names': ['glIsRenderbufferEXT', 'glIsRenderbuffer'],
446   'arguments': 'GLuint renderbuffer', },
447 { 'return_type': 'GLboolean',
448   'names': ['glIsShader'],
449   'arguments': 'GLuint shader', },
450 { 'return_type': 'GLboolean',
451   'names': ['glIsTexture'],
452   'arguments': 'GLuint texture', },
453 { 'return_type': 'void',
454   'names': ['glLineWidth'],
455   'arguments': 'GLfloat width', },
456 { 'return_type': 'void',
457   'names': ['glLinkProgram'],
458   'arguments': 'GLuint program', },
459 { 'return_type': 'void*',
460   'known_as': 'glMapBuffer',
461   'names': ['glMapBufferOES', 'glMapBuffer'],
462   'arguments': 'GLenum target, GLenum access', },
463 { 'return_type': 'void*',
464   'names': ['glMapBufferRange'],
465   'arguments':
466       'GLenum target, GLintptr offset, GLsizeiptr length, GLenum access', },
467 { 'return_type': 'void',
468   'names': ['glFlushMappedBufferRange'],
469   'arguments': 'GLenum target, GLintptr offset, GLsizeiptr length', },
470 { 'return_type': 'void',
471   'names': ['glPixelStorei'],
472   'arguments': 'GLenum pname, GLint param', },
473 { 'return_type': 'void',
474   'names': ['glPointParameteri'],
475   'arguments': 'GLenum pname, GLint param', },
476 { 'return_type': 'void',
477   'names': ['glPolygonOffset'],
478   'arguments': 'GLfloat factor, GLfloat units', },
479 { 'return_type': 'void',
480   'known_as': 'glProgramBinary',
481   'versions': [{ 'name': 'glProgramBinaryOES' },
482                { 'name': 'glProgramBinary',
483                  'extensions': ['GL_ARB_get_program_binary'] },
484                { 'name': 'glProgramBinary' }],
485   'arguments': 'GLuint program, GLenum binaryFormat, '
486                'const GLvoid* binary, GLsizei length' },
487 { 'return_type': 'void',
488   'versions': [{ 'name': 'glProgramParameteri',
489                  'extensions': ['GL_ARB_get_program_binary'] },
490                { 'name': 'glProgramParameteri' }],
491   'arguments': 'GLuint program, GLenum pname, GLint value' },
492 { 'return_type': 'void',
493   'names': ['glQueryCounter'],
494   'arguments': 'GLuint id, GLenum target', },
495 { 'return_type': 'void',
496   'names': ['glReadBuffer'],
497   'arguments': 'GLenum src', },
498 { 'return_type': 'void',
499   'names': ['glReadPixels'],
500   'arguments':
501     'GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, '
502     'GLenum type, void* pixels', },
503 { 'return_type': 'void',
504   'names': ['glReleaseShaderCompiler'],
505   'arguments': 'void', },
506 # Multisampling API is different in different GL versions, some require an
507 # explicit resolve step for renderbuffers and/or FBO texture attachments and
508 # some do not. Multiple alternatives might be present in a single
509 # implementation, which require different use of the API and may have
510 # different performance (explicit resolve performing worse, for example).
511 # So even though the function signature is the same across versions, we split
512 # their definitions so that the function to use can be chosen correctly at a
513 # higher level.
514 # TODO(oetuaho@nvidia.com): Some of these might still be possible to combine.
515 # This could also fix weirdness in the mock bindings that's caused by the same
516 # function name appearing multiple times.
517 # This is the ES3 function, which requires explicit resolve:
518 { 'return_type': 'void',
519   'names': ['glRenderbufferStorageMultisample'],
520   'arguments': 'GLenum target, GLsizei samples, GLenum internalformat, '
521                'GLsizei width, GLsizei height', },
522 # In desktop GL, EXT and core versions both have an explicit resolve step,
523 # though desktop core GL implicitly resolves when drawing to a window.
524 # TODO(oetuaho@nvidia.com): Right now this function also doubles as ES2 EXT
525 # function, which has implicit resolve, and for which the fallback is wrong.
526 # Fix this.
527 { 'return_type': 'void',
528   'names': ['glRenderbufferStorageMultisampleEXT',
529             'glRenderbufferStorageMultisample'],
530   'arguments': 'GLenum target, GLsizei samples, GLenum internalformat, '
531                'GLsizei width, GLsizei height', },
532 { 'return_type': 'void',
533   'names': ['glRenderbufferStorageMultisampleANGLE',
534             'glRenderbufferStorageMultisample'],
535   'arguments': 'GLenum target, GLsizei samples, GLenum internalformat, '
536                'GLsizei width, GLsizei height', },
537 { 'return_type': 'void',
538   'names': ['glRenderbufferStorageMultisampleIMG'],
539   'arguments': 'GLenum target, GLsizei samples, GLenum internalformat, '
540                'GLsizei width, GLsizei height', },
541 { 'return_type': 'void',
542   'names': ['glRenderbufferStorageEXT', 'glRenderbufferStorage'],
543   'arguments':
544       'GLenum target, GLenum internalformat, GLsizei width, GLsizei height', },
545 { 'return_type': 'void',
546   'names': ['glSampleCoverage'],
547   'arguments': 'GLclampf value, GLboolean invert', },
548 { 'return_type': 'void',
549   'names': ['glScissor'],
550   'arguments': 'GLint x, GLint y, GLsizei width, GLsizei height', },
551 { 'return_type': 'void',
552   'names': ['glShaderBinary'],
553   'arguments': 'GLsizei n, const GLuint* shaders, GLenum binaryformat, '
554                'const void* binary, GLsizei length', },
555 { 'return_type': 'void',
556   'names': ['glShaderSource'],
557   'arguments': 'GLuint shader, GLsizei count, const char* const* str, '
558                'const GLint* length',
559   'logging_code': """
560   GL_SERVICE_LOG_CODE_BLOCK({
561     for (GLsizei ii = 0; ii < count; ++ii) {
562       if (str[ii]) {
563         if (length && length[ii] >= 0) {
564           std::string source(str[ii], length[ii]);
565           GL_SERVICE_LOG("  " << ii << ": ---\\n" << source << "\\n---");
566         } else {
567           GL_SERVICE_LOG("  " << ii << ": ---\\n" << str[ii] << "\\n---");
568         }
569       } else {
570         GL_SERVICE_LOG("  " << ii << ": NULL");
571       }
572     }
573   });
574 """, },
575 { 'return_type': 'void',
576   'names': ['glStencilFunc'],
577   'arguments': 'GLenum func, GLint ref, GLuint mask', },
578 { 'return_type': 'void',
579   'names': ['glStencilFuncSeparate'],
580   'arguments': 'GLenum face, GLenum func, GLint ref, GLuint mask', },
581 { 'return_type': 'void',
582   'names': ['glStencilMask'],
583   'arguments': 'GLuint mask', },
584 { 'return_type': 'void',
585   'names': ['glStencilMaskSeparate'],
586   'arguments': 'GLenum face, GLuint mask', },
587 { 'return_type': 'void',
588   'names': ['glStencilOp'],
589   'arguments': 'GLenum fail, GLenum zfail, GLenum zpass', },
590 { 'return_type': 'void',
591   'names': ['glStencilOpSeparate'],
592   'arguments': 'GLenum face, GLenum fail, GLenum zfail, GLenum zpass', },
593 { 'return_type': 'void',
594   'names': ['glTexImage2D'],
595   'arguments':
596       'GLenum target, GLint level, GLint internalformat, GLsizei width, '
597       'GLsizei height, GLint border, GLenum format, GLenum type, '
598       'const void* pixels', },
599 { 'return_type': 'void',
600   'names': ['glTexParameterf'],
601   'arguments': 'GLenum target, GLenum pname, GLfloat param', },
602 { 'return_type': 'void',
603   'names': ['glTexParameterfv'],
604   'arguments': 'GLenum target, GLenum pname, const GLfloat* params', },
605 { 'return_type': 'void',
606   'names': ['glTexParameteri'],
607   'arguments': 'GLenum target, GLenum pname, GLint param', },
608 { 'return_type': 'void',
609   'names': ['glTexParameteriv'],
610   'arguments': 'GLenum target, GLenum pname, const GLint* params', },
611 { 'return_type': 'void',
612   'names': ['glTexStorage2DEXT'],
613   'arguments': 'GLenum target, GLsizei levels, GLenum internalformat, '
614                'GLsizei width, GLsizei height', },
615 { 'return_type': 'void',
616   'names': ['glTexSubImage2D'],
617   'arguments':
618      'GLenum target, GLint level, GLint xoffset, GLint yoffset, '
619      'GLsizei width, GLsizei height, GLenum format, GLenum type, '
620      'const void* pixels', },
621 { 'return_type': 'void',
622   'names': ['glUniform1f'],
623   'arguments': 'GLint location, GLfloat x', },
624 { 'return_type': 'void',
625   'names': ['glUniform1fv'],
626   'arguments': 'GLint location, GLsizei count, const GLfloat* v', },
627 { 'return_type': 'void',
628   'names': ['glUniform1i'],
629   'arguments': 'GLint location, GLint x', },
630 { 'return_type': 'void',
631   'names': ['glUniform1iv'],
632   'arguments': 'GLint location, GLsizei count, const GLint* v', },
633 { 'return_type': 'void',
634   'names': ['glUniform2f'],
635   'arguments': 'GLint location, GLfloat x, GLfloat y', },
636 { 'return_type': 'void',
637   'names': ['glUniform2fv'],
638   'arguments': 'GLint location, GLsizei count, const GLfloat* v', },
639 { 'return_type': 'void',
640   'names': ['glUniform2i'],
641   'arguments': 'GLint location, GLint x, GLint y', },
642 { 'return_type': 'void',
643   'names': ['glUniform2iv'],
644   'arguments': 'GLint location, GLsizei count, const GLint* v', },
645 { 'return_type': 'void',
646   'names': ['glUniform3f'],
647   'arguments': 'GLint location, GLfloat x, GLfloat y, GLfloat z', },
648 { 'return_type': 'void',
649   'names': ['glUniform3fv'],
650   'arguments': 'GLint location, GLsizei count, const GLfloat* v', },
651 { 'return_type': 'void',
652   'names': ['glUniform3i'],
653   'arguments': 'GLint location, GLint x, GLint y, GLint z', },
654 { 'return_type': 'void',
655   'names': ['glUniform3iv'],
656   'arguments': 'GLint location, GLsizei count, const GLint* v', },
657 { 'return_type': 'void',
658   'names': ['glUniform4f'],
659   'arguments': 'GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w', },
660 { 'return_type': 'void',
661   'names': ['glUniform4fv'],
662   'arguments': 'GLint location, GLsizei count, const GLfloat* v', },
663 { 'return_type': 'void',
664   'names': ['glUniform4i'],
665   'arguments': 'GLint location, GLint x, GLint y, GLint z, GLint w', },
666 { 'return_type': 'void',
667   'names': ['glUniform4iv'],
668   'arguments': 'GLint location, GLsizei count, const GLint* v', },
669 { 'return_type': 'void',
670   'names': ['glUniformMatrix2fv'],
671   'arguments': 'GLint location, GLsizei count, '
672                'GLboolean transpose, const GLfloat* value', },
673 { 'return_type': 'void',
674   'names': ['glUniformMatrix3fv'],
675   'arguments': 'GLint location, GLsizei count, '
676                'GLboolean transpose, const GLfloat* value', },
677 { 'return_type': 'void',
678   'names': ['glUniformMatrix4fv'],
679   'arguments': 'GLint location, GLsizei count, '
680                'GLboolean transpose, const GLfloat* value', },
681 { 'return_type': 'GLboolean',
682   'known_as': 'glUnmapBuffer',
683   'names': ['glUnmapBufferOES', 'glUnmapBuffer'],
684   'arguments': 'GLenum target', },
685 { 'return_type': 'void',
686   'names': ['glUseProgram'],
687   'arguments': 'GLuint program', },
688 { 'return_type': 'void',
689   'names': ['glValidateProgram'],
690   'arguments': 'GLuint program', },
691 { 'return_type': 'void',
692   'names': ['glVertexAttrib1f'],
693   'arguments': 'GLuint indx, GLfloat x', },
694 { 'return_type': 'void',
695   'names': ['glVertexAttrib1fv'],
696   'arguments': 'GLuint indx, const GLfloat* values', },
697 { 'return_type': 'void',
698   'names': ['glVertexAttrib2f'],
699   'arguments': 'GLuint indx, GLfloat x, GLfloat y', },
700 { 'return_type': 'void',
701   'names': ['glVertexAttrib2fv'],
702   'arguments': 'GLuint indx, const GLfloat* values', },
703 { 'return_type': 'void',
704   'names': ['glVertexAttrib3f'],
705   'arguments': 'GLuint indx, GLfloat x, GLfloat y, GLfloat z', },
706 { 'return_type': 'void',
707   'names': ['glVertexAttrib3fv'],
708   'arguments': 'GLuint indx, const GLfloat* values', },
709 { 'return_type': 'void',
710   'names': ['glVertexAttrib4f'],
711   'arguments': 'GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w', },
712 { 'return_type': 'void',
713   'names': ['glVertexAttrib4fv'],
714   'arguments': 'GLuint indx, const GLfloat* values', },
715 { 'return_type': 'void',
716   'names': ['glVertexAttribPointer'],
717   'arguments': 'GLuint indx, GLint size, GLenum type, GLboolean normalized, '
718                'GLsizei stride, const void* ptr', },
719 { 'return_type': 'void',
720   'names': ['glViewport'],
721   'arguments': 'GLint x, GLint y, GLsizei width, GLsizei height', },
722 { 'return_type': 'void',
723   'names': ['glGenFencesNV'],
724   'arguments': 'GLsizei n, GLuint* fences', },
725 { 'return_type': 'void',
726   'names': ['glDeleteFencesNV'],
727   'arguments': 'GLsizei n, const GLuint* fences', },
728 { 'return_type': 'void',
729   'names': ['glSetFenceNV'],
730   'arguments': 'GLuint fence, GLenum condition', },
731 { 'return_type': 'GLboolean',
732   'names': ['glTestFenceNV'],
733   'arguments': 'GLuint fence', },
734 { 'return_type': 'void',
735   'names': ['glFinishFenceNV'],
736   'arguments': 'GLuint fence', },
737 { 'return_type': 'GLboolean',
738   'names': ['glIsFenceNV'],
739   'arguments': 'GLuint fence', },
740 { 'return_type': 'void',
741   'names': ['glGetFenceivNV'],
742   'arguments': 'GLuint fence, GLenum pname, GLint* params', },
743 { 'return_type': 'GLsync',
744   'names': ['glFenceSync'],
745   'arguments': 'GLenum condition, GLbitfield flags', },
746 { 'return_type': 'void',
747   'names': ['glDeleteSync'],
748   'arguments': 'GLsync sync', },
749 { 'return_type': 'void',
750   'names': ['glGetSynciv'],
751   'arguments':
752     'GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length,'
753     'GLint* values', },
754 { 'return_type': 'GLenum',
755   'names': ['glClientWaitSync'],
756   'arguments':
757     'GLsync sync, GLbitfield flags, GLuint64 timeout', },
758 { 'return_type': 'void',
759   'known_as': 'glDrawArraysInstancedANGLE',
760   'names': ['glDrawArraysInstancedARB', 'glDrawArraysInstancedANGLE'],
761   'arguments': 'GLenum mode, GLint first, GLsizei count, GLsizei primcount', },
762 { 'return_type': 'void',
763   'known_as': 'glDrawElementsInstancedANGLE',
764   'names': ['glDrawElementsInstancedARB', 'glDrawElementsInstancedANGLE'],
765   'arguments':
766       'GLenum mode, GLsizei count, GLenum type, const void* indices, '
767       'GLsizei primcount', },
768 { 'return_type': 'void',
769   'known_as': 'glVertexAttribDivisorANGLE',
770   'names': ['glVertexAttribDivisorARB', 'glVertexAttribDivisorANGLE'],
771   'arguments':
772       'GLuint index, GLuint divisor', },
773 { 'return_type': 'void',
774   'known_as': 'glGenVertexArraysOES',
775   'versions': [{ 'name': 'glGenVertexArrays',
776                  'gl_versions': ['gl3', 'gl4'] },
777                { 'name': 'glGenVertexArrays',
778                  'extensions': ['GL_ARB_vertex_array_object'] },
779                { 'name': 'glGenVertexArraysOES' },
780                { 'name': 'glGenVertexArraysAPPLE',
781                  'extensions': ['GL_APPLE_vertex_array_object'] }],
782   'arguments': 'GLsizei n, GLuint* arrays', },
783 { 'return_type': 'void',
784   'known_as': 'glDeleteVertexArraysOES',
785   'versions': [{ 'name': 'glDeleteVertexArrays',
786                  'gl_versions': ['gl3', 'gl4'] },
787                { 'name': 'glDeleteVertexArrays',
788                  'extensions': ['GL_ARB_vertex_array_object'] },
789                { 'name': 'glDeleteVertexArraysOES' },
790                { 'name': 'glDeleteVertexArraysAPPLE',
791                  'extensions': ['GL_APPLE_vertex_array_object'] }],
792   'arguments': 'GLsizei n, const GLuint* arrays' },
793 { 'return_type': 'void',
794   'known_as': 'glBindVertexArrayOES',
795   'versions': [{ 'name': 'glBindVertexArray',
796                  'gl_versions': ['gl3', 'gl4'] },
797                { 'name': 'glBindVertexArray',
798                  'extensions': ['GL_ARB_vertex_array_object'] },
799                { 'name': 'glBindVertexArrayOES' },
800                { 'name': 'glBindVertexArrayAPPLE',
801                  'extensions': ['GL_APPLE_vertex_array_object'] }],
802   'arguments': 'GLuint array' },
803 { 'return_type': 'GLboolean',
804   'known_as': 'glIsVertexArrayOES',
805   'versions': [{ 'name': 'glIsVertexArray',
806                  'gl_versions': ['gl3', 'gl4'] },
807                { 'name': 'glIsVertexArray',
808                  'extensions': ['GL_ARB_vertex_array_object'] },
809                { 'name': 'glIsVertexArrayOES' },
810                { 'name': 'glIsVertexArrayAPPLE',
811                  'extensions': ['GL_APPLE_vertex_array_object'] }],
812   'arguments': 'GLuint array' },
813 { 'return_type': 'void',
814   'known_as': 'glDiscardFramebufferEXT',
815   'versions': [{ 'name': 'glInvalidateFramebuffer',
816                  'gl_versions': ['es3'],
817                  'extensions': [] },
818                { 'name': 'glDiscardFramebufferEXT',
819                  'gl_versions': ['es1', 'es2'] }],
820   'arguments': 'GLenum target, GLsizei numAttachments, '
821       'const GLenum* attachments' },
822 ]
823
824 GL_NULLDRAW_FUNCTIONS = [
825 { 'return_type': 'void',
826   'names': ['glClear'],
827   'arguments': 'GLbitfield mask', },
828 { 'return_type': 'void',
829   'names': ['glDrawArrays'],
830   'arguments': 'GLenum mode, GLint first, GLsizei count', },
831 { 'return_type': 'void',
832   'names': ['glDrawElements'],
833   'arguments':
834       'GLenum mode, GLsizei count, GLenum type, const void* indices', },
835 ]
836
837 OSMESA_FUNCTIONS = [
838 { 'return_type': 'OSMesaContext',
839   'names': ['OSMesaCreateContext'],
840   'arguments': 'GLenum format, OSMesaContext sharelist', },
841 { 'return_type': 'OSMesaContext',
842   'names': ['OSMesaCreateContextExt'],
843   'arguments':
844       'GLenum format, GLint depthBits, GLint stencilBits, GLint accumBits, '
845       'OSMesaContext sharelist', },
846 { 'return_type': 'void',
847   'names': ['OSMesaDestroyContext'],
848   'arguments': 'OSMesaContext ctx', },
849 { 'return_type': 'GLboolean',
850   'names': ['OSMesaMakeCurrent'],
851   'arguments': 'OSMesaContext ctx, void* buffer, GLenum type, GLsizei width, '
852                'GLsizei height', },
853 { 'return_type': 'OSMesaContext',
854   'names': ['OSMesaGetCurrentContext'],
855   'arguments': 'void', },
856 { 'return_type': 'void',
857   'names': ['OSMesaPixelStore'],
858   'arguments': 'GLint pname, GLint value', },
859 { 'return_type': 'void',
860   'names': ['OSMesaGetIntegerv'],
861   'arguments': 'GLint pname, GLint* value', },
862 { 'return_type': 'GLboolean',
863   'names': ['OSMesaGetDepthBuffer'],
864   'arguments':
865       'OSMesaContext c, GLint* width, GLint* height, GLint* bytesPerValue, '
866       'void** buffer', },
867 { 'return_type': 'GLboolean',
868   'names': ['OSMesaGetColorBuffer'],
869   'arguments': 'OSMesaContext c, GLint* width, GLint* height, GLint* format, '
870                'void** buffer', },
871 { 'return_type': 'OSMESAproc',
872   'names': ['OSMesaGetProcAddress'],
873   'arguments': 'const char* funcName', },
874 { 'return_type': 'void',
875   'names': ['OSMesaColorClamp'],
876   'arguments': 'GLboolean enable', },
877 ]
878
879 EGL_FUNCTIONS = [
880 { 'return_type': 'EGLint',
881   'names': ['eglGetError'],
882   'arguments': 'void', },
883 { 'return_type': 'EGLDisplay',
884   'names': ['eglGetDisplay'],
885   'arguments': 'EGLNativeDisplayType display_id', },
886 { 'return_type': 'EGLBoolean',
887   'names': ['eglInitialize'],
888   'arguments': 'EGLDisplay dpy, EGLint* major, EGLint* minor', },
889 { 'return_type': 'EGLBoolean',
890   'names': ['eglTerminate'],
891   'arguments': 'EGLDisplay dpy', },
892 { 'return_type': 'const char*',
893   'names': ['eglQueryString'],
894   'arguments': 'EGLDisplay dpy, EGLint name', },
895 { 'return_type': 'EGLBoolean',
896   'names': ['eglGetConfigs'],
897   'arguments': 'EGLDisplay dpy, EGLConfig* configs, EGLint config_size, '
898                'EGLint* num_config', },
899 { 'return_type': 'EGLBoolean',
900   'names': ['eglChooseConfig'],
901   'arguments': 'EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, '
902                'EGLint config_size, EGLint* num_config', },
903 { 'return_type': 'EGLBoolean',
904   'names': ['eglGetConfigAttrib'],
905   'arguments':
906       'EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value', },
907 { 'return_type': 'EGLImageKHR',
908   'versions': [{ 'name': 'eglCreateImageKHR',
909                  'extensions': ['EGL_KHR_image_base'] }],
910   'arguments':
911       'EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, '
912       'const EGLint* attrib_list' },
913 { 'return_type': 'EGLBoolean',
914   'versions': [{ 'name' : 'eglDestroyImageKHR',
915                  'extensions': ['EGL_KHR_image_base'] }],
916   'arguments': 'EGLDisplay dpy, EGLImageKHR image' },
917 { 'return_type': 'EGLSurface',
918   'names': ['eglCreateWindowSurface'],
919   'arguments': 'EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, '
920                'const EGLint* attrib_list', },
921 { 'return_type': 'EGLSurface',
922   'names': ['eglCreatePbufferSurface'],
923   'arguments': 'EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list', },
924 { 'return_type': 'EGLSurface',
925   'names': ['eglCreatePixmapSurface'],
926   'arguments': 'EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, '
927                'const EGLint* attrib_list', },
928 { 'return_type': 'EGLBoolean',
929   'names': ['eglDestroySurface'],
930   'arguments': 'EGLDisplay dpy, EGLSurface surface', },
931 { 'return_type': 'EGLBoolean',
932   'names': ['eglQuerySurface'],
933   'arguments':
934       'EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint* value', },
935 { 'return_type': 'EGLBoolean',
936   'names': ['eglBindAPI'],
937   'arguments': 'EGLenum api', },
938 { 'return_type': 'EGLenum',
939   'names': ['eglQueryAPI'],
940   'arguments': 'void', },
941 { 'return_type': 'EGLBoolean',
942   'names': ['eglWaitClient'],
943   'arguments': 'void', },
944 { 'return_type': 'EGLBoolean',
945   'names': ['eglReleaseThread'],
946   'arguments': 'void', },
947 { 'return_type': 'EGLSurface',
948   'names': ['eglCreatePbufferFromClientBuffer'],
949   'arguments':
950       'EGLDisplay dpy, EGLenum buftype, void* buffer, EGLConfig config, '
951       'const EGLint* attrib_list', },
952 { 'return_type': 'EGLBoolean',
953   'names': ['eglSurfaceAttrib'],
954   'arguments':
955       'EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value', },
956 { 'return_type': 'EGLBoolean',
957   'names': ['eglBindTexImage'],
958   'arguments': 'EGLDisplay dpy, EGLSurface surface, EGLint buffer', },
959 { 'return_type': 'EGLBoolean',
960   'names': ['eglReleaseTexImage'],
961   'arguments': 'EGLDisplay dpy, EGLSurface surface, EGLint buffer', },
962 { 'return_type': 'EGLBoolean',
963   'names': ['eglSwapInterval'],
964   'arguments': 'EGLDisplay dpy, EGLint interval', },
965 { 'return_type': 'EGLContext',
966   'names': ['eglCreateContext'],
967   'arguments': 'EGLDisplay dpy, EGLConfig config, EGLContext share_context, '
968               'const EGLint* attrib_list', },
969 { 'return_type': 'EGLBoolean',
970   'names': ['eglDestroyContext'],
971   'arguments': 'EGLDisplay dpy, EGLContext ctx', },
972 { 'return_type': 'EGLBoolean',
973   'names': ['eglMakeCurrent'],
974   'arguments':
975       'EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx', },
976 { 'return_type': 'EGLContext',
977   'names': ['eglGetCurrentContext'],
978   'arguments': 'void', },
979 { 'return_type': 'EGLSurface',
980   'names': ['eglGetCurrentSurface'],
981   'arguments': 'EGLint readdraw', },
982 { 'return_type': 'EGLDisplay',
983   'names': ['eglGetCurrentDisplay'],
984   'arguments': 'void', },
985 { 'return_type': 'EGLBoolean',
986   'names': ['eglQueryContext'],
987   'arguments':
988       'EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value', },
989 { 'return_type': 'EGLBoolean',
990   'names': ['eglWaitGL'],
991   'arguments': 'void', },
992 { 'return_type': 'EGLBoolean',
993   'names': ['eglWaitNative'],
994   'arguments': 'EGLint engine', },
995 { 'return_type': 'EGLBoolean',
996   'names': ['eglSwapBuffers'],
997   'arguments': 'EGLDisplay dpy, EGLSurface surface', },
998 { 'return_type': 'EGLBoolean',
999   'names': ['eglCopyBuffers'],
1000   'arguments':
1001       'EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target', },
1002 { 'return_type': '__eglMustCastToProperFunctionPointerType',
1003   'names': ['eglGetProcAddress'],
1004   'arguments': 'const char* procname', },
1005 { 'return_type': 'EGLBoolean',
1006   'names': ['eglPostSubBufferNV'],
1007   'arguments': 'EGLDisplay dpy, EGLSurface surface, '
1008     'EGLint x, EGLint y, EGLint width, EGLint height', },
1009 { 'return_type': 'EGLBoolean',
1010   'names': ['eglQuerySurfacePointerANGLE'],
1011   'arguments':
1012       'EGLDisplay dpy, EGLSurface surface, EGLint attribute, void** value', },
1013 { 'return_type': 'EGLSyncKHR',
1014   'versions': [{ 'name': 'eglCreateSyncKHR',
1015                  'extensions': ['EGL_KHR_fence_sync'] }],
1016   'arguments': 'EGLDisplay dpy, EGLenum type, const EGLint* attrib_list' },
1017 { 'return_type': 'EGLint',
1018   'versions': [{ 'name': 'eglClientWaitSyncKHR',
1019                  'extensions': ['EGL_KHR_fence_sync'] }],
1020   'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, '
1021       'EGLTimeKHR timeout' },
1022 { 'return_type': 'EGLBoolean',
1023   'versions': [{ 'name': 'eglGetSyncAttribKHR',
1024                  'extensions': ['EGL_KHR_fence_sync'] }],
1025   'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, '
1026       'EGLint* value' },
1027 { 'return_type': 'EGLBoolean',
1028   'versions': [{ 'name': 'eglDestroySyncKHR',
1029                  'extensions': ['EGL_KHR_fence_sync'] }],
1030   'arguments': 'EGLDisplay dpy, EGLSyncKHR sync' },
1031 { 'return_type': 'EGLBoolean',
1032   'names': ['eglGetSyncValuesCHROMIUM'],
1033   'arguments':
1034       'EGLDisplay dpy, EGLSurface surface, '
1035       'EGLuint64CHROMIUM* ust, EGLuint64CHROMIUM* msc, '
1036       'EGLuint64CHROMIUM* sbc', },
1037 { 'return_type': 'EGLint',
1038   'versions': [{ 'name': 'eglWaitSyncKHR',
1039                  'extensions': ['EGL_KHR_fence_sync'] }],
1040   'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint flags' }
1041 ]
1042
1043 WGL_FUNCTIONS = [
1044 { 'return_type': 'HGLRC',
1045   'names': ['wglCreateContext'],
1046   'arguments': 'HDC hdc', },
1047 { 'return_type': 'HGLRC',
1048   'names': ['wglCreateLayerContext'],
1049   'arguments': 'HDC hdc, int iLayerPlane', },
1050 { 'return_type': 'BOOL',
1051   'names': ['wglCopyContext'],
1052   'arguments': 'HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask', },
1053 { 'return_type': 'BOOL',
1054   'names': ['wglDeleteContext'],
1055   'arguments': 'HGLRC hglrc', },
1056 { 'return_type': 'HGLRC',
1057   'names': ['wglGetCurrentContext'],
1058   'arguments': '', },
1059 { 'return_type': 'HDC',
1060   'names': ['wglGetCurrentDC'],
1061   'arguments': '', },
1062 { 'return_type': 'BOOL',
1063   'names': ['wglMakeCurrent'],
1064   'arguments': 'HDC hdc, HGLRC hglrc', },
1065 { 'return_type': 'BOOL',
1066   'names': ['wglShareLists'],
1067   'arguments': 'HGLRC hglrc1, HGLRC hglrc2', },
1068 { 'return_type': 'BOOL',
1069   'names': ['wglSwapIntervalEXT'],
1070   'arguments': 'int interval', },
1071 { 'return_type': 'BOOL',
1072   'names': ['wglSwapLayerBuffers'],
1073   'arguments': 'HDC hdc, UINT fuPlanes', },
1074 { 'return_type': 'const char*',
1075   'names': ['wglGetExtensionsStringARB'],
1076   'arguments': 'HDC hDC', },
1077 { 'return_type': 'const char*',
1078   'names': ['wglGetExtensionsStringEXT'],
1079   'arguments': '', },
1080 { 'return_type': 'BOOL',
1081   'names': ['wglChoosePixelFormatARB'],
1082   'arguments':
1083       'HDC dc, const int* int_attrib_list, const float* float_attrib_list, '
1084       'UINT max_formats, int* formats, UINT* num_formats', },
1085 { 'return_type': 'HPBUFFERARB',
1086   'names': ['wglCreatePbufferARB'],
1087   'arguments': 'HDC hDC, int iPixelFormat, int iWidth, int iHeight, '
1088                'const int* piAttribList', },
1089 { 'return_type': 'HDC',
1090   'names': ['wglGetPbufferDCARB'],
1091   'arguments': 'HPBUFFERARB hPbuffer', },
1092 { 'return_type': 'int',
1093   'names': ['wglReleasePbufferDCARB'],
1094   'arguments': 'HPBUFFERARB hPbuffer, HDC hDC', },
1095 { 'return_type': 'BOOL',
1096   'names': ['wglDestroyPbufferARB'],
1097   'arguments': 'HPBUFFERARB hPbuffer', },
1098 { 'return_type': 'BOOL',
1099   'names': ['wglQueryPbufferARB'],
1100   'arguments': 'HPBUFFERARB hPbuffer, int iAttribute, int* piValue', },
1101 ]
1102
1103 GLX_FUNCTIONS = [
1104 { 'return_type': 'int',
1105   'names': ['glXWaitVideoSyncSGI'],
1106   'arguments': 'int divisor, int remainder, unsigned int* count', },
1107 { 'return_type': 'XVisualInfo*',
1108   'names': ['glXChooseVisual'],
1109   'arguments': 'Display* dpy, int screen, int* attribList', },
1110 { 'return_type': 'void',
1111   'names': ['glXCopySubBufferMESA'],
1112   'arguments': 'Display* dpy, GLXDrawable drawable, '
1113                'int x, int y, int width, int height', },
1114 { 'return_type': 'GLXContext',
1115   'names': ['glXCreateContext'],
1116   'arguments':
1117       'Display* dpy, XVisualInfo* vis, GLXContext shareList, int direct', },
1118 { 'return_type': 'void',
1119   'names': ['glXBindTexImageEXT'],
1120   'arguments':
1121       'Display* dpy, GLXDrawable drawable, int buffer, int* attribList', },
1122 { 'return_type': 'void',
1123   'names': ['glXReleaseTexImageEXT'],
1124   'arguments': 'Display* dpy, GLXDrawable drawable, int buffer', },
1125 { 'return_type': 'void',
1126   'names': ['glXDestroyContext'],
1127   'arguments': 'Display* dpy, GLXContext ctx', },
1128 { 'return_type': 'int',
1129   'names': ['glXMakeCurrent'],
1130   'arguments': 'Display* dpy, GLXDrawable drawable, GLXContext ctx', },
1131 { 'return_type': 'void',
1132   'names': ['glXCopyContext'],
1133   'arguments':
1134       'Display* dpy, GLXContext src, GLXContext dst, unsigned long mask', },
1135 { 'return_type': 'void',
1136   'names': ['glXSwapBuffers'],
1137   'arguments': 'Display* dpy, GLXDrawable drawable', },
1138 { 'return_type': 'GLXPixmap',
1139   'names': ['glXCreateGLXPixmap'],
1140   'arguments': 'Display* dpy, XVisualInfo* visual, Pixmap pixmap', },
1141 { 'return_type': 'void',
1142   'names': ['glXDestroyGLXPixmap'],
1143   'arguments': 'Display* dpy, GLXPixmap pixmap', },
1144 { 'return_type': 'int',
1145   'names': ['glXQueryExtension'],
1146   'arguments': 'Display* dpy, int* errorb, int* event', },
1147 { 'return_type': 'int',
1148   'names': ['glXQueryVersion'],
1149   'arguments': 'Display* dpy, int* maj, int* min', },
1150 { 'return_type': 'int',
1151   'names': ['glXIsDirect'],
1152   'arguments': 'Display* dpy, GLXContext ctx', },
1153 { 'return_type': 'int',
1154   'names': ['glXGetConfig'],
1155   'arguments': 'Display* dpy, XVisualInfo* visual, int attrib, int* value', },
1156 { 'return_type': 'GLXContext',
1157   'names': ['glXGetCurrentContext'],
1158   'arguments': 'void', },
1159 { 'return_type': 'GLXDrawable',
1160   'names': ['glXGetCurrentDrawable'],
1161   'arguments': 'void', },
1162 { 'return_type': 'void',
1163   'names': ['glXWaitGL'],
1164   'arguments': 'void', },
1165 { 'return_type': 'void',
1166   'names': ['glXWaitX'],
1167   'arguments': 'void', },
1168 { 'return_type': 'void',
1169   'names': ['glXUseXFont'],
1170   'arguments': 'Font font, int first, int count, int list', },
1171 { 'return_type': 'const char*',
1172   'names': ['glXQueryExtensionsString'],
1173   'arguments': 'Display* dpy, int screen', },
1174 { 'return_type': 'const char*',
1175   'names': ['glXQueryServerString'],
1176   'arguments': 'Display* dpy, int screen, int name', },
1177 { 'return_type': 'const char*',
1178   'names': ['glXGetClientString'],
1179   'arguments': 'Display* dpy, int name', },
1180 { 'return_type': 'Display*',
1181   'names': ['glXGetCurrentDisplay'],
1182   'arguments': 'void', },
1183 { 'return_type': 'GLXFBConfig*',
1184   'names': ['glXChooseFBConfig'],
1185   'arguments':
1186       'Display* dpy, int screen, const int* attribList, int* nitems', },
1187 { 'return_type': 'int',
1188   'names': ['glXGetFBConfigAttrib'],
1189   'arguments': 'Display* dpy, GLXFBConfig config, int attribute, int* value', },
1190 { 'return_type': 'GLXFBConfig*',
1191   'names': ['glXGetFBConfigs'],
1192   'arguments': 'Display* dpy, int screen, int* nelements', },
1193 { 'return_type': 'XVisualInfo*',
1194   'names': ['glXGetVisualFromFBConfig'],
1195   'arguments': 'Display* dpy, GLXFBConfig config', },
1196 { 'return_type': 'GLXWindow',
1197   'names': ['glXCreateWindow'],
1198   'arguments':
1199       'Display* dpy, GLXFBConfig config, Window win, const int* attribList', },
1200 { 'return_type': 'void',
1201   'names': ['glXDestroyWindow'],
1202   'arguments': 'Display* dpy, GLXWindow window', },
1203 { 'return_type': 'GLXPixmap',
1204   'names': ['glXCreatePixmap'],
1205   'arguments': 'Display* dpy, GLXFBConfig config, '
1206                'Pixmap pixmap, const int* attribList', },
1207 { 'return_type': 'void',
1208   'names': ['glXDestroyPixmap'],
1209   'arguments': 'Display* dpy, GLXPixmap pixmap', },
1210 { 'return_type': 'GLXPbuffer',
1211   'names': ['glXCreatePbuffer'],
1212   'arguments': 'Display* dpy, GLXFBConfig config, const int* attribList', },
1213 { 'return_type': 'void',
1214   'names': ['glXDestroyPbuffer'],
1215   'arguments': 'Display* dpy, GLXPbuffer pbuf', },
1216 { 'return_type': 'void',
1217   'names': ['glXQueryDrawable'],
1218   'arguments':
1219       'Display* dpy, GLXDrawable draw, int attribute, unsigned int* value', },
1220 { 'return_type': 'GLXContext',
1221   'names': ['glXCreateNewContext'],
1222   'arguments': 'Display* dpy, GLXFBConfig config, int renderType, '
1223                'GLXContext shareList, int direct', },
1224 { 'return_type': 'int',
1225   'names': ['glXMakeContextCurrent'],
1226   'arguments':
1227       'Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx', },
1228 { 'return_type': 'GLXDrawable',
1229   'names': ['glXGetCurrentReadDrawable'],
1230   'arguments': 'void', },
1231 { 'return_type': 'int',
1232   'names': ['glXQueryContext'],
1233   'arguments': 'Display* dpy, GLXContext ctx, int attribute, int* value', },
1234 { 'return_type': 'void',
1235   'names': ['glXSelectEvent'],
1236   'arguments': 'Display* dpy, GLXDrawable drawable, unsigned long mask', },
1237 { 'return_type': 'void',
1238   'names': ['glXGetSelectedEvent'],
1239   'arguments': 'Display* dpy, GLXDrawable drawable, unsigned long* mask', },
1240 { 'return_type': 'void',
1241   'names': ['glXSwapIntervalMESA'],
1242   'arguments': 'unsigned int interval', },
1243 { 'return_type': 'void',
1244   'names': ['glXSwapIntervalEXT'],
1245   'arguments': 'Display* dpy, GLXDrawable drawable, int interval', },
1246 { 'return_type': 'GLXFBConfig',
1247   'names': ['glXGetFBConfigFromVisualSGIX'],
1248   'arguments': 'Display* dpy, XVisualInfo* visualInfo', },
1249 { 'return_type': 'GLXContext',
1250   'names': ['glXCreateContextAttribsARB'],
1251   'arguments':
1252       'Display* dpy, GLXFBConfig config, GLXContext share_context, int direct, '
1253       'const int* attrib_list', },
1254 { 'return_type': 'bool',
1255   'names': ['glXGetSyncValuesOML'],
1256   'arguments':
1257       'Display* dpy, GLXDrawable drawable, int64* ust, int64* msc, '
1258       'int64* sbc' },
1259 { 'return_type': 'bool',
1260   'names': ['glXGetMscRateOML'],
1261   'arguments':
1262       'Display* dpy, GLXDrawable drawable, int32* numerator, '
1263       'int32* denominator' },
1264 ]
1265
1266 FUNCTION_SETS = [
1267   [GL_FUNCTIONS, GL_NULLDRAW_FUNCTIONS, 'gl', [
1268       'GL/glext.h',
1269       'GLES2/gl2ext.h',
1270       # Files below are Chromium-specific and shipped with Chromium sources.
1271       'GL/glextchromium.h',
1272       'GLES2/gl2chromium.h',
1273       'GLES2/gl2extchromium.h'
1274   ], []],
1275   [OSMESA_FUNCTIONS, [], 'osmesa', [], []],
1276   [EGL_FUNCTIONS, [], 'egl', [
1277       'EGL/eglext.h',
1278       # Files below are Chromium-specific and shipped with Chromium sources.
1279       'EGL/eglextchromium.h',
1280     ],
1281     [
1282       'EGL_ANGLE_d3d_share_handle_client_buffer',
1283       'EGL_ANGLE_surface_d3d_texture_2d_share_handle',
1284     ],
1285   ],
1286   [WGL_FUNCTIONS, [], 'wgl', ['GL/wglext.h'], []],
1287   [GLX_FUNCTIONS, [], 'glx', ['GL/glx.h', 'GL/glxext.h'], []],
1288 ]
1289
1290 def GenerateHeader(file, functions, set_name, used_extensions):
1291   """Generates gl_bindings_autogen_x.h"""
1292
1293   # Write file header.
1294   file.write(
1295 """// Copyright (c) 2012 The Chromium Authors. All rights reserved.
1296 // Use of this source code is governed by a BSD-style license that can be
1297 // found in the LICENSE file.
1298
1299 // This file is automatically generated.
1300
1301 #ifndef UI_GFX_GL_GL_BINDINGS_AUTOGEN_%(name)s_H_
1302 #define UI_GFX_GL_GL_BINDINGS_AUTOGEN_%(name)s_H_
1303
1304 namespace gfx {
1305
1306 class GLContext;
1307
1308 """ % {'name': set_name.upper()})
1309
1310   # Write typedefs for function pointer types. Always use the GL name for the
1311   # typedef.
1312   file.write('\n')
1313   for func in functions:
1314     file.write('typedef %s (GL_BINDING_CALL *%sProc)(%s);\n' %
1315         (func['return_type'], func['known_as'], func['arguments']))
1316
1317   # Write declarations for booleans indicating which extensions are available.
1318   file.write('\n')
1319   file.write("struct Extensions%s {\n" % set_name.upper())
1320   for extension in sorted(used_extensions):
1321     file.write('  bool b_%s;\n' % extension)
1322   file.write('};\n')
1323   file.write('\n')
1324
1325   # Write Procs struct.
1326   file.write("struct Procs%s {\n" % set_name.upper())
1327   for func in functions:
1328     file.write('  %sProc %sFn;\n' % (func['known_as'], func['known_as']))
1329   file.write('};\n')
1330   file.write('\n')
1331
1332   # Write Api class.
1333   file.write(
1334 """class GL_EXPORT %(name)sApi {
1335  public:
1336   %(name)sApi();
1337   virtual ~%(name)sApi();
1338
1339 """ % {'name': set_name.upper()})
1340   for func in functions:
1341     file.write('  virtual %s %sFn(%s) = 0;\n' %
1342       (func['return_type'], func['known_as'], func['arguments']))
1343   file.write('};\n')
1344   file.write('\n')
1345
1346   file.write( '}  // namespace gfx\n')
1347
1348   # Write macros to invoke function pointers. Always use the GL name for the
1349   # macro.
1350   file.write('\n')
1351   for func in functions:
1352     file.write('#define %s ::gfx::g_current_%s_context->%sFn\n' %
1353         (func['known_as'], set_name.lower(), func['known_as']))
1354
1355   file.write('\n')
1356   file.write('#endif  //  UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' %
1357       set_name.upper())
1358
1359
1360 def GenerateAPIHeader(file, functions, set_name):
1361   """Generates gl_bindings_api_autogen_x.h"""
1362
1363   # Write file header.
1364   file.write(
1365 """// Copyright (c) 2012 The Chromium Authors. All rights reserved.
1366 // Use of this source code is governed by a BSD-style license that can be
1367 // found in the LICENSE file.
1368
1369 // This file is automatically generated.
1370
1371 """ % {'name': set_name.upper()})
1372
1373   # Write API declaration.
1374   for func in functions:
1375     file.write('  virtual %s %sFn(%s) OVERRIDE;\n' %
1376       (func['return_type'], func['known_as'], func['arguments']))
1377
1378   file.write('\n')
1379
1380
1381 def GenerateMockHeader(file, functions, set_name):
1382   """Generates gl_mock_autogen_x.h"""
1383
1384   # Write file header.
1385   file.write(
1386 """// Copyright (c) 2012 The Chromium Authors. All rights reserved.
1387 // Use of this source code is governed by a BSD-style license that can be
1388 // found in the LICENSE file.
1389
1390 // This file is automatically generated.
1391
1392 """ % {'name': set_name.upper()})
1393
1394   # Write API declaration.
1395   for func in functions:
1396     args = func['arguments']
1397     if args == 'void':
1398       args = ''
1399     arg_count = 0
1400     if len(args):
1401       arg_count = func['arguments'].count(',') + 1
1402     file.write('  MOCK_METHOD%d(%s, %s(%s));\n' %
1403       (arg_count, func['known_as'][2:], func['return_type'], args))
1404
1405   file.write('\n')
1406
1407
1408 def GenerateSource(
1409   file, functions, nulldraw_functions, set_name, used_extensions):
1410   """Generates gl_bindings_autogen_x.cc"""
1411
1412   # Write file header.
1413   file.write(
1414 """// Copyright (c) 2011 The Chromium Authors. All rights reserved.
1415 // Use of this source code is governed by a BSD-style license that can be
1416 // found in the LICENSE file.
1417
1418 // This file is automatically generated.
1419
1420 #include <string>
1421 #include "base/debug/trace_event.h"
1422 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
1423 #include "ui/gl/gl_bindings.h"
1424 #include "ui/gl/gl_context.h"
1425 #include "ui/gl/gl_implementation.h"
1426 #include "ui/gl/gl_version_info.h"
1427 #include "ui/gl/gl_%s_api_implementation.h"
1428
1429 using gpu::gles2::GLES2Util;
1430
1431 namespace gfx {
1432 """ % set_name.lower())
1433
1434   file.write('\n')
1435   file.write('static bool g_debugBindingsInitialized;\n')
1436   file.write('Driver%s g_driver_%s;\n' % (set_name.upper(), set_name.lower()))
1437   file.write('\n')
1438
1439   # Write stub functions that take the place of some functions before a context
1440   # is initialized. This is done to provide clear asserts on debug build and to
1441   # avoid crashing in case of a bug on release build.
1442   file.write('\n')
1443   for func in functions:
1444     unique_names = set([version['name'] for version in func['versions']])
1445     if len(unique_names) > 1:
1446       file.write('%s %sNotBound(%s) {\n' %
1447           (func['return_type'], func['known_as'], func['arguments']))
1448       file.write('  NOTREACHED();\n')
1449       return_type = func['return_type'].lower()
1450       # Returning 0 works for booleans, integers and pointers.
1451       if return_type != 'void':
1452         file.write('  return 0;\n')
1453       file.write('}\n')
1454
1455   # Write function to initialize the function pointers that are always the same
1456   # and to initialize bindings where choice of the function depends on the
1457   # extension string or the GL version to point to stub functions.
1458   file.write('\n')
1459   file.write('void Driver%s::InitializeStaticBindings() {\n' %
1460              set_name.upper())
1461
1462   def WriteFuncBinding(file, known_as, version_name):
1463     file.write(
1464         '  fn.%sFn = reinterpret_cast<%sProc>(GetGLProcAddress("%s"));\n' %
1465         (known_as, known_as, version_name))
1466
1467   for func in functions:
1468     unique_names = set([version['name'] for version in func['versions']])
1469     if len(unique_names) == 1:
1470       WriteFuncBinding(file, func['known_as'], func['known_as'])
1471     else:
1472       file.write('  fn.%sFn = reinterpret_cast<%sProc>(%sNotBound);\n' %
1473           (func['known_as'], func['known_as'], func['known_as']))
1474
1475   file.write('}\n')
1476   file.write('\n')
1477
1478   # Write function to initialize bindings where choice of the function depends
1479   # on the extension string or the GL version.
1480   file.write("""void Driver%s::InitializeDynamicBindings(GLContext* context) {
1481   DCHECK(context && context->IsCurrent(NULL));
1482   const GLVersionInfo* ver ALLOW_UNUSED = context->GetVersionInfo();
1483   std::string extensions ALLOW_UNUSED = context->GetExtensions();
1484   extensions += " ";
1485
1486 """ % set_name.upper())
1487   for extension in sorted(used_extensions):
1488     # Extra space at the end of the extension name is intentional, it is used
1489     # as a separator
1490     file.write('  ext.b_%s = extensions.find("%s ") != std::string::npos;\n' %
1491         (extension, extension))
1492
1493   def WrapOr(cond):
1494     if ' || ' in cond:
1495       return '(%s)' % cond
1496     return cond
1497
1498   def WrapAnd(cond):
1499     if ' && ' in cond:
1500       return '(%s)' % cond
1501     return cond
1502
1503   def VersionCondition(version):
1504     conditions = []
1505     if 'gl_versions' in version:
1506       gl_versions = version['gl_versions']
1507       version_cond = ' || '.join(['ver->is_%s' % gl for gl in gl_versions])
1508       conditions.append(WrapOr(version_cond))
1509     if 'extensions' in version and version['extensions']:
1510       ext_cond = ' || '.join(['ext.b_%s' % e for e in version['extensions']])
1511       conditions.append(WrapOr(ext_cond))
1512     return ' && '.join(conditions)
1513
1514   def WriteConditionalFuncBinding(file, func):
1515     # Functions with only one version are always bound unconditionally
1516     assert len(func['versions']) > 1
1517     known_as = func['known_as']
1518     i = 0
1519     first_version = True
1520     while i < len(func['versions']):
1521       version = func['versions'][i]
1522       cond = VersionCondition(version)
1523       combined_conditions = [WrapAnd(cond)]
1524       last_version = i + 1 == len(func['versions'])
1525       while not last_version and \
1526           func['versions'][i + 1]['name'] == version['name']:
1527         i += 1
1528         combinable_cond = VersionCondition(func['versions'][i])
1529         combined_conditions.append(WrapAnd(combinable_cond))
1530         last_version = i + 1 == len(func['versions'])
1531       if len(combined_conditions) > 1:
1532         if [1 for cond in combined_conditions if cond == '']:
1533           cond = ''
1534         else:
1535           cond = ' || '.join(combined_conditions)
1536       # Don't make the last possible binding conditional on anything else but
1537       # that the function isn't already bound to avoid verbose specification
1538       # of functions which have both ARB and core versions with the same name,
1539       # and to be able to bind to mock extension functions in unit tests which
1540       # call InitializeDynamicGLBindings with a stub context that doesn't have
1541       # extensions in its extension string.
1542       # TODO(oetuaho@nvidia.com): Get rid of the fallback.
1543       # http://crbug.com/325668
1544       if cond != '' and not last_version:
1545         if not first_version:
1546           file.write('  if (!fn.%sFn && (%s))\n  ' % (known_as, cond))
1547         else:
1548           file.write('  if (%s)\n  ' % cond)
1549       elif not first_version:
1550         file.write('  if (!fn.%sFn)\n  ' % known_as)
1551       WriteFuncBinding(file, known_as, version['name'])
1552       i += 1
1553       first_version = False
1554
1555   for func in functions:
1556     unique_names = set([version['name'] for version in func['versions']])
1557     if len(unique_names) > 1:
1558       file.write('\n')
1559       file.write('  fn.%sFn = 0;\n' % func['known_as'])
1560       file.write('  debug_fn.%sFn = 0;\n' % func['known_as'])
1561       WriteConditionalFuncBinding(file, func)
1562
1563   # Some new function pointers have been added, so update them in debug bindings
1564   file.write('\n')
1565   file.write('  if (g_debugBindingsInitialized)\n')
1566   file.write('    InitializeDebugBindings();\n')
1567   file.write('}\n')
1568   file.write('\n')
1569
1570   # Write empty stubs for functions that want one.
1571   file.write('extern "C" {\n')
1572   for func in nulldraw_functions:
1573     known_as = func['known_as']
1574     return_type = func['return_type']
1575     arguments = func['arguments']
1576     file.write('\n')
1577     file.write('static %s GL_BINDING_CALL Stub_%s(%s) {}\n' %
1578         (return_type, known_as, arguments))
1579   file.write('}  // extern "C"\n')
1580
1581   # Write logging wrappers for each function.
1582   file.write('extern "C" {\n')
1583   for func in functions:
1584     return_type = func['return_type']
1585     arguments = func['arguments']
1586     file.write('\n')
1587     file.write('static %s GL_BINDING_CALL Debug_%s(%s) {\n' %
1588         (return_type, func['known_as'], arguments))
1589     argument_names = re.sub(
1590         r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', arguments)
1591     argument_names = re.sub(
1592         r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', argument_names)
1593     log_argument_names = re.sub(
1594         r'const char\* ([a-zA-Z0-9_]+)', r'CONSTCHAR_\1', arguments)
1595     log_argument_names = re.sub(
1596         r'(const )?[a-zA-Z0-9_]+\* ([a-zA-Z0-9_]+)',
1597         r'CONSTVOID_\2', log_argument_names)
1598     log_argument_names = re.sub(
1599         r'(?<!E)GLenum ([a-zA-Z0-9_]+)', r'GLenum_\1', log_argument_names)
1600     log_argument_names = re.sub(
1601         r'(?<!E)GLboolean ([a-zA-Z0-9_]+)', r'GLboolean_\1', log_argument_names)
1602     log_argument_names = re.sub(
1603         r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2',
1604         log_argument_names)
1605     log_argument_names = re.sub(
1606         r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2',
1607         log_argument_names)
1608     log_argument_names = re.sub(
1609         r'CONSTVOID_([a-zA-Z0-9_]+)',
1610         r'static_cast<const void*>(\1)', log_argument_names)
1611     log_argument_names = re.sub(
1612         r'CONSTCHAR_([a-zA-Z0-9_]+)', r'\1', log_argument_names)
1613     log_argument_names = re.sub(
1614         r'GLenum_([a-zA-Z0-9_]+)', r'GLES2Util::GetStringEnum(\1)',
1615         log_argument_names)
1616     log_argument_names = re.sub(
1617         r'GLboolean_([a-zA-Z0-9_]+)', r'GLES2Util::GetStringBool(\1)',
1618         log_argument_names)
1619     log_argument_names = log_argument_names.replace(',', ' << ", " <<')
1620     if argument_names == 'void' or argument_names == '':
1621       argument_names = ''
1622       log_argument_names = ''
1623     else:
1624       log_argument_names = " << " + log_argument_names
1625     function_name = func['known_as']
1626     if return_type == 'void':
1627       file.write('  GL_SERVICE_LOG("%s" << "(" %s << ")");\n' %
1628           (function_name, log_argument_names))
1629       file.write('  g_driver_%s.debug_fn.%sFn(%s);\n' %
1630           (set_name.lower(), function_name, argument_names))
1631       if 'logging_code' in func:
1632         file.write("%s\n" % func['logging_code'])
1633     else:
1634       file.write('  GL_SERVICE_LOG("%s" << "(" %s << ")");\n' %
1635           (function_name, log_argument_names))
1636       file.write('  %s result = g_driver_%s.debug_fn.%sFn(%s);\n' %
1637           (return_type, set_name.lower(), function_name, argument_names))
1638       if 'logging_code' in func:
1639         file.write("%s\n" % func['logging_code'])
1640       else:
1641         file.write('  GL_SERVICE_LOG("GL_RESULT: " << result);\n')
1642       file.write('  return result;\n')
1643     file.write('}\n')
1644   file.write('}  // extern "C"\n')
1645
1646   # Write function to initialize the debug function pointers.
1647   file.write('\n')
1648   file.write('void Driver%s::InitializeDebugBindings() {\n' %
1649              set_name.upper())
1650   for func in functions:
1651     first_name = func['known_as']
1652     file.write('  if (!debug_fn.%sFn) {\n' % first_name)
1653     file.write('    debug_fn.%sFn = fn.%sFn;\n' % (first_name, first_name))
1654     file.write('    fn.%sFn = Debug_%s;\n' % (first_name, first_name))
1655     file.write('  }\n')
1656   file.write('  g_debugBindingsInitialized = true;\n')
1657   file.write('}\n')
1658
1659   # Write function to initialize the nulldraw function pointers.
1660   if nulldraw_functions:
1661     file.write('\n')
1662     file.write('void Driver%s::InitializeNullDrawBindings() {\n' %
1663                set_name.upper())
1664
1665     for func in nulldraw_functions:
1666       first_name = func['known_as']
1667       file.write('  fn.%sFn = Stub_%s;\n' % (first_name, first_name))
1668     file.write('}\n')
1669
1670   # Write function to clear all function pointers.
1671   file.write('\n')
1672   file.write("""void Driver%s::ClearBindings() {
1673   memset(this, 0, sizeof(*this));
1674 }
1675 """ % set_name.upper())
1676
1677   # Write GLApiBase functions
1678   for func in functions:
1679     function_name = func['known_as']
1680     return_type = func['return_type']
1681     arguments = func['arguments']
1682     file.write('\n')
1683     file.write('%s %sApiBase::%sFn(%s) {\n' %
1684         (return_type, set_name.upper(), function_name, arguments))
1685     argument_names = re.sub(
1686         r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', arguments)
1687     argument_names = re.sub(
1688         r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', argument_names)
1689     if argument_names == 'void' or argument_names == '':
1690       argument_names = ''
1691     if return_type == 'void':
1692       file.write('  driver_->fn.%sFn(%s);\n' %
1693           (function_name, argument_names))
1694     else:
1695       file.write('  return driver_->fn.%sFn(%s);\n' %
1696           (function_name, argument_names))
1697     file.write('}\n')
1698
1699   # Write TraceGLApi functions
1700   for func in functions:
1701     function_name = func['known_as']
1702     return_type = func['return_type']
1703     arguments = func['arguments']
1704     file.write('\n')
1705     file.write('%s Trace%sApi::%sFn(%s) {\n' %
1706         (return_type, set_name.upper(), function_name, arguments))
1707     argument_names = re.sub(
1708         r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', arguments)
1709     argument_names = re.sub(
1710         r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', argument_names)
1711     if argument_names == 'void' or argument_names == '':
1712       argument_names = ''
1713     file.write('  TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::%s")\n' %
1714                function_name)
1715     if return_type == 'void':
1716       file.write('  %s_api_->%sFn(%s);\n' %
1717           (set_name.lower(), function_name, argument_names))
1718     else:
1719       file.write('  return %s_api_->%sFn(%s);\n' %
1720           (set_name.lower(), function_name, argument_names))
1721     file.write('}\n')
1722
1723   file.write('\n')
1724   file.write('}  // namespace gfx\n')
1725
1726
1727 def GetUniquelyNamedFunctions(functions):
1728   uniquely_named_functions = {}
1729
1730   for func in functions:
1731     for version in func['versions']:
1732       uniquely_named_functions[version['name']] = ({
1733         'name': version['name'],
1734         'return_type': func['return_type'],
1735         'arguments': func['arguments'],
1736         'known_as': func['known_as']
1737       })
1738   return uniquely_named_functions
1739
1740
1741 def GenerateMockBindingsHeader(file, functions):
1742   """Headers for functions that invoke MockGLInterface members"""
1743
1744   file.write(
1745 """// Copyright (c) 2014 The Chromium Authors. All rights reserved.
1746 // Use of this source code is governed by a BSD-style license that can be
1747 // found in the LICENSE file.
1748
1749 // This file is automatically generated.
1750
1751 """)
1752   uniquely_named_functions = GetUniquelyNamedFunctions(functions)
1753
1754   for key in sorted(uniquely_named_functions.iterkeys()):
1755     func = uniquely_named_functions[key]
1756     file.write('static %s GL_BINDING_CALL Mock_%s(%s);\n' %
1757         (func['return_type'], func['name'], func['arguments']))
1758
1759
1760 def GenerateMockBindingsSource(file, functions):
1761   """Generates functions that invoke MockGLInterface members and a
1762   GetGLProcAddress function that returns addresses to those functions."""
1763
1764   file.write(
1765 """// Copyright (c) 2011 The Chromium Authors. All rights reserved.
1766 // Use of this source code is governed by a BSD-style license that can be
1767 // found in the LICENSE file.
1768
1769 // This file is automatically generated.
1770
1771 #include <string.h>
1772
1773 #include "ui/gl/gl_mock.h"
1774
1775 namespace gfx {
1776
1777 // This is called mainly to prevent the compiler combining the code of mock
1778 // functions with identical contents, so that their function pointers will be
1779 // different.
1780 void MakeFunctionUnique(const char *func_name) {
1781     VLOG(2) << "Calling mock " << func_name;
1782 }
1783
1784 """)
1785   # Write functions that trampoline into the set MockGLInterface instance.
1786   uniquely_named_functions = GetUniquelyNamedFunctions(functions)
1787   sorted_function_names = sorted(uniquely_named_functions.iterkeys())
1788
1789   for key in sorted_function_names:
1790     func = uniquely_named_functions[key]
1791     file.write('\n')
1792     file.write('%s GL_BINDING_CALL MockGLInterface::Mock_%s(%s) {\n' %
1793         (func['return_type'], func['name'], func['arguments']))
1794     file.write('  MakeFunctionUnique("%s");\n' % func['name'])
1795     arg_re = r'(const )?[a-zA-Z0-9]+((\s*const\s*)?\*)* ([a-zA-Z0-9]+)'
1796     argument_names = re.sub(arg_re, r'\4', func['arguments'])
1797     if argument_names == 'void':
1798       argument_names = ''
1799     function_name = func['known_as'][2:]
1800     if func['return_type'] == 'void':
1801       file.write('  interface_->%s(%s);\n' %
1802           (function_name, argument_names))
1803     else:
1804       file.write('  return interface_->%s(%s);\n' %
1805           (function_name, argument_names))
1806     file.write('}\n')
1807
1808   # Write an 'invalid' function to catch code calling through uninitialized
1809   # function pointers or trying to interpret the return value of
1810   # GLProcAddress().
1811   file.write('\n')
1812   file.write('static void MockInvalidFunction() {\n')
1813   file.write('  NOTREACHED();\n')
1814   file.write('}\n')
1815
1816   # Write a function to lookup a mock GL function based on its name.
1817   file.write('\n')
1818   file.write('void* GL_BINDING_CALL ' +
1819       'MockGLInterface::GetGLProcAddress(const char* name) {\n')
1820   for key in sorted_function_names:
1821     name = uniquely_named_functions[key]['name']
1822     file.write('  if (strcmp(name, "%s") == 0)\n' % name)
1823     file.write('    return reinterpret_cast<void*>(Mock_%s);\n' % name)
1824   # Always return a non-NULL pointer like some EGL implementations do.
1825   file.write('  return reinterpret_cast<void*>(&MockInvalidFunction);\n')
1826   file.write('}\n')
1827
1828   file.write('\n')
1829   file.write('}  // namespace gfx\n')
1830
1831
1832 def ParseExtensionFunctionsFromHeader(header_file):
1833   """Parse a C extension header file and return a map from extension names to
1834   a list of functions.
1835
1836   Args:
1837     header_file: Line-iterable C header file.
1838   Returns:
1839     Map of extension name => functions.
1840   """
1841   extension_start = re.compile(
1842       r'#ifndef ((?:GL|EGL|WGL|GLX)_[A-Z]+_[a-zA-Z]\w+)')
1843   extension_function = re.compile(r'.+\s+([a-z]+\w+)\s*\(')
1844   typedef = re.compile(r'typedef .*')
1845   macro_start = re.compile(r'^#(if|ifdef|ifndef).*')
1846   macro_end = re.compile(r'^#endif.*')
1847   macro_depth = 0
1848   current_extension = None
1849   current_extension_depth = 0
1850   extensions = collections.defaultdict(lambda: [])
1851   for line in header_file:
1852     if macro_start.match(line):
1853       macro_depth += 1
1854     elif macro_end.match(line):
1855       macro_depth -= 1
1856       if macro_depth < current_extension_depth:
1857         current_extension = None
1858     match = extension_start.match(line)
1859     if match:
1860       current_extension = match.group(1)
1861       current_extension_depth = macro_depth
1862       assert current_extension not in extensions, \
1863           "Duplicate extension: " + current_extension
1864     match = extension_function.match(line)
1865     if match and current_extension and not typedef.match(line):
1866       extensions[current_extension].append(match.group(1))
1867   return extensions
1868
1869
1870 def GetExtensionFunctions(extension_headers):
1871   """Parse extension functions from a list of header files.
1872
1873   Args:
1874     extension_headers: List of header file names.
1875   Returns:
1876     Map of extension name => list of functions.
1877   """
1878   extensions = {}
1879   for header in extension_headers:
1880     extensions.update(ParseExtensionFunctionsFromHeader(open(header)))
1881   return extensions
1882
1883
1884 def GetFunctionToExtensionMap(extensions):
1885   """Construct map from a function names to extensions which define the
1886   function.
1887
1888   Args:
1889     extensions: Map of extension name => functions.
1890   Returns:
1891     Map of function name => extension name.
1892   """
1893   function_to_extensions = {}
1894   for extension, functions in extensions.items():
1895     for function in functions:
1896       if not function in function_to_extensions:
1897         function_to_extensions[function] = []
1898       function_to_extensions[function].append(extension)
1899   return function_to_extensions
1900
1901
1902 def LooksLikeExtensionFunction(function):
1903   """Heuristic to see if a function name is consistent with extension function
1904   naming."""
1905   vendor = re.match(r'\w+?([A-Z][A-Z]+)$', function)
1906   return vendor is not None and not vendor.group(1) in ['GL', 'API', 'DC']
1907
1908
1909 def FillExtensionsFromHeaders(functions, extension_headers, extra_extensions):
1910   """Determine which functions belong to extensions based on extension headers,
1911   and fill in this information to the functions table for functions that don't
1912   already have the information.
1913
1914   Args:
1915     functions: List of (return type, function versions, arguments).
1916     extension_headers: List of header file names.
1917     extra_extensions: Extensions to add to the list.
1918   Returns:
1919     Set of used extensions.
1920   """
1921   # Parse known extensions.
1922   extensions = GetExtensionFunctions(extension_headers)
1923   functions_to_extensions = GetFunctionToExtensionMap(extensions)
1924
1925   # Fill in the extension information.
1926   used_extensions = set()
1927   for func in functions:
1928     for version in func['versions']:
1929       name = version['name']
1930       # Make sure we know about all extensions and extension functions.
1931       if 'extensions' in version:
1932         used_extensions.update(version['extensions'])
1933       elif name in functions_to_extensions:
1934         # If there are multiple versions with the same name, assume that they
1935         # already have all the correct conditions, we can't just blindly add
1936         # the same extension conditions to all of them
1937         if len([v for v in func['versions'] if v['name'] == name]) == 1:
1938           version['extensions'] = functions_to_extensions[name]
1939           used_extensions.update(version['extensions'])
1940       elif LooksLikeExtensionFunction(name):
1941         raise RuntimeError('%s looks like an extension function but does not '
1942             'belong to any of the known extensions.' % name)
1943
1944   # Add extensions that do not have any functions.
1945   used_extensions.update(extra_extensions)
1946
1947   return used_extensions
1948
1949
1950 def ResolveHeader(header, header_paths):
1951   paths = header_paths.split(':')
1952
1953   # Always use a path for Chromium-specific extensions. They are extracted
1954   # to separate files.
1955   paths.append('.')
1956   paths.append('../../gpu')
1957
1958   root = os.path.abspath(os.path.dirname(__file__))
1959
1960   for path in paths:
1961     result = os.path.join(path, header)
1962     if not os.path.isabs(path):
1963       result = os.path.relpath(os.path.join(root, result), os.getcwd())
1964     if os.path.exists(result):
1965       # Always use forward slashes as path separators. Otherwise backslashes
1966       # may be incorrectly interpreted as escape characters.
1967       return result.replace(os.path.sep, '/')
1968
1969   raise Exception('Header %s not found.' % header)
1970
1971
1972 def main(argv):
1973   """This is the main function."""
1974
1975   parser = optparse.OptionParser()
1976   parser.add_option('--inputs', action='store_true')
1977   parser.add_option('--header-paths')
1978
1979   options, args = parser.parse_args(argv)
1980
1981   if options.inputs:
1982     for [_, _, _, headers, _] in FUNCTION_SETS:
1983       for header in headers:
1984         print ResolveHeader(header, options.header_paths)
1985     return 0
1986
1987   directory = '.'
1988   if len(args) >= 1:
1989     directory = args[0]
1990
1991   for [functions,
1992        nulldraw_functions,
1993        set_name,
1994        extension_headers,
1995        extensions] in FUNCTION_SETS:
1996     # Function names can be specified in two ways (list of unique names or list
1997     # of versions with different binding conditions). Fill in the data to the
1998     # versions list in case it is missing, so that can be used from here on:
1999     for func in functions + nulldraw_functions:
2000       assert 'versions' in func or 'names' in func, 'Function with no names'
2001       if 'versions' not in func:
2002         func['versions'] = [{'name': n} for n in func['names']]
2003       # Use the first version's name unless otherwise specified
2004       if 'known_as' not in func:
2005         func['known_as'] = func['versions'][0]['name']
2006       # Make sure that 'names' is not accidentally used instead of 'versions'
2007       if 'names' in func:
2008         del func['names']
2009
2010     extension_headers = [ResolveHeader(h, options.header_paths)
2011                          for h in extension_headers]
2012     used_extensions = FillExtensionsFromHeaders(
2013         functions, extension_headers, extensions)
2014
2015     header_file = open(
2016         os.path.join(directory, 'gl_bindings_autogen_%s.h' % set_name), 'wb')
2017     GenerateHeader(header_file, functions, set_name, used_extensions)
2018     header_file.close()
2019
2020     header_file = open(
2021         os.path.join(directory, 'gl_bindings_api_autogen_%s.h' % set_name),
2022         'wb')
2023     GenerateAPIHeader(header_file, functions, set_name)
2024     header_file.close()
2025
2026     source_file = open(
2027         os.path.join(directory, 'gl_bindings_autogen_%s.cc' % set_name), 'wb')
2028     GenerateSource(source_file,
2029                    functions,
2030                    nulldraw_functions,
2031                    set_name,
2032                    used_extensions)
2033     source_file.close()
2034
2035   header_file = open(
2036       os.path.join(directory, 'gl_mock_autogen_gl.h'), 'wb')
2037   GenerateMockHeader(header_file, GL_FUNCTIONS, 'gl')
2038   header_file.close()
2039
2040   header_file = open(os.path.join(directory, 'gl_bindings_autogen_mock.h'),
2041                      'wb')
2042   GenerateMockBindingsHeader(header_file, GL_FUNCTIONS)
2043   header_file.close()
2044
2045   source_file = open(os.path.join(directory, 'gl_bindings_autogen_mock.cc'),
2046                      'wb')
2047   GenerateMockBindingsSource(source_file, GL_FUNCTIONS)
2048   source_file.close()
2049   return 0
2050
2051
2052 if __name__ == '__main__':
2053   sys.exit(main(sys.argv[1:]))