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