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