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