1 #!/usr/bin/env python 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 3 # Use of this source code is governed by a BSD-style license that can be 4 # found in the LICENSE file. 5 6 """code generator for GL/GLES extension wrangler.""" 7 8 import optparse 9 import os 10 import collections 11 import re 12 import sys 13 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. 20 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. 30 31 By default, the function gets its name from the first name in its names or 32 versions array. This can be overridden by supplying a 'known_as' key. 33 """ 34 GL_FUNCTIONS = [ 35 { 'return_type': 'void', 36 'names': ['glActiveTexture'], 37 'arguments': 'GLenum texture', }, 38 { 'return_type': 'void', 39 'names': ['glAttachShader'], 40 'arguments': 'GLuint program, GLuint shader', }, 41 { 'return_type': 'void', 42 'names': ['glBeginQuery'], 43 'arguments': 'GLenum target, GLuint id', }, 44 { 'return_type': 'void', 45 'names': ['glBeginQueryARB', 'glBeginQueryEXT'], 46 'arguments': 'GLenum target, GLuint id', }, 47 { 'return_type': 'void', 48 'names': ['glBindAttribLocation'], 49 'arguments': 'GLuint program, GLuint index, const char* name', }, 50 { 'return_type': 'void', 51 'names': ['glBindBuffer'], 52 'arguments': 'GLenum target, GLuint buffer', }, 53 { 'return_type': 'void', 54 'names': ['glBindFragDataLocation'], 55 'arguments': 'GLuint program, GLuint colorNumber, const char* name', }, 56 { 'return_type': 'void', 57 'names': ['glBindFragDataLocationIndexed'], 58 'arguments': 59 'GLuint program, GLuint colorNumber, GLuint index, const char* name', }, 60 { 'return_type': 'void', 61 'names': ['glBindFramebufferEXT', 'glBindFramebuffer'], 62 'arguments': 'GLenum target, GLuint framebuffer', }, 63 { 'return_type': 'void', 64 'names': ['glBindRenderbufferEXT', 'glBindRenderbuffer'], 65 'arguments': 'GLenum target, GLuint renderbuffer', }, 66 { 'return_type': 'void', 67 'names': ['glBindTexture'], 68 'arguments': 'GLenum target, GLuint texture', }, 69 { 'return_type': 'void', 70 'names': ['glBlendColor'], 71 'arguments': 'GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha', }, 72 { 'return_type': 'void', 73 'names': ['glBlendEquation'], 74 'arguments': ' GLenum mode ', }, 75 { 'return_type': 'void', 76 'names': ['glBlendEquationSeparate'], 77 'arguments': 'GLenum modeRGB, GLenum modeAlpha', }, 78 { 'return_type': 'void', 79 'names': ['glBlendFunc'], 80 'arguments': 'GLenum sfactor, GLenum dfactor', }, 81 { 'return_type': 'void', 82 'names': ['glBlendFuncSeparate'], 83 'arguments': 84 'GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha', }, 85 { 'return_type': 'void', 86 'names': ['glBlitFramebuffer'], 87 'arguments': 'GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, ' 88 'GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, ' 89 'GLbitfield mask, GLenum filter', }, 90 { 'return_type': 'void', 91 'names': ['glBlitFramebufferEXT', 'glBlitFramebuffer'], 92 'arguments': 'GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, ' 93 'GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, ' 94 'GLbitfield mask, GLenum filter', }, 95 { 'return_type': 'void', 96 'names': ['glBlitFramebufferANGLE', 'glBlitFramebuffer'], 97 'arguments': 'GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, ' 98 'GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, ' 99 'GLbitfield mask, GLenum filter', }, 100 { 'return_type': 'void', 101 'names': ['glBufferData'], 102 'arguments': 103 'GLenum target, GLsizeiptr size, const void* data, GLenum usage', }, 104 { 'return_type': 'void', 105 'names': ['glBufferSubData'], 106 'arguments': 107 'GLenum target, GLintptr offset, GLsizeiptr size, const void* data', }, 108 { 'return_type': 'GLenum', 109 'names': ['glCheckFramebufferStatusEXT', 110 'glCheckFramebufferStatus'], 111 'arguments': 'GLenum target', 112 'logging_code': """ 113 GL_SERVICE_LOG("GL_RESULT: " << GLES2Util::GetStringEnum(result)); 114 """, }, 115 { 'return_type': 'void', 116 'names': ['glClear'], 117 'arguments': 'GLbitfield mask', }, 118 { 'return_type': 'void', 119 'names': ['glClearColor'], 120 'arguments': 'GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha', }, 121 { 'return_type': 'void', 122 'names': ['glClearDepth'], 123 'arguments': 'GLclampd depth', }, 124 { 'return_type': 'void', 125 'names': ['glClearDepthf'], 126 'arguments': 'GLclampf depth', }, 127 { 'return_type': 'void', 128 'names': ['glClearStencil'], 129 'arguments': 'GLint s', }, 130 { 'return_type': 'void', 131 'names': ['glColorMask'], 132 'arguments': 133 'GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha', }, 134 { 'return_type': 'void', 135 'names': ['glCompileShader'], 136 'arguments': 'GLuint shader', }, 137 { 'return_type': 'void', 138 'names': ['glCompressedTexImage2D'], 139 'arguments': 140 'GLenum target, GLint level, GLenum internalformat, GLsizei width, ' 141 'GLsizei height, GLint border, GLsizei imageSize, const void* data', }, 142 { 'return_type': 'void', 143 'names': ['glCompressedTexSubImage2D'], 144 'arguments': 145 'GLenum target, GLint level, GLint xoffset, GLint yoffset, ' 146 'GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, ' 147 'const void* data', }, 148 { 'return_type': 'void', 149 'names': ['glCopyTexImage2D'], 150 'arguments': 151 'GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, ' 152 'GLsizei width, GLsizei height, GLint border', }, 153 { 'return_type': 'void', 154 'names': ['glCopyTexSubImage2D'], 155 'arguments': 156 'GLenum target, GLint level, GLint xoffset, ' 157 'GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height', }, 158 { 'return_type': 'GLuint', 159 'names': ['glCreateProgram'], 160 'arguments': 'void', }, 161 { 'return_type': 'GLuint', 162 'names': ['glCreateShader'], 163 'arguments': 'GLenum type', }, 164 { 'return_type': 'void', 165 'names': ['glCullFace'], 166 'arguments': 'GLenum mode', }, 167 { 'return_type': 'void', 168 'names': ['glDeleteBuffersARB', 'glDeleteBuffers'], 169 'arguments': 'GLsizei n, const GLuint* buffers', }, 170 { 'return_type': 'void', 171 'names': ['glDeleteFramebuffersEXT', 'glDeleteFramebuffers'], 172 'arguments': 'GLsizei n, const GLuint* framebuffers', }, 173 { 'return_type': 'void', 174 'names': ['glDeleteProgram'], 175 'arguments': 'GLuint program', }, 176 { 'return_type': 'void', 177 'names': ['glDeleteQueries'], 178 'arguments': 'GLsizei n, const GLuint* ids', }, 179 { 'return_type': 'void', 180 'names': ['glDeleteQueriesARB', 'glDeleteQueriesEXT'], 181 'arguments': 'GLsizei n, const GLuint* ids', }, 182 { 'return_type': 'void', 183 'names': ['glDeleteRenderbuffersEXT', 'glDeleteRenderbuffers'], 184 'arguments': 'GLsizei n, const GLuint* renderbuffers', }, 185 { 'return_type': 'void', 186 'names': ['glDeleteShader'], 187 'arguments': 'GLuint shader', }, 188 { 'return_type': 'void', 189 'names': ['glDeleteTextures'], 190 'arguments': 'GLsizei n, const GLuint* textures', }, 191 { 'return_type': 'void', 192 'names': ['glDepthFunc'], 193 'arguments': 'GLenum func', }, 194 { 'return_type': 'void', 195 'names': ['glDepthMask'], 196 'arguments': 'GLboolean flag', }, 197 { 'return_type': 'void', 198 'names': ['glDepthRange'], 199 'arguments': 'GLclampd zNear, GLclampd zFar', }, 200 { 'return_type': 'void', 201 'names': ['glDepthRangef'], 202 'arguments': 'GLclampf zNear, GLclampf zFar', }, 203 { 'return_type': 'void', 204 'names': ['glDetachShader'], 205 'arguments': 'GLuint program, GLuint shader', }, 206 { 'return_type': 'void', 207 'names': ['glDisable'], 208 'arguments': 'GLenum cap', }, 209 { 'return_type': 'void', 210 'names': ['glDisableVertexAttribArray'], 211 'arguments': 'GLuint index', }, 212 { 'return_type': 'void', 213 'names': ['glDrawArrays'], 214 'arguments': 'GLenum mode, GLint first, GLsizei count', }, 215 { 'return_type': 'void', 216 'names': ['glDrawBuffer'], 217 'arguments': 'GLenum mode', }, 218 { 'return_type': 'void', 219 'names': ['glDrawBuffersARB', 'glDrawBuffersEXT'], 220 'arguments': 'GLsizei n, const GLenum* bufs', }, 221 { 'return_type': 'void', 222 'names': ['glDrawElements'], 223 'arguments': 224 'GLenum mode, GLsizei count, GLenum type, const void* indices', }, 225 { 'return_type': 'void', 226 'names': ['glEGLImageTargetTexture2DOES'], 227 'arguments': 'GLenum target, GLeglImageOES image', }, 228 { 'return_type': 'void', 229 'names': ['glEGLImageTargetRenderbufferStorageOES'], 230 'arguments': 'GLenum target, GLeglImageOES image', }, 231 { 'return_type': 'void', 232 'names': ['glEnable'], 233 'arguments': 'GLenum cap', }, 234 { 'return_type': 'void', 235 'names': ['glEnableVertexAttribArray'], 236 'arguments': 'GLuint index', }, 237 { 'return_type': 'void', 238 'names': ['glEndQuery'], 239 'arguments': 'GLenum target', }, 240 { 'return_type': 'void', 241 'names': ['glEndQueryARB', 'glEndQueryEXT'], 242 'arguments': 'GLenum target', }, 243 { 'return_type': 'void', 244 'names': ['glFinish'], 245 'arguments': 'void', }, 246 { 'return_type': 'void', 247 'names': ['glFlush'], 248 'arguments': 'void', }, 249 { 'return_type': 'void', 250 'names': ['glFramebufferRenderbufferEXT', 'glFramebufferRenderbuffer'], 251 'arguments': \ 252 'GLenum target, GLenum attachment, GLenum renderbuffertarget, ' 253 'GLuint renderbuffer', }, 254 { 'return_type': 'void', 255 'names': ['glFramebufferTexture2DEXT', 'glFramebufferTexture2D'], 256 'arguments': 257 'GLenum target, GLenum attachment, GLenum textarget, GLuint texture, ' 258 'GLint level', }, 259 { 'return_type': 'void', 260 'names': ['glFramebufferTexture2DMultisampleEXT'], 261 'arguments': 262 'GLenum target, GLenum attachment, GLenum textarget, GLuint texture, ' 263 'GLint level, GLsizei samples', }, 264 { 'return_type': 'void', 265 'names': ['glFramebufferTexture2DMultisampleIMG'], 266 'arguments': 267 'GLenum target, GLenum attachment, GLenum textarget, GLuint texture, ' 268 'GLint level, GLsizei samples', }, 269 { 'return_type': 'void', 270 'names': ['glFrontFace'], 271 'arguments': 'GLenum mode', }, 272 { 'return_type': 'void', 273 'names': ['glGenBuffersARB', 'glGenBuffers'], 274 'arguments': 'GLsizei n, GLuint* buffers', }, 275 { 'return_type': 'void', 276 'names': ['glGenQueries'], 277 'arguments': 'GLsizei n, GLuint* ids', }, 278 { 'return_type': 'void', 279 'names': ['glGenQueriesARB', 'glGenQueriesEXT'], 280 'arguments': 'GLsizei n, GLuint* ids', }, 281 { 'return_type': 'void', 282 'names': ['glGenerateMipmapEXT', 'glGenerateMipmap'], 283 'arguments': 'GLenum target', }, 284 { 'return_type': 'void', 285 'names': ['glGenFramebuffersEXT', 'glGenFramebuffers'], 286 'arguments': 'GLsizei n, GLuint* framebuffers', }, 287 { 'return_type': 'void', 288 'names': ['glGenRenderbuffersEXT', 'glGenRenderbuffers'], 289 'arguments': 'GLsizei n, GLuint* renderbuffers', }, 290 { 'return_type': 'void', 291 'names': ['glGenTextures'], 292 'arguments': 'GLsizei n, GLuint* textures', }, 293 { 'return_type': 'void', 294 'names': ['glGetActiveAttrib'], 295 'arguments': 296 'GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, ' 297 'GLint* size, GLenum* type, char* name', }, 298 { 'return_type': 'void', 299 'names': ['glGetActiveUniform'], 300 'arguments': 301 'GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, ' 302 'GLint* size, GLenum* type, char* name', }, 303 { 'return_type': 'void', 304 'names': ['glGetAttachedShaders'], 305 'arguments': 306 'GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders', }, 307 { 'return_type': 'GLint', 308 'names': ['glGetAttribLocation'], 309 'arguments': 'GLuint program, const char* name', }, 310 { 'return_type': 'void', 311 'names': ['glGetBooleanv'], 312 'arguments': 'GLenum pname, GLboolean* params', }, 313 { 'return_type': 'void', 314 'names': ['glGetBufferParameteriv'], 315 'arguments': 'GLenum target, GLenum pname, GLint* params', }, 316 { 'return_type': 'GLenum', 317 'names': ['glGetError'], 318 'arguments': 'void', 319 'logging_code': """ 320 GL_SERVICE_LOG("GL_RESULT: " << GLES2Util::GetStringError(result)); 321 """, }, 322 { 'return_type': 'void', 323 'names': ['glGetFloatv'], 324 'arguments': 'GLenum pname, GLfloat* params', }, 325 { 'return_type': 'void', 326 'names': ['glGetFramebufferAttachmentParameterivEXT', 327 'glGetFramebufferAttachmentParameteriv'], 328 'arguments': 'GLenum target, ' 329 'GLenum attachment, GLenum pname, GLint* params', }, 330 { 'return_type': 'GLenum', 331 'names': ['glGetGraphicsResetStatusARB', 332 'glGetGraphicsResetStatusEXT'], 333 'arguments': 'void', }, 334 { 'return_type': 'void', 335 'names': ['glGetIntegerv'], 336 'arguments': 'GLenum pname, GLint* params', }, 337 { 'return_type': 'void', 338 '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'], 353 'arguments': 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'], 385 'arguments': 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'], 393 'arguments': 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'], 412 'arguments': 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', 433 'names': ['glHint'], 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'], 474 'arguments': 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'], 515 'arguments': 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 528 # higher level. 529 # TODO(oetuaho (at] 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 (at] nvidia.com): Right now this function also doubles as ES2 EXT 540 # function, which has implicit resolve, and for which the fallback is wrong. 541 # Fix this. 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'], 558 'arguments': 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', 574 'logging_code': """ 575 GL_SERVICE_LOG_CODE_BLOCK({ 576 for (GLsizei ii = 0; ii < count; ++ii) { 577 if (str[ii]) { 578 if (length && length[ii] >= 0) { 579 std::string source(str[ii], length[ii]); 580 GL_SERVICE_LOG(" " << ii << ": ---\\n" << source << "\\n---"); 581 } else { 582 GL_SERVICE_LOG(" " << ii << ": ---\\n" << str[ii] << "\\n---"); 583 } 584 } else { 585 GL_SERVICE_LOG(" " << ii << ": NULL"); 586 } 587 } 588 }); 589 """, }, 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'], 610 'arguments': 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'], 638 'arguments': 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'], 775 'arguments': 776 'GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length,' 777 'GLint* values', }, 778 { 'return_type': 'GLenum', 779 'names': ['glClientWaitSync'], 780 'arguments': 781 'GLsync sync, GLbitfield flags, GLuint64 timeout', }, 782 { 'return_type': 'GLenum', 783 'names': ['glWaitSync'], 784 'arguments': 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'], 795 'arguments': 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'], 802 'arguments': 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'], 848 'extensions': [] }, 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 ] 872 873 OSMESA_FUNCTIONS = [ 874 { 'return_type': 'OSMesaContext', 875 'names': ['OSMesaCreateContext'], 876 'arguments': 'GLenum format, OSMesaContext sharelist', }, 877 { 'return_type': 'OSMesaContext', 878 'names': ['OSMesaCreateContextExt'], 879 'arguments': 880 'GLenum format, GLint depthBits, GLint stencilBits, GLint accumBits, ' 881 'OSMesaContext sharelist', }, 882 { 'return_type': 'void', 883 'names': ['OSMesaDestroyContext'], 884 'arguments': 'OSMesaContext ctx', }, 885 { 'return_type': 'GLboolean', 886 'names': ['OSMesaMakeCurrent'], 887 'arguments': 'OSMesaContext ctx, void* buffer, GLenum type, GLsizei width, ' 888 'GLsizei height', }, 889 { 'return_type': 'OSMesaContext', 890 'names': ['OSMesaGetCurrentContext'], 891 'arguments': 'void', }, 892 { 'return_type': 'void', 893 'names': ['OSMesaPixelStore'], 894 'arguments': 'GLint pname, GLint value', }, 895 { 'return_type': 'void', 896 'names': ['OSMesaGetIntegerv'], 897 'arguments': 'GLint pname, GLint* value', }, 898 { 'return_type': 'GLboolean', 899 'names': ['OSMesaGetDepthBuffer'], 900 'arguments': 901 'OSMesaContext c, GLint* width, GLint* height, GLint* bytesPerValue, ' 902 'void** buffer', }, 903 { 'return_type': 'GLboolean', 904 'names': ['OSMesaGetColorBuffer'], 905 'arguments': 'OSMesaContext c, GLint* width, GLint* height, GLint* format, ' 906 'void** buffer', }, 907 { 'return_type': 'OSMESAproc', 908 'names': ['OSMesaGetProcAddress'], 909 'arguments': 'const char* funcName', }, 910 { 'return_type': 'void', 911 'names': ['OSMesaColorClamp'], 912 'arguments': 'GLboolean enable', }, 913 ] 914 915 EGL_FUNCTIONS = [ 916 { 'return_type': 'EGLint', 917 'names': ['eglGetError'], 918 'arguments': 'void', }, 919 { 'return_type': 'EGLDisplay', 920 'names': ['eglGetDisplay'], 921 'arguments': 'EGLNativeDisplayType display_id', }, 922 { 'return_type': 'EGLDisplay', 923 'known_as': 'eglGetPlatformDisplayEXT', 924 'versions': [{ 'name': 'eglGetPlatformDisplayEXT', 925 'extensions': ['EGL_ANGLE_platform_angle'] }], 926 'arguments': 'EGLenum platform, void* native_display, ' 927 'const EGLint* attrib_list', }, 928 { 'return_type': 'EGLBoolean', 929 'names': ['eglInitialize'], 930 'arguments': 'EGLDisplay dpy, EGLint* major, EGLint* minor', }, 931 { 'return_type': 'EGLBoolean', 932 'names': ['eglTerminate'], 933 'arguments': 'EGLDisplay dpy', }, 934 { 'return_type': 'const char*', 935 'names': ['eglQueryString'], 936 'arguments': 'EGLDisplay dpy, EGLint name', }, 937 { 'return_type': 'EGLBoolean', 938 'names': ['eglGetConfigs'], 939 'arguments': 'EGLDisplay dpy, EGLConfig* configs, EGLint config_size, ' 940 'EGLint* num_config', }, 941 { 'return_type': 'EGLBoolean', 942 'names': ['eglChooseConfig'], 943 'arguments': 'EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, ' 944 'EGLint config_size, EGLint* num_config', }, 945 { 'return_type': 'EGLBoolean', 946 'names': ['eglGetConfigAttrib'], 947 'arguments': 948 'EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value', }, 949 { 'return_type': 'EGLImageKHR', 950 'versions': [{ 'name': 'eglCreateImageKHR', 951 'extensions': 952 ['EGL_KHR_image_base', 'EGL_KHR_gl_texture_2D_image'] }], 953 'arguments': 954 'EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, ' 955 'const EGLint* attrib_list' }, 956 { 'return_type': 'EGLBoolean', 957 'versions': [{ 'name' : 'eglDestroyImageKHR', 958 'extensions': ['EGL_KHR_image_base'] }], 959 'arguments': 'EGLDisplay dpy, EGLImageKHR image' }, 960 { 'return_type': 'EGLSurface', 961 'names': ['eglCreateWindowSurface'], 962 'arguments': 'EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, ' 963 'const EGLint* attrib_list', }, 964 { 'return_type': 'EGLSurface', 965 'names': ['eglCreatePbufferSurface'], 966 'arguments': 'EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list', }, 967 { 'return_type': 'EGLSurface', 968 'names': ['eglCreatePixmapSurface'], 969 'arguments': 'EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, ' 970 'const EGLint* attrib_list', }, 971 { 'return_type': 'EGLBoolean', 972 'names': ['eglDestroySurface'], 973 'arguments': 'EGLDisplay dpy, EGLSurface surface', }, 974 { 'return_type': 'EGLBoolean', 975 'names': ['eglQuerySurface'], 976 'arguments': 977 'EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint* value', }, 978 { 'return_type': 'EGLBoolean', 979 'names': ['eglBindAPI'], 980 'arguments': 'EGLenum api', }, 981 { 'return_type': 'EGLenum', 982 'names': ['eglQueryAPI'], 983 'arguments': 'void', }, 984 { 'return_type': 'EGLBoolean', 985 'names': ['eglWaitClient'], 986 'arguments': 'void', }, 987 { 'return_type': 'EGLBoolean', 988 'names': ['eglReleaseThread'], 989 'arguments': 'void', }, 990 { 'return_type': 'EGLSurface', 991 'names': ['eglCreatePbufferFromClientBuffer'], 992 'arguments': 993 'EGLDisplay dpy, EGLenum buftype, void* buffer, EGLConfig config, ' 994 'const EGLint* attrib_list', }, 995 { 'return_type': 'EGLBoolean', 996 'names': ['eglSurfaceAttrib'], 997 'arguments': 998 'EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value', }, 999 { 'return_type': 'EGLBoolean', 1000 'names': ['eglBindTexImage'], 1001 'arguments': 'EGLDisplay dpy, EGLSurface surface, EGLint buffer', }, 1002 { 'return_type': 'EGLBoolean', 1003 'names': ['eglReleaseTexImage'], 1004 'arguments': 'EGLDisplay dpy, EGLSurface surface, EGLint buffer', }, 1005 { 'return_type': 'EGLBoolean', 1006 'names': ['eglSwapInterval'], 1007 'arguments': 'EGLDisplay dpy, EGLint interval', }, 1008 { 'return_type': 'EGLContext', 1009 'names': ['eglCreateContext'], 1010 'arguments': 'EGLDisplay dpy, EGLConfig config, EGLContext share_context, ' 1011 'const EGLint* attrib_list', }, 1012 { 'return_type': 'EGLBoolean', 1013 'names': ['eglDestroyContext'], 1014 'arguments': 'EGLDisplay dpy, EGLContext ctx', }, 1015 { 'return_type': 'EGLBoolean', 1016 'names': ['eglMakeCurrent'], 1017 'arguments': 1018 'EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx', }, 1019 { 'return_type': 'EGLContext', 1020 'names': ['eglGetCurrentContext'], 1021 'arguments': 'void', }, 1022 { 'return_type': 'EGLSurface', 1023 'names': ['eglGetCurrentSurface'], 1024 'arguments': 'EGLint readdraw', }, 1025 { 'return_type': 'EGLDisplay', 1026 'names': ['eglGetCurrentDisplay'], 1027 'arguments': 'void', }, 1028 { 'return_type': 'EGLBoolean', 1029 'names': ['eglQueryContext'], 1030 'arguments': 1031 'EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value', }, 1032 { 'return_type': 'EGLBoolean', 1033 'names': ['eglWaitGL'], 1034 'arguments': 'void', }, 1035 { 'return_type': 'EGLBoolean', 1036 'names': ['eglWaitNative'], 1037 'arguments': 'EGLint engine', }, 1038 { 'return_type': 'EGLBoolean', 1039 'names': ['eglSwapBuffers'], 1040 'arguments': 'EGLDisplay dpy, EGLSurface surface', }, 1041 { 'return_type': 'EGLBoolean', 1042 'names': ['eglCopyBuffers'], 1043 'arguments': 1044 'EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target', }, 1045 { 'return_type': '__eglMustCastToProperFunctionPointerType', 1046 'names': ['eglGetProcAddress'], 1047 'arguments': 'const char* procname', }, 1048 { 'return_type': 'EGLBoolean', 1049 'names': ['eglPostSubBufferNV'], 1050 'arguments': 'EGLDisplay dpy, EGLSurface surface, ' 1051 'EGLint x, EGLint y, EGLint width, EGLint height', }, 1052 { 'return_type': 'EGLBoolean', 1053 'names': ['eglQuerySurfacePointerANGLE'], 1054 'arguments': 1055 'EGLDisplay dpy, EGLSurface surface, EGLint attribute, void** value', }, 1056 { 'return_type': 'EGLSyncKHR', 1057 'versions': [{ 'name': 'eglCreateSyncKHR', 1058 'extensions': ['EGL_KHR_fence_sync'] }], 1059 'arguments': 'EGLDisplay dpy, EGLenum type, const EGLint* attrib_list' }, 1060 { 'return_type': 'EGLint', 1061 'versions': [{ 'name': 'eglClientWaitSyncKHR', 1062 'extensions': ['EGL_KHR_fence_sync'] }], 1063 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, ' 1064 'EGLTimeKHR timeout' }, 1065 { 'return_type': 'EGLBoolean', 1066 'versions': [{ 'name': 'eglGetSyncAttribKHR', 1067 'extensions': ['EGL_KHR_fence_sync'] }], 1068 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, ' 1069 'EGLint* value' }, 1070 { 'return_type': 'EGLBoolean', 1071 'versions': [{ 'name': 'eglDestroySyncKHR', 1072 'extensions': ['EGL_KHR_fence_sync'] }], 1073 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync' }, 1074 { 'return_type': 'EGLBoolean', 1075 'names': ['eglGetSyncValuesCHROMIUM'], 1076 'arguments': 1077 'EGLDisplay dpy, EGLSurface surface, ' 1078 'EGLuint64CHROMIUM* ust, EGLuint64CHROMIUM* msc, ' 1079 'EGLuint64CHROMIUM* sbc', }, 1080 { 'return_type': 'EGLint', 1081 'versions': [{ 'name': 'eglWaitSyncKHR', 1082 'extensions': ['EGL_KHR_fence_sync', 'EGL_KHR_wait_sync'] }], 1083 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint flags' } 1084 ] 1085 1086 WGL_FUNCTIONS = [ 1087 { 'return_type': 'HGLRC', 1088 'names': ['wglCreateContext'], 1089 'arguments': 'HDC hdc', }, 1090 { 'return_type': 'HGLRC', 1091 'names': ['wglCreateLayerContext'], 1092 'arguments': 'HDC hdc, int iLayerPlane', }, 1093 { 'return_type': 'BOOL', 1094 'names': ['wglCopyContext'], 1095 'arguments': 'HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask', }, 1096 { 'return_type': 'BOOL', 1097 'names': ['wglDeleteContext'], 1098 'arguments': 'HGLRC hglrc', }, 1099 { 'return_type': 'HGLRC', 1100 'names': ['wglGetCurrentContext'], 1101 'arguments': '', }, 1102 { 'return_type': 'HDC', 1103 'names': ['wglGetCurrentDC'], 1104 'arguments': '', }, 1105 { 'return_type': 'BOOL', 1106 'names': ['wglMakeCurrent'], 1107 'arguments': 'HDC hdc, HGLRC hglrc', }, 1108 { 'return_type': 'BOOL', 1109 'names': ['wglShareLists'], 1110 'arguments': 'HGLRC hglrc1, HGLRC hglrc2', }, 1111 { 'return_type': 'BOOL', 1112 'names': ['wglSwapIntervalEXT'], 1113 'arguments': 'int interval', }, 1114 { 'return_type': 'BOOL', 1115 'names': ['wglSwapLayerBuffers'], 1116 'arguments': 'HDC hdc, UINT fuPlanes', }, 1117 { 'return_type': 'const char*', 1118 'names': ['wglGetExtensionsStringARB'], 1119 'arguments': 'HDC hDC', }, 1120 { 'return_type': 'const char*', 1121 'names': ['wglGetExtensionsStringEXT'], 1122 'arguments': '', }, 1123 { 'return_type': 'BOOL', 1124 'names': ['wglChoosePixelFormatARB'], 1125 'arguments': 1126 'HDC dc, const int* int_attrib_list, const float* float_attrib_list, ' 1127 'UINT max_formats, int* formats, UINT* num_formats', }, 1128 { 'return_type': 'HPBUFFERARB', 1129 'names': ['wglCreatePbufferARB'], 1130 'arguments': 'HDC hDC, int iPixelFormat, int iWidth, int iHeight, ' 1131 'const int* piAttribList', }, 1132 { 'return_type': 'HDC', 1133 'names': ['wglGetPbufferDCARB'], 1134 'arguments': 'HPBUFFERARB hPbuffer', }, 1135 { 'return_type': 'int', 1136 'names': ['wglReleasePbufferDCARB'], 1137 'arguments': 'HPBUFFERARB hPbuffer, HDC hDC', }, 1138 { 'return_type': 'BOOL', 1139 'names': ['wglDestroyPbufferARB'], 1140 'arguments': 'HPBUFFERARB hPbuffer', }, 1141 { 'return_type': 'BOOL', 1142 'names': ['wglQueryPbufferARB'], 1143 'arguments': 'HPBUFFERARB hPbuffer, int iAttribute, int* piValue', }, 1144 ] 1145 1146 GLX_FUNCTIONS = [ 1147 { 'return_type': 'int', 1148 'names': ['glXWaitVideoSyncSGI'], 1149 'arguments': 'int divisor, int remainder, unsigned int* count', }, 1150 { 'return_type': 'XVisualInfo*', 1151 'names': ['glXChooseVisual'], 1152 'arguments': 'Display* dpy, int screen, int* attribList', }, 1153 { 'return_type': 'void', 1154 'names': ['glXCopySubBufferMESA'], 1155 'arguments': 'Display* dpy, GLXDrawable drawable, ' 1156 'int x, int y, int width, int height', }, 1157 { 'return_type': 'GLXContext', 1158 'names': ['glXCreateContext'], 1159 'arguments': 1160 'Display* dpy, XVisualInfo* vis, GLXContext shareList, int direct', }, 1161 { 'return_type': 'void', 1162 'names': ['glXBindTexImageEXT'], 1163 'arguments': 1164 'Display* dpy, GLXDrawable drawable, int buffer, int* attribList', }, 1165 { 'return_type': 'void', 1166 'names': ['glXReleaseTexImageEXT'], 1167 'arguments': 'Display* dpy, GLXDrawable drawable, int buffer', }, 1168 { 'return_type': 'void', 1169 'names': ['glXDestroyContext'], 1170 'arguments': 'Display* dpy, GLXContext ctx', }, 1171 { 'return_type': 'int', 1172 'names': ['glXMakeCurrent'], 1173 'arguments': 'Display* dpy, GLXDrawable drawable, GLXContext ctx', }, 1174 { 'return_type': 'void', 1175 'names': ['glXCopyContext'], 1176 'arguments': 1177 'Display* dpy, GLXContext src, GLXContext dst, unsigned long mask', }, 1178 { 'return_type': 'void', 1179 'names': ['glXSwapBuffers'], 1180 'arguments': 'Display* dpy, GLXDrawable drawable', }, 1181 { 'return_type': 'GLXPixmap', 1182 'names': ['glXCreateGLXPixmap'], 1183 'arguments': 'Display* dpy, XVisualInfo* visual, Pixmap pixmap', }, 1184 { 'return_type': 'void', 1185 'names': ['glXDestroyGLXPixmap'], 1186 'arguments': 'Display* dpy, GLXPixmap pixmap', }, 1187 { 'return_type': 'int', 1188 'names': ['glXQueryExtension'], 1189 'arguments': 'Display* dpy, int* errorb, int* event', }, 1190 { 'return_type': 'int', 1191 'names': ['glXQueryVersion'], 1192 'arguments': 'Display* dpy, int* maj, int* min', }, 1193 { 'return_type': 'int', 1194 'names': ['glXIsDirect'], 1195 'arguments': 'Display* dpy, GLXContext ctx', }, 1196 { 'return_type': 'int', 1197 'names': ['glXGetConfig'], 1198 'arguments': 'Display* dpy, XVisualInfo* visual, int attrib, int* value', }, 1199 { 'return_type': 'GLXContext', 1200 'names': ['glXGetCurrentContext'], 1201 'arguments': 'void', }, 1202 { 'return_type': 'GLXDrawable', 1203 'names': ['glXGetCurrentDrawable'], 1204 'arguments': 'void', }, 1205 { 'return_type': 'void', 1206 'names': ['glXWaitGL'], 1207 'arguments': 'void', }, 1208 { 'return_type': 'void', 1209 'names': ['glXWaitX'], 1210 'arguments': 'void', }, 1211 { 'return_type': 'void', 1212 'names': ['glXUseXFont'], 1213 'arguments': 'Font font, int first, int count, int list', }, 1214 { 'return_type': 'const char*', 1215 'names': ['glXQueryExtensionsString'], 1216 'arguments': 'Display* dpy, int screen', }, 1217 { 'return_type': 'const char*', 1218 'names': ['glXQueryServerString'], 1219 'arguments': 'Display* dpy, int screen, int name', }, 1220 { 'return_type': 'const char*', 1221 'names': ['glXGetClientString'], 1222 'arguments': 'Display* dpy, int name', }, 1223 { 'return_type': 'Display*', 1224 'names': ['glXGetCurrentDisplay'], 1225 'arguments': 'void', }, 1226 { 'return_type': 'GLXFBConfig*', 1227 'names': ['glXChooseFBConfig'], 1228 'arguments': 1229 'Display* dpy, int screen, const int* attribList, int* nitems', }, 1230 { 'return_type': 'int', 1231 'names': ['glXGetFBConfigAttrib'], 1232 'arguments': 'Display* dpy, GLXFBConfig config, int attribute, int* value', }, 1233 { 'return_type': 'GLXFBConfig*', 1234 'names': ['glXGetFBConfigs'], 1235 'arguments': 'Display* dpy, int screen, int* nelements', }, 1236 { 'return_type': 'XVisualInfo*', 1237 'names': ['glXGetVisualFromFBConfig'], 1238 'arguments': 'Display* dpy, GLXFBConfig config', }, 1239 { 'return_type': 'GLXWindow', 1240 'names': ['glXCreateWindow'], 1241 'arguments': 1242 'Display* dpy, GLXFBConfig config, Window win, const int* attribList', }, 1243 { 'return_type': 'void', 1244 'names': ['glXDestroyWindow'], 1245 'arguments': 'Display* dpy, GLXWindow window', }, 1246 { 'return_type': 'GLXPixmap', 1247 'names': ['glXCreatePixmap'], 1248 'arguments': 'Display* dpy, GLXFBConfig config, ' 1249 'Pixmap pixmap, const int* attribList', }, 1250 { 'return_type': 'void', 1251 'names': ['glXDestroyPixmap'], 1252 'arguments': 'Display* dpy, GLXPixmap pixmap', }, 1253 { 'return_type': 'GLXPbuffer', 1254 'names': ['glXCreatePbuffer'], 1255 'arguments': 'Display* dpy, GLXFBConfig config, const int* attribList', }, 1256 { 'return_type': 'void', 1257 'names': ['glXDestroyPbuffer'], 1258 'arguments': 'Display* dpy, GLXPbuffer pbuf', }, 1259 { 'return_type': 'void', 1260 'names': ['glXQueryDrawable'], 1261 'arguments': 1262 'Display* dpy, GLXDrawable draw, int attribute, unsigned int* value', }, 1263 { 'return_type': 'GLXContext', 1264 'names': ['glXCreateNewContext'], 1265 'arguments': 'Display* dpy, GLXFBConfig config, int renderType, ' 1266 'GLXContext shareList, int direct', }, 1267 { 'return_type': 'int', 1268 'names': ['glXMakeContextCurrent'], 1269 'arguments': 1270 'Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx', }, 1271 { 'return_type': 'GLXDrawable', 1272 'names': ['glXGetCurrentReadDrawable'], 1273 'arguments': 'void', }, 1274 { 'return_type': 'int', 1275 'names': ['glXQueryContext'], 1276 'arguments': 'Display* dpy, GLXContext ctx, int attribute, int* value', }, 1277 { 'return_type': 'void', 1278 'names': ['glXSelectEvent'], 1279 'arguments': 'Display* dpy, GLXDrawable drawable, unsigned long mask', }, 1280 { 'return_type': 'void', 1281 'names': ['glXGetSelectedEvent'], 1282 'arguments': 'Display* dpy, GLXDrawable drawable, unsigned long* mask', }, 1283 { 'return_type': 'void', 1284 'names': ['glXSwapIntervalMESA'], 1285 'arguments': 'unsigned int interval', }, 1286 { 'return_type': 'void', 1287 'names': ['glXSwapIntervalEXT'], 1288 'arguments': 'Display* dpy, GLXDrawable drawable, int interval', }, 1289 { 'return_type': 'GLXFBConfig', 1290 'names': ['glXGetFBConfigFromVisualSGIX'], 1291 'arguments': 'Display* dpy, XVisualInfo* visualInfo', }, 1292 { 'return_type': 'GLXContext', 1293 'names': ['glXCreateContextAttribsARB'], 1294 'arguments': 1295 'Display* dpy, GLXFBConfig config, GLXContext share_context, int direct, ' 1296 'const int* attrib_list', }, 1297 { 'return_type': 'bool', 1298 'names': ['glXGetSyncValuesOML'], 1299 'arguments': 1300 'Display* dpy, GLXDrawable drawable, int64* ust, int64* msc, ' 1301 'int64* sbc' }, 1302 { 'return_type': 'bool', 1303 'names': ['glXGetMscRateOML'], 1304 'arguments': 1305 'Display* dpy, GLXDrawable drawable, int32* numerator, ' 1306 'int32* denominator' }, 1307 ] 1308 1309 FUNCTION_SETS = [ 1310 [GL_FUNCTIONS, 'gl', [ 1311 'GL/glext.h', 1312 'GLES2/gl2ext.h', 1313 # Files below are Chromium-specific and shipped with Chromium sources. 1314 'GL/glextchromium.h', 1315 'GLES2/gl2chromium.h', 1316 'GLES2/gl2extchromium.h' 1317 ], []], 1318 [OSMESA_FUNCTIONS, 'osmesa', [], []], 1319 [EGL_FUNCTIONS, 'egl', [ 1320 'EGL/eglext.h', 1321 # Files below are Chromium-specific and shipped with Chromium sources. 1322 'EGL/eglextchromium.h', 1323 ], 1324 [ 1325 'EGL_ANGLE_d3d_share_handle_client_buffer', 1326 'EGL_ANGLE_surface_d3d_texture_2d_share_handle', 1327 ], 1328 ], 1329 [WGL_FUNCTIONS, 'wgl', ['GL/wglext.h'], []], 1330 [GLX_FUNCTIONS, 'glx', ['GL/glx.h', 'GL/glxext.h'], []], 1331 ] 1332 1333 def GenerateHeader(file, functions, set_name, used_extensions): 1334 """Generates gl_bindings_autogen_x.h""" 1335 1336 # Write file header. 1337 file.write( 1338 """// Copyright (c) 2012 The Chromium Authors. All rights reserved. 1339 // Use of this source code is governed by a BSD-style license that can be 1340 // found in the LICENSE file. 1341 1342 // This file is automatically generated. 1343 1344 #ifndef UI_GFX_GL_GL_BINDINGS_AUTOGEN_%(name)s_H_ 1345 #define UI_GFX_GL_GL_BINDINGS_AUTOGEN_%(name)s_H_ 1346 1347 namespace gfx { 1348 1349 class GLContext; 1350 1351 """ % {'name': set_name.upper()}) 1352 1353 # Write typedefs for function pointer types. Always use the GL name for the 1354 # typedef. 1355 file.write('\n') 1356 for func in functions: 1357 file.write('typedef %s (GL_BINDING_CALL *%sProc)(%s);\n' % 1358 (func['return_type'], func['known_as'], func['arguments'])) 1359 1360 # Write declarations for booleans indicating which extensions are available. 1361 file.write('\n') 1362 file.write("struct Extensions%s {\n" % set_name.upper()) 1363 for extension in sorted(used_extensions): 1364 file.write(' bool b_%s;\n' % extension) 1365 file.write('};\n') 1366 file.write('\n') 1367 1368 # Write Procs struct. 1369 file.write("struct Procs%s {\n" % set_name.upper()) 1370 for func in functions: 1371 file.write(' %sProc %sFn;\n' % (func['known_as'], func['known_as'])) 1372 file.write('};\n') 1373 file.write('\n') 1374 1375 # Write Api class. 1376 file.write( 1377 """class GL_EXPORT %(name)sApi { 1378 public: 1379 %(name)sApi(); 1380 virtual ~%(name)sApi(); 1381 1382 """ % {'name': set_name.upper()}) 1383 for func in functions: 1384 file.write(' virtual %s %sFn(%s) = 0;\n' % 1385 (func['return_type'], func['known_as'], func['arguments'])) 1386 file.write('};\n') 1387 file.write('\n') 1388 1389 file.write( '} // namespace gfx\n') 1390 1391 # Write macros to invoke function pointers. Always use the GL name for the 1392 # macro. 1393 file.write('\n') 1394 for func in functions: 1395 file.write('#define %s ::gfx::g_current_%s_context->%sFn\n' % 1396 (func['known_as'], set_name.lower(), func['known_as'])) 1397 1398 file.write('\n') 1399 file.write('#endif // UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' % 1400 set_name.upper()) 1401 1402 1403 def GenerateAPIHeader(file, functions, set_name): 1404 """Generates gl_bindings_api_autogen_x.h""" 1405 1406 # Write file header. 1407 file.write( 1408 """// Copyright (c) 2012 The Chromium Authors. All rights reserved. 1409 // Use of this source code is governed by a BSD-style license that can be 1410 // found in the LICENSE file. 1411 1412 // This file is automatically generated. 1413 1414 """ % {'name': set_name.upper()}) 1415 1416 # Write API declaration. 1417 for func in functions: 1418 file.write(' virtual %s %sFn(%s) OVERRIDE;\n' % 1419 (func['return_type'], func['known_as'], func['arguments'])) 1420 1421 file.write('\n') 1422 1423 1424 def GenerateMockHeader(file, functions, set_name): 1425 """Generates gl_mock_autogen_x.h""" 1426 1427 # Write file header. 1428 file.write( 1429 """// Copyright (c) 2012 The Chromium Authors. All rights reserved. 1430 // Use of this source code is governed by a BSD-style license that can be 1431 // found in the LICENSE file. 1432 1433 // This file is automatically generated. 1434 1435 """ % {'name': set_name.upper()}) 1436 1437 # Write API declaration. 1438 for func in functions: 1439 args = func['arguments'] 1440 if args == 'void': 1441 args = '' 1442 arg_count = 0 1443 if len(args): 1444 arg_count = func['arguments'].count(',') + 1 1445 file.write(' MOCK_METHOD%d(%s, %s(%s));\n' % 1446 (arg_count, func['known_as'][2:], func['return_type'], args)) 1447 1448 file.write('\n') 1449 1450 1451 def GenerateSource(file, functions, set_name, used_extensions): 1452 """Generates gl_bindings_autogen_x.cc""" 1453 1454 # Write file header. 1455 file.write( 1456 """// Copyright (c) 2011 The Chromium Authors. All rights reserved. 1457 // Use of this source code is governed by a BSD-style license that can be 1458 // found in the LICENSE file. 1459 1460 // This file is automatically generated. 1461 1462 #include <string> 1463 #include "base/debug/trace_event.h" 1464 #include "gpu/command_buffer/common/gles2_cmd_utils.h" 1465 #include "ui/gl/gl_bindings.h" 1466 #include "ui/gl/gl_context.h" 1467 #include "ui/gl/gl_implementation.h" 1468 #include "ui/gl/gl_version_info.h" 1469 #include "ui/gl/gl_%s_api_implementation.h" 1470 1471 using gpu::gles2::GLES2Util; 1472 1473 namespace gfx { 1474 """ % set_name.lower()) 1475 1476 file.write('\n') 1477 file.write('static bool g_debugBindingsInitialized;\n') 1478 file.write('Driver%s g_driver_%s;\n' % (set_name.upper(), set_name.lower())) 1479 file.write('\n') 1480 1481 # Write stub functions that take the place of some functions before a context 1482 # is initialized. This is done to provide clear asserts on debug build and to 1483 # avoid crashing in case of a bug on release build. 1484 file.write('\n') 1485 for func in functions: 1486 unique_names = set([version['name'] for version in func['versions']]) 1487 if len(unique_names) > 1: 1488 file.write('%s %sNotBound(%s) {\n' % 1489 (func['return_type'], func['known_as'], func['arguments'])) 1490 file.write(' NOTREACHED();\n') 1491 return_type = func['return_type'].lower() 1492 # Returning 0 works for booleans, integers and pointers. 1493 if return_type != 'void': 1494 file.write(' return 0;\n') 1495 file.write('}\n') 1496 1497 # Write function to initialize the function pointers that are always the same 1498 # and to initialize bindings where choice of the function depends on the 1499 # extension string or the GL version to point to stub functions. 1500 file.write('\n') 1501 file.write('void Driver%s::InitializeStaticBindings() {\n' % 1502 set_name.upper()) 1503 1504 def WriteFuncBinding(file, known_as, version_name): 1505 file.write( 1506 ' fn.%sFn = reinterpret_cast<%sProc>(GetGLProcAddress("%s"));\n' % 1507 (known_as, known_as, version_name)) 1508 1509 for func in functions: 1510 unique_names = set([version['name'] for version in func['versions']]) 1511 if len(unique_names) == 1: 1512 WriteFuncBinding(file, func['known_as'], func['known_as']) 1513 else: 1514 file.write(' fn.%sFn = reinterpret_cast<%sProc>(%sNotBound);\n' % 1515 (func['known_as'], func['known_as'], func['known_as'])) 1516 1517 file.write('}\n') 1518 file.write('\n') 1519 1520 # Write function to initialize bindings where choice of the function depends 1521 # on the extension string or the GL version. 1522 file.write("""void Driver%s::InitializeDynamicBindings(GLContext* context) { 1523 DCHECK(context && context->IsCurrent(NULL)); 1524 const GLVersionInfo* ver ALLOW_UNUSED = context->GetVersionInfo(); 1525 std::string extensions ALLOW_UNUSED = context->GetExtensions(); 1526 extensions += " "; 1527 1528 """ % set_name.upper()) 1529 for extension in sorted(used_extensions): 1530 # Extra space at the end of the extension name is intentional, it is used 1531 # as a separator 1532 file.write(' ext.b_%s = extensions.find("%s ") != std::string::npos;\n' % 1533 (extension, extension)) 1534 1535 def WrapOr(cond): 1536 if ' || ' in cond: 1537 return '(%s)' % cond 1538 return cond 1539 1540 def WrapAnd(cond): 1541 if ' && ' in cond: 1542 return '(%s)' % cond 1543 return cond 1544 1545 def VersionCondition(version): 1546 conditions = [] 1547 if 'gl_versions' in version: 1548 gl_versions = version['gl_versions'] 1549 version_cond = ' || '.join(['ver->is_%s' % gl for gl in gl_versions]) 1550 conditions.append(WrapOr(version_cond)) 1551 if 'extensions' in version and version['extensions']: 1552 ext_cond = ' || '.join(['ext.b_%s' % e for e in version['extensions']]) 1553 conditions.append(WrapOr(ext_cond)) 1554 return ' && '.join(conditions) 1555 1556 def WriteConditionalFuncBinding(file, func): 1557 # Functions with only one version are always bound unconditionally 1558 assert len(func['versions']) > 1 1559 known_as = func['known_as'] 1560 i = 0 1561 first_version = True 1562 while i < len(func['versions']): 1563 version = func['versions'][i] 1564 cond = VersionCondition(version) 1565 combined_conditions = [WrapAnd(cond)] 1566 last_version = i + 1 == len(func['versions']) 1567 while not last_version and \ 1568 func['versions'][i + 1]['name'] == version['name']: 1569 i += 1 1570 combinable_cond = VersionCondition(func['versions'][i]) 1571 combined_conditions.append(WrapAnd(combinable_cond)) 1572 last_version = i + 1 == len(func['versions']) 1573 if len(combined_conditions) > 1: 1574 if [1 for cond in combined_conditions if cond == '']: 1575 cond = '' 1576 else: 1577 cond = ' || '.join(combined_conditions) 1578 # Don't make the last possible binding conditional on anything else but 1579 # that the function isn't already bound to avoid verbose specification 1580 # of functions which have both ARB and core versions with the same name, 1581 # and to be able to bind to mock extension functions in unit tests which 1582 # call InitializeDynamicGLBindings with a stub context that doesn't have 1583 # extensions in its extension string. 1584 # TODO(oetuaho (at] nvidia.com): Get rid of the fallback. 1585 # http://crbug.com/325668 1586 if cond != '' and not last_version: 1587 if not first_version: 1588 file.write(' if (!fn.%sFn && (%s))\n ' % (known_as, cond)) 1589 else: 1590 file.write(' if (%s)\n ' % cond) 1591 elif not first_version: 1592 file.write(' if (!fn.%sFn)\n ' % known_as) 1593 WriteFuncBinding(file, known_as, version['name']) 1594 i += 1 1595 first_version = False 1596 1597 for func in functions: 1598 unique_names = set([version['name'] for version in func['versions']]) 1599 if len(unique_names) > 1: 1600 file.write('\n') 1601 file.write(' fn.%sFn = 0;\n' % func['known_as']) 1602 file.write(' debug_fn.%sFn = 0;\n' % func['known_as']) 1603 WriteConditionalFuncBinding(file, func) 1604 1605 # Some new function pointers have been added, so update them in debug bindings 1606 file.write('\n') 1607 file.write(' if (g_debugBindingsInitialized)\n') 1608 file.write(' InitializeDebugBindings();\n') 1609 file.write('}\n') 1610 file.write('\n') 1611 1612 # Write logging wrappers for each function. 1613 file.write('extern "C" {\n') 1614 for func in functions: 1615 return_type = func['return_type'] 1616 arguments = func['arguments'] 1617 file.write('\n') 1618 file.write('static %s GL_BINDING_CALL Debug_%s(%s) {\n' % 1619 (return_type, func['known_as'], arguments)) 1620 argument_names = re.sub( 1621 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', arguments) 1622 argument_names = re.sub( 1623 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', argument_names) 1624 log_argument_names = re.sub( 1625 r'const char\* ([a-zA-Z0-9_]+)', r'CONSTCHAR_\1', arguments) 1626 log_argument_names = re.sub( 1627 r'(const )?[a-zA-Z0-9_]+\* ([a-zA-Z0-9_]+)', 1628 r'CONSTVOID_\2', log_argument_names) 1629 log_argument_names = re.sub( 1630 r'(?<!E)GLenum ([a-zA-Z0-9_]+)', r'GLenum_\1', log_argument_names) 1631 log_argument_names = re.sub( 1632 r'(?<!E)GLboolean ([a-zA-Z0-9_]+)', r'GLboolean_\1', log_argument_names) 1633 log_argument_names = re.sub( 1634 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', 1635 log_argument_names) 1636 log_argument_names = re.sub( 1637 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', 1638 log_argument_names) 1639 log_argument_names = re.sub( 1640 r'CONSTVOID_([a-zA-Z0-9_]+)', 1641 r'static_cast<const void*>(\1)', log_argument_names) 1642 log_argument_names = re.sub( 1643 r'CONSTCHAR_([a-zA-Z0-9_]+)', r'\1', log_argument_names) 1644 log_argument_names = re.sub( 1645 r'GLenum_([a-zA-Z0-9_]+)', r'GLES2Util::GetStringEnum(\1)', 1646 log_argument_names) 1647 log_argument_names = re.sub( 1648 r'GLboolean_([a-zA-Z0-9_]+)', r'GLES2Util::GetStringBool(\1)', 1649 log_argument_names) 1650 log_argument_names = log_argument_names.replace(',', ' << ", " <<') 1651 if argument_names == 'void' or argument_names == '': 1652 argument_names = '' 1653 log_argument_names = '' 1654 else: 1655 log_argument_names = " << " + log_argument_names 1656 function_name = func['known_as'] 1657 if return_type == 'void': 1658 file.write(' GL_SERVICE_LOG("%s" << "(" %s << ")");\n' % 1659 (function_name, log_argument_names)) 1660 file.write(' g_driver_%s.debug_fn.%sFn(%s);\n' % 1661 (set_name.lower(), function_name, argument_names)) 1662 if 'logging_code' in func: 1663 file.write("%s\n" % func['logging_code']) 1664 else: 1665 file.write(' GL_SERVICE_LOG("%s" << "(" %s << ")");\n' % 1666 (function_name, log_argument_names)) 1667 file.write(' %s result = g_driver_%s.debug_fn.%sFn(%s);\n' % 1668 (return_type, set_name.lower(), function_name, argument_names)) 1669 if 'logging_code' in func: 1670 file.write("%s\n" % func['logging_code']) 1671 else: 1672 file.write(' GL_SERVICE_LOG("GL_RESULT: " << result);\n') 1673 file.write(' return result;\n') 1674 file.write('}\n') 1675 file.write('} // extern "C"\n') 1676 1677 # Write function to initialize the debug function pointers. 1678 file.write('\n') 1679 file.write('void Driver%s::InitializeDebugBindings() {\n' % 1680 set_name.upper()) 1681 for func in functions: 1682 first_name = func['known_as'] 1683 file.write(' if (!debug_fn.%sFn) {\n' % first_name) 1684 file.write(' debug_fn.%sFn = fn.%sFn;\n' % (first_name, first_name)) 1685 file.write(' fn.%sFn = Debug_%s;\n' % (first_name, first_name)) 1686 file.write(' }\n') 1687 file.write(' g_debugBindingsInitialized = true;\n') 1688 file.write('}\n') 1689 1690 # Write function to clear all function pointers. 1691 file.write('\n') 1692 file.write("""void Driver%s::ClearBindings() { 1693 memset(this, 0, sizeof(*this)); 1694 } 1695 """ % set_name.upper()) 1696 1697 def MakeArgNames(arguments): 1698 argument_names = re.sub( 1699 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', arguments) 1700 argument_names = re.sub( 1701 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', argument_names) 1702 if argument_names == 'void' or argument_names == '': 1703 argument_names = '' 1704 return argument_names 1705 1706 # Write GLApiBase functions 1707 for func in functions: 1708 function_name = func['known_as'] 1709 return_type = func['return_type'] 1710 arguments = func['arguments'] 1711 file.write('\n') 1712 file.write('%s %sApiBase::%sFn(%s) {\n' % 1713 (return_type, set_name.upper(), function_name, arguments)) 1714 argument_names = MakeArgNames(arguments) 1715 if return_type == 'void': 1716 file.write(' driver_->fn.%sFn(%s);\n' % 1717 (function_name, argument_names)) 1718 else: 1719 file.write(' return driver_->fn.%sFn(%s);\n' % 1720 (function_name, argument_names)) 1721 file.write('}\n') 1722 1723 # Write TraceGLApi functions 1724 for func in functions: 1725 function_name = func['known_as'] 1726 return_type = func['return_type'] 1727 arguments = func['arguments'] 1728 file.write('\n') 1729 file.write('%s Trace%sApi::%sFn(%s) {\n' % 1730 (return_type, set_name.upper(), function_name, arguments)) 1731 argument_names = MakeArgNames(arguments) 1732 file.write(' TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::%s")\n' % 1733 function_name) 1734 if return_type == 'void': 1735 file.write(' %s_api_->%sFn(%s);\n' % 1736 (set_name.lower(), function_name, argument_names)) 1737 else: 1738 file.write(' return %s_api_->%sFn(%s);\n' % 1739 (set_name.lower(), function_name, argument_names)) 1740 file.write('}\n') 1741 1742 # Write NoContextGLApi functions 1743 if set_name.upper() == "GL": 1744 for func in functions: 1745 function_name = func['known_as'] 1746 return_type = func['return_type'] 1747 arguments = func['arguments'] 1748 file.write('\n') 1749 file.write('%s NoContextGLApi::%sFn(%s) {\n' % 1750 (return_type, function_name, arguments)) 1751 argument_names = MakeArgNames(arguments) 1752 no_context_error = "Trying to call %s() without current GL context" % function_name 1753 file.write(' NOTREACHED() << "%s";\n' % no_context_error) 1754 file.write(' LOG(ERROR) << "%s";\n' % no_context_error) 1755 default_value = { 'GLenum': 'static_cast<GLenum>(0)', 1756 'GLuint': '0U', 1757 'GLint': '0', 1758 'GLboolean': 'GL_FALSE', 1759 'GLbyte': '0', 1760 'GLubyte': '0', 1761 'GLbutfield': '0', 1762 'GLushort': '0', 1763 'GLsizei': '0', 1764 'GLfloat': '0.0f', 1765 'GLdouble': '0.0', 1766 'GLsync': 'NULL'} 1767 if return_type.endswith('*'): 1768 file.write(' return NULL;\n') 1769 elif return_type != 'void': 1770 file.write(' return %s;\n' % default_value[return_type]) 1771 file.write('}\n') 1772 1773 file.write('\n') 1774 file.write('} // namespace gfx\n') 1775 1776 1777 def GetUniquelyNamedFunctions(functions): 1778 uniquely_named_functions = {} 1779 1780 for func in functions: 1781 for version in func['versions']: 1782 uniquely_named_functions[version['name']] = ({ 1783 'name': version['name'], 1784 'return_type': func['return_type'], 1785 'arguments': func['arguments'], 1786 'known_as': func['known_as'] 1787 }) 1788 return uniquely_named_functions 1789 1790 1791 def GenerateMockBindingsHeader(file, functions): 1792 """Headers for functions that invoke MockGLInterface members""" 1793 1794 file.write( 1795 """// Copyright (c) 2014 The Chromium Authors. All rights reserved. 1796 // Use of this source code is governed by a BSD-style license that can be 1797 // found in the LICENSE file. 1798 1799 // This file is automatically generated. 1800 1801 """) 1802 uniquely_named_functions = GetUniquelyNamedFunctions(functions) 1803 1804 for key in sorted(uniquely_named_functions.iterkeys()): 1805 func = uniquely_named_functions[key] 1806 file.write('static %s GL_BINDING_CALL Mock_%s(%s);\n' % 1807 (func['return_type'], func['name'], func['arguments'])) 1808 1809 1810 def GenerateMockBindingsSource(file, functions): 1811 """Generates functions that invoke MockGLInterface members and a 1812 GetGLProcAddress function that returns addresses to those functions.""" 1813 1814 file.write( 1815 """// Copyright (c) 2011 The Chromium Authors. All rights reserved. 1816 // Use of this source code is governed by a BSD-style license that can be 1817 // found in the LICENSE file. 1818 1819 // This file is automatically generated. 1820 1821 #include <string.h> 1822 1823 #include "ui/gl/gl_mock.h" 1824 1825 namespace gfx { 1826 1827 // This is called mainly to prevent the compiler combining the code of mock 1828 // functions with identical contents, so that their function pointers will be 1829 // different. 1830 void MakeFunctionUnique(const char *func_name) { 1831 VLOG(2) << "Calling mock " << func_name; 1832 } 1833 1834 """) 1835 # Write functions that trampoline into the set MockGLInterface instance. 1836 uniquely_named_functions = GetUniquelyNamedFunctions(functions) 1837 sorted_function_names = sorted(uniquely_named_functions.iterkeys()) 1838 1839 for key in sorted_function_names: 1840 func = uniquely_named_functions[key] 1841 file.write('\n') 1842 file.write('%s GL_BINDING_CALL MockGLInterface::Mock_%s(%s) {\n' % 1843 (func['return_type'], func['name'], func['arguments'])) 1844 file.write(' MakeFunctionUnique("%s");\n' % func['name']) 1845 arg_re = r'(const )?[a-zA-Z0-9]+((\s*const\s*)?\*)* ([a-zA-Z0-9]+)' 1846 argument_names = re.sub(arg_re, r'\4', func['arguments']) 1847 if argument_names == 'void': 1848 argument_names = '' 1849 function_name = func['known_as'][2:] 1850 if func['return_type'] == 'void': 1851 file.write(' interface_->%s(%s);\n' % 1852 (function_name, argument_names)) 1853 else: 1854 file.write(' return interface_->%s(%s);\n' % 1855 (function_name, argument_names)) 1856 file.write('}\n') 1857 1858 # Write an 'invalid' function to catch code calling through uninitialized 1859 # function pointers or trying to interpret the return value of 1860 # GLProcAddress(). 1861 file.write('\n') 1862 file.write('static void MockInvalidFunction() {\n') 1863 file.write(' NOTREACHED();\n') 1864 file.write('}\n') 1865 1866 # Write a function to lookup a mock GL function based on its name. 1867 file.write('\n') 1868 file.write('void* GL_BINDING_CALL ' + 1869 'MockGLInterface::GetGLProcAddress(const char* name) {\n') 1870 for key in sorted_function_names: 1871 name = uniquely_named_functions[key]['name'] 1872 file.write(' if (strcmp(name, "%s") == 0)\n' % name) 1873 file.write(' return reinterpret_cast<void*>(Mock_%s);\n' % name) 1874 # Always return a non-NULL pointer like some EGL implementations do. 1875 file.write(' return reinterpret_cast<void*>(&MockInvalidFunction);\n') 1876 file.write('}\n') 1877 1878 file.write('\n') 1879 file.write('} // namespace gfx\n') 1880 1881 1882 def ParseExtensionFunctionsFromHeader(header_file): 1883 """Parse a C extension header file and return a map from extension names to 1884 a list of functions. 1885 1886 Args: 1887 header_file: Line-iterable C header file. 1888 Returns: 1889 Map of extension name => functions. 1890 """ 1891 extension_start = re.compile( 1892 r'#ifndef ((?:GL|EGL|WGL|GLX)_[A-Z]+_[a-zA-Z]\w+)') 1893 extension_function = re.compile(r'.+\s+([a-z]+\w+)\s*\(') 1894 typedef = re.compile(r'typedef .*') 1895 macro_start = re.compile(r'^#(if|ifdef|ifndef).*') 1896 macro_end = re.compile(r'^#endif.*') 1897 macro_depth = 0 1898 current_extension = None 1899 current_extension_depth = 0 1900 extensions = collections.defaultdict(lambda: []) 1901 for line in header_file: 1902 if macro_start.match(line): 1903 macro_depth += 1 1904 elif macro_end.match(line): 1905 macro_depth -= 1 1906 if macro_depth < current_extension_depth: 1907 current_extension = None 1908 match = extension_start.match(line) 1909 if match: 1910 current_extension = match.group(1) 1911 current_extension_depth = macro_depth 1912 assert current_extension not in extensions, \ 1913 "Duplicate extension: " + current_extension 1914 match = extension_function.match(line) 1915 if match and current_extension and not typedef.match(line): 1916 extensions[current_extension].append(match.group(1)) 1917 return extensions 1918 1919 1920 def GetExtensionFunctions(extension_headers): 1921 """Parse extension functions from a list of header files. 1922 1923 Args: 1924 extension_headers: List of header file names. 1925 Returns: 1926 Map of extension name => list of functions. 1927 """ 1928 extensions = {} 1929 for header in extension_headers: 1930 extensions.update(ParseExtensionFunctionsFromHeader(open(header))) 1931 return extensions 1932 1933 1934 def GetFunctionToExtensionMap(extensions): 1935 """Construct map from a function names to extensions which define the 1936 function. 1937 1938 Args: 1939 extensions: Map of extension name => functions. 1940 Returns: 1941 Map of function name => extension name. 1942 """ 1943 function_to_extensions = {} 1944 for extension, functions in extensions.items(): 1945 for function in functions: 1946 if not function in function_to_extensions: 1947 function_to_extensions[function] = [] 1948 function_to_extensions[function].append(extension) 1949 return function_to_extensions 1950 1951 1952 def LooksLikeExtensionFunction(function): 1953 """Heuristic to see if a function name is consistent with extension function 1954 naming.""" 1955 vendor = re.match(r'\w+?([A-Z][A-Z]+)$', function) 1956 return vendor is not None and not vendor.group(1) in ['GL', 'API', 'DC'] 1957 1958 1959 def FillExtensionsFromHeaders(functions, extension_headers, extra_extensions): 1960 """Determine which functions belong to extensions based on extension headers, 1961 and fill in this information to the functions table for functions that don't 1962 already have the information. 1963 1964 Args: 1965 functions: List of (return type, function versions, arguments). 1966 extension_headers: List of header file names. 1967 extra_extensions: Extensions to add to the list. 1968 Returns: 1969 Set of used extensions. 1970 """ 1971 # Parse known extensions. 1972 extensions = GetExtensionFunctions(extension_headers) 1973 functions_to_extensions = GetFunctionToExtensionMap(extensions) 1974 1975 # Fill in the extension information. 1976 used_extensions = set() 1977 for func in functions: 1978 for version in func['versions']: 1979 name = version['name'] 1980 # Make sure we know about all extensions and extension functions. 1981 if 'extensions' in version: 1982 used_extensions.update(version['extensions']) 1983 elif name in functions_to_extensions: 1984 # If there are multiple versions with the same name, assume that they 1985 # already have all the correct conditions, we can't just blindly add 1986 # the same extension conditions to all of them 1987 if len([v for v in func['versions'] if v['name'] == name]) == 1: 1988 version['extensions'] = functions_to_extensions[name] 1989 used_extensions.update(version['extensions']) 1990 elif LooksLikeExtensionFunction(name): 1991 raise RuntimeError('%s looks like an extension function but does not ' 1992 'belong to any of the known extensions.' % name) 1993 1994 # Add extensions that do not have any functions. 1995 used_extensions.update(extra_extensions) 1996 1997 return used_extensions 1998 1999 2000 def ResolveHeader(header, header_paths): 2001 paths = header_paths.split(':') 2002 2003 for path in paths: 2004 result = os.path.join(path, header) 2005 if not os.path.isabs(path): 2006 result = os.path.relpath(os.path.join(os.getcwd(), result), os.getcwd()) 2007 if os.path.exists(result): 2008 # Always use forward slashes as path separators. Otherwise backslashes 2009 # may be incorrectly interpreted as escape characters. 2010 return result.replace(os.path.sep, '/') 2011 2012 raise Exception('Header %s not found.' % header) 2013 2014 2015 def main(argv): 2016 """This is the main function.""" 2017 2018 parser = optparse.OptionParser() 2019 parser.add_option('--inputs', action='store_true') 2020 parser.add_option('--header-paths') 2021 2022 options, args = parser.parse_args(argv) 2023 2024 if options.inputs: 2025 for [_, _, headers, _] in FUNCTION_SETS: 2026 for header in headers: 2027 print ResolveHeader(header, options.header_paths) 2028 return 0 2029 2030 directory = '.' 2031 if len(args) >= 1: 2032 directory = args[0] 2033 2034 for [functions, set_name, extension_headers, extensions] in FUNCTION_SETS: 2035 # Function names can be specified in two ways (list of unique names or list 2036 # of versions with different binding conditions). Fill in the data to the 2037 # versions list in case it is missing, so that can be used from here on: 2038 for func in functions: 2039 assert 'versions' in func or 'names' in func, 'Function with no names' 2040 if 'versions' not in func: 2041 func['versions'] = [{'name': n} for n in func['names']] 2042 # Use the first version's name unless otherwise specified 2043 if 'known_as' not in func: 2044 func['known_as'] = func['versions'][0]['name'] 2045 # Make sure that 'names' is not accidentally used instead of 'versions' 2046 if 'names' in func: 2047 del func['names'] 2048 2049 extension_headers = [ResolveHeader(h, options.header_paths) 2050 for h in extension_headers] 2051 used_extensions = FillExtensionsFromHeaders( 2052 functions, extension_headers, extensions) 2053 2054 header_file = open( 2055 os.path.join(directory, 'gl_bindings_autogen_%s.h' % set_name), 'wb') 2056 GenerateHeader(header_file, functions, set_name, used_extensions) 2057 header_file.close() 2058 2059 header_file = open( 2060 os.path.join(directory, 'gl_bindings_api_autogen_%s.h' % set_name), 2061 'wb') 2062 GenerateAPIHeader(header_file, functions, set_name) 2063 header_file.close() 2064 2065 source_file = open( 2066 os.path.join(directory, 'gl_bindings_autogen_%s.cc' % set_name), 'wb') 2067 GenerateSource(source_file, functions, set_name, used_extensions) 2068 source_file.close() 2069 2070 header_file = open( 2071 os.path.join(directory, 'gl_mock_autogen_gl.h'), 'wb') 2072 GenerateMockHeader(header_file, GL_FUNCTIONS, 'gl') 2073 header_file.close() 2074 2075 header_file = open(os.path.join(directory, 'gl_bindings_autogen_mock.h'), 2076 'wb') 2077 GenerateMockBindingsHeader(header_file, GL_FUNCTIONS) 2078 header_file.close() 2079 2080 source_file = open(os.path.join(directory, 'gl_bindings_autogen_mock.cc'), 2081 'wb') 2082 GenerateMockBindingsSource(source_file, GL_FUNCTIONS) 2083 source_file.close() 2084 return 0 2085 2086 2087 if __name__ == '__main__': 2088 sys.exit(main(sys.argv[1:])) 2089