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