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