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