Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / ui / gl / generate_bindings.py
blob020269f08d7dc694e96967cb07a2386cbe1461a2
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 'known_as': 'glTexStorage2DEXT',
624 'versions': [{ 'name': 'glTexStorage2D',
625 'gl_versions': ['es3'] },
626 { 'name': 'glTexStorage2D',
627 'extensions': ['GL_ARB_texture_storage'] },
628 { 'name': 'glTexStorage2DEXT',
629 'extensions': ['GL_EXT_texture_storage'] }],
630 'arguments': 'GLenum target, GLsizei levels, GLenum internalformat, '
631 'GLsizei width, GLsizei height', },
632 { 'return_type': 'void',
633 'names': ['glTexSubImage2D'],
634 'arguments':
635 'GLenum target, GLint level, GLint xoffset, GLint yoffset, '
636 'GLsizei width, GLsizei height, GLenum format, GLenum type, '
637 'const void* pixels', },
638 { 'return_type': 'void',
639 'names': ['glUniform1f'],
640 'arguments': 'GLint location, GLfloat x', },
641 { 'return_type': 'void',
642 'names': ['glUniform1fv'],
643 'arguments': 'GLint location, GLsizei count, const GLfloat* v', },
644 { 'return_type': 'void',
645 'names': ['glUniform1i'],
646 'arguments': 'GLint location, GLint x', },
647 { 'return_type': 'void',
648 'names': ['glUniform1iv'],
649 'arguments': 'GLint location, GLsizei count, const GLint* v', },
650 { 'return_type': 'void',
651 'names': ['glUniform2f'],
652 'arguments': 'GLint location, GLfloat x, GLfloat y', },
653 { 'return_type': 'void',
654 'names': ['glUniform2fv'],
655 'arguments': 'GLint location, GLsizei count, const GLfloat* v', },
656 { 'return_type': 'void',
657 'names': ['glUniform2i'],
658 'arguments': 'GLint location, GLint x, GLint y', },
659 { 'return_type': 'void',
660 'names': ['glUniform2iv'],
661 'arguments': 'GLint location, GLsizei count, const GLint* v', },
662 { 'return_type': 'void',
663 'names': ['glUniform3f'],
664 'arguments': 'GLint location, GLfloat x, GLfloat y, GLfloat z', },
665 { 'return_type': 'void',
666 'names': ['glUniform3fv'],
667 'arguments': 'GLint location, GLsizei count, const GLfloat* v', },
668 { 'return_type': 'void',
669 'names': ['glUniform3i'],
670 'arguments': 'GLint location, GLint x, GLint y, GLint z', },
671 { 'return_type': 'void',
672 'names': ['glUniform3iv'],
673 'arguments': 'GLint location, GLsizei count, const GLint* v', },
674 { 'return_type': 'void',
675 'names': ['glUniform4f'],
676 'arguments': 'GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w', },
677 { 'return_type': 'void',
678 'names': ['glUniform4fv'],
679 'arguments': 'GLint location, GLsizei count, const GLfloat* v', },
680 { 'return_type': 'void',
681 'names': ['glUniform4i'],
682 'arguments': 'GLint location, GLint x, GLint y, GLint z, GLint w', },
683 { 'return_type': 'void',
684 'names': ['glUniform4iv'],
685 'arguments': 'GLint location, GLsizei count, const GLint* v', },
686 { 'return_type': 'void',
687 'names': ['glUniformMatrix2fv'],
688 'arguments': 'GLint location, GLsizei count, '
689 'GLboolean transpose, const GLfloat* value', },
690 { 'return_type': 'void',
691 'names': ['glUniformMatrix3fv'],
692 'arguments': 'GLint location, GLsizei count, '
693 'GLboolean transpose, const GLfloat* value', },
694 { 'return_type': 'void',
695 'names': ['glUniformMatrix4fv'],
696 'arguments': 'GLint location, GLsizei count, '
697 'GLboolean transpose, const GLfloat* value', },
698 { 'return_type': 'GLboolean',
699 'known_as': 'glUnmapBuffer',
700 'names': ['glUnmapBufferOES', 'glUnmapBuffer'],
701 'arguments': 'GLenum target', },
702 { 'return_type': 'void',
703 'names': ['glUseProgram'],
704 'arguments': 'GLuint program', },
705 { 'return_type': 'void',
706 'names': ['glValidateProgram'],
707 'arguments': 'GLuint program', },
708 { 'return_type': 'void',
709 'names': ['glVertexAttrib1f'],
710 'arguments': 'GLuint indx, GLfloat x', },
711 { 'return_type': 'void',
712 'names': ['glVertexAttrib1fv'],
713 'arguments': 'GLuint indx, const GLfloat* values', },
714 { 'return_type': 'void',
715 'names': ['glVertexAttrib2f'],
716 'arguments': 'GLuint indx, GLfloat x, GLfloat y', },
717 { 'return_type': 'void',
718 'names': ['glVertexAttrib2fv'],
719 'arguments': 'GLuint indx, const GLfloat* values', },
720 { 'return_type': 'void',
721 'names': ['glVertexAttrib3f'],
722 'arguments': 'GLuint indx, GLfloat x, GLfloat y, GLfloat z', },
723 { 'return_type': 'void',
724 'names': ['glVertexAttrib3fv'],
725 'arguments': 'GLuint indx, const GLfloat* values', },
726 { 'return_type': 'void',
727 'names': ['glVertexAttrib4f'],
728 'arguments': 'GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w', },
729 { 'return_type': 'void',
730 'names': ['glVertexAttrib4fv'],
731 'arguments': 'GLuint indx, const GLfloat* values', },
732 { 'return_type': 'void',
733 'names': ['glVertexAttribPointer'],
734 'arguments': 'GLuint indx, GLint size, GLenum type, GLboolean normalized, '
735 'GLsizei stride, const void* ptr', },
736 { 'return_type': 'void',
737 'names': ['glViewport'],
738 'arguments': 'GLint x, GLint y, GLsizei width, GLsizei height', },
739 { 'return_type': 'void',
740 'names': ['glGenFencesNV'],
741 'arguments': 'GLsizei n, GLuint* fences', },
742 { 'return_type': 'void',
743 'names': ['glDeleteFencesNV'],
744 'arguments': 'GLsizei n, const GLuint* fences', },
745 { 'return_type': 'void',
746 'names': ['glSetFenceNV'],
747 'arguments': 'GLuint fence, GLenum condition', },
748 { 'return_type': 'GLboolean',
749 'names': ['glTestFenceNV'],
750 'arguments': 'GLuint fence', },
751 { 'return_type': 'void',
752 'names': ['glFinishFenceNV'],
753 'arguments': 'GLuint fence', },
754 { 'return_type': 'GLboolean',
755 'names': ['glIsFenceNV'],
756 'arguments': 'GLuint fence', },
757 { 'return_type': 'void',
758 'names': ['glGetFenceivNV'],
759 'arguments': 'GLuint fence, GLenum pname, GLint* params', },
760 { 'return_type': 'GLsync',
761 'names': ['glFenceSync'],
762 'arguments': 'GLenum condition, GLbitfield flags', },
763 { 'return_type': 'GLboolean',
764 'names': ['glIsSync'],
765 'arguments': 'GLsync sync', },
766 { 'return_type': 'void',
767 'names': ['glDeleteSync'],
768 'arguments': 'GLsync sync', },
769 { 'return_type': 'void',
770 'names': ['glGetSynciv'],
771 'arguments':
772 'GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length,'
773 'GLint* values', },
774 { 'return_type': 'GLenum',
775 'names': ['glClientWaitSync'],
776 'arguments':
777 'GLsync sync, GLbitfield flags, GLuint64 timeout', },
778 { 'return_type': 'GLenum',
779 'names': ['glWaitSync'],
780 'arguments':
781 'GLsync sync, GLbitfield flags, GLuint64 timeout', },
782 { 'return_type': 'void',
783 'known_as': 'glDrawArraysInstancedANGLE',
784 'names': ['glDrawArraysInstancedARB', 'glDrawArraysInstancedANGLE',
785 'glDrawArraysInstanced'],
786 'arguments': 'GLenum mode, GLint first, GLsizei count, GLsizei primcount', },
787 { 'return_type': 'void',
788 'known_as': 'glDrawElementsInstancedANGLE',
789 'names': ['glDrawElementsInstancedARB', 'glDrawElementsInstancedANGLE',
790 'glDrawElementsInstanced'],
791 'arguments':
792 'GLenum mode, GLsizei count, GLenum type, const void* indices, '
793 'GLsizei primcount', },
794 { 'return_type': 'void',
795 'known_as': 'glVertexAttribDivisorANGLE',
796 'names': ['glVertexAttribDivisorARB', 'glVertexAttribDivisorANGLE',
797 'glVertexAttribDivisor'],
798 'arguments':
799 'GLuint index, GLuint divisor', },
800 { 'return_type': 'void',
801 'known_as': 'glGenVertexArraysOES',
802 'versions': [{ 'name': 'glGenVertexArrays',
803 'gl_versions': ['gl3', 'gl4'] },
804 { 'name': 'glGenVertexArrays',
805 'extensions': ['GL_ARB_vertex_array_object'] },
806 { 'name': 'glGenVertexArraysOES' },
807 { 'name': 'glGenVertexArraysAPPLE',
808 'extensions': ['GL_APPLE_vertex_array_object'] }],
809 'arguments': 'GLsizei n, GLuint* arrays', },
810 { 'return_type': 'void',
811 'known_as': 'glDeleteVertexArraysOES',
812 'versions': [{ 'name': 'glDeleteVertexArrays',
813 'gl_versions': ['gl3', 'gl4'] },
814 { 'name': 'glDeleteVertexArrays',
815 'extensions': ['GL_ARB_vertex_array_object'] },
816 { 'name': 'glDeleteVertexArraysOES' },
817 { 'name': 'glDeleteVertexArraysAPPLE',
818 'extensions': ['GL_APPLE_vertex_array_object'] }],
819 'arguments': 'GLsizei n, const GLuint* arrays' },
820 { 'return_type': 'void',
821 'known_as': 'glBindVertexArrayOES',
822 'versions': [{ 'name': 'glBindVertexArray',
823 'gl_versions': ['gl3', 'gl4'] },
824 { 'name': 'glBindVertexArray',
825 'extensions': ['GL_ARB_vertex_array_object'] },
826 { 'name': 'glBindVertexArrayOES' },
827 { 'name': 'glBindVertexArrayAPPLE',
828 'extensions': ['GL_APPLE_vertex_array_object'] }],
829 'arguments': 'GLuint array' },
830 { 'return_type': 'GLboolean',
831 'known_as': 'glIsVertexArrayOES',
832 'versions': [{ 'name': 'glIsVertexArray',
833 'gl_versions': ['gl3', 'gl4'] },
834 { 'name': 'glIsVertexArray',
835 'extensions': ['GL_ARB_vertex_array_object'] },
836 { 'name': 'glIsVertexArrayOES' },
837 { 'name': 'glIsVertexArrayAPPLE',
838 'extensions': ['GL_APPLE_vertex_array_object'] }],
839 'arguments': 'GLuint array' },
840 { 'return_type': 'void',
841 'known_as': 'glDiscardFramebufferEXT',
842 'versions': [{ 'name': 'glInvalidateFramebuffer',
843 'gl_versions': ['es3'],
844 'extensions': [] },
845 { 'name': 'glDiscardFramebufferEXT',
846 'gl_versions': ['es1', 'es2'] }],
847 'arguments': 'GLenum target, GLsizei numAttachments, '
848 'const GLenum* attachments' },
849 { 'return_type': 'void',
850 'known_as': 'glMatrixLoadfEXT',
851 'versions': [{ 'name': 'glMatrixLoadfEXT',
852 'gl_versions': ['gl4'],
853 'extensions': ['GL_EXT_direct_state_access'] },
854 { 'name': 'glMatrixLoadfEXT',
855 'gl_versions': ['es3'],
856 'extensions': ['GL_NV_path_rendering'] }],
857 'arguments': 'GLenum matrixMode, const GLfloat* m' },
858 { 'return_type': 'void',
859 'known_as': 'glMatrixLoadIdentityEXT',
860 'versions': [{ 'name': 'glMatrixLoadIdentityEXT',
861 'gl_versions': ['gl4'],
862 'extensions': ['GL_EXT_direct_state_access'] },
863 { 'name': 'glMatrixLoadIdentityEXT',
864 'gl_versions': ['es3'],
865 'extensions': ['GL_NV_path_rendering'] }],
866 'arguments': 'GLenum matrixMode' },
869 OSMESA_FUNCTIONS = [
870 { 'return_type': 'OSMesaContext',
871 'names': ['OSMesaCreateContext'],
872 'arguments': 'GLenum format, OSMesaContext sharelist', },
873 { 'return_type': 'OSMesaContext',
874 'names': ['OSMesaCreateContextExt'],
875 'arguments':
876 'GLenum format, GLint depthBits, GLint stencilBits, GLint accumBits, '
877 'OSMesaContext sharelist', },
878 { 'return_type': 'void',
879 'names': ['OSMesaDestroyContext'],
880 'arguments': 'OSMesaContext ctx', },
881 { 'return_type': 'GLboolean',
882 'names': ['OSMesaMakeCurrent'],
883 'arguments': 'OSMesaContext ctx, void* buffer, GLenum type, GLsizei width, '
884 'GLsizei height', },
885 { 'return_type': 'OSMesaContext',
886 'names': ['OSMesaGetCurrentContext'],
887 'arguments': 'void', },
888 { 'return_type': 'void',
889 'names': ['OSMesaPixelStore'],
890 'arguments': 'GLint pname, GLint value', },
891 { 'return_type': 'void',
892 'names': ['OSMesaGetIntegerv'],
893 'arguments': 'GLint pname, GLint* value', },
894 { 'return_type': 'GLboolean',
895 'names': ['OSMesaGetDepthBuffer'],
896 'arguments':
897 'OSMesaContext c, GLint* width, GLint* height, GLint* bytesPerValue, '
898 'void** buffer', },
899 { 'return_type': 'GLboolean',
900 'names': ['OSMesaGetColorBuffer'],
901 'arguments': 'OSMesaContext c, GLint* width, GLint* height, GLint* format, '
902 'void** buffer', },
903 { 'return_type': 'OSMESAproc',
904 'names': ['OSMesaGetProcAddress'],
905 'arguments': 'const char* funcName', },
906 { 'return_type': 'void',
907 'names': ['OSMesaColorClamp'],
908 'arguments': 'GLboolean enable', },
911 EGL_FUNCTIONS = [
912 { 'return_type': 'EGLint',
913 'names': ['eglGetError'],
914 'arguments': 'void', },
915 { 'return_type': 'EGLDisplay',
916 'names': ['eglGetDisplay'],
917 'arguments': 'EGLNativeDisplayType display_id', },
918 { 'return_type': 'EGLBoolean',
919 'names': ['eglInitialize'],
920 'arguments': 'EGLDisplay dpy, EGLint* major, EGLint* minor', },
921 { 'return_type': 'EGLBoolean',
922 'names': ['eglTerminate'],
923 'arguments': 'EGLDisplay dpy', },
924 { 'return_type': 'const char*',
925 'names': ['eglQueryString'],
926 'arguments': 'EGLDisplay dpy, EGLint name', },
927 { 'return_type': 'EGLBoolean',
928 'names': ['eglGetConfigs'],
929 'arguments': 'EGLDisplay dpy, EGLConfig* configs, EGLint config_size, '
930 'EGLint* num_config', },
931 { 'return_type': 'EGLBoolean',
932 'names': ['eglChooseConfig'],
933 'arguments': 'EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, '
934 'EGLint config_size, EGLint* num_config', },
935 { 'return_type': 'EGLBoolean',
936 'names': ['eglGetConfigAttrib'],
937 'arguments':
938 'EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value', },
939 { 'return_type': 'EGLImageKHR',
940 'versions': [{ 'name': 'eglCreateImageKHR',
941 'extensions':
942 ['EGL_KHR_image_base', 'EGL_KHR_gl_texture_2D_image'] }],
943 'arguments':
944 'EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, '
945 'const EGLint* attrib_list' },
946 { 'return_type': 'EGLBoolean',
947 'versions': [{ 'name' : 'eglDestroyImageKHR',
948 'extensions': ['EGL_KHR_image_base'] }],
949 'arguments': 'EGLDisplay dpy, EGLImageKHR image' },
950 { 'return_type': 'EGLSurface',
951 'names': ['eglCreateWindowSurface'],
952 'arguments': 'EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, '
953 'const EGLint* attrib_list', },
954 { 'return_type': 'EGLSurface',
955 'names': ['eglCreatePbufferSurface'],
956 'arguments': 'EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list', },
957 { 'return_type': 'EGLSurface',
958 'names': ['eglCreatePixmapSurface'],
959 'arguments': 'EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, '
960 'const EGLint* attrib_list', },
961 { 'return_type': 'EGLBoolean',
962 'names': ['eglDestroySurface'],
963 'arguments': 'EGLDisplay dpy, EGLSurface surface', },
964 { 'return_type': 'EGLBoolean',
965 'names': ['eglQuerySurface'],
966 'arguments':
967 'EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint* value', },
968 { 'return_type': 'EGLBoolean',
969 'names': ['eglBindAPI'],
970 'arguments': 'EGLenum api', },
971 { 'return_type': 'EGLenum',
972 'names': ['eglQueryAPI'],
973 'arguments': 'void', },
974 { 'return_type': 'EGLBoolean',
975 'names': ['eglWaitClient'],
976 'arguments': 'void', },
977 { 'return_type': 'EGLBoolean',
978 'names': ['eglReleaseThread'],
979 'arguments': 'void', },
980 { 'return_type': 'EGLSurface',
981 'names': ['eglCreatePbufferFromClientBuffer'],
982 'arguments':
983 'EGLDisplay dpy, EGLenum buftype, void* buffer, EGLConfig config, '
984 'const EGLint* attrib_list', },
985 { 'return_type': 'EGLBoolean',
986 'names': ['eglSurfaceAttrib'],
987 'arguments':
988 'EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value', },
989 { 'return_type': 'EGLBoolean',
990 'names': ['eglBindTexImage'],
991 'arguments': 'EGLDisplay dpy, EGLSurface surface, EGLint buffer', },
992 { 'return_type': 'EGLBoolean',
993 'names': ['eglReleaseTexImage'],
994 'arguments': 'EGLDisplay dpy, EGLSurface surface, EGLint buffer', },
995 { 'return_type': 'EGLBoolean',
996 'names': ['eglSwapInterval'],
997 'arguments': 'EGLDisplay dpy, EGLint interval', },
998 { 'return_type': 'EGLContext',
999 'names': ['eglCreateContext'],
1000 'arguments': 'EGLDisplay dpy, EGLConfig config, EGLContext share_context, '
1001 'const EGLint* attrib_list', },
1002 { 'return_type': 'EGLBoolean',
1003 'names': ['eglDestroyContext'],
1004 'arguments': 'EGLDisplay dpy, EGLContext ctx', },
1005 { 'return_type': 'EGLBoolean',
1006 'names': ['eglMakeCurrent'],
1007 'arguments':
1008 'EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx', },
1009 { 'return_type': 'EGLContext',
1010 'names': ['eglGetCurrentContext'],
1011 'arguments': 'void', },
1012 { 'return_type': 'EGLSurface',
1013 'names': ['eglGetCurrentSurface'],
1014 'arguments': 'EGLint readdraw', },
1015 { 'return_type': 'EGLDisplay',
1016 'names': ['eglGetCurrentDisplay'],
1017 'arguments': 'void', },
1018 { 'return_type': 'EGLBoolean',
1019 'names': ['eglQueryContext'],
1020 'arguments':
1021 'EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value', },
1022 { 'return_type': 'EGLBoolean',
1023 'names': ['eglWaitGL'],
1024 'arguments': 'void', },
1025 { 'return_type': 'EGLBoolean',
1026 'names': ['eglWaitNative'],
1027 'arguments': 'EGLint engine', },
1028 { 'return_type': 'EGLBoolean',
1029 'names': ['eglSwapBuffers'],
1030 'arguments': 'EGLDisplay dpy, EGLSurface surface', },
1031 { 'return_type': 'EGLBoolean',
1032 'names': ['eglCopyBuffers'],
1033 'arguments':
1034 'EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target', },
1035 { 'return_type': '__eglMustCastToProperFunctionPointerType',
1036 'names': ['eglGetProcAddress'],
1037 'arguments': 'const char* procname', },
1038 { 'return_type': 'EGLBoolean',
1039 'names': ['eglPostSubBufferNV'],
1040 'arguments': 'EGLDisplay dpy, EGLSurface surface, '
1041 'EGLint x, EGLint y, EGLint width, EGLint height', },
1042 { 'return_type': 'EGLBoolean',
1043 'names': ['eglQuerySurfacePointerANGLE'],
1044 'arguments':
1045 'EGLDisplay dpy, EGLSurface surface, EGLint attribute, void** value', },
1046 { 'return_type': 'EGLSyncKHR',
1047 'versions': [{ 'name': 'eglCreateSyncKHR',
1048 'extensions': ['EGL_KHR_fence_sync'] }],
1049 'arguments': 'EGLDisplay dpy, EGLenum type, const EGLint* attrib_list' },
1050 { 'return_type': 'EGLint',
1051 'versions': [{ 'name': 'eglClientWaitSyncKHR',
1052 'extensions': ['EGL_KHR_fence_sync'] }],
1053 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, '
1054 'EGLTimeKHR timeout' },
1055 { 'return_type': 'EGLBoolean',
1056 'versions': [{ 'name': 'eglGetSyncAttribKHR',
1057 'extensions': ['EGL_KHR_fence_sync'] }],
1058 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, '
1059 'EGLint* value' },
1060 { 'return_type': 'EGLBoolean',
1061 'versions': [{ 'name': 'eglDestroySyncKHR',
1062 'extensions': ['EGL_KHR_fence_sync'] }],
1063 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync' },
1064 { 'return_type': 'EGLBoolean',
1065 'names': ['eglGetSyncValuesCHROMIUM'],
1066 'arguments':
1067 'EGLDisplay dpy, EGLSurface surface, '
1068 'EGLuint64CHROMIUM* ust, EGLuint64CHROMIUM* msc, '
1069 'EGLuint64CHROMIUM* sbc', },
1070 { 'return_type': 'EGLint',
1071 'versions': [{ 'name': 'eglWaitSyncKHR',
1072 'extensions': ['EGL_KHR_fence_sync'] }],
1073 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint flags' }
1076 WGL_FUNCTIONS = [
1077 { 'return_type': 'HGLRC',
1078 'names': ['wglCreateContext'],
1079 'arguments': 'HDC hdc', },
1080 { 'return_type': 'HGLRC',
1081 'names': ['wglCreateLayerContext'],
1082 'arguments': 'HDC hdc, int iLayerPlane', },
1083 { 'return_type': 'BOOL',
1084 'names': ['wglCopyContext'],
1085 'arguments': 'HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask', },
1086 { 'return_type': 'BOOL',
1087 'names': ['wglDeleteContext'],
1088 'arguments': 'HGLRC hglrc', },
1089 { 'return_type': 'HGLRC',
1090 'names': ['wglGetCurrentContext'],
1091 'arguments': '', },
1092 { 'return_type': 'HDC',
1093 'names': ['wglGetCurrentDC'],
1094 'arguments': '', },
1095 { 'return_type': 'BOOL',
1096 'names': ['wglMakeCurrent'],
1097 'arguments': 'HDC hdc, HGLRC hglrc', },
1098 { 'return_type': 'BOOL',
1099 'names': ['wglShareLists'],
1100 'arguments': 'HGLRC hglrc1, HGLRC hglrc2', },
1101 { 'return_type': 'BOOL',
1102 'names': ['wglSwapIntervalEXT'],
1103 'arguments': 'int interval', },
1104 { 'return_type': 'BOOL',
1105 'names': ['wglSwapLayerBuffers'],
1106 'arguments': 'HDC hdc, UINT fuPlanes', },
1107 { 'return_type': 'const char*',
1108 'names': ['wglGetExtensionsStringARB'],
1109 'arguments': 'HDC hDC', },
1110 { 'return_type': 'const char*',
1111 'names': ['wglGetExtensionsStringEXT'],
1112 'arguments': '', },
1113 { 'return_type': 'BOOL',
1114 'names': ['wglChoosePixelFormatARB'],
1115 'arguments':
1116 'HDC dc, const int* int_attrib_list, const float* float_attrib_list, '
1117 'UINT max_formats, int* formats, UINT* num_formats', },
1118 { 'return_type': 'HPBUFFERARB',
1119 'names': ['wglCreatePbufferARB'],
1120 'arguments': 'HDC hDC, int iPixelFormat, int iWidth, int iHeight, '
1121 'const int* piAttribList', },
1122 { 'return_type': 'HDC',
1123 'names': ['wglGetPbufferDCARB'],
1124 'arguments': 'HPBUFFERARB hPbuffer', },
1125 { 'return_type': 'int',
1126 'names': ['wglReleasePbufferDCARB'],
1127 'arguments': 'HPBUFFERARB hPbuffer, HDC hDC', },
1128 { 'return_type': 'BOOL',
1129 'names': ['wglDestroyPbufferARB'],
1130 'arguments': 'HPBUFFERARB hPbuffer', },
1131 { 'return_type': 'BOOL',
1132 'names': ['wglQueryPbufferARB'],
1133 'arguments': 'HPBUFFERARB hPbuffer, int iAttribute, int* piValue', },
1136 GLX_FUNCTIONS = [
1137 { 'return_type': 'int',
1138 'names': ['glXWaitVideoSyncSGI'],
1139 'arguments': 'int divisor, int remainder, unsigned int* count', },
1140 { 'return_type': 'XVisualInfo*',
1141 'names': ['glXChooseVisual'],
1142 'arguments': 'Display* dpy, int screen, int* attribList', },
1143 { 'return_type': 'void',
1144 'names': ['glXCopySubBufferMESA'],
1145 'arguments': 'Display* dpy, GLXDrawable drawable, '
1146 'int x, int y, int width, int height', },
1147 { 'return_type': 'GLXContext',
1148 'names': ['glXCreateContext'],
1149 'arguments':
1150 'Display* dpy, XVisualInfo* vis, GLXContext shareList, int direct', },
1151 { 'return_type': 'void',
1152 'names': ['glXBindTexImageEXT'],
1153 'arguments':
1154 'Display* dpy, GLXDrawable drawable, int buffer, int* attribList', },
1155 { 'return_type': 'void',
1156 'names': ['glXReleaseTexImageEXT'],
1157 'arguments': 'Display* dpy, GLXDrawable drawable, int buffer', },
1158 { 'return_type': 'void',
1159 'names': ['glXDestroyContext'],
1160 'arguments': 'Display* dpy, GLXContext ctx', },
1161 { 'return_type': 'int',
1162 'names': ['glXMakeCurrent'],
1163 'arguments': 'Display* dpy, GLXDrawable drawable, GLXContext ctx', },
1164 { 'return_type': 'void',
1165 'names': ['glXCopyContext'],
1166 'arguments':
1167 'Display* dpy, GLXContext src, GLXContext dst, unsigned long mask', },
1168 { 'return_type': 'void',
1169 'names': ['glXSwapBuffers'],
1170 'arguments': 'Display* dpy, GLXDrawable drawable', },
1171 { 'return_type': 'GLXPixmap',
1172 'names': ['glXCreateGLXPixmap'],
1173 'arguments': 'Display* dpy, XVisualInfo* visual, Pixmap pixmap', },
1174 { 'return_type': 'void',
1175 'names': ['glXDestroyGLXPixmap'],
1176 'arguments': 'Display* dpy, GLXPixmap pixmap', },
1177 { 'return_type': 'int',
1178 'names': ['glXQueryExtension'],
1179 'arguments': 'Display* dpy, int* errorb, int* event', },
1180 { 'return_type': 'int',
1181 'names': ['glXQueryVersion'],
1182 'arguments': 'Display* dpy, int* maj, int* min', },
1183 { 'return_type': 'int',
1184 'names': ['glXIsDirect'],
1185 'arguments': 'Display* dpy, GLXContext ctx', },
1186 { 'return_type': 'int',
1187 'names': ['glXGetConfig'],
1188 'arguments': 'Display* dpy, XVisualInfo* visual, int attrib, int* value', },
1189 { 'return_type': 'GLXContext',
1190 'names': ['glXGetCurrentContext'],
1191 'arguments': 'void', },
1192 { 'return_type': 'GLXDrawable',
1193 'names': ['glXGetCurrentDrawable'],
1194 'arguments': 'void', },
1195 { 'return_type': 'void',
1196 'names': ['glXWaitGL'],
1197 'arguments': 'void', },
1198 { 'return_type': 'void',
1199 'names': ['glXWaitX'],
1200 'arguments': 'void', },
1201 { 'return_type': 'void',
1202 'names': ['glXUseXFont'],
1203 'arguments': 'Font font, int first, int count, int list', },
1204 { 'return_type': 'const char*',
1205 'names': ['glXQueryExtensionsString'],
1206 'arguments': 'Display* dpy, int screen', },
1207 { 'return_type': 'const char*',
1208 'names': ['glXQueryServerString'],
1209 'arguments': 'Display* dpy, int screen, int name', },
1210 { 'return_type': 'const char*',
1211 'names': ['glXGetClientString'],
1212 'arguments': 'Display* dpy, int name', },
1213 { 'return_type': 'Display*',
1214 'names': ['glXGetCurrentDisplay'],
1215 'arguments': 'void', },
1216 { 'return_type': 'GLXFBConfig*',
1217 'names': ['glXChooseFBConfig'],
1218 'arguments':
1219 'Display* dpy, int screen, const int* attribList, int* nitems', },
1220 { 'return_type': 'int',
1221 'names': ['glXGetFBConfigAttrib'],
1222 'arguments': 'Display* dpy, GLXFBConfig config, int attribute, int* value', },
1223 { 'return_type': 'GLXFBConfig*',
1224 'names': ['glXGetFBConfigs'],
1225 'arguments': 'Display* dpy, int screen, int* nelements', },
1226 { 'return_type': 'XVisualInfo*',
1227 'names': ['glXGetVisualFromFBConfig'],
1228 'arguments': 'Display* dpy, GLXFBConfig config', },
1229 { 'return_type': 'GLXWindow',
1230 'names': ['glXCreateWindow'],
1231 'arguments':
1232 'Display* dpy, GLXFBConfig config, Window win, const int* attribList', },
1233 { 'return_type': 'void',
1234 'names': ['glXDestroyWindow'],
1235 'arguments': 'Display* dpy, GLXWindow window', },
1236 { 'return_type': 'GLXPixmap',
1237 'names': ['glXCreatePixmap'],
1238 'arguments': 'Display* dpy, GLXFBConfig config, '
1239 'Pixmap pixmap, const int* attribList', },
1240 { 'return_type': 'void',
1241 'names': ['glXDestroyPixmap'],
1242 'arguments': 'Display* dpy, GLXPixmap pixmap', },
1243 { 'return_type': 'GLXPbuffer',
1244 'names': ['glXCreatePbuffer'],
1245 'arguments': 'Display* dpy, GLXFBConfig config, const int* attribList', },
1246 { 'return_type': 'void',
1247 'names': ['glXDestroyPbuffer'],
1248 'arguments': 'Display* dpy, GLXPbuffer pbuf', },
1249 { 'return_type': 'void',
1250 'names': ['glXQueryDrawable'],
1251 'arguments':
1252 'Display* dpy, GLXDrawable draw, int attribute, unsigned int* value', },
1253 { 'return_type': 'GLXContext',
1254 'names': ['glXCreateNewContext'],
1255 'arguments': 'Display* dpy, GLXFBConfig config, int renderType, '
1256 'GLXContext shareList, int direct', },
1257 { 'return_type': 'int',
1258 'names': ['glXMakeContextCurrent'],
1259 'arguments':
1260 'Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx', },
1261 { 'return_type': 'GLXDrawable',
1262 'names': ['glXGetCurrentReadDrawable'],
1263 'arguments': 'void', },
1264 { 'return_type': 'int',
1265 'names': ['glXQueryContext'],
1266 'arguments': 'Display* dpy, GLXContext ctx, int attribute, int* value', },
1267 { 'return_type': 'void',
1268 'names': ['glXSelectEvent'],
1269 'arguments': 'Display* dpy, GLXDrawable drawable, unsigned long mask', },
1270 { 'return_type': 'void',
1271 'names': ['glXGetSelectedEvent'],
1272 'arguments': 'Display* dpy, GLXDrawable drawable, unsigned long* mask', },
1273 { 'return_type': 'void',
1274 'names': ['glXSwapIntervalMESA'],
1275 'arguments': 'unsigned int interval', },
1276 { 'return_type': 'void',
1277 'names': ['glXSwapIntervalEXT'],
1278 'arguments': 'Display* dpy, GLXDrawable drawable, int interval', },
1279 { 'return_type': 'GLXFBConfig',
1280 'names': ['glXGetFBConfigFromVisualSGIX'],
1281 'arguments': 'Display* dpy, XVisualInfo* visualInfo', },
1282 { 'return_type': 'GLXContext',
1283 'names': ['glXCreateContextAttribsARB'],
1284 'arguments':
1285 'Display* dpy, GLXFBConfig config, GLXContext share_context, int direct, '
1286 'const int* attrib_list', },
1287 { 'return_type': 'bool',
1288 'names': ['glXGetSyncValuesOML'],
1289 'arguments':
1290 'Display* dpy, GLXDrawable drawable, int64* ust, int64* msc, '
1291 'int64* sbc' },
1292 { 'return_type': 'bool',
1293 'names': ['glXGetMscRateOML'],
1294 'arguments':
1295 'Display* dpy, GLXDrawable drawable, int32* numerator, '
1296 'int32* denominator' },
1299 FUNCTION_SETS = [
1300 [GL_FUNCTIONS, 'gl', [
1301 'GL/glext.h',
1302 'GLES2/gl2ext.h',
1303 # Files below are Chromium-specific and shipped with Chromium sources.
1304 'GL/glextchromium.h',
1305 'GLES2/gl2chromium.h',
1306 'GLES2/gl2extchromium.h'
1307 ], []],
1308 [OSMESA_FUNCTIONS, 'osmesa', [], []],
1309 [EGL_FUNCTIONS, 'egl', [
1310 'EGL/eglext.h',
1311 # Files below are Chromium-specific and shipped with Chromium sources.
1312 'EGL/eglextchromium.h',
1315 'EGL_ANGLE_d3d_share_handle_client_buffer',
1316 'EGL_ANGLE_surface_d3d_texture_2d_share_handle',
1319 [WGL_FUNCTIONS, 'wgl', ['GL/wglext.h'], []],
1320 [GLX_FUNCTIONS, 'glx', ['GL/glx.h', 'GL/glxext.h'], []],
1323 def GenerateHeader(file, functions, set_name, used_extensions):
1324 """Generates gl_bindings_autogen_x.h"""
1326 # Write file header.
1327 file.write(
1328 """// Copyright (c) 2012 The Chromium Authors. All rights reserved.
1329 // Use of this source code is governed by a BSD-style license that can be
1330 // found in the LICENSE file.
1332 // This file is automatically generated.
1334 #ifndef UI_GFX_GL_GL_BINDINGS_AUTOGEN_%(name)s_H_
1335 #define UI_GFX_GL_GL_BINDINGS_AUTOGEN_%(name)s_H_
1337 namespace gfx {
1339 class GLContext;
1341 """ % {'name': set_name.upper()})
1343 # Write typedefs for function pointer types. Always use the GL name for the
1344 # typedef.
1345 file.write('\n')
1346 for func in functions:
1347 file.write('typedef %s (GL_BINDING_CALL *%sProc)(%s);\n' %
1348 (func['return_type'], func['known_as'], func['arguments']))
1350 # Write declarations for booleans indicating which extensions are available.
1351 file.write('\n')
1352 file.write("struct Extensions%s {\n" % set_name.upper())
1353 for extension in sorted(used_extensions):
1354 file.write(' bool b_%s;\n' % extension)
1355 file.write('};\n')
1356 file.write('\n')
1358 # Write Procs struct.
1359 file.write("struct Procs%s {\n" % set_name.upper())
1360 for func in functions:
1361 file.write(' %sProc %sFn;\n' % (func['known_as'], func['known_as']))
1362 file.write('};\n')
1363 file.write('\n')
1365 # Write Api class.
1366 file.write(
1367 """class GL_EXPORT %(name)sApi {
1368 public:
1369 %(name)sApi();
1370 virtual ~%(name)sApi();
1372 """ % {'name': set_name.upper()})
1373 for func in functions:
1374 file.write(' virtual %s %sFn(%s) = 0;\n' %
1375 (func['return_type'], func['known_as'], func['arguments']))
1376 file.write('};\n')
1377 file.write('\n')
1379 file.write( '} // namespace gfx\n')
1381 # Write macros to invoke function pointers. Always use the GL name for the
1382 # macro.
1383 file.write('\n')
1384 for func in functions:
1385 file.write('#define %s ::gfx::g_current_%s_context->%sFn\n' %
1386 (func['known_as'], set_name.lower(), func['known_as']))
1388 file.write('\n')
1389 file.write('#endif // UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' %
1390 set_name.upper())
1393 def GenerateAPIHeader(file, functions, set_name):
1394 """Generates gl_bindings_api_autogen_x.h"""
1396 # Write file header.
1397 file.write(
1398 """// Copyright (c) 2012 The Chromium Authors. All rights reserved.
1399 // Use of this source code is governed by a BSD-style license that can be
1400 // found in the LICENSE file.
1402 // This file is automatically generated.
1404 """ % {'name': set_name.upper()})
1406 # Write API declaration.
1407 for func in functions:
1408 file.write(' virtual %s %sFn(%s) OVERRIDE;\n' %
1409 (func['return_type'], func['known_as'], func['arguments']))
1411 file.write('\n')
1414 def GenerateMockHeader(file, functions, set_name):
1415 """Generates gl_mock_autogen_x.h"""
1417 # Write file header.
1418 file.write(
1419 """// Copyright (c) 2012 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 """ % {'name': set_name.upper()})
1427 # Write API declaration.
1428 for func in functions:
1429 args = func['arguments']
1430 if args == 'void':
1431 args = ''
1432 arg_count = 0
1433 if len(args):
1434 arg_count = func['arguments'].count(',') + 1
1435 file.write(' MOCK_METHOD%d(%s, %s(%s));\n' %
1436 (arg_count, func['known_as'][2:], func['return_type'], args))
1438 file.write('\n')
1441 def GenerateSource(file, functions, set_name, used_extensions):
1442 """Generates gl_bindings_autogen_x.cc"""
1444 # Write file header.
1445 file.write(
1446 """// Copyright (c) 2011 The Chromium Authors. All rights reserved.
1447 // Use of this source code is governed by a BSD-style license that can be
1448 // found in the LICENSE file.
1450 // This file is automatically generated.
1452 #include <string>
1453 #include "base/debug/trace_event.h"
1454 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
1455 #include "ui/gl/gl_bindings.h"
1456 #include "ui/gl/gl_context.h"
1457 #include "ui/gl/gl_implementation.h"
1458 #include "ui/gl/gl_version_info.h"
1459 #include "ui/gl/gl_%s_api_implementation.h"
1461 using gpu::gles2::GLES2Util;
1463 namespace gfx {
1464 """ % set_name.lower())
1466 file.write('\n')
1467 file.write('static bool g_debugBindingsInitialized;\n')
1468 file.write('Driver%s g_driver_%s;\n' % (set_name.upper(), set_name.lower()))
1469 file.write('\n')
1471 # Write stub functions that take the place of some functions before a context
1472 # is initialized. This is done to provide clear asserts on debug build and to
1473 # avoid crashing in case of a bug on release build.
1474 file.write('\n')
1475 for func in functions:
1476 unique_names = set([version['name'] for version in func['versions']])
1477 if len(unique_names) > 1:
1478 file.write('%s %sNotBound(%s) {\n' %
1479 (func['return_type'], func['known_as'], func['arguments']))
1480 file.write(' NOTREACHED();\n')
1481 return_type = func['return_type'].lower()
1482 # Returning 0 works for booleans, integers and pointers.
1483 if return_type != 'void':
1484 file.write(' return 0;\n')
1485 file.write('}\n')
1487 # Write function to initialize the function pointers that are always the same
1488 # and to initialize bindings where choice of the function depends on the
1489 # extension string or the GL version to point to stub functions.
1490 file.write('\n')
1491 file.write('void Driver%s::InitializeStaticBindings() {\n' %
1492 set_name.upper())
1494 def WriteFuncBinding(file, known_as, version_name):
1495 file.write(
1496 ' fn.%sFn = reinterpret_cast<%sProc>(GetGLProcAddress("%s"));\n' %
1497 (known_as, known_as, version_name))
1499 for func in functions:
1500 unique_names = set([version['name'] for version in func['versions']])
1501 if len(unique_names) == 1:
1502 WriteFuncBinding(file, func['known_as'], func['known_as'])
1503 else:
1504 file.write(' fn.%sFn = reinterpret_cast<%sProc>(%sNotBound);\n' %
1505 (func['known_as'], func['known_as'], func['known_as']))
1507 file.write('}\n')
1508 file.write('\n')
1510 # Write function to initialize bindings where choice of the function depends
1511 # on the extension string or the GL version.
1512 file.write("""void Driver%s::InitializeDynamicBindings(GLContext* context) {
1513 DCHECK(context && context->IsCurrent(NULL));
1514 const GLVersionInfo* ver ALLOW_UNUSED = context->GetVersionInfo();
1515 std::string extensions ALLOW_UNUSED = context->GetExtensions();
1516 extensions += " ";
1518 """ % set_name.upper())
1519 for extension in sorted(used_extensions):
1520 # Extra space at the end of the extension name is intentional, it is used
1521 # as a separator
1522 file.write(' ext.b_%s = extensions.find("%s ") != std::string::npos;\n' %
1523 (extension, extension))
1525 def WrapOr(cond):
1526 if ' || ' in cond:
1527 return '(%s)' % cond
1528 return cond
1530 def WrapAnd(cond):
1531 if ' && ' in cond:
1532 return '(%s)' % cond
1533 return cond
1535 def VersionCondition(version):
1536 conditions = []
1537 if 'gl_versions' in version:
1538 gl_versions = version['gl_versions']
1539 version_cond = ' || '.join(['ver->is_%s' % gl for gl in gl_versions])
1540 conditions.append(WrapOr(version_cond))
1541 if 'extensions' in version and version['extensions']:
1542 ext_cond = ' || '.join(['ext.b_%s' % e for e in version['extensions']])
1543 conditions.append(WrapOr(ext_cond))
1544 return ' && '.join(conditions)
1546 def WriteConditionalFuncBinding(file, func):
1547 # Functions with only one version are always bound unconditionally
1548 assert len(func['versions']) > 1
1549 known_as = func['known_as']
1550 i = 0
1551 first_version = True
1552 while i < len(func['versions']):
1553 version = func['versions'][i]
1554 cond = VersionCondition(version)
1555 combined_conditions = [WrapAnd(cond)]
1556 last_version = i + 1 == len(func['versions'])
1557 while not last_version and \
1558 func['versions'][i + 1]['name'] == version['name']:
1559 i += 1
1560 combinable_cond = VersionCondition(func['versions'][i])
1561 combined_conditions.append(WrapAnd(combinable_cond))
1562 last_version = i + 1 == len(func['versions'])
1563 if len(combined_conditions) > 1:
1564 if [1 for cond in combined_conditions if cond == '']:
1565 cond = ''
1566 else:
1567 cond = ' || '.join(combined_conditions)
1568 # Don't make the last possible binding conditional on anything else but
1569 # that the function isn't already bound to avoid verbose specification
1570 # of functions which have both ARB and core versions with the same name,
1571 # and to be able to bind to mock extension functions in unit tests which
1572 # call InitializeDynamicGLBindings with a stub context that doesn't have
1573 # extensions in its extension string.
1574 # TODO(oetuaho@nvidia.com): Get rid of the fallback.
1575 # http://crbug.com/325668
1576 if cond != '' and not last_version:
1577 if not first_version:
1578 file.write(' if (!fn.%sFn && (%s))\n ' % (known_as, cond))
1579 else:
1580 file.write(' if (%s)\n ' % cond)
1581 elif not first_version:
1582 file.write(' if (!fn.%sFn)\n ' % known_as)
1583 WriteFuncBinding(file, known_as, version['name'])
1584 i += 1
1585 first_version = False
1587 for func in functions:
1588 unique_names = set([version['name'] for version in func['versions']])
1589 if len(unique_names) > 1:
1590 file.write('\n')
1591 file.write(' fn.%sFn = 0;\n' % func['known_as'])
1592 file.write(' debug_fn.%sFn = 0;\n' % func['known_as'])
1593 WriteConditionalFuncBinding(file, func)
1595 # Some new function pointers have been added, so update them in debug bindings
1596 file.write('\n')
1597 file.write(' if (g_debugBindingsInitialized)\n')
1598 file.write(' InitializeDebugBindings();\n')
1599 file.write('}\n')
1600 file.write('\n')
1602 # Write logging wrappers for each function.
1603 file.write('extern "C" {\n')
1604 for func in functions:
1605 return_type = func['return_type']
1606 arguments = func['arguments']
1607 file.write('\n')
1608 file.write('static %s GL_BINDING_CALL Debug_%s(%s) {\n' %
1609 (return_type, func['known_as'], arguments))
1610 argument_names = re.sub(
1611 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', arguments)
1612 argument_names = re.sub(
1613 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', argument_names)
1614 log_argument_names = re.sub(
1615 r'const char\* ([a-zA-Z0-9_]+)', r'CONSTCHAR_\1', arguments)
1616 log_argument_names = re.sub(
1617 r'(const )?[a-zA-Z0-9_]+\* ([a-zA-Z0-9_]+)',
1618 r'CONSTVOID_\2', log_argument_names)
1619 log_argument_names = re.sub(
1620 r'(?<!E)GLenum ([a-zA-Z0-9_]+)', r'GLenum_\1', log_argument_names)
1621 log_argument_names = re.sub(
1622 r'(?<!E)GLboolean ([a-zA-Z0-9_]+)', r'GLboolean_\1', log_argument_names)
1623 log_argument_names = re.sub(
1624 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2',
1625 log_argument_names)
1626 log_argument_names = re.sub(
1627 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2',
1628 log_argument_names)
1629 log_argument_names = re.sub(
1630 r'CONSTVOID_([a-zA-Z0-9_]+)',
1631 r'static_cast<const void*>(\1)', log_argument_names)
1632 log_argument_names = re.sub(
1633 r'CONSTCHAR_([a-zA-Z0-9_]+)', r'\1', log_argument_names)
1634 log_argument_names = re.sub(
1635 r'GLenum_([a-zA-Z0-9_]+)', r'GLES2Util::GetStringEnum(\1)',
1636 log_argument_names)
1637 log_argument_names = re.sub(
1638 r'GLboolean_([a-zA-Z0-9_]+)', r'GLES2Util::GetStringBool(\1)',
1639 log_argument_names)
1640 log_argument_names = log_argument_names.replace(',', ' << ", " <<')
1641 if argument_names == 'void' or argument_names == '':
1642 argument_names = ''
1643 log_argument_names = ''
1644 else:
1645 log_argument_names = " << " + log_argument_names
1646 function_name = func['known_as']
1647 if return_type == 'void':
1648 file.write(' GL_SERVICE_LOG("%s" << "(" %s << ")");\n' %
1649 (function_name, log_argument_names))
1650 file.write(' g_driver_%s.debug_fn.%sFn(%s);\n' %
1651 (set_name.lower(), function_name, argument_names))
1652 if 'logging_code' in func:
1653 file.write("%s\n" % func['logging_code'])
1654 else:
1655 file.write(' GL_SERVICE_LOG("%s" << "(" %s << ")");\n' %
1656 (function_name, log_argument_names))
1657 file.write(' %s result = g_driver_%s.debug_fn.%sFn(%s);\n' %
1658 (return_type, set_name.lower(), function_name, argument_names))
1659 if 'logging_code' in func:
1660 file.write("%s\n" % func['logging_code'])
1661 else:
1662 file.write(' GL_SERVICE_LOG("GL_RESULT: " << result);\n')
1663 file.write(' return result;\n')
1664 file.write('}\n')
1665 file.write('} // extern "C"\n')
1667 # Write function to initialize the debug function pointers.
1668 file.write('\n')
1669 file.write('void Driver%s::InitializeDebugBindings() {\n' %
1670 set_name.upper())
1671 for func in functions:
1672 first_name = func['known_as']
1673 file.write(' if (!debug_fn.%sFn) {\n' % first_name)
1674 file.write(' debug_fn.%sFn = fn.%sFn;\n' % (first_name, first_name))
1675 file.write(' fn.%sFn = Debug_%s;\n' % (first_name, first_name))
1676 file.write(' }\n')
1677 file.write(' g_debugBindingsInitialized = true;\n')
1678 file.write('}\n')
1680 # Write function to clear all function pointers.
1681 file.write('\n')
1682 file.write("""void Driver%s::ClearBindings() {
1683 memset(this, 0, sizeof(*this));
1685 """ % set_name.upper())
1687 def MakeArgNames(arguments):
1688 argument_names = re.sub(
1689 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', arguments)
1690 argument_names = re.sub(
1691 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', argument_names)
1692 if argument_names == 'void' or argument_names == '':
1693 argument_names = ''
1694 return argument_names
1696 # Write GLApiBase functions
1697 for func in functions:
1698 function_name = func['known_as']
1699 return_type = func['return_type']
1700 arguments = func['arguments']
1701 file.write('\n')
1702 file.write('%s %sApiBase::%sFn(%s) {\n' %
1703 (return_type, set_name.upper(), function_name, arguments))
1704 argument_names = MakeArgNames(arguments)
1705 if return_type == 'void':
1706 file.write(' driver_->fn.%sFn(%s);\n' %
1707 (function_name, argument_names))
1708 else:
1709 file.write(' return driver_->fn.%sFn(%s);\n' %
1710 (function_name, argument_names))
1711 file.write('}\n')
1713 # Write TraceGLApi functions
1714 for func in functions:
1715 function_name = func['known_as']
1716 return_type = func['return_type']
1717 arguments = func['arguments']
1718 file.write('\n')
1719 file.write('%s Trace%sApi::%sFn(%s) {\n' %
1720 (return_type, set_name.upper(), function_name, arguments))
1721 argument_names = MakeArgNames(arguments)
1722 file.write(' TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::%s")\n' %
1723 function_name)
1724 if return_type == 'void':
1725 file.write(' %s_api_->%sFn(%s);\n' %
1726 (set_name.lower(), function_name, argument_names))
1727 else:
1728 file.write(' return %s_api_->%sFn(%s);\n' %
1729 (set_name.lower(), function_name, argument_names))
1730 file.write('}\n')
1732 # Write NoContextGLApi functions
1733 if set_name.upper() == "GL":
1734 for func in functions:
1735 function_name = func['known_as']
1736 return_type = func['return_type']
1737 arguments = func['arguments']
1738 file.write('\n')
1739 file.write('%s NoContextGLApi::%sFn(%s) {\n' %
1740 (return_type, function_name, arguments))
1741 argument_names = MakeArgNames(arguments)
1742 no_context_error = "Trying to call %s() without current GL context" % function_name
1743 file.write(' NOTREACHED() << "%s";\n' % no_context_error)
1744 file.write(' LOG(ERROR) << "%s";\n' % no_context_error)
1745 default_value = { 'GLenum': 'static_cast<GLenum>(0)',
1746 'GLuint': '0U',
1747 'GLint': '0',
1748 'GLboolean': 'GL_FALSE',
1749 'GLbyte': '0',
1750 'GLubyte': '0',
1751 'GLbutfield': '0',
1752 'GLushort': '0',
1753 'GLsizei': '0',
1754 'GLfloat': '0.0f',
1755 'GLdouble': '0.0',
1756 'GLsync': 'NULL'}
1757 if return_type.endswith('*'):
1758 file.write(' return NULL;\n')
1759 elif return_type != 'void':
1760 file.write(' return %s;\n' % default_value[return_type])
1761 file.write('}\n')
1763 file.write('\n')
1764 file.write('} // namespace gfx\n')
1767 def GetUniquelyNamedFunctions(functions):
1768 uniquely_named_functions = {}
1770 for func in functions:
1771 for version in func['versions']:
1772 uniquely_named_functions[version['name']] = ({
1773 'name': version['name'],
1774 'return_type': func['return_type'],
1775 'arguments': func['arguments'],
1776 'known_as': func['known_as']
1778 return uniquely_named_functions
1781 def GenerateMockBindingsHeader(file, functions):
1782 """Headers for functions that invoke MockGLInterface members"""
1784 file.write(
1785 """// Copyright (c) 2014 The Chromium Authors. All rights reserved.
1786 // Use of this source code is governed by a BSD-style license that can be
1787 // found in the LICENSE file.
1789 // This file is automatically generated.
1791 """)
1792 uniquely_named_functions = GetUniquelyNamedFunctions(functions)
1794 for key in sorted(uniquely_named_functions.iterkeys()):
1795 func = uniquely_named_functions[key]
1796 file.write('static %s GL_BINDING_CALL Mock_%s(%s);\n' %
1797 (func['return_type'], func['name'], func['arguments']))
1800 def GenerateMockBindingsSource(file, functions):
1801 """Generates functions that invoke MockGLInterface members and a
1802 GetGLProcAddress function that returns addresses to those functions."""
1804 file.write(
1805 """// Copyright (c) 2011 The Chromium Authors. All rights reserved.
1806 // Use of this source code is governed by a BSD-style license that can be
1807 // found in the LICENSE file.
1809 // This file is automatically generated.
1811 #include <string.h>
1813 #include "ui/gl/gl_mock.h"
1815 namespace gfx {
1817 // This is called mainly to prevent the compiler combining the code of mock
1818 // functions with identical contents, so that their function pointers will be
1819 // different.
1820 void MakeFunctionUnique(const char *func_name) {
1821 VLOG(2) << "Calling mock " << func_name;
1824 """)
1825 # Write functions that trampoline into the set MockGLInterface instance.
1826 uniquely_named_functions = GetUniquelyNamedFunctions(functions)
1827 sorted_function_names = sorted(uniquely_named_functions.iterkeys())
1829 for key in sorted_function_names:
1830 func = uniquely_named_functions[key]
1831 file.write('\n')
1832 file.write('%s GL_BINDING_CALL MockGLInterface::Mock_%s(%s) {\n' %
1833 (func['return_type'], func['name'], func['arguments']))
1834 file.write(' MakeFunctionUnique("%s");\n' % func['name'])
1835 arg_re = r'(const )?[a-zA-Z0-9]+((\s*const\s*)?\*)* ([a-zA-Z0-9]+)'
1836 argument_names = re.sub(arg_re, r'\4', func['arguments'])
1837 if argument_names == 'void':
1838 argument_names = ''
1839 function_name = func['known_as'][2:]
1840 if func['return_type'] == 'void':
1841 file.write(' interface_->%s(%s);\n' %
1842 (function_name, argument_names))
1843 else:
1844 file.write(' return interface_->%s(%s);\n' %
1845 (function_name, argument_names))
1846 file.write('}\n')
1848 # Write an 'invalid' function to catch code calling through uninitialized
1849 # function pointers or trying to interpret the return value of
1850 # GLProcAddress().
1851 file.write('\n')
1852 file.write('static void MockInvalidFunction() {\n')
1853 file.write(' NOTREACHED();\n')
1854 file.write('}\n')
1856 # Write a function to lookup a mock GL function based on its name.
1857 file.write('\n')
1858 file.write('void* GL_BINDING_CALL ' +
1859 'MockGLInterface::GetGLProcAddress(const char* name) {\n')
1860 for key in sorted_function_names:
1861 name = uniquely_named_functions[key]['name']
1862 file.write(' if (strcmp(name, "%s") == 0)\n' % name)
1863 file.write(' return reinterpret_cast<void*>(Mock_%s);\n' % name)
1864 # Always return a non-NULL pointer like some EGL implementations do.
1865 file.write(' return reinterpret_cast<void*>(&MockInvalidFunction);\n')
1866 file.write('}\n')
1868 file.write('\n')
1869 file.write('} // namespace gfx\n')
1872 def ParseExtensionFunctionsFromHeader(header_file):
1873 """Parse a C extension header file and return a map from extension names to
1874 a list of functions.
1876 Args:
1877 header_file: Line-iterable C header file.
1878 Returns:
1879 Map of extension name => functions.
1881 extension_start = re.compile(
1882 r'#ifndef ((?:GL|EGL|WGL|GLX)_[A-Z]+_[a-zA-Z]\w+)')
1883 extension_function = re.compile(r'.+\s+([a-z]+\w+)\s*\(')
1884 typedef = re.compile(r'typedef .*')
1885 macro_start = re.compile(r'^#(if|ifdef|ifndef).*')
1886 macro_end = re.compile(r'^#endif.*')
1887 macro_depth = 0
1888 current_extension = None
1889 current_extension_depth = 0
1890 extensions = collections.defaultdict(lambda: [])
1891 for line in header_file:
1892 if macro_start.match(line):
1893 macro_depth += 1
1894 elif macro_end.match(line):
1895 macro_depth -= 1
1896 if macro_depth < current_extension_depth:
1897 current_extension = None
1898 match = extension_start.match(line)
1899 if match:
1900 current_extension = match.group(1)
1901 current_extension_depth = macro_depth
1902 assert current_extension not in extensions, \
1903 "Duplicate extension: " + current_extension
1904 match = extension_function.match(line)
1905 if match and current_extension and not typedef.match(line):
1906 extensions[current_extension].append(match.group(1))
1907 return extensions
1910 def GetExtensionFunctions(extension_headers):
1911 """Parse extension functions from a list of header files.
1913 Args:
1914 extension_headers: List of header file names.
1915 Returns:
1916 Map of extension name => list of functions.
1918 extensions = {}
1919 for header in extension_headers:
1920 extensions.update(ParseExtensionFunctionsFromHeader(open(header)))
1921 return extensions
1924 def GetFunctionToExtensionMap(extensions):
1925 """Construct map from a function names to extensions which define the
1926 function.
1928 Args:
1929 extensions: Map of extension name => functions.
1930 Returns:
1931 Map of function name => extension name.
1933 function_to_extensions = {}
1934 for extension, functions in extensions.items():
1935 for function in functions:
1936 if not function in function_to_extensions:
1937 function_to_extensions[function] = []
1938 function_to_extensions[function].append(extension)
1939 return function_to_extensions
1942 def LooksLikeExtensionFunction(function):
1943 """Heuristic to see if a function name is consistent with extension function
1944 naming."""
1945 vendor = re.match(r'\w+?([A-Z][A-Z]+)$', function)
1946 return vendor is not None and not vendor.group(1) in ['GL', 'API', 'DC']
1949 def FillExtensionsFromHeaders(functions, extension_headers, extra_extensions):
1950 """Determine which functions belong to extensions based on extension headers,
1951 and fill in this information to the functions table for functions that don't
1952 already have the information.
1954 Args:
1955 functions: List of (return type, function versions, arguments).
1956 extension_headers: List of header file names.
1957 extra_extensions: Extensions to add to the list.
1958 Returns:
1959 Set of used extensions.
1961 # Parse known extensions.
1962 extensions = GetExtensionFunctions(extension_headers)
1963 functions_to_extensions = GetFunctionToExtensionMap(extensions)
1965 # Fill in the extension information.
1966 used_extensions = set()
1967 for func in functions:
1968 for version in func['versions']:
1969 name = version['name']
1970 # Make sure we know about all extensions and extension functions.
1971 if 'extensions' in version:
1972 used_extensions.update(version['extensions'])
1973 elif name in functions_to_extensions:
1974 # If there are multiple versions with the same name, assume that they
1975 # already have all the correct conditions, we can't just blindly add
1976 # the same extension conditions to all of them
1977 if len([v for v in func['versions'] if v['name'] == name]) == 1:
1978 version['extensions'] = functions_to_extensions[name]
1979 used_extensions.update(version['extensions'])
1980 elif LooksLikeExtensionFunction(name):
1981 raise RuntimeError('%s looks like an extension function but does not '
1982 'belong to any of the known extensions.' % name)
1984 # Add extensions that do not have any functions.
1985 used_extensions.update(extra_extensions)
1987 return used_extensions
1990 def ResolveHeader(header, header_paths):
1991 paths = header_paths.split(':')
1993 for path in paths:
1994 result = os.path.join(path, header)
1995 if not os.path.isabs(path):
1996 result = os.path.relpath(os.path.join(os.getcwd(), result), os.getcwd())
1997 if os.path.exists(result):
1998 # Always use forward slashes as path separators. Otherwise backslashes
1999 # may be incorrectly interpreted as escape characters.
2000 return result.replace(os.path.sep, '/')
2002 raise Exception('Header %s not found.' % header)
2005 def main(argv):
2006 """This is the main function."""
2008 parser = optparse.OptionParser()
2009 parser.add_option('--inputs', action='store_true')
2010 parser.add_option('--header-paths')
2012 options, args = parser.parse_args(argv)
2014 if options.inputs:
2015 for [_, _, headers, _] in FUNCTION_SETS:
2016 for header in headers:
2017 print ResolveHeader(header, options.header_paths)
2018 return 0
2020 directory = '.'
2021 if len(args) >= 1:
2022 directory = args[0]
2024 for [functions, set_name, extension_headers, extensions] in FUNCTION_SETS:
2025 # Function names can be specified in two ways (list of unique names or list
2026 # of versions with different binding conditions). Fill in the data to the
2027 # versions list in case it is missing, so that can be used from here on:
2028 for func in functions:
2029 assert 'versions' in func or 'names' in func, 'Function with no names'
2030 if 'versions' not in func:
2031 func['versions'] = [{'name': n} for n in func['names']]
2032 # Use the first version's name unless otherwise specified
2033 if 'known_as' not in func:
2034 func['known_as'] = func['versions'][0]['name']
2035 # Make sure that 'names' is not accidentally used instead of 'versions'
2036 if 'names' in func:
2037 del func['names']
2039 extension_headers = [ResolveHeader(h, options.header_paths)
2040 for h in extension_headers]
2041 used_extensions = FillExtensionsFromHeaders(
2042 functions, extension_headers, extensions)
2044 header_file = open(
2045 os.path.join(directory, 'gl_bindings_autogen_%s.h' % set_name), 'wb')
2046 GenerateHeader(header_file, functions, set_name, used_extensions)
2047 header_file.close()
2049 header_file = open(
2050 os.path.join(directory, 'gl_bindings_api_autogen_%s.h' % set_name),
2051 'wb')
2052 GenerateAPIHeader(header_file, functions, set_name)
2053 header_file.close()
2055 source_file = open(
2056 os.path.join(directory, 'gl_bindings_autogen_%s.cc' % set_name), 'wb')
2057 GenerateSource(source_file, functions, set_name, used_extensions)
2058 source_file.close()
2060 header_file = open(
2061 os.path.join(directory, 'gl_mock_autogen_gl.h'), 'wb')
2062 GenerateMockHeader(header_file, GL_FUNCTIONS, 'gl')
2063 header_file.close()
2065 header_file = open(os.path.join(directory, 'gl_bindings_autogen_mock.h'),
2066 'wb')
2067 GenerateMockBindingsHeader(header_file, GL_FUNCTIONS)
2068 header_file.close()
2070 source_file = open(os.path.join(directory, 'gl_bindings_autogen_mock.cc'),
2071 'wb')
2072 GenerateMockBindingsSource(source_file, GL_FUNCTIONS)
2073 source_file.close()
2074 return 0
2077 if __name__ == '__main__':
2078 sys.exit(main(sys.argv[1:]))