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