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