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