1 #!/usr/bin/env python 2 # 3 # Copyright (c) 2013-2015 The Khronos Group Inc. 4 # 5 # Permission is hereby granted, free of charge, to any person obtaining a 6 # copy of this software and/or associated documentation files (the 7 # "Materials"), to deal in the Materials without restriction, including 8 # without limitation the rights to use, copy, modify, merge, publish, 9 # distribute, sublicense, and/or sell copies of the Materials, and to 10 # permit persons to whom the Materials are furnished to do so, subject to 11 # the following conditions: 12 # 13 # The above copyright notice and this permission notice shall be included 14 # in all copies or substantial portions of the Materials. 15 # 16 # THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 # MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. 23 24 import sys, time, pdb, string, cProfile 25 from reg import * 26 27 # debug - start header generation in debugger 28 # dump - dump registry after loading 29 # profile - enable Python profiling 30 # protect - whether to use #ifndef protections 31 # registry <filename> - use specified XML registry instead of gl.xml 32 # target - string name of target header, or all targets if None 33 # timeit - time length of registry loading & header generation 34 # validate - validate return & parameter group tags against <group> 35 debug = False 36 dump = False 37 profile = False 38 protect = True 39 target = None 40 timeit = False 41 validate= False 42 # Default input / log files 43 errFilename = None 44 diagFilename = 'diag.txt' 45 regFilename = 'gl.xml' 46 47 if __name__ == '__main__': 48 i = 1 49 while (i < len(sys.argv)): 50 arg = sys.argv[i] 51 i = i + 1 52 if (arg == '-debug'): 53 write('Enabling debug (-debug)', file=sys.stderr) 54 debug = True 55 elif (arg == '-dump'): 56 write('Enabling dump (-dump)', file=sys.stderr) 57 dump = True 58 elif (arg == '-noprotect'): 59 write('Disabling inclusion protection in output headers', file=sys.stderr) 60 protect = False 61 elif (arg == '-profile'): 62 write('Enabling profiling (-profile)', file=sys.stderr) 63 profile = True 64 elif (arg == '-registry'): 65 regFilename = sys.argv[i] 66 i = i+1 67 write('Using registry ', regFilename, file=sys.stderr) 68 elif (arg == '-time'): 69 write('Enabling timing (-time)', file=sys.stderr) 70 timeit = True 71 elif (arg == '-validate'): 72 write('Enabling group validation (-validate)', file=sys.stderr) 73 validate = True 74 elif (arg[0:1] == '-'): 75 write('Unrecognized argument:', arg, file=sys.stderr) 76 exit(1) 77 else: 78 target = arg 79 write('Using target', target, file=sys.stderr) 80 81 # Simple timer functions 82 startTime = None 83 def startTimer(): 84 global startTime 85 startTime = time.clock() 86 def endTimer(msg): 87 global startTime 88 endTime = time.clock() 89 if (timeit): 90 write(msg, endTime - startTime) 91 startTime = None 92 93 # Load & parse registry 94 reg = Registry() 95 96 startTimer() 97 tree = etree.parse(regFilename) 98 endTimer('Time to make ElementTree =') 99 100 startTimer() 101 reg.loadElementTree(tree) 102 endTimer('Time to parse ElementTree =') 103 104 if (validate): 105 reg.validateGroups() 106 107 if (dump): 108 write('***************************************') 109 write('Performing Registry dump to regdump.txt') 110 write('***************************************') 111 reg.dumpReg(filehandle = open('regdump.txt','w')) 112 113 # Turn a list of strings into a regexp string matching exactly those strings 114 def makeREstring(list): 115 return '^(' + '|'.join(list) + ')$' 116 117 # These are "mandatory" OpenGL ES 1 extensions, to 118 # be included in the core GLES/gl.h header. 119 es1CoreList = [ 120 'GL_OES_read_format', 121 'GL_OES_compressed_paletted_texture', 122 'GL_OES_point_size_array', 123 'GL_OES_point_sprite' 124 ] 125 126 # Descriptive names for various regexp patterns used to select 127 # versions and extensions 128 129 allVersions = allExtensions = '.*' 130 noVersions = noExtensions = None 131 gl12andLaterPat = '1\.[2-9]|[234]\.[0-9]' 132 gles2onlyPat = '2\.[0-9]' 133 gles2and30Pat = '2\.[0-9]|3.0' 134 gles2and30and31Pat = '2.[0-9]|3.[01]' 135 es1CorePat = makeREstring(es1CoreList) 136 # Extensions in old glcorearb.h but not yet tagged accordingly in gl.xml 137 glCoreARBPat = None 138 glx13andLaterPat = '1\.[3-9]' 139 140 # Copyright text prefixing all headers (list of strings). 141 prefixStrings = [ 142 '/*', 143 '** Copyright (c) 2013-2015 The Khronos Group Inc.', 144 '**', 145 '** Permission is hereby granted, free of charge, to any person obtaining a', 146 '** copy of this software and/or associated documentation files (the', 147 '** "Materials"), to deal in the Materials without restriction, including', 148 '** without limitation the rights to use, copy, modify, merge, publish,', 149 '** distribute, sublicense, and/or sell copies of the Materials, and to', 150 '** permit persons to whom the Materials are furnished to do so, subject to', 151 '** the following conditions:', 152 '**', 153 '** The above copyright notice and this permission notice shall be included', 154 '** in all copies or substantial portions of the Materials.', 155 '**', 156 '** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,', 157 '** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF', 158 '** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.', 159 '** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY', 160 '** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,', 161 '** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE', 162 '** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.', 163 '*/', 164 '/*', 165 '** This header is generated from the Khronos OpenGL / OpenGL ES XML', 166 '** API Registry. The current version of the Registry, generator scripts', 167 '** used to make the header, and the header can be found at', 168 '** http://www.opengl.org/registry/', 169 '**', 170 '** Khronos $' + 'Revision$ on $' + 'Date$', 171 '*/', 172 '' 173 ] 174 175 # glext.h / glcorearb.h define calling conventions inline (no GL *platform.h) 176 glExtPlatformStrings = [ 177 '#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)', 178 '#ifndef WIN32_LEAN_AND_MEAN', 179 '#define WIN32_LEAN_AND_MEAN 1', 180 '#endif', 181 '#include <windows.h>', 182 '#endif', 183 '', 184 '#ifndef APIENTRY', 185 '#define APIENTRY', 186 '#endif', 187 '#ifndef APIENTRYP', 188 '#define APIENTRYP APIENTRY *', 189 '#endif', 190 '#ifndef GLAPI', 191 '#define GLAPI extern', 192 '#endif', 193 '' 194 ] 195 196 glCorearbPlatformStrings = glExtPlatformStrings + [ 197 '/* glcorearb.h is for use with OpenGL core profile implementations.', 198 '** It should should be placed in the same directory as gl.h and', 199 '** included as <GL/glcorearb.h>.', 200 '**', 201 '** glcorearb.h includes only APIs in the latest OpenGL core profile', 202 '** implementation together with APIs in newer ARB extensions which ', 203 '** can be supported by the core profile. It does not, and never will', 204 '** include functionality removed from the core profile, such as', 205 '** fixed-function vertex and fragment processing.', 206 '**', 207 '** Do not #include both <GL/glcorearb.h> and either of <GL/gl.h> or', 208 '** <GL/glext.h> in the same source file.', 209 '*/', 210 '' 211 ] 212 213 # wglext.h needs Windows include 214 wglPlatformStrings = [ 215 '#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)', 216 '#define WIN32_LEAN_AND_MEAN 1', 217 '#include <windows.h>', 218 '#endif', 219 '', 220 ] 221 222 # GLES 1/2/3 core .h have separate *platform.h files to define calling conventions 223 gles1PlatformStrings = [ '#include <GLES/glplatform.h>', '' ] 224 gles2PlatformStrings = [ '#include <GLES2/gl2platform.h>', '' ] 225 gles3PlatformStrings = [ '#include <GLES3/gl3platform.h>', '' ] 226 eglPlatformStrings = [ '#include <EGL/eglplatform.h>', '' ] 227 228 # GLES headers have a small addition to calling convention headers for function pointer typedefs 229 apiEntryPrefixStrings = [ 230 '#ifndef GL_APIENTRYP', 231 '#define GL_APIENTRYP GL_APIENTRY*', 232 '#endif', 233 '' 234 ] 235 236 # Insert generation date in a comment for headers not having *GLEXT_VERSION macros 237 genDateCommentString = [ 238 format("/* Generated on date %s */" % time.strftime("%Y%m%d")), 239 '' 240 ] 241 242 # GL_GLEXT_VERSION is defined only in glext.h 243 glextVersionStrings = [ 244 format("#define GL_GLEXT_VERSION %s" % time.strftime("%Y%m%d")), 245 '' 246 ] 247 # WGL_WGLEXT_VERSION is defined only in wglext.h 248 wglextVersionStrings = [ 249 format("#define WGL_WGLEXT_VERSION %s" % time.strftime("%Y%m%d")), 250 '' 251 ] 252 # GLX_GLXEXT_VERSION is defined only in glxext.h 253 glxextVersionStrings = [ 254 format("#define GLX_GLXEXT_VERSION %s" % time.strftime("%Y%m%d")), 255 '' 256 ] 257 # EGL_EGLEXT_VERSION is defined only in eglext.h 258 eglextVersionStrings = [ 259 format("#define EGL_EGLEXT_VERSION %s" % time.strftime("%Y%m%d")), 260 '' 261 ] 262 263 # Defaults for generating re-inclusion protection wrappers (or not) 264 protectFile = protect 265 protectFeature = protect 266 protectProto = protect 267 268 buildList = [ 269 # GL API 1.2+ + extensions - GL/glext.h 270 CGeneratorOptions( 271 filename = 'GL/glext.h', 272 apiname = 'gl', 273 profile = 'compatibility', 274 versions = allVersions, 275 emitversions = gl12andLaterPat, 276 defaultExtensions = 'gl', # Default extensions for GL 277 addExtensions = None, 278 removeExtensions = None, 279 prefixText = prefixStrings + glExtPlatformStrings + glextVersionStrings, 280 genFuncPointers = True, 281 protectFile = protectFile, 282 protectFeature = protectFeature, 283 protectProto = protectProto, 284 protectProtoStr = 'GL_GLEXT_PROTOTYPES', 285 apicall = 'GLAPI ', 286 apientry = 'APIENTRY ', 287 apientryp = 'APIENTRYP '), 288 # GL core profile + extensions - GL/glcorearb.h 289 CGeneratorOptions( 290 filename = 'GL/glcorearb.h', 291 apiname = 'gl', 292 profile = 'core', 293 versions = allVersions, 294 emitversions = allVersions, 295 defaultExtensions = 'glcore', # Default extensions for GL core profile (only) 296 addExtensions = glCoreARBPat, 297 removeExtensions = None, 298 prefixText = prefixStrings + glCorearbPlatformStrings, 299 genFuncPointers = True, 300 protectFile = protectFile, 301 protectFeature = protectFeature, 302 protectProto = protectProto, 303 protectProtoStr = 'GL_GLEXT_PROTOTYPES', 304 apicall = 'GLAPI ', 305 apientry = 'APIENTRY ', 306 apientryp = 'APIENTRYP '), 307 # GLES 1.x API + mandatory extensions - GLES/gl.h (no function pointers) 308 CGeneratorOptions( 309 filename = 'GLES/gl.h', 310 apiname = 'gles1', 311 profile = 'common', 312 versions = allVersions, 313 emitversions = allVersions, 314 defaultExtensions = None, # No default extensions 315 addExtensions = es1CorePat, # Add mandatory ES1 extensions in GLES1/gl.h 316 removeExtensions = None, 317 prefixText = prefixStrings + gles1PlatformStrings + genDateCommentString, 318 genFuncPointers = False, 319 protectFile = protectFile, 320 protectFeature = protectFeature, 321 protectProto = False, # Core ES API functions are in the static link libraries 322 protectProtoStr = 'GL_GLEXT_PROTOTYPES', 323 apicall = 'GL_API ', 324 apientry = 'GL_APIENTRY ', 325 apientryp = 'GL_APIENTRYP '), 326 # GLES 1.x extensions - GLES/glext.h 327 CGeneratorOptions( 328 filename = 'GLES/glext.h', 329 apiname = 'gles1', 330 profile = 'common', 331 versions = allVersions, 332 emitversions = noVersions, 333 defaultExtensions = 'gles1', # Default extensions for GLES 1 334 addExtensions = None, 335 removeExtensions = es1CorePat, # Remove mandatory ES1 extensions in GLES1/glext.h 336 prefixText = prefixStrings + apiEntryPrefixStrings + genDateCommentString, 337 genFuncPointers = True, 338 protectFile = protectFile, 339 protectFeature = protectFeature, 340 protectProto = protectProto, 341 protectProtoStr = 'GL_GLEXT_PROTOTYPES', 342 apicall = 'GL_API ', 343 apientry = 'GL_APIENTRY ', 344 apientryp = 'GL_APIENTRYP '), 345 # GLES 2.0 API - GLES2/gl2.h (now with function pointers) 346 CGeneratorOptions( 347 filename = 'GLES2/gl2.h', 348 apiname = 'gles2', 349 profile = 'common', 350 versions = gles2onlyPat, 351 emitversions = allVersions, 352 defaultExtensions = None, # No default extensions 353 addExtensions = None, 354 removeExtensions = None, 355 prefixText = prefixStrings + gles2PlatformStrings + apiEntryPrefixStrings + genDateCommentString, 356 genFuncPointers = True, 357 protectFile = protectFile, 358 protectFeature = protectFeature, 359 protectProto = protectProto, # Core ES API functions are in the static link libraries 360 protectProtoStr = 'GL_GLEXT_PROTOTYPES', 361 apicall = 'GL_APICALL ', 362 apientry = 'GL_APIENTRY ', 363 apientryp = 'GL_APIENTRYP '), 364 # GLES 3.1 / 3.0 / 2.0 extensions - GLES2/gl2ext.h 365 CGeneratorOptions( 366 filename = 'GLES2/gl2ext.h', 367 apiname = 'gles2', 368 profile = 'common', 369 versions = gles2onlyPat, 370 emitversions = None, 371 defaultExtensions = 'gles2', # Default extensions for GLES 2 372 addExtensions = None, 373 removeExtensions = None, 374 prefixText = prefixStrings + apiEntryPrefixStrings + genDateCommentString, 375 genFuncPointers = True, 376 protectFile = protectFile, 377 protectFeature = protectFeature, 378 protectProto = protectProto, 379 protectProtoStr = 'GL_GLEXT_PROTOTYPES', 380 apicall = 'GL_APICALL ', 381 apientry = 'GL_APIENTRY ', 382 apientryp = 'GL_APIENTRYP '), 383 # GLES 3.1 API - GLES3/gl31.h (now with function pointers) 384 CGeneratorOptions( 385 filename = 'GLES3/gl31.h', 386 apiname = 'gles2', 387 profile = 'common', 388 versions = gles2and30and31Pat, 389 emitversions = allVersions, 390 defaultExtensions = None, # No default extensions 391 addExtensions = None, 392 removeExtensions = None, 393 prefixText = prefixStrings + gles3PlatformStrings + apiEntryPrefixStrings + genDateCommentString, 394 genFuncPointers = True, 395 protectFile = protectFile, 396 protectFeature = protectFeature, 397 protectProto = protectProto, # Core ES API functions are in the static link libraries 398 protectProtoStr = 'GL_GLEXT_PROTOTYPES', 399 apicall = 'GL_APICALL ', 400 apientry = 'GL_APIENTRY ', 401 apientryp = 'GL_APIENTRYP '), 402 # GLES 3.0 API - GLES3/gl3.h (now with function pointers) 403 CGeneratorOptions( 404 filename = 'GLES3/gl3.h', 405 apiname = 'gles2', 406 profile = 'common', 407 versions = gles2and30Pat, 408 emitversions = allVersions, 409 defaultExtensions = None, # No default extensions 410 addExtensions = None, 411 removeExtensions = None, 412 prefixText = prefixStrings + gles3PlatformStrings + apiEntryPrefixStrings + genDateCommentString, 413 genFuncPointers = True, 414 protectFile = protectFile, 415 protectFeature = protectFeature, 416 protectProto = protectProto, # Core ES API functions are in the static link libraries 417 protectProtoStr = 'GL_GLEXT_PROTOTYPES', 418 apicall = 'GL_APICALL ', 419 apientry = 'GL_APIENTRY ', 420 apientryp = 'GL_APIENTRYP '), 421 # EGL API - EGL/egl.h (no function pointers, yet @@@) 422 CGeneratorOptions( 423 filename = 'EGL/egl.h', 424 apiname = 'egl', 425 profile = None, 426 versions = allVersions, 427 emitversions = allVersions, 428 defaultExtensions = None, # No default extensions 429 addExtensions = None, 430 removeExtensions = None, 431 prefixText = prefixStrings + eglPlatformStrings + genDateCommentString, 432 genFuncPointers = False, 433 protectFile = protectFile, 434 protectFeature = protectFeature, 435 protectProto = False, 436 protectProtoStr = 'EGL_EGLEXT_PROTOTYPES', 437 apicall = 'EGLAPI ', 438 apientry = 'EGLAPIENTRY ', 439 apientryp = 'EGLAPIENTRYP '), 440 # EGL extensions - EGL/eglext.h (no function pointers, yet @@@) 441 CGeneratorOptions( 442 filename = 'EGL/eglext.h', 443 apiname = 'egl', 444 profile = None, 445 versions = allVersions, 446 emitversions = None, 447 defaultExtensions = 'egl', # Default extensions for EGL 448 addExtensions = None, 449 removeExtensions = None, 450 prefixText = prefixStrings + eglPlatformStrings + eglextVersionStrings, 451 genFuncPointers = True, 452 protectFile = protectFile, 453 protectFeature = protectFeature, 454 protectProto = protectProto, 455 protectProtoStr = 'EGL_EGLEXT_PROTOTYPES', 456 apicall = 'EGLAPI ', 457 apientry = 'EGLAPIENTRY ', 458 apientryp = 'EGLAPIENTRYP '), 459 # GLX 1.* API - GL/glx.h 460 CGeneratorOptions( 461 filename = 'GL/glx.h', 462 apiname = 'glx', 463 profile = None, 464 versions = allVersions, 465 emitversions = allVersions, 466 defaultExtensions = None, # No default extensions 467 addExtensions = None, 468 removeExtensions = None, 469 # add glXPlatformStrings? 470 prefixText = prefixStrings + genDateCommentString, 471 genFuncPointers = True, 472 protectFile = protectFile, 473 protectFeature = protectFeature, 474 protectProto = protectProto, 475 protectProtoStr = 'GLX_GLXEXT_PROTOTYPES', 476 apicall = '', 477 apientry = '', 478 apientryp = ' *'), 479 # GLX 1.3+ API + extensions - GL/glxext.h (no function pointers, yet @@@) 480 CGeneratorOptions( 481 filename = 'GL/glxext.h', 482 apiname = 'glx', 483 profile = None, 484 versions = allVersions, 485 emitversions = glx13andLaterPat, 486 defaultExtensions = 'glx', # Default extensions for GLX 487 addExtensions = None, 488 removeExtensions = None, 489 # add glXPlatformStrings? 490 prefixText = prefixStrings + glxextVersionStrings, 491 genFuncPointers = True, 492 protectFile = protectFile, 493 protectFeature = protectFeature, 494 protectProto = protectProto, 495 protectProtoStr = 'GLX_GLXEXT_PROTOTYPES', 496 apicall = '', 497 apientry = '', 498 apientryp = ' *'), 499 # WGL API + extensions - GL/wgl.h (no function pointers, yet @@@) 500 CGeneratorOptions( 501 filename = 'GL/wgl.h', 502 apiname = 'wgl', 503 profile = None, 504 versions = allVersions, 505 emitversions = allVersions, 506 defaultExtensions = 'wgl', # Default extensions for WGL 507 addExtensions = None, 508 removeExtensions = None, 509 prefixText = prefixStrings + wglPlatformStrings + genDateCommentString, 510 genFuncPointers = True, 511 protectFile = protectFile, 512 protectFeature = protectFeature, 513 protectProto = protectProto, 514 protectProtoStr = 'WGL_WGLEXT_PROTOTYPES', 515 apicall = '', 516 apientry = 'WINAPI ', 517 apientryp = 'WINAPI * '), 518 # WGL extensions - GL/wglext.h (no function pointers, yet @@@) 519 CGeneratorOptions( 520 filename = 'GL/wglext.h', 521 apiname = 'wgl', 522 profile = None, 523 versions = allVersions, 524 emitversions = None, 525 defaultExtensions = 'wgl', # Default extensions for WGL 526 addExtensions = None, 527 removeExtensions = None, 528 prefixText = prefixStrings + wglPlatformStrings + wglextVersionStrings, 529 genFuncPointers = True, 530 protectFile = protectFile, 531 protectFeature = protectFeature, 532 protectProto = protectProto, 533 protectProtoStr = 'WGL_WGLEXT_PROTOTYPES', 534 apicall = '', 535 apientry = 'WINAPI ', 536 apientryp = 'WINAPI * '), 537 # End of list 538 None 539 ] 540 541 # create error/warning & diagnostic files 542 if (errFilename): 543 errWarn = open(errFilename,'w') 544 else: 545 errWarn = sys.stderr 546 diag = open(diagFilename, 'w') 547 548 def genHeaders(): 549 # Loop over targets, building each 550 generated = 0 551 for genOpts in buildList: 552 if (genOpts == None): 553 break 554 if (target and target != genOpts.filename): 555 # write('*** Skipping', genOpts.filename) 556 continue 557 write('*** Building', genOpts.filename) 558 generated = generated + 1 559 startTimer() 560 gen = COutputGenerator(errFile=errWarn, 561 warnFile=errWarn, 562 diagFile=diag) 563 reg.setGenerator(gen) 564 reg.apiGen(genOpts) 565 write('** Generated', genOpts.filename) 566 endTimer('Time to generate ' + genOpts.filename + ' =') 567 if (target and generated == 0): 568 write('Failed to generate target:', target) 569 570 if (debug): 571 pdb.run('genHeaders()') 572 elif (profile): 573 import cProfile, pstats 574 cProfile.run('genHeaders()', 'profile.txt') 575 p = pstats.Stats('profile.txt') 576 p.strip_dirs().sort_stats('time').print_stats(50) 577 else: 578 genHeaders() 579