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 GL_FUNCTIONS = [
     15 { 'return_type': 'void',
     16   'names': ['glActiveTexture'],
     17   'arguments': 'GLenum texture', },
     18 { 'return_type': 'void',
     19   'names': ['glAttachShader'],
     20   'arguments': 'GLuint program, GLuint shader', },
     21 { 'return_type': 'void',
     22   'names': ['glBeginQuery'],
     23   'arguments': 'GLenum target, GLuint id', },
     24 { 'return_type': 'void',
     25   'names': ['glBeginQueryARB', 'glBeginQueryEXT'],
     26   'arguments': 'GLenum target, GLuint id', },
     27 { 'return_type': 'void',
     28   'names': ['glBindAttribLocation'],
     29   'arguments': 'GLuint program, GLuint index, const char* name', },
     30 { 'return_type': 'void',
     31   'names': ['glBindBuffer'],
     32   'arguments': 'GLenum target, GLuint buffer', },
     33 { 'return_type': 'void',
     34   'names': ['glBindFragDataLocation'],
     35   'arguments': 'GLuint program, GLuint colorNumber, const char* name', },
     36 { 'return_type': 'void',
     37   'names': ['glBindFragDataLocationIndexed'],
     38   'arguments':
     39       'GLuint program, GLuint colorNumber, GLuint index, const char* name', },
     40 { 'return_type': 'void',
     41   'names': ['glBindFramebufferEXT', 'glBindFramebuffer'],
     42   'arguments': 'GLenum target, GLuint framebuffer', },
     43 { 'return_type': 'void',
     44   'names': ['glBindRenderbufferEXT', 'glBindRenderbuffer'],
     45   'arguments': 'GLenum target, GLuint renderbuffer', },
     46 { 'return_type': 'void',
     47   'names': ['glBindTexture'],
     48   'arguments': 'GLenum target, GLuint texture', },
     49 { 'return_type': 'void',
     50   'names': ['glBlendColor'],
     51   'arguments': 'GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha', },
     52 { 'return_type': 'void',
     53   'names': ['glBlendEquation'],
     54   'arguments': ' GLenum mode ', },
     55 { 'return_type': 'void',
     56   'names': ['glBlendEquationSeparate'],
     57   'arguments': 'GLenum modeRGB, GLenum modeAlpha', },
     58 { 'return_type': 'void',
     59   'names': ['glBlendFunc'],
     60   'arguments': 'GLenum sfactor, GLenum dfactor', },
     61 { 'return_type': 'void',
     62   'names': ['glBlendFuncSeparate'],
     63   'arguments':
     64       'GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha', },
     65 { 'return_type': 'void',
     66   'names': ['glBlitFramebuffer'],
     67   'arguments': 'GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, '
     68                'GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, '
     69                'GLbitfield mask, GLenum filter', },
     70 { 'return_type': 'void',
     71   'names': ['glBlitFramebufferEXT', 'glBlitFramebuffer'],
     72   'arguments': 'GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, '
     73                'GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, '
     74                'GLbitfield mask, GLenum filter', },
     75 { 'return_type': 'void',
     76   'names': ['glBlitFramebufferANGLE', 'glBlitFramebuffer'],
     77   'arguments': 'GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, '
     78                'GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, '
     79                'GLbitfield mask, GLenum filter', },
     80 { 'return_type': 'void',
     81   'names': ['glBufferData'],
     82   'arguments': 'GLenum target, GLsizei size, const void* data, GLenum usage', },
     83 { 'return_type': 'void',
     84   'names': ['glBufferSubData'],
     85   'arguments': 'GLenum target, GLint offset, GLsizei size, const void* data', },
     86 { 'return_type': 'GLenum',
     87   'names': ['glCheckFramebufferStatusEXT',
     88             'glCheckFramebufferStatus'],
     89   'arguments': 'GLenum target',
     90   'logging_code': """
     91   GL_SERVICE_LOG("GL_RESULT: " << GLES2Util::GetStringEnum(result));
     92 """, },
     93 { 'return_type': 'void',
     94   'names': ['glClear'],
     95   'arguments': 'GLbitfield mask', },
     96 { 'return_type': 'void',
     97   'names': ['glClearColor'],
     98   'arguments': 'GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha', },
     99 { 'return_type': 'void',
    100   'names': ['glClearDepth'],
    101   'arguments': 'GLclampd depth', },
    102 { 'return_type': 'void',
    103   'names': ['glClearDepthf'],
    104   'arguments': 'GLclampf depth', },
    105 { 'return_type': 'void',
    106   'names': ['glClearStencil'],
    107   'arguments': 'GLint s', },
    108 { 'return_type': 'void',
    109   'names': ['glColorMask'],
    110   'arguments':
    111       'GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha', },
    112 { 'return_type': 'void',
    113   'names': ['glCompileShader'],
    114   'arguments': 'GLuint shader', },
    115 { 'return_type': 'void',
    116   'names': ['glCompressedTexImage2D'],
    117   'arguments':
    118       'GLenum target, GLint level, GLenum internalformat, GLsizei width, '
    119       'GLsizei height, GLint border, GLsizei imageSize, const void* data', },
    120 { 'return_type': 'void',
    121   'names': ['glCompressedTexSubImage2D'],
    122   'arguments':
    123      'GLenum target, GLint level, GLint xoffset, GLint yoffset, '
    124      'GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, '
    125      'const void* data', },
    126 { 'return_type': 'void',
    127   'names': ['glCopyTexImage2D'],
    128   'arguments':
    129       'GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, '
    130       'GLsizei width, GLsizei height, GLint border', },
    131 { 'return_type': 'void',
    132   'names': ['glCopyTexSubImage2D'],
    133   'arguments':
    134       'GLenum target, GLint level, GLint xoffset, '
    135       'GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height', },
    136 { 'return_type': 'GLuint',
    137   'names': ['glCreateProgram'],
    138   'arguments': 'void', },
    139 { 'return_type': 'GLuint',
    140   'names': ['glCreateShader'],
    141   'arguments': 'GLenum type', },
    142 { 'return_type': 'void',
    143   'names': ['glCullFace'],
    144   'arguments': 'GLenum mode', },
    145 { 'return_type': 'void',
    146   'names': ['glDeleteBuffersARB', 'glDeleteBuffers'],
    147   'arguments': 'GLsizei n, const GLuint* buffers', },
    148 { 'return_type': 'void',
    149   'names': ['glDeleteFramebuffersEXT', 'glDeleteFramebuffers'],
    150   'arguments': 'GLsizei n, const GLuint* framebuffers', },
    151 { 'return_type': 'void',
    152   'names': ['glDeleteProgram'],
    153   'arguments': 'GLuint program', },
    154 { 'return_type': 'void',
    155   'names': ['glDeleteQueries'],
    156   'arguments': 'GLsizei n, const GLuint* ids', },
    157 { 'return_type': 'void',
    158   'names': ['glDeleteQueriesARB', 'glDeleteQueriesEXT'],
    159   'arguments': 'GLsizei n, const GLuint* ids', },
    160 { 'return_type': 'void',
    161   'names': ['glDeleteRenderbuffersEXT', 'glDeleteRenderbuffers'],
    162   'arguments': 'GLsizei n, const GLuint* renderbuffers', },
    163 { 'return_type': 'void',
    164   'names': ['glDeleteShader'],
    165   'arguments': 'GLuint shader', },
    166 { 'return_type': 'void',
    167   'names': ['glDeleteTextures'],
    168   'arguments': 'GLsizei n, const GLuint* textures', },
    169 { 'return_type': 'void',
    170   'names': ['glDepthFunc'],
    171   'arguments': 'GLenum func', },
    172 { 'return_type': 'void',
    173   'names': ['glDepthMask'],
    174   'arguments': 'GLboolean flag', },
    175 { 'return_type': 'void',
    176   'names': ['glDepthRange'],
    177   'arguments': 'GLclampd zNear, GLclampd zFar', },
    178 { 'return_type': 'void',
    179   'names': ['glDepthRangef'],
    180   'arguments': 'GLclampf zNear, GLclampf zFar', },
    181 { 'return_type': 'void',
    182   'names': ['glDetachShader'],
    183   'arguments': 'GLuint program, GLuint shader', },
    184 { 'return_type': 'void',
    185   'names': ['glDisable'],
    186   'arguments': 'GLenum cap', },
    187 { 'return_type': 'void',
    188   'names': ['glDisableVertexAttribArray'],
    189   'arguments': 'GLuint index', },
    190 { 'return_type': 'void',
    191   'names': ['glDrawArrays'],
    192   'arguments': 'GLenum mode, GLint first, GLsizei count', },
    193 { 'return_type': 'void',
    194   'names': ['glDrawBuffer'],
    195   'arguments': 'GLenum mode', },
    196 { 'return_type': 'void',
    197   'names': ['glDrawBuffersARB', 'glDrawBuffersEXT'],
    198   'arguments': 'GLsizei n, const GLenum* bufs', },
    199 { 'return_type': 'void',
    200   'names': ['glDrawElements'],
    201   'arguments':
    202       'GLenum mode, GLsizei count, GLenum type, const void* indices', },
    203 { 'return_type': 'void',
    204   'names': ['glEGLImageTargetTexture2DOES'],
    205   'arguments': 'GLenum target, GLeglImageOES image', },
    206 { 'return_type': 'void',
    207   'names': ['glEGLImageTargetRenderbufferStorageOES'],
    208   'arguments': 'GLenum target, GLeglImageOES image', },
    209 { 'return_type': 'void',
    210   'names': ['glEnable'],
    211   'arguments': 'GLenum cap', },
    212 { 'return_type': 'void',
    213   'names': ['glEnableVertexAttribArray'],
    214   'arguments': 'GLuint index', },
    215 { 'return_type': 'void',
    216   'names': ['glEndQuery'],
    217   'arguments': 'GLenum target', },
    218 { 'return_type': 'void',
    219   'names': ['glEndQueryARB', 'glEndQueryEXT'],
    220   'arguments': 'GLenum target', },
    221 { 'return_type': 'void',
    222   'names': ['glFinish'],
    223   'arguments': 'void', },
    224 { 'return_type': 'void',
    225   'names': ['glFlush'],
    226   'arguments': 'void', },
    227 { 'return_type': 'void',
    228   'names': ['glFramebufferRenderbufferEXT', 'glFramebufferRenderbuffer'],
    229   'arguments': \
    230       'GLenum target, GLenum attachment, GLenum renderbuffertarget, '
    231       'GLuint renderbuffer', },
    232 { 'return_type': 'void',
    233   'names': ['glFramebufferTexture2DEXT', 'glFramebufferTexture2D'],
    234   'arguments':
    235       'GLenum target, GLenum attachment, GLenum textarget, GLuint texture, '
    236       'GLint level', },
    237 { 'return_type': 'void',
    238   'names': ['glFramebufferTexture2DMultisampleEXT'],
    239   'arguments':
    240       'GLenum target, GLenum attachment, GLenum textarget, GLuint texture, '
    241       'GLint level, GLsizei samples', },
    242 { 'return_type': 'void',
    243   'names': ['glFramebufferTexture2DMultisampleIMG'],
    244   'arguments':
    245       'GLenum target, GLenum attachment, GLenum textarget, GLuint texture, '
    246       'GLint level, GLsizei samples', },
    247 { 'return_type': 'void',
    248   'names': ['glFrontFace'],
    249   'arguments': 'GLenum mode', },
    250 { 'return_type': 'void',
    251   'names': ['glGenBuffersARB', 'glGenBuffers'],
    252   'arguments': 'GLsizei n, GLuint* buffers', },
    253 { 'return_type': 'void',
    254   'names': ['glGenQueries'],
    255   'arguments': 'GLsizei n, GLuint* ids', },
    256 { 'return_type': 'void',
    257   'names': ['glGenQueriesARB', 'glGenQueriesEXT'],
    258   'arguments': 'GLsizei n, GLuint* ids', },
    259 { 'return_type': 'void',
    260   'names': ['glGenerateMipmapEXT', 'glGenerateMipmap'],
    261   'arguments': 'GLenum target', },
    262 { 'return_type': 'void',
    263   'names': ['glGenFramebuffersEXT', 'glGenFramebuffers'],
    264   'arguments': 'GLsizei n, GLuint* framebuffers', },
    265 { 'return_type': 'void',
    266   'names': ['glGenRenderbuffersEXT', 'glGenRenderbuffers'],
    267   'arguments': 'GLsizei n, GLuint* renderbuffers', },
    268 { 'return_type': 'void',
    269   'names': ['glGenTextures'],
    270   'arguments': 'GLsizei n, GLuint* textures', },
    271 { 'return_type': 'void',
    272   'names': ['glGetActiveAttrib'],
    273   'arguments':
    274       'GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, '
    275       'GLint* size, GLenum* type, char* name', },
    276 { 'return_type': 'void',
    277   'names': ['glGetActiveUniform'],
    278   'arguments':
    279       'GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, '
    280       'GLint* size, GLenum* type, char* name', },
    281 { 'return_type': 'void',
    282   'names': ['glGetAttachedShaders'],
    283   'arguments':
    284       'GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders', },
    285 { 'return_type': 'GLint',
    286   'names': ['glGetAttribLocation'],
    287   'arguments': 'GLuint program, const char* name', },
    288 { 'return_type': 'void',
    289   'names': ['glGetBooleanv'],
    290   'arguments': 'GLenum pname, GLboolean* params', },
    291 { 'return_type': 'void',
    292   'names': ['glGetBufferParameteriv'],
    293   'arguments': 'GLenum target, GLenum pname, GLint* params', },
    294 { 'return_type': 'GLenum',
    295   'names': ['glGetError'],
    296   'arguments': 'void',
    297   'logging_code': """
    298   GL_SERVICE_LOG("GL_RESULT: " << GLES2Util::GetStringError(result));
    299 """, },
    300 { 'return_type': 'void',
    301   'names': ['glGetFloatv'],
    302   'arguments': 'GLenum pname, GLfloat* params', },
    303 { 'return_type': 'void',
    304   'names': ['glGetFramebufferAttachmentParameterivEXT',
    305             'glGetFramebufferAttachmentParameteriv'],
    306   'arguments': 'GLenum target, '
    307                'GLenum attachment, GLenum pname, GLint* params', },
    308 { 'return_type': 'GLenum',
    309   'names': ['glGetGraphicsResetStatusARB',
    310             'glGetGraphicsResetStatusEXT'],
    311   'arguments': 'void', },
    312 { 'return_type': 'void',
    313   'names': ['glGetIntegerv'],
    314   'arguments': 'GLenum pname, GLint* params', },
    315 { 'return_type': 'void',
    316   'names': ['glGetProgramBinary', 'glGetProgramBinaryOES'],
    317   'arguments': 'GLuint program, GLsizei bufSize, GLsizei* length, '
    318                'GLenum* binaryFormat, GLvoid* binary',
    319   'other_extensions': ['ARB_get_program_binary',
    320                        'OES_get_program_binary'] },
    321 { 'return_type': 'void',
    322   'names': ['glGetProgramiv'],
    323   'arguments': 'GLuint program, GLenum pname, GLint* params', },
    324 { 'return_type': 'void',
    325   'names': ['glGetProgramInfoLog'],
    326   'arguments':
    327       'GLuint program, GLsizei bufsize, GLsizei* length, char* infolog', },
    328 { 'return_type': 'void',
    329   'names': ['glGetQueryiv'],
    330   'arguments': 'GLenum target, GLenum pname, GLint* params', },
    331 { 'return_type': 'void',
    332   'names': ['glGetQueryivARB', 'glGetQueryivEXT'],
    333   'arguments': 'GLenum target, GLenum pname, GLint* params', },
    334 { 'return_type': 'void',
    335   'names': ['glGetQueryObjecti64v'],
    336   'arguments': 'GLuint id, GLenum pname, GLint64* params', },
    337 { 'return_type': 'void',
    338   'names': ['glGetQueryObjectiv'],
    339   'arguments': 'GLuint id, GLenum pname, GLint* params', },
    340 { 'return_type': 'void',
    341   'names': ['glGetQueryObjectui64v'],
    342   'arguments': 'GLuint id, GLenum pname, GLuint64* params', },
    343 { 'return_type': 'void',
    344   'names': ['glGetQueryObjectuiv'],
    345   'arguments': 'GLuint id, GLenum pname, GLuint* params', },
    346 { 'return_type': 'void',
    347   'names': ['glGetQueryObjectuivARB', 'glGetQueryObjectuivEXT'],
    348   'arguments': 'GLuint id, GLenum pname, GLuint* params', },
    349 { 'return_type': 'void',
    350   'names': ['glGetRenderbufferParameterivEXT', 'glGetRenderbufferParameteriv'],
    351   'arguments': 'GLenum target, GLenum pname, GLint* params', },
    352 { 'return_type': 'void',
    353   'names': ['glGetShaderiv'],
    354   'arguments': 'GLuint shader, GLenum pname, GLint* params', },
    355 { 'return_type': 'void',
    356   'names': ['glGetShaderInfoLog'],
    357   'arguments':
    358       'GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog', },
    359 { 'return_type': 'void',
    360   'names': ['glGetShaderPrecisionFormat'],
    361   'arguments': 'GLenum shadertype, GLenum precisiontype, '
    362                'GLint* range, GLint* precision', },
    363 { 'return_type': 'void',
    364   'names': ['glGetShaderSource'],
    365   'arguments':
    366       'GLuint shader, GLsizei bufsize, GLsizei* length, char* source', },
    367 { 'return_type': 'const GLubyte*',
    368   'names': ['glGetString'],
    369   'arguments': 'GLenum name', },
    370 { 'return_type': 'void',
    371   'names': ['glGetTexLevelParameterfv'],
    372   'arguments': 'GLenum target, GLint level, GLenum pname, GLfloat* params', },
    373 { 'return_type': 'void',
    374   'names': ['glGetTexLevelParameteriv'],
    375   'arguments': 'GLenum target, GLint level, GLenum pname, GLint* params', },
    376 { 'return_type': 'void',
    377   'names': ['glGetTexParameterfv'],
    378   'arguments': 'GLenum target, GLenum pname, GLfloat* params', },
    379 { 'return_type': 'void',
    380   'names': ['glGetTexParameteriv'],
    381   'arguments': 'GLenum target, GLenum pname, GLint* params', },
    382 { 'return_type': 'void',
    383   'names': ['glGetTranslatedShaderSourceANGLE'],
    384   'arguments':
    385       'GLuint shader, GLsizei bufsize, GLsizei* length, char* source', },
    386 { 'return_type': 'void',
    387   'names': ['glGetUniformfv'],
    388   'arguments': 'GLuint program, GLint location, GLfloat* params', },
    389 { 'return_type': 'void',
    390   'names': ['glGetUniformiv'],
    391   'arguments': 'GLuint program, GLint location, GLint* params', },
    392 { 'return_type': 'GLint',
    393   'names': ['glGetUniformLocation'],
    394   'arguments': 'GLuint program, const char* name', },
    395 { 'return_type': 'void',
    396   'names': ['glGetVertexAttribfv'],
    397   'arguments': 'GLuint index, GLenum pname, GLfloat* params', },
    398 { 'return_type': 'void',
    399   'names': ['glGetVertexAttribiv'],
    400   'arguments': 'GLuint index, GLenum pname, GLint* params', },
    401 { 'return_type': 'void',
    402   'names': ['glGetVertexAttribPointerv'],
    403   'arguments': 'GLuint index, GLenum pname, void** pointer', },
    404 { 'return_type': 'void',
    405   'names': ['glHint'],
    406   'arguments': 'GLenum target, GLenum mode', },
    407 { 'return_type': 'GLboolean',
    408   'names': ['glIsBuffer'],
    409   'arguments': 'GLuint buffer', },
    410 { 'return_type': 'GLboolean',
    411   'names': ['glIsEnabled'],
    412   'arguments': 'GLenum cap', },
    413 { 'return_type': 'GLboolean',
    414   'names': ['glIsFramebufferEXT', 'glIsFramebuffer'],
    415   'arguments': 'GLuint framebuffer', },
    416 { 'return_type': 'GLboolean',
    417   'names': ['glIsProgram'],
    418   'arguments': 'GLuint program', },
    419 { 'return_type': 'GLboolean',
    420   'names': ['glIsQueryARB', 'glIsQueryEXT'],
    421   'arguments': 'GLuint query', },
    422 { 'return_type': 'GLboolean',
    423   'names': ['glIsRenderbufferEXT', 'glIsRenderbuffer'],
    424   'arguments': 'GLuint renderbuffer', },
    425 { 'return_type': 'GLboolean',
    426   'names': ['glIsShader'],
    427   'arguments': 'GLuint shader', },
    428 { 'return_type': 'GLboolean',
    429   'names': ['glIsTexture'],
    430   'arguments': 'GLuint texture', },
    431 { 'return_type': 'void',
    432   'names': ['glLineWidth'],
    433   'arguments': 'GLfloat width', },
    434 { 'return_type': 'void',
    435   'names': ['glLinkProgram'],
    436   'arguments': 'GLuint program', },
    437 { 'return_type': 'void*',
    438   'names': ['glMapBuffer', 'glMapBufferOES'],
    439   'arguments': 'GLenum target, GLenum access', },
    440 { 'return_type': 'void*',
    441   'names': ['glMapBufferRange'],
    442   'arguments':
    443       'GLenum target, GLintptr offset, GLsizeiptr length, GLenum access', },
    444 { 'return_type': 'void',
    445   'names': ['glFlushMappedBufferRange'],
    446   'arguments': 'GLenum target, GLintptr offset, GLsizeiptr length', },
    447 { 'return_type': 'void',
    448   'names': ['glPixelStorei'],
    449   'arguments': 'GLenum pname, GLint param', },
    450 { 'return_type': 'void',
    451   'names': ['glPointParameteri'],
    452   'arguments': 'GLenum pname, GLint param', },
    453 { 'return_type': 'void',
    454   'names': ['glPolygonOffset'],
    455   'arguments': 'GLfloat factor, GLfloat units', },
    456 { 'return_type': 'void',
    457   'names': ['glProgramBinary', 'glProgramBinaryOES'],
    458   'arguments': 'GLuint program, GLenum binaryFormat, '
    459                'const GLvoid* binary, GLsizei length',
    460   'other_extensions': ['ARB_get_program_binary',
    461                        'OES_get_program_binary'] },
    462 { 'return_type': 'void',
    463   'names': ['glProgramParameteri'],
    464   'arguments': 'GLuint program, GLenum pname, GLint value',
    465   'other_extensions': ['ARB_get_program_binary'] },
    466 { 'return_type': 'void',
    467   'names': ['glQueryCounter'],
    468   'arguments': 'GLuint id, GLenum target', },
    469 { 'return_type': 'void',
    470   'names': ['glReadBuffer'],
    471   'arguments': 'GLenum src', },
    472 { 'return_type': 'void',
    473   'names': ['glReadPixels'],
    474   'arguments':
    475     'GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, '
    476     'GLenum type, void* pixels', },
    477 { 'return_type': 'void',
    478   'names': ['glReleaseShaderCompiler'],
    479   'arguments': 'void', },
    480 { 'return_type': 'void',
    481   'names': ['glRenderbufferStorageMultisample'],
    482   'arguments': 'GLenum target, GLsizei samples, GLenum internalformat, '
    483                'GLsizei width, GLsizei height', },
    484 { 'return_type': 'void',
    485   'names': ['glRenderbufferStorageMultisampleEXT',
    486             'glRenderbufferStorageMultisample'],
    487   'arguments': 'GLenum target, GLsizei samples, GLenum internalformat, '
    488                'GLsizei width, GLsizei height', },
    489 { 'return_type': 'void',
    490   'names': ['glRenderbufferStorageMultisampleANGLE',
    491             'glRenderbufferStorageMultisample'],
    492   'arguments': 'GLenum target, GLsizei samples, GLenum internalformat, '
    493                'GLsizei width, GLsizei height', },
    494 { 'return_type': 'void',
    495   'names': ['glRenderbufferStorageMultisampleIMG'],
    496   'arguments': 'GLenum target, GLsizei samples, GLenum internalformat, '
    497                'GLsizei width, GLsizei height', },
    498 { 'return_type': 'void',
    499   'names': ['glRenderbufferStorageEXT', 'glRenderbufferStorage'],
    500   'arguments':
    501       'GLenum target, GLenum internalformat, GLsizei width, GLsizei height', },
    502 { 'return_type': 'void',
    503   'names': ['glSampleCoverage'],
    504   'arguments': 'GLclampf value, GLboolean invert', },
    505 { 'return_type': 'void',
    506   'names': ['glScissor'],
    507   'arguments': 'GLint x, GLint y, GLsizei width, GLsizei height', },
    508 { 'return_type': 'void',
    509   'names': ['glShaderBinary'],
    510   'arguments': 'GLsizei n, const GLuint* shaders, GLenum binaryformat, '
    511                'const void* binary, GLsizei length', },
    512 { 'return_type': 'void',
    513   'names': ['glShaderSource'],
    514   'arguments':
    515       'GLuint shader, GLsizei count, const char* const* str, const GLint* length',
    516   'logging_code': """
    517   GL_SERVICE_LOG_CODE_BLOCK({
    518     for (GLsizei ii = 0; ii < count; ++ii) {
    519       if (str[ii]) {
    520         if (length && length[ii] >= 0) {
    521           std::string source(str[ii], length[ii]);
    522           GL_SERVICE_LOG("  " << ii << ": ---\\n" << source << "\\n---");
    523         } else {
    524           GL_SERVICE_LOG("  " << ii << ": ---\\n" << str[ii] << "\\n---");
    525         }
    526       } else {
    527         GL_SERVICE_LOG("  " << ii << ": NULL");
    528       }
    529     }
    530   });
    531 """, },
    532 { 'return_type': 'void',
    533   'names': ['glStencilFunc'],
    534   'arguments': 'GLenum func, GLint ref, GLuint mask', },
    535 { 'return_type': 'void',
    536   'names': ['glStencilFuncSeparate'],
    537   'arguments': 'GLenum face, GLenum func, GLint ref, GLuint mask', },
    538 { 'return_type': 'void',
    539   'names': ['glStencilMask'],
    540   'arguments': 'GLuint mask', },
    541 { 'return_type': 'void',
    542   'names': ['glStencilMaskSeparate'],
    543   'arguments': 'GLenum face, GLuint mask', },
    544 { 'return_type': 'void',
    545   'names': ['glStencilOp'],
    546   'arguments': 'GLenum fail, GLenum zfail, GLenum zpass', },
    547 { 'return_type': 'void',
    548   'names': ['glStencilOpSeparate'],
    549   'arguments': 'GLenum face, GLenum fail, GLenum zfail, GLenum zpass', },
    550 { 'return_type': 'void',
    551   'names': ['glTexImage2D'],
    552   'arguments':
    553       'GLenum target, GLint level, GLint internalformat, GLsizei width, '
    554       'GLsizei height, GLint border, GLenum format, GLenum type, '
    555       'const void* pixels', },
    556 { 'return_type': 'void',
    557   'names': ['glTexParameterf'],
    558   'arguments': 'GLenum target, GLenum pname, GLfloat param', },
    559 { 'return_type': 'void',
    560   'names': ['glTexParameterfv'],
    561   'arguments': 'GLenum target, GLenum pname, const GLfloat* params', },
    562 { 'return_type': 'void',
    563   'names': ['glTexParameteri'],
    564   'arguments': 'GLenum target, GLenum pname, GLint param', },
    565 { 'return_type': 'void',
    566   'names': ['glTexParameteriv'],
    567   'arguments': 'GLenum target, GLenum pname, const GLint* params', },
    568 { 'return_type': 'void',
    569   'names': ['glTexStorage2DEXT'],
    570   'arguments': 'GLenum target, GLsizei levels, GLenum internalformat, '
    571                'GLsizei width, GLsizei height', },
    572 { 'return_type': 'void',
    573   'names': ['glTexSubImage2D'],
    574   'arguments':
    575      'GLenum target, GLint level, GLint xoffset, GLint yoffset, '
    576      'GLsizei width, GLsizei height, GLenum format, GLenum type, '
    577      'const void* pixels', },
    578 { 'return_type': 'void',
    579   'names': ['glUniform1f'],
    580   'arguments': 'GLint location, GLfloat x', },
    581 { 'return_type': 'void',
    582   'names': ['glUniform1fv'],
    583   'arguments': 'GLint location, GLsizei count, const GLfloat* v', },
    584 { 'return_type': 'void',
    585   'names': ['glUniform1i'],
    586   'arguments': 'GLint location, GLint x', },
    587 { 'return_type': 'void',
    588   'names': ['glUniform1iv'],
    589   'arguments': 'GLint location, GLsizei count, const GLint* v', },
    590 { 'return_type': 'void',
    591   'names': ['glUniform2f'],
    592   'arguments': 'GLint location, GLfloat x, GLfloat y', },
    593 { 'return_type': 'void',
    594   'names': ['glUniform2fv'],
    595   'arguments': 'GLint location, GLsizei count, const GLfloat* v', },
    596 { 'return_type': 'void',
    597   'names': ['glUniform2i'],
    598   'arguments': 'GLint location, GLint x, GLint y', },
    599 { 'return_type': 'void',
    600   'names': ['glUniform2iv'],
    601   'arguments': 'GLint location, GLsizei count, const GLint* v', },
    602 { 'return_type': 'void',
    603   'names': ['glUniform3f'],
    604   'arguments': 'GLint location, GLfloat x, GLfloat y, GLfloat z', },
    605 { 'return_type': 'void',
    606   'names': ['glUniform3fv'],
    607   'arguments': 'GLint location, GLsizei count, const GLfloat* v', },
    608 { 'return_type': 'void',
    609   'names': ['glUniform3i'],
    610   'arguments': 'GLint location, GLint x, GLint y, GLint z', },
    611 { 'return_type': 'void',
    612   'names': ['glUniform3iv'],
    613   'arguments': 'GLint location, GLsizei count, const GLint* v', },
    614 { 'return_type': 'void',
    615   'names': ['glUniform4f'],
    616   'arguments': 'GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w', },
    617 { 'return_type': 'void',
    618   'names': ['glUniform4fv'],
    619   'arguments': 'GLint location, GLsizei count, const GLfloat* v', },
    620 { 'return_type': 'void',
    621   'names': ['glUniform4i'],
    622   'arguments': 'GLint location, GLint x, GLint y, GLint z, GLint w', },
    623 { 'return_type': 'void',
    624   'names': ['glUniform4iv'],
    625   'arguments': 'GLint location, GLsizei count, const GLint* v', },
    626 { 'return_type': 'void',
    627   'names': ['glUniformMatrix2fv'],
    628   'arguments': 'GLint location, GLsizei count, '
    629                'GLboolean transpose, const GLfloat* value', },
    630 { 'return_type': 'void',
    631   'names': ['glUniformMatrix3fv'],
    632   'arguments': 'GLint location, GLsizei count, '
    633                'GLboolean transpose, const GLfloat* value', },
    634 { 'return_type': 'void',
    635   'names': ['glUniformMatrix4fv'],
    636   'arguments': 'GLint location, GLsizei count, '
    637                'GLboolean transpose, const GLfloat* value', },
    638 { 'return_type': 'GLboolean',
    639   'names': ['glUnmapBuffer', 'glUnmapBufferOES'],
    640   'arguments': 'GLenum target', },
    641 { 'return_type': 'void',
    642   'names': ['glUseProgram'],
    643   'arguments': 'GLuint program', },
    644 { 'return_type': 'void',
    645   'names': ['glValidateProgram'],
    646   'arguments': 'GLuint program', },
    647 { 'return_type': 'void',
    648   'names': ['glVertexAttrib1f'],
    649   'arguments': 'GLuint indx, GLfloat x', },
    650 { 'return_type': 'void',
    651   'names': ['glVertexAttrib1fv'],
    652   'arguments': 'GLuint indx, const GLfloat* values', },
    653 { 'return_type': 'void',
    654   'names': ['glVertexAttrib2f'],
    655   'arguments': 'GLuint indx, GLfloat x, GLfloat y', },
    656 { 'return_type': 'void',
    657   'names': ['glVertexAttrib2fv'],
    658   'arguments': 'GLuint indx, const GLfloat* values', },
    659 { 'return_type': 'void',
    660   'names': ['glVertexAttrib3f'],
    661   'arguments': 'GLuint indx, GLfloat x, GLfloat y, GLfloat z', },
    662 { 'return_type': 'void',
    663   'names': ['glVertexAttrib3fv'],
    664   'arguments': 'GLuint indx, const GLfloat* values', },
    665 { 'return_type': 'void',
    666   'names': ['glVertexAttrib4f'],
    667   'arguments': 'GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w', },
    668 { 'return_type': 'void',
    669   'names': ['glVertexAttrib4fv'],
    670   'arguments': 'GLuint indx, const GLfloat* values', },
    671 { 'return_type': 'void',
    672   'names': ['glVertexAttribPointer'],
    673   'arguments': 'GLuint indx, GLint size, GLenum type, GLboolean normalized, '
    674                'GLsizei stride, const void* ptr', },
    675 { 'return_type': 'void',
    676   'names': ['glViewport'],
    677   'arguments': 'GLint x, GLint y, GLsizei width, GLsizei height', },
    678 { 'return_type': 'void',
    679   'names': ['glGenFencesNV'],
    680   'arguments': 'GLsizei n, GLuint* fences', },
    681 { 'return_type': 'void',
    682   'names': ['glDeleteFencesNV'],
    683   'arguments': 'GLsizei n, const GLuint* fences', },
    684 { 'return_type': 'void',
    685   'names': ['glSetFenceNV'],
    686   'arguments': 'GLuint fence, GLenum condition', },
    687 { 'return_type': 'GLboolean',
    688   'names': ['glTestFenceNV'],
    689   'arguments': 'GLuint fence', },
    690 { 'return_type': 'void',
    691   'names': ['glFinishFenceNV'],
    692   'arguments': 'GLuint fence', },
    693 { 'return_type': 'GLboolean',
    694   'names': ['glIsFenceNV'],
    695   'arguments': 'GLuint fence', },
    696 { 'return_type': 'void',
    697   'names': ['glGetFenceivNV'],
    698   'arguments': 'GLuint fence, GLenum pname, GLint* params', },
    699 { 'return_type': 'GLsync',
    700   'names': ['glFenceSync'],
    701   'arguments': 'GLenum condition, GLbitfield flags', },
    702 { 'return_type': 'void',
    703   'names': ['glDeleteSync'],
    704   'arguments': 'GLsync sync', },
    705 { 'return_type': 'void',
    706   'names': ['glGetSynciv'],
    707   'arguments':
    708     'GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length,'
    709     'GLint* values', },
    710 { 'return_type': 'GLenum',
    711   'names': ['glClientWaitSync'],
    712   'arguments':
    713     'GLsync sync, GLbitfield flags, GLuint64 timeout', },
    714 { 'return_type': 'GLenum',
    715   'names': ['glWaitSync'],
    716   'arguments':
    717     'GLsync sync, GLbitfield flags, GLuint64 timeout', },
    718 { 'return_type': 'void',
    719   'names': ['glDrawArraysInstancedANGLE', 'glDrawArraysInstancedARB'],
    720   'arguments': 'GLenum mode, GLint first, GLsizei count, GLsizei primcount', },
    721 { 'return_type': 'void',
    722   'names': ['glDrawElementsInstancedANGLE', 'glDrawElementsInstancedARB'],
    723   'arguments':
    724       'GLenum mode, GLsizei count, GLenum type, const void* indices, '
    725       'GLsizei primcount', },
    726 { 'return_type': 'void',
    727   'names': ['glVertexAttribDivisorANGLE', 'glVertexAttribDivisorARB'],
    728   'arguments':
    729       'GLuint index, GLuint divisor', },
    730 { 'return_type': 'void',
    731   'names': ['glGenVertexArraysOES',
    732             'glGenVertexArraysAPPLE',
    733             'glGenVertexArrays'],
    734   'arguments': 'GLsizei n, GLuint* arrays',
    735   'other_extensions': ['OES_vertex_array_object',
    736                        'APPLE_vertex_array_object',
    737                        'ARB_vertex_array_object'] },
    738 { 'return_type': 'void',
    739   'names': ['glDeleteVertexArraysOES',
    740             'glDeleteVertexArraysAPPLE',
    741             'glDeleteVertexArrays'],
    742   'arguments': 'GLsizei n, const GLuint* arrays',
    743   'other_extensions': ['OES_vertex_array_object',
    744                        'APPLE_vertex_array_object',
    745                        'ARB_vertex_array_object'] },
    746 { 'return_type': 'void',
    747   'names': ['glBindVertexArrayOES',
    748             'glBindVertexArrayAPPLE',
    749             'glBindVertexArray'],
    750   'arguments': 'GLuint array',
    751   'other_extensions': ['OES_vertex_array_object',
    752                        'APPLE_vertex_array_object',
    753                        'ARB_vertex_array_object'] },
    754 { 'return_type': 'GLboolean',
    755   'names': ['glIsVertexArrayOES',
    756             'glIsVertexArrayAPPLE',
    757             'glIsVertexArray'],
    758   'arguments': 'GLuint array',
    759   'other_extensions': ['OES_vertex_array_object',
    760                        'APPLE_vertex_array_object',
    761                        'ARB_vertex_array_object'] },
    762 { 'return_type': 'void',
    763   'names': ['glDiscardFramebufferEXT', 'glInvalidateFramebuffer'],
    764   'arguments': 'GLenum target, GLsizei numAttachments, '
    765       'const GLenum* attachments' },
    766 ]
    767 
    768 OSMESA_FUNCTIONS = [
    769 { 'return_type': 'OSMesaContext',
    770   'names': ['OSMesaCreateContext'],
    771   'arguments': 'GLenum format, OSMesaContext sharelist', },
    772 { 'return_type': 'OSMesaContext',
    773   'names': ['OSMesaCreateContextExt'],
    774   'arguments':
    775       'GLenum format, GLint depthBits, GLint stencilBits, GLint accumBits, '
    776       'OSMesaContext sharelist', },
    777 { 'return_type': 'void',
    778   'names': ['OSMesaDestroyContext'],
    779   'arguments': 'OSMesaContext ctx', },
    780 { 'return_type': 'GLboolean',
    781   'names': ['OSMesaMakeCurrent'],
    782   'arguments': 'OSMesaContext ctx, void* buffer, GLenum type, GLsizei width, '
    783                'GLsizei height', },
    784 { 'return_type': 'OSMesaContext',
    785   'names': ['OSMesaGetCurrentContext'],
    786   'arguments': 'void', },
    787 { 'return_type': 'void',
    788   'names': ['OSMesaPixelStore'],
    789   'arguments': 'GLint pname, GLint value', },
    790 { 'return_type': 'void',
    791   'names': ['OSMesaGetIntegerv'],
    792   'arguments': 'GLint pname, GLint* value', },
    793 { 'return_type': 'GLboolean',
    794   'names': ['OSMesaGetDepthBuffer'],
    795   'arguments':
    796       'OSMesaContext c, GLint* width, GLint* height, GLint* bytesPerValue, '
    797       'void** buffer', },
    798 { 'return_type': 'GLboolean',
    799   'names': ['OSMesaGetColorBuffer'],
    800   'arguments': 'OSMesaContext c, GLint* width, GLint* height, GLint* format, '
    801                'void** buffer', },
    802 { 'return_type': 'OSMESAproc',
    803   'names': ['OSMesaGetProcAddress'],
    804   'arguments': 'const char* funcName', },
    805 { 'return_type': 'void',
    806   'names': ['OSMesaColorClamp'],
    807   'arguments': 'GLboolean enable', },
    808 ]
    809 
    810 EGL_FUNCTIONS = [
    811 { 'return_type': 'EGLint',
    812   'names': ['eglGetError'],
    813   'arguments': 'void', },
    814 { 'return_type': 'EGLDisplay',
    815   'names': ['eglGetDisplay'],
    816   'arguments': 'EGLNativeDisplayType display_id', },
    817 { 'return_type': 'EGLBoolean',
    818   'names': ['eglInitialize'],
    819   'arguments': 'EGLDisplay dpy, EGLint* major, EGLint* minor', },
    820 { 'return_type': 'EGLBoolean',
    821   'names': ['eglTerminate'],
    822   'arguments': 'EGLDisplay dpy', },
    823 { 'return_type': 'const char*',
    824   'names': ['eglQueryString'],
    825   'arguments': 'EGLDisplay dpy, EGLint name', },
    826 { 'return_type': 'EGLBoolean',
    827   'names': ['eglGetConfigs'],
    828   'arguments': 'EGLDisplay dpy, EGLConfig* configs, EGLint config_size, '
    829                'EGLint* num_config', },
    830 { 'return_type': 'EGLBoolean',
    831   'names': ['eglChooseConfig'],
    832   'arguments': 'EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, '
    833                'EGLint config_size, EGLint* num_config', },
    834 { 'return_type': 'EGLBoolean',
    835   'names': ['eglGetConfigAttrib'],
    836   'arguments':
    837       'EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value', },
    838 { 'return_type': 'EGLImageKHR',
    839   'names': ['eglCreateImageKHR'],
    840   'arguments':
    841       'EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, '
    842       'const EGLint* attrib_list',
    843   'other_extensions': ['EGL_KHR_image_base', 'EGL_KHR_gl_texture_2D_image'] },
    844 { 'return_type': 'EGLBoolean',
    845   'names': ['eglDestroyImageKHR'],
    846   'arguments': 'EGLDisplay dpy, EGLImageKHR image',
    847   'other_extensions': ['EGL_KHR_image_base'] },
    848 { 'return_type': 'EGLSurface',
    849   'names': ['eglCreateWindowSurface'],
    850   'arguments': 'EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, '
    851                'const EGLint* attrib_list', },
    852 { 'return_type': 'EGLSurface',
    853   'names': ['eglCreatePbufferSurface'],
    854   'arguments': 'EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list', },
    855 { 'return_type': 'EGLSurface',
    856   'names': ['eglCreatePixmapSurface'],
    857   'arguments': 'EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, '
    858                'const EGLint* attrib_list', },
    859 { 'return_type': 'EGLBoolean',
    860   'names': ['eglDestroySurface'],
    861   'arguments': 'EGLDisplay dpy, EGLSurface surface', },
    862 { 'return_type': 'EGLBoolean',
    863   'names': ['eglQuerySurface'],
    864   'arguments':
    865       'EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint* value', },
    866 { 'return_type': 'EGLBoolean',
    867   'names': ['eglBindAPI'],
    868   'arguments': 'EGLenum api', },
    869 { 'return_type': 'EGLenum',
    870   'names': ['eglQueryAPI'],
    871   'arguments': 'void', },
    872 { 'return_type': 'EGLBoolean',
    873   'names': ['eglWaitClient'],
    874   'arguments': 'void', },
    875 { 'return_type': 'EGLBoolean',
    876   'names': ['eglReleaseThread'],
    877   'arguments': 'void', },
    878 { 'return_type': 'EGLSurface',
    879   'names': ['eglCreatePbufferFromClientBuffer'],
    880   'arguments':
    881       'EGLDisplay dpy, EGLenum buftype, void* buffer, EGLConfig config, '
    882       'const EGLint* attrib_list', },
    883 { 'return_type': 'EGLBoolean',
    884   'names': ['eglSurfaceAttrib'],
    885   'arguments':
    886       'EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value', },
    887 { 'return_type': 'EGLBoolean',
    888   'names': ['eglBindTexImage'],
    889   'arguments': 'EGLDisplay dpy, EGLSurface surface, EGLint buffer', },
    890 { 'return_type': 'EGLBoolean',
    891   'names': ['eglReleaseTexImage'],
    892   'arguments': 'EGLDisplay dpy, EGLSurface surface, EGLint buffer', },
    893 { 'return_type': 'EGLBoolean',
    894   'names': ['eglSwapInterval'],
    895   'arguments': 'EGLDisplay dpy, EGLint interval', },
    896 { 'return_type': 'EGLContext',
    897   'names': ['eglCreateContext'],
    898   'arguments': 'EGLDisplay dpy, EGLConfig config, EGLContext share_context, '
    899               'const EGLint* attrib_list', },
    900 { 'return_type': 'EGLBoolean',
    901   'names': ['eglDestroyContext'],
    902   'arguments': 'EGLDisplay dpy, EGLContext ctx', },
    903 { 'return_type': 'EGLBoolean',
    904   'names': ['eglMakeCurrent'],
    905   'arguments':
    906       'EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx', },
    907 { 'return_type': 'EGLContext',
    908   'names': ['eglGetCurrentContext'],
    909   'arguments': 'void', },
    910 { 'return_type': 'EGLSurface',
    911   'names': ['eglGetCurrentSurface'],
    912   'arguments': 'EGLint readdraw', },
    913 { 'return_type': 'EGLDisplay',
    914   'names': ['eglGetCurrentDisplay'],
    915   'arguments': 'void', },
    916 { 'return_type': 'EGLBoolean',
    917   'names': ['eglQueryContext'],
    918   'arguments':
    919       'EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value', },
    920 { 'return_type': 'EGLBoolean',
    921   'names': ['eglWaitGL'],
    922   'arguments': 'void', },
    923 { 'return_type': 'EGLBoolean',
    924   'names': ['eglWaitNative'],
    925   'arguments': 'EGLint engine', },
    926 { 'return_type': 'EGLBoolean',
    927   'names': ['eglSwapBuffers'],
    928   'arguments': 'EGLDisplay dpy, EGLSurface surface', },
    929 { 'return_type': 'EGLBoolean',
    930   'names': ['eglCopyBuffers'],
    931   'arguments':
    932       'EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target', },
    933 { 'return_type': '__eglMustCastToProperFunctionPointerType',
    934   'names': ['eglGetProcAddress'],
    935   'arguments': 'const char* procname', },
    936 { 'return_type': 'EGLBoolean',
    937   'names': ['eglPostSubBufferNV'],
    938   'arguments': 'EGLDisplay dpy, EGLSurface surface, '
    939     'EGLint x, EGLint y, EGLint width, EGLint height', },
    940 { 'return_type': 'EGLBoolean',
    941   'names': ['eglQuerySurfacePointerANGLE'],
    942   'arguments':
    943       'EGLDisplay dpy, EGLSurface surface, EGLint attribute, void** value', },
    944 { 'return_type': 'EGLSyncKHR',
    945   'names': ['eglCreateSyncKHR'],
    946   'arguments': 'EGLDisplay dpy, EGLenum type, const EGLint* attrib_list',
    947   'other_extensions': ['EGL_KHR_fence_sync'] },
    948 { 'return_type': 'EGLint',
    949   'names': ['eglClientWaitSyncKHR'],
    950   'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, '
    951       'EGLTimeKHR timeout',
    952   'other_extensions': ['EGL_KHR_fence_sync'] },
    953 { 'return_type': 'EGLBoolean',
    954   'names': ['eglGetSyncAttribKHR'],
    955   'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, '
    956       'EGLint* value',
    957   'other_extensions': ['EGL_KHR_fence_sync'] },
    958 { 'return_type': 'EGLBoolean',
    959   'names': ['eglDestroySyncKHR'],
    960   'arguments': 'EGLDisplay dpy, EGLSyncKHR sync',
    961   'other_extensions': ['EGL_KHR_fence_sync'] },
    962 { 'return_type': 'EGLBoolean',
    963   'names': ['eglGetSyncValuesCHROMIUM'],
    964   'arguments':
    965       'EGLDisplay dpy, EGLSurface surface, '
    966       'EGLuint64CHROMIUM* ust, EGLuint64CHROMIUM* msc, '
    967       'EGLuint64CHROMIUM* sbc', },
    968 { 'return_type': 'EGLint',
    969   'names': ['eglWaitSyncKHR'],
    970   'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint flags',
    971   'other_extensions': ['EGL_KHR_wait_sync'] },
    972 ]
    973 
    974 WGL_FUNCTIONS = [
    975 { 'return_type': 'HGLRC',
    976   'names': ['wglCreateContext'],
    977   'arguments': 'HDC hdc', },
    978 { 'return_type': 'HGLRC',
    979   'names': ['wglCreateLayerContext'],
    980   'arguments': 'HDC hdc, int iLayerPlane', },
    981 { 'return_type': 'BOOL',
    982   'names': ['wglCopyContext'],
    983   'arguments': 'HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask', },
    984 { 'return_type': 'BOOL',
    985   'names': ['wglDeleteContext'],
    986   'arguments': 'HGLRC hglrc', },
    987 { 'return_type': 'HGLRC',
    988   'names': ['wglGetCurrentContext'],
    989   'arguments': '', },
    990 { 'return_type': 'HDC',
    991   'names': ['wglGetCurrentDC'],
    992   'arguments': '', },
    993 { 'return_type': 'BOOL',
    994   'names': ['wglMakeCurrent'],
    995   'arguments': 'HDC hdc, HGLRC hglrc', },
    996 { 'return_type': 'BOOL',
    997   'names': ['wglShareLists'],
    998   'arguments': 'HGLRC hglrc1, HGLRC hglrc2', },
    999 { 'return_type': 'BOOL',
   1000   'names': ['wglSwapIntervalEXT'],
   1001   'arguments': 'int interval', },
   1002 { 'return_type': 'BOOL',
   1003   'names': ['wglSwapLayerBuffers'],
   1004   'arguments': 'HDC hdc, UINT fuPlanes', },
   1005 { 'return_type': 'const char*',
   1006   'names': ['wglGetExtensionsStringARB'],
   1007   'arguments': 'HDC hDC', },
   1008 { 'return_type': 'const char*',
   1009   'names': ['wglGetExtensionsStringEXT'],
   1010   'arguments': '', },
   1011 { 'return_type': 'BOOL',
   1012   'names': ['wglChoosePixelFormatARB'],
   1013   'arguments':
   1014       'HDC dc, const int* int_attrib_list, const float* float_attrib_list, '
   1015       'UINT max_formats, int* formats, UINT* num_formats', },
   1016 { 'return_type': 'HPBUFFERARB',
   1017   'names': ['wglCreatePbufferARB'],
   1018   'arguments': 'HDC hDC, int iPixelFormat, int iWidth, int iHeight, '
   1019                'const int* piAttribList', },
   1020 { 'return_type': 'HDC',
   1021   'names': ['wglGetPbufferDCARB'],
   1022   'arguments': 'HPBUFFERARB hPbuffer', },
   1023 { 'return_type': 'int',
   1024   'names': ['wglReleasePbufferDCARB'],
   1025   'arguments': 'HPBUFFERARB hPbuffer, HDC hDC', },
   1026 { 'return_type': 'BOOL',
   1027   'names': ['wglDestroyPbufferARB'],
   1028   'arguments': 'HPBUFFERARB hPbuffer', },
   1029 { 'return_type': 'BOOL',
   1030   'names': ['wglQueryPbufferARB'],
   1031   'arguments': 'HPBUFFERARB hPbuffer, int iAttribute, int* piValue', },
   1032 ]
   1033 
   1034 GLX_FUNCTIONS = [
   1035 { 'return_type': 'int',
   1036   'names': ['glXWaitVideoSyncSGI'],
   1037   'arguments': 'int divisor, int remainder, unsigned int* count', },
   1038 { 'return_type': 'XVisualInfo*',
   1039   'names': ['glXChooseVisual'],
   1040   'arguments': 'Display* dpy, int screen, int* attribList', },
   1041 { 'return_type': 'void',
   1042   'names': ['glXCopySubBufferMESA'],
   1043   'arguments': 'Display* dpy, GLXDrawable drawable, '
   1044                'int x, int y, int width, int height', },
   1045 { 'return_type': 'GLXContext',
   1046   'names': ['glXCreateContext'],
   1047   'arguments':
   1048       'Display* dpy, XVisualInfo* vis, GLXContext shareList, int direct', },
   1049 { 'return_type': 'void',
   1050   'names': ['glXBindTexImageEXT'],
   1051   'arguments':
   1052       'Display* dpy, GLXDrawable drawable, int buffer, int* attribList', },
   1053 { 'return_type': 'void',
   1054   'names': ['glXReleaseTexImageEXT'],
   1055   'arguments': 'Display* dpy, GLXDrawable drawable, int buffer', },
   1056 { 'return_type': 'void',
   1057   'names': ['glXDestroyContext'],
   1058   'arguments': 'Display* dpy, GLXContext ctx', },
   1059 { 'return_type': 'int',
   1060   'names': ['glXMakeCurrent'],
   1061   'arguments': 'Display* dpy, GLXDrawable drawable, GLXContext ctx', },
   1062 { 'return_type': 'void',
   1063   'names': ['glXCopyContext'],
   1064   'arguments':
   1065       'Display* dpy, GLXContext src, GLXContext dst, unsigned long mask', },
   1066 { 'return_type': 'void',
   1067   'names': ['glXSwapBuffers'],
   1068   'arguments': 'Display* dpy, GLXDrawable drawable', },
   1069 { 'return_type': 'GLXPixmap',
   1070   'names': ['glXCreateGLXPixmap'],
   1071   'arguments': 'Display* dpy, XVisualInfo* visual, Pixmap pixmap', },
   1072 { 'return_type': 'void',
   1073   'names': ['glXDestroyGLXPixmap'],
   1074   'arguments': 'Display* dpy, GLXPixmap pixmap', },
   1075 { 'return_type': 'int',
   1076   'names': ['glXQueryExtension'],
   1077   'arguments': 'Display* dpy, int* errorb, int* event', },
   1078 { 'return_type': 'int',
   1079   'names': ['glXQueryVersion'],
   1080   'arguments': 'Display* dpy, int* maj, int* min', },
   1081 { 'return_type': 'int',
   1082   'names': ['glXIsDirect'],
   1083   'arguments': 'Display* dpy, GLXContext ctx', },
   1084 { 'return_type': 'int',
   1085   'names': ['glXGetConfig'],
   1086   'arguments': 'Display* dpy, XVisualInfo* visual, int attrib, int* value', },
   1087 { 'return_type': 'GLXContext',
   1088   'names': ['glXGetCurrentContext'],
   1089   'arguments': 'void', },
   1090 { 'return_type': 'GLXDrawable',
   1091   'names': ['glXGetCurrentDrawable'],
   1092   'arguments': 'void', },
   1093 { 'return_type': 'void',
   1094   'names': ['glXWaitGL'],
   1095   'arguments': 'void', },
   1096 { 'return_type': 'void',
   1097   'names': ['glXWaitX'],
   1098   'arguments': 'void', },
   1099 { 'return_type': 'void',
   1100   'names': ['glXUseXFont'],
   1101   'arguments': 'Font font, int first, int count, int list', },
   1102 { 'return_type': 'const char*',
   1103   'names': ['glXQueryExtensionsString'],
   1104   'arguments': 'Display* dpy, int screen', },
   1105 { 'return_type': 'const char*',
   1106   'names': ['glXQueryServerString'],
   1107   'arguments': 'Display* dpy, int screen, int name', },
   1108 { 'return_type': 'const char*',
   1109   'names': ['glXGetClientString'],
   1110   'arguments': 'Display* dpy, int name', },
   1111 { 'return_type': 'Display*',
   1112   'names': ['glXGetCurrentDisplay'],
   1113   'arguments': 'void', },
   1114 { 'return_type': 'GLXFBConfig*',
   1115   'names': ['glXChooseFBConfig'],
   1116   'arguments':
   1117       'Display* dpy, int screen, const int* attribList, int* nitems', },
   1118 { 'return_type': 'int',
   1119   'names': ['glXGetFBConfigAttrib'],
   1120   'arguments': 'Display* dpy, GLXFBConfig config, int attribute, int* value', },
   1121 { 'return_type': 'GLXFBConfig*',
   1122   'names': ['glXGetFBConfigs'],
   1123   'arguments': 'Display* dpy, int screen, int* nelements', },
   1124 { 'return_type': 'XVisualInfo*',
   1125   'names': ['glXGetVisualFromFBConfig'],
   1126   'arguments': 'Display* dpy, GLXFBConfig config', },
   1127 { 'return_type': 'GLXWindow',
   1128   'names': ['glXCreateWindow'],
   1129   'arguments':
   1130       'Display* dpy, GLXFBConfig config, Window win, const int* attribList', },
   1131 { 'return_type': 'void',
   1132   'names': ['glXDestroyWindow'],
   1133   'arguments': 'Display* dpy, GLXWindow window', },
   1134 { 'return_type': 'GLXPixmap',
   1135   'names': ['glXCreatePixmap'],
   1136   'arguments': 'Display* dpy, GLXFBConfig config, '
   1137                'Pixmap pixmap, const int* attribList', },
   1138 { 'return_type': 'void',
   1139   'names': ['glXDestroyPixmap'],
   1140   'arguments': 'Display* dpy, GLXPixmap pixmap', },
   1141 { 'return_type': 'GLXPbuffer',
   1142   'names': ['glXCreatePbuffer'],
   1143   'arguments': 'Display* dpy, GLXFBConfig config, const int* attribList', },
   1144 { 'return_type': 'void',
   1145   'names': ['glXDestroyPbuffer'],
   1146   'arguments': 'Display* dpy, GLXPbuffer pbuf', },
   1147 { 'return_type': 'void',
   1148   'names': ['glXQueryDrawable'],
   1149   'arguments':
   1150       'Display* dpy, GLXDrawable draw, int attribute, unsigned int* value', },
   1151 { 'return_type': 'GLXContext',
   1152   'names': ['glXCreateNewContext'],
   1153   'arguments': 'Display* dpy, GLXFBConfig config, int renderType, '
   1154                'GLXContext shareList, int direct', },
   1155 { 'return_type': 'int',
   1156   'names': ['glXMakeContextCurrent'],
   1157   'arguments':
   1158       'Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx', },
   1159 { 'return_type': 'GLXDrawable',
   1160   'names': ['glXGetCurrentReadDrawable'],
   1161   'arguments': 'void', },
   1162 { 'return_type': 'int',
   1163   'names': ['glXQueryContext'],
   1164   'arguments': 'Display* dpy, GLXContext ctx, int attribute, int* value', },
   1165 { 'return_type': 'void',
   1166   'names': ['glXSelectEvent'],
   1167   'arguments': 'Display* dpy, GLXDrawable drawable, unsigned long mask', },
   1168 { 'return_type': 'void',
   1169   'names': ['glXGetSelectedEvent'],
   1170   'arguments': 'Display* dpy, GLXDrawable drawable, unsigned long* mask', },
   1171 { 'return_type': 'void',
   1172   'names': ['glXSwapIntervalMESA'],
   1173   'arguments': 'unsigned int interval', },
   1174 { 'return_type': 'void',
   1175   'names': ['glXSwapIntervalEXT'],
   1176   'arguments': 'Display* dpy, GLXDrawable drawable, int interval', },
   1177 { 'return_type': 'GLXFBConfig',
   1178   'names': ['glXGetFBConfigFromVisualSGIX'],
   1179   'arguments': 'Display* dpy, XVisualInfo* visualInfo', },
   1180 { 'return_type': 'GLXContext',
   1181   'names': ['glXCreateContextAttribsARB'],
   1182   'arguments':
   1183       'Display* dpy, GLXFBConfig config, GLXContext share_context, int direct, '
   1184       'const int* attrib_list', },
   1185 { 'return_type': 'bool',
   1186   'names': ['glXGetSyncValuesOML'],
   1187   'arguments':
   1188       'Display* dpy, GLXDrawable drawable, int64* ust, int64* msc, '
   1189       'int64* sbc' },
   1190 { 'return_type': 'bool',
   1191   'names': ['glXGetMscRateOML'],
   1192   'arguments':
   1193       'Display* dpy, GLXDrawable drawable, int32* numerator, '
   1194       'int32* denominator' },
   1195 ]
   1196 
   1197 FUNCTION_SETS = [
   1198   [GL_FUNCTIONS, 'gl', [
   1199       'GL/glext.h',
   1200       'GLES2/gl2ext.h',
   1201       # Files below are Chromium-specific and shipped with Chromium sources.
   1202       'GL/glextchromium.h',
   1203       'GLES2/gl2chromium.h',
   1204       'GLES2/gl2extchromium.h'
   1205   ], []],
   1206   [OSMESA_FUNCTIONS, 'osmesa', [], []],
   1207   [EGL_FUNCTIONS, 'egl', [
   1208       'EGL/eglext.h',
   1209       # Files below are Chromium-specific and shipped with Chromium sources.
   1210       'EGL/eglextchromium.h',
   1211     ],
   1212     [
   1213       'EGL_ANGLE_d3d_share_handle_client_buffer',
   1214       'EGL_ANGLE_surface_d3d_texture_2d_share_handle',
   1215     ],
   1216   ],
   1217   [WGL_FUNCTIONS, 'wgl', ['GL/wglext.h'], []],
   1218   [GLX_FUNCTIONS, 'glx', ['GL/glx.h', 'GL/glxext.h'], []],
   1219 ]
   1220 
   1221 def GenerateHeader(file, functions, set_name, used_extension_functions):
   1222   """Generates gl_bindings_autogen_x.h"""
   1223 
   1224   # Write file header.
   1225   file.write(
   1226 """// Copyright (c) 2012 The Chromium Authors. All rights reserved.
   1227 // Use of this source code is governed by a BSD-style license that can be
   1228 // found in the LICENSE file.
   1229 
   1230 // This file is automatically generated.
   1231 
   1232 #ifndef UI_GFX_GL_GL_BINDINGS_AUTOGEN_%(name)s_H_
   1233 #define UI_GFX_GL_GL_BINDINGS_AUTOGEN_%(name)s_H_
   1234 
   1235 namespace gfx {
   1236 
   1237 class GLContext;
   1238 
   1239 """ % {'name': set_name.upper()})
   1240 
   1241   # Write typedefs for function pointer types. Always use the GL name for the
   1242   # typedef.
   1243   file.write('\n')
   1244   for func in functions:
   1245     file.write('typedef %s (GL_BINDING_CALL *%sProc)(%s);\n' %
   1246         (func['return_type'], func['names'][0], func['arguments']))
   1247 
   1248   # Write declarations for booleans indicating which extensions are available.
   1249   file.write('\n')
   1250   file.write("struct Extensions%s {\n" % set_name.upper())
   1251   for extension, ext_functions in used_extension_functions:
   1252     file.write('  bool b_%s;\n' % extension)
   1253   file.write('};\n')
   1254   file.write('\n')
   1255 
   1256   # Write Procs struct.
   1257   file.write("struct Procs%s {\n" % set_name.upper())
   1258   for func in functions:
   1259     file.write('  %sProc %sFn;\n' % (func['names'][0], func['names'][0]))
   1260   file.write('};\n')
   1261   file.write('\n')
   1262 
   1263   # Write Api class.
   1264   file.write(
   1265 """class GL_EXPORT %(name)sApi {
   1266  public:
   1267   %(name)sApi();
   1268   virtual ~%(name)sApi();
   1269 
   1270 """ % {'name': set_name.upper()})
   1271   for func in functions:
   1272     file.write('  virtual %s %sFn(%s) = 0;\n' %
   1273       (func['return_type'], func['names'][0], func['arguments']))
   1274   file.write('};\n')
   1275   file.write('\n')
   1276 
   1277   file.write( '}  // namespace gfx\n')
   1278 
   1279   # Write macros to invoke function pointers. Always use the GL name for the
   1280   # macro.
   1281   file.write('\n')
   1282   for func in functions:
   1283     file.write('#define %s ::gfx::g_current_%s_context->%sFn\n' %
   1284         (func['names'][0], set_name.lower(), func['names'][0]))
   1285 
   1286   file.write('\n')
   1287   file.write('#endif  //  UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' %
   1288       set_name.upper())
   1289 
   1290 
   1291 def GenerateAPIHeader(file, functions, set_name, used_extension_functions):
   1292   """Generates gl_bindings_api_autogen_x.h"""
   1293 
   1294   # Write file header.
   1295   file.write(
   1296 """// Copyright (c) 2012 The Chromium Authors. All rights reserved.
   1297 // Use of this source code is governed by a BSD-style license that can be
   1298 // found in the LICENSE file.
   1299 
   1300 // This file is automatically generated.
   1301 
   1302 """ % {'name': set_name.upper()})
   1303 
   1304   # Write API declaration.
   1305   for func in functions:
   1306     file.write('  virtual %s %sFn(%s) OVERRIDE;\n' %
   1307       (func['return_type'], func['names'][0], func['arguments']))
   1308 
   1309   file.write('\n')
   1310 
   1311 
   1312 def GenerateMockHeader(file, functions, set_name, used_extension_functions):
   1313   """Generates gl_mock_autogen_x.h"""
   1314 
   1315   # Write file header.
   1316   file.write(
   1317 """// Copyright (c) 2012 The Chromium Authors. All rights reserved.
   1318 // Use of this source code is governed by a BSD-style license that can be
   1319 // found in the LICENSE file.
   1320 
   1321 // This file is automatically generated.
   1322 
   1323 """ % {'name': set_name.upper()})
   1324 
   1325   # Write API declaration.
   1326   for func in functions:
   1327     args = func['arguments']
   1328     if args == 'void':
   1329       args = ''
   1330     arg_count = 0
   1331     if len(args):
   1332       arg_count = func['arguments'].count(',') + 1
   1333     file.write('  MOCK_METHOD%d(%s, %s(%s));\n' %
   1334       (arg_count, func['names'][0][2:], func['return_type'], args))
   1335 
   1336   file.write('\n')
   1337 
   1338 
   1339 def GenerateInterfaceHeader(
   1340     file, functions, set_name, used_extension_functions):
   1341   """Generates gl_interface_autogen_x.h"""
   1342 
   1343   # Write file header.
   1344   file.write(
   1345 """// Copyright (c) 2012 The Chromium Authors. All rights reserved.
   1346 // Use of this source code is governed by a BSD-style license that can be
   1347 // found in the LICENSE file.
   1348 
   1349 // This file is automatically generated.
   1350 
   1351 """ % {'name': set_name.upper()})
   1352 
   1353   # Write API declaration.
   1354   for func in functions:
   1355     args = func['arguments']
   1356     if args == 'void':
   1357       args = ''
   1358     file.write('  virtual %s %s(%s) = 0;\n' %
   1359       (func['return_type'], func['names'][0][2:], args))
   1360 
   1361   file.write('\n')
   1362 
   1363 
   1364 def GenerateSource(file, functions, set_name, used_extension_functions):
   1365   """Generates gl_bindings_autogen_x.cc"""
   1366 
   1367   # Write file header.
   1368   file.write(
   1369 """// Copyright (c) 2011 The Chromium Authors. All rights reserved.
   1370 // Use of this source code is governed by a BSD-style license that can be
   1371 // found in the LICENSE file.
   1372 
   1373 // This file is automatically generated.
   1374 
   1375 #include <string>
   1376 #include "base/debug/trace_event.h"
   1377 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
   1378 #include "ui/gl/gl_bindings.h"
   1379 #include "ui/gl/gl_context.h"
   1380 #include "ui/gl/gl_implementation.h"
   1381 #include "ui/gl/gl_%s_api_implementation.h"
   1382 
   1383 using gpu::gles2::GLES2Util;
   1384 
   1385 namespace gfx {
   1386 """ % set_name.lower())
   1387 
   1388   # Write definitions of function pointers.
   1389   file.write('\n')
   1390   file.write('static bool g_debugBindingsInitialized;\n')
   1391   file.write('Driver%s g_driver_%s;\n' % (set_name.upper(), set_name.lower()))
   1392   file.write('\n')
   1393 
   1394   # Write function to initialize the core function pointers. The code assumes
   1395   # any non-NULL pointer returned by GetGLCoreProcAddress() is valid, although
   1396   # it may be overwritten by an extension function pointer later.
   1397   file.write('\n')
   1398   file.write('void Driver%s::InitializeBindings() {\n' %
   1399              set_name.upper())
   1400   for func in functions:
   1401     first_name = func['names'][0]
   1402     for i, name in enumerate(func['names']):
   1403       if i:
   1404         file.write('  if (!fn.%sFn)\n  ' % first_name)
   1405       file.write(
   1406           '  fn.%sFn = reinterpret_cast<%sProc>('
   1407           'GetGLCoreProcAddress("%s"));\n' %
   1408           (first_name, first_name, name))
   1409   file.write('}\n')
   1410   file.write('\n')
   1411 
   1412   # Write function to initialize the extension function pointers. This function
   1413   # uses a current context to query which extensions are actually supported.
   1414   file.write("""void Driver%s::InitializeExtensionBindings(
   1415     GLContext* context) {
   1416 """ % set_name.upper())
   1417   file.write('  DCHECK(context && context->IsCurrent(NULL));\n')
   1418   for extension, ext_functions in used_extension_functions:
   1419     file.write('  ext.b_%s = context->HasExtension("%s");\n' %
   1420         (extension, extension))
   1421     file.write('  if (ext.b_%s) {\n' %
   1422         (extension))
   1423     queried_entry_points = set()
   1424     for entry_point_name, function_name in ext_functions:
   1425       # Replace the pointer unconditionally unless this extension has several
   1426       # alternatives for the same entry point (e.g.,
   1427       # GL_ARB_blend_func_extended).
   1428       if entry_point_name in queried_entry_points:
   1429         file.write('    if (!fn.%sFn)\n  ' % entry_point_name)
   1430       file.write(
   1431          '    fn.%sFn = reinterpret_cast<%sProc>(GetGLProcAddress("%s"));\n' %
   1432              (entry_point_name, entry_point_name, function_name))
   1433       queried_entry_points.add(entry_point_name)
   1434     file.write('  }\n')
   1435   file.write('  if (g_debugBindingsInitialized)\n')
   1436   file.write('    UpdateDebugExtensionBindings();\n')
   1437   file.write('}\n')
   1438   file.write('\n')
   1439 
   1440   # Write logging wrappers for each function.
   1441   file.write('extern "C" {\n')
   1442   for func in functions:
   1443     names = func['names']
   1444     return_type = func['return_type']
   1445     arguments = func['arguments']
   1446     file.write('\n')
   1447     file.write('static %s GL_BINDING_CALL Debug_%s(%s) {\n' %
   1448         (return_type, names[0], arguments))
   1449     argument_names = re.sub(
   1450         r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', arguments)
   1451     argument_names = re.sub(
   1452         r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', argument_names)
   1453     log_argument_names = re.sub(
   1454         r'const char\* ([a-zA-Z0-9_]+)', r'CONSTCHAR_\1', arguments)
   1455     log_argument_names = re.sub(
   1456         r'(const )?[a-zA-Z0-9_]+\* ([a-zA-Z0-9_]+)',
   1457         r'CONSTVOID_\2', log_argument_names)
   1458     log_argument_names = re.sub(
   1459         r'(?<!E)GLenum ([a-zA-Z0-9_]+)', r'GLenum_\1', log_argument_names)
   1460     log_argument_names = re.sub(
   1461         r'(?<!E)GLboolean ([a-zA-Z0-9_]+)', r'GLboolean_\1', log_argument_names)
   1462     log_argument_names = re.sub(
   1463         r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2',
   1464         log_argument_names)
   1465     log_argument_names = re.sub(
   1466         r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2',
   1467         log_argument_names)
   1468     log_argument_names = re.sub(
   1469         r'CONSTVOID_([a-zA-Z0-9_]+)',
   1470         r'static_cast<const void*>(\1)', log_argument_names);
   1471     log_argument_names = re.sub(
   1472         r'CONSTCHAR_([a-zA-Z0-9_]+)', r'\1', log_argument_names);
   1473     log_argument_names = re.sub(
   1474         r'GLenum_([a-zA-Z0-9_]+)', r'GLES2Util::GetStringEnum(\1)',
   1475         log_argument_names)
   1476     log_argument_names = re.sub(
   1477         r'GLboolean_([a-zA-Z0-9_]+)', r'GLES2Util::GetStringBool(\1)',
   1478         log_argument_names)
   1479     log_argument_names = log_argument_names.replace(',', ' << ", " <<')
   1480     if argument_names == 'void' or argument_names == '':
   1481       argument_names = ''
   1482       log_argument_names = ''
   1483     else:
   1484       log_argument_names = " << " + log_argument_names
   1485     function_name = names[0]
   1486     if return_type == 'void':
   1487       file.write('  GL_SERVICE_LOG("%s" << "(" %s << ")");\n' %
   1488           (function_name, log_argument_names))
   1489       file.write('  g_driver_%s.debug_fn.%sFn(%s);\n' %
   1490           (set_name.lower(), function_name, argument_names))
   1491       if 'logging_code' in func:
   1492         file.write("%s\n" % func['logging_code'])
   1493     else:
   1494       file.write('  GL_SERVICE_LOG("%s" << "(" %s << ")");\n' %
   1495           (function_name, log_argument_names))
   1496       file.write('  %s result = g_driver_%s.debug_fn.%sFn(%s);\n' %
   1497           (return_type, set_name.lower(), function_name, argument_names))
   1498       if 'logging_code' in func:
   1499         file.write("%s\n" % func['logging_code'])
   1500       else:
   1501         file.write('  GL_SERVICE_LOG("GL_RESULT: " << result);\n');
   1502       file.write('  return result;\n')
   1503     file.write('}\n')
   1504   file.write('}  // extern "C"\n')
   1505 
   1506   # Write function to initialize the debug function pointers.
   1507   file.write('\n')
   1508   file.write('void Driver%s::InitializeDebugBindings() {\n' %
   1509              set_name.upper())
   1510   for func in functions:
   1511     first_name = func['names'][0]
   1512     file.write('  if (!debug_fn.%sFn) {\n' % first_name)
   1513     file.write('    debug_fn.%sFn = fn.%sFn;\n' % (first_name, first_name))
   1514     file.write('    fn.%sFn = Debug_%s;\n' % (first_name, first_name))
   1515     file.write('  }\n')
   1516   file.write('  g_debugBindingsInitialized = true;\n')
   1517   file.write('}\n')
   1518 
   1519   # Write function to update the debug function pointers to extension functions
   1520   # after the extensions have been initialized.
   1521   file.write('\n')
   1522   file.write('void Driver%s::UpdateDebugExtensionBindings() {\n' %
   1523              set_name.upper())
   1524   for extension, ext_functions in used_extension_functions:
   1525     for name, _ in ext_functions:
   1526       file.write('  if (debug_fn.%sFn != fn.%sFn &&\n' % (name, name))
   1527       file.write('      fn.%sFn != Debug_%s) {\n' % (name, name))
   1528       file.write('    debug_fn.%sFn = fn.%sFn;\n' % (name, name))
   1529       file.write('    fn.%sFn = Debug_%s;\n' % (name, name))
   1530       file.write('  }\n')
   1531   file.write('}\n')
   1532 
   1533   # Write function to clear all function pointers.
   1534   file.write('\n')
   1535   file.write("""void Driver%s::ClearBindings() {
   1536   memset(this, 0, sizeof(*this));
   1537 }
   1538 """ % set_name.upper())
   1539 
   1540   # Write GLApiBase functions
   1541   for func in functions:
   1542     names = func['names']
   1543     return_type = func['return_type']
   1544     arguments = func['arguments']
   1545     file.write('\n')
   1546     file.write('%s %sApiBase::%sFn(%s) {\n' %
   1547         (return_type, set_name.upper(), names[0], arguments))
   1548     argument_names = re.sub(
   1549         r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', arguments)
   1550     argument_names = re.sub(
   1551         r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', argument_names)
   1552     if argument_names == 'void' or argument_names == '':
   1553       argument_names = ''
   1554     function_name = names[0]
   1555     if return_type == 'void':
   1556       file.write('  driver_->fn.%sFn(%s);\n' %
   1557           (function_name, argument_names))
   1558     else:
   1559       file.write('  return driver_->fn.%sFn(%s);\n' %
   1560           (function_name, argument_names))
   1561     file.write('}\n')
   1562 
   1563   # Write TraceGLApi functions
   1564   for func in functions:
   1565     names = func['names']
   1566     return_type = func['return_type']
   1567     arguments = func['arguments']
   1568     file.write('\n')
   1569     file.write('%s Trace%sApi::%sFn(%s) {\n' %
   1570         (return_type, set_name.upper(), names[0], arguments))
   1571     argument_names = re.sub(
   1572         r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', arguments)
   1573     argument_names = re.sub(
   1574         r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', argument_names)
   1575     if argument_names == 'void' or argument_names == '':
   1576       argument_names = ''
   1577     function_name = names[0]
   1578     file.write('  TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::%s")\n' %
   1579                function_name)
   1580     if return_type == 'void':
   1581       file.write('  %s_api_->%sFn(%s);\n' %
   1582           (set_name.lower(), function_name, argument_names))
   1583     else:
   1584       file.write('  return %s_api_->%sFn(%s);\n' %
   1585           (set_name.lower(), function_name, argument_names))
   1586     file.write('}\n')
   1587 
   1588   file.write('\n')
   1589   file.write('}  // namespace gfx\n')
   1590 
   1591 
   1592 def GenerateMockSource(file, functions):
   1593   """Generates functions that invoke a mock GLInterface"""
   1594 
   1595   file.write(
   1596 """// Copyright (c) 2011 The Chromium Authors. All rights reserved.
   1597 // Use of this source code is governed by a BSD-style license that can be
   1598 // found in the LICENSE file.
   1599 
   1600 // This file is automatically generated.
   1601 
   1602 #include <string.h>
   1603 
   1604 #include "ui/gl/gl_interface.h"
   1605 
   1606 namespace gfx {
   1607 """)
   1608   # Write function that trampoline into the GLInterface.
   1609   for func in functions:
   1610     file.write('\n')
   1611     file.write('%s GL_BINDING_CALL Mock_%s(%s) {\n' %
   1612         (func['return_type'], func['names'][0], func['arguments']))
   1613     argument_names = re.sub(r'(const )?[a-zA-Z0-9]+((\s*const\s*)?\*)* ([a-zA-Z0-9]+)', r'\4',
   1614                               func['arguments'])
   1615     if argument_names == 'void':
   1616       argument_names = ''
   1617     function_name = func['names'][0][2:]
   1618     if func['return_type'] == 'void':
   1619       file.write('  GLInterface::GetGLInterface()->%s(%s);\n' %
   1620           (function_name, argument_names))
   1621     else:
   1622       file.write('  return GLInterface::GetGLInterface()->%s(%s);\n' %
   1623           (function_name, argument_names))
   1624     file.write('}\n')
   1625 
   1626   # Write an 'invalid' function to catch code calling through uninitialized
   1627   # function pointers or trying to interpret the return value of
   1628   # GLProcAddress().
   1629   file.write('\n')
   1630   file.write('static void MockInvalidFunction() {\n')
   1631   file.write('  NOTREACHED();\n')
   1632   file.write('}\n')
   1633 
   1634   # Write a function to lookup a mock GL function based on its name.
   1635   file.write('\n')
   1636   file.write('void* GL_BINDING_CALL GetMockGLProcAddress(const char* name) {\n')
   1637   for func in functions:
   1638     first_name = func['names'][0]
   1639     file.write('  if (strcmp(name, "%s") == 0)\n' % first_name)
   1640     file.write('    return reinterpret_cast<void*>(Mock_%s);\n' % first_name)
   1641   # Always return a non-NULL pointer like some EGL implementations do.
   1642   file.write('  return reinterpret_cast<void*>(&MockInvalidFunction);\n')
   1643   file.write('}\n');
   1644 
   1645   file.write('\n')
   1646   file.write('}  // namespace gfx\n')
   1647 
   1648 
   1649 def ParseExtensionFunctionsFromHeader(header_file):
   1650   """Parse a C extension header file and return a map from extension names to
   1651   a list of functions.
   1652 
   1653   Args:
   1654     header_file: Line-iterable C header file.
   1655   Returns:
   1656     Map of extension name => functions.
   1657   """
   1658   extension_start = re.compile(
   1659       r'#ifndef ((?:GL|EGL|WGL|GLX)_[A-Z]+_[a-zA-Z]\w+)')
   1660   extension_function = re.compile(r'.+\s+([a-z]+\w+)\s*\(')
   1661   typedef = re.compile(r'typedef .*')
   1662   macro_start = re.compile(r'^#(if|ifdef|ifndef).*')
   1663   macro_end = re.compile(r'^#endif.*')
   1664   macro_depth = 0
   1665   current_extension = None
   1666   current_extension_depth = 0
   1667   extensions = collections.defaultdict(lambda: [])
   1668   for line in header_file:
   1669     if macro_start.match(line):
   1670       macro_depth += 1
   1671     elif macro_end.match(line):
   1672       macro_depth -= 1
   1673       if macro_depth < current_extension_depth:
   1674         current_extension = None
   1675     match = extension_start.match(line)
   1676     if match:
   1677       current_extension = match.group(1)
   1678       current_extension_depth = macro_depth
   1679       assert current_extension not in extensions, \
   1680           "Duplicate extension: " + current_extension
   1681     match = extension_function.match(line)
   1682     if match and current_extension and not typedef.match(line):
   1683       extensions[current_extension].append(match.group(1))
   1684   return extensions
   1685 
   1686 
   1687 def GetExtensionFunctions(extension_headers):
   1688   """Parse extension functions from a list of header files.
   1689 
   1690   Args:
   1691     extension_headers: List of header file names.
   1692   Returns:
   1693     Map of extension name => list of functions.
   1694   """
   1695   extensions = {}
   1696   for header in extension_headers:
   1697     extensions.update(ParseExtensionFunctionsFromHeader(open(header)))
   1698   return extensions
   1699 
   1700 
   1701 def GetFunctionToExtensionMap(extensions):
   1702   """Construct map from a function names to extensions which define the
   1703   function.
   1704 
   1705   Args:
   1706     extensions: Map of extension name => functions.
   1707   Returns:
   1708     Map of function name => extension name.
   1709   """
   1710   function_to_extensions = {}
   1711   for extension, functions in extensions.items():
   1712     for function in functions:
   1713       if not function in function_to_extensions:
   1714         function_to_extensions[function] = []
   1715       function_to_extensions[function].append(extension)
   1716   return function_to_extensions
   1717 
   1718 
   1719 def LooksLikeExtensionFunction(function):
   1720   """Heuristic to see if a function name is consistent with extension function
   1721   naming."""
   1722   vendor = re.match(r'\w+?([A-Z][A-Z]+)$', function)
   1723   return vendor is not None and not vendor.group(1) in ['GL', 'API', 'DC']
   1724 
   1725 
   1726 def GetUsedExtensionFunctions(functions, extension_headers, extra_extensions):
   1727   """Determine which functions belong to extensions.
   1728 
   1729   Args:
   1730     functions: List of (return type, function names, arguments).
   1731     extension_headers: List of header file names.
   1732   Returns:
   1733     List of (extension name, [function name alternatives]) sorted with least
   1734     preferred extensions first.
   1735   """
   1736   # Parse known extensions.
   1737   extensions = GetExtensionFunctions(extension_headers)
   1738   functions_to_extensions = GetFunctionToExtensionMap(extensions)
   1739 
   1740   # Collect all used extension functions.
   1741   used_extension_functions = collections.defaultdict(lambda: [])
   1742   for func in functions:
   1743     for name in func['names']:
   1744       # Make sure we know about all extension functions.
   1745       if (LooksLikeExtensionFunction(name) and
   1746           not name in functions_to_extensions):
   1747         raise RuntimeError('%s looks like an extension function but does not '
   1748             'belong to any of the known extensions.' % name)
   1749       if name in functions_to_extensions:
   1750         extensions = functions_to_extensions[name][:]
   1751         if 'other_extensions' in func:
   1752           extensions.extend(func['other_extensions'])
   1753         for extension in extensions:
   1754           used_extension_functions[extension].append((func['names'][0], name))
   1755 
   1756   # Add extensions that do not have any functions.
   1757   used_extension_functions.update(dict(
   1758       [(e, []) for e in extra_extensions if e not in used_extension_functions]))
   1759 
   1760   def ExtensionSortKey(name):
   1761     # Prefer ratified extensions and EXTs.
   1762     preferences = ['_ARB_', '_OES_', '_EXT_', '']
   1763     for i, category in enumerate(preferences):
   1764       if category in name:
   1765         return -i
   1766   used_extension_functions = sorted(used_extension_functions.items(),
   1767       key = lambda item: ExtensionSortKey(item[0]))
   1768   return used_extension_functions
   1769 
   1770 
   1771 def ResolveHeader(header, header_paths):
   1772   paths = header_paths.split(':')
   1773 
   1774   # Always use a path for Chromium-specific extensions. They are extracted
   1775   # to separate files.
   1776   paths.append('.')
   1777   paths.append('../../gpu')
   1778 
   1779   root = os.path.abspath(os.path.dirname(__file__))
   1780 
   1781   for path in paths:
   1782     result = os.path.join(path, header)
   1783     if not os.path.isabs(path):
   1784       result = os.path.relpath(os.path.join(root, result), os.getcwd())
   1785     if os.path.exists(result):
   1786       # Always use forward slashes as path separators. Otherwise backslashes
   1787       # may be incorrectly interpreted as escape characters.
   1788       return result.replace(os.path.sep, '/')
   1789 
   1790   raise Exception('Header %s not found.' % header)
   1791 
   1792 
   1793 def main(argv):
   1794   """This is the main function."""
   1795 
   1796   parser = optparse.OptionParser()
   1797   parser.add_option('--inputs', action='store_true')
   1798   parser.add_option('--header-paths')
   1799 
   1800   options, args = parser.parse_args(argv)
   1801 
   1802   if options.inputs:
   1803     for [_, _, headers, _] in FUNCTION_SETS:
   1804       for header in headers:
   1805         print ResolveHeader(header, options.header_paths)
   1806     return 0
   1807 
   1808   if len(args) >= 1:
   1809     dir = args[0]
   1810   else:
   1811     dir = '.'
   1812 
   1813   for [functions, set_name, extension_headers, extensions] in FUNCTION_SETS:
   1814     extension_headers = [ResolveHeader(h, options.header_paths)
   1815                          for h in extension_headers]
   1816     used_extension_functions = GetUsedExtensionFunctions(
   1817         functions, extension_headers, extensions)
   1818 
   1819     header_file = open(
   1820         os.path.join(dir, 'gl_bindings_autogen_%s.h' % set_name), 'wb')
   1821     GenerateHeader(header_file, functions, set_name, used_extension_functions)
   1822     header_file.close()
   1823 
   1824     header_file = open(
   1825         os.path.join(dir, 'gl_bindings_api_autogen_%s.h' % set_name), 'wb')
   1826     GenerateAPIHeader(
   1827         header_file, functions, set_name, used_extension_functions)
   1828     header_file.close()
   1829 
   1830     source_file = open(
   1831         os.path.join(dir, 'gl_bindings_autogen_%s.cc' % set_name), 'wb')
   1832     GenerateSource(source_file, functions, set_name, used_extension_functions)
   1833     source_file.close()
   1834 
   1835     header_file = open(
   1836         os.path.join(dir, 'gl_interface_autogen_%s.h' % set_name), 'wb')
   1837     GenerateInterfaceHeader(
   1838         header_file, functions, set_name, used_extension_functions)
   1839     header_file.close()
   1840 
   1841     header_file = open(
   1842         os.path.join(dir, 'gl_mock_autogen_%s.h' % set_name), 'wb')
   1843     GenerateMockHeader(
   1844         header_file, functions, set_name, used_extension_functions)
   1845     header_file.close()
   1846 
   1847   source_file = open(os.path.join(dir, 'gl_bindings_autogen_mock.cc'), 'wb')
   1848   GenerateMockSource(source_file, GL_FUNCTIONS)
   1849   source_file.close()
   1850   return 0
   1851 
   1852 
   1853 if __name__ == '__main__':
   1854   sys.exit(main(sys.argv[1:]))
   1855