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