Home | History | Annotate | Download | only in gl
      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