| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/env python |
| 2 # | |
| 3 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 6 | 5 |
| 7 """code generator for GL/GLES extension wrangler.""" | 6 """code generator for GL/GLES extension wrangler.""" |
| 8 | 7 |
| 9 import os | 8 import os |
| 10 import collections | 9 import collections |
| 11 import re | 10 import re |
| 12 import sys | 11 import sys |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 [GL_FUNCTIONS, 'gl', ['../../../third_party/mesa/MesaLib/include/GL/glext.h', | 474 [GL_FUNCTIONS, 'gl', ['../../../third_party/mesa/MesaLib/include/GL/glext.h', |
| 476 '../../../gpu/GLES2/gl2ext.h']], | 475 '../../../gpu/GLES2/gl2ext.h']], |
| 477 [OSMESA_FUNCTIONS, 'osmesa', []], | 476 [OSMESA_FUNCTIONS, 'osmesa', []], |
| 478 [EGL_FUNCTIONS, 'egl', ['../../../gpu/EGL/eglext.h']], | 477 [EGL_FUNCTIONS, 'egl', ['../../../gpu/EGL/eglext.h']], |
| 479 [WGL_FUNCTIONS, 'wgl', [ | 478 [WGL_FUNCTIONS, 'wgl', [ |
| 480 '../../../third_party/mesa/MesaLib/include/GL/wglext.h']], | 479 '../../../third_party/mesa/MesaLib/include/GL/wglext.h']], |
| 481 [GLX_FUNCTIONS, 'glx', [ | 480 [GLX_FUNCTIONS, 'glx', [ |
| 482 '../../../third_party/mesa/MesaLib/include/GL/glxext.h']], | 481 '../../../third_party/mesa/MesaLib/include/GL/glxext.h']], |
| 483 ] | 482 ] |
| 484 | 483 |
| 484 |
| 485 def GenerateHeader(file, functions, set_name, used_extension_functions): | 485 def GenerateHeader(file, functions, set_name, used_extension_functions): |
| 486 """Generates gl_binding_autogen_x.h""" | 486 """Generates gl_binding_autogen_x.h""" |
| 487 | 487 |
| 488 # Write file header. | 488 # Write file header. |
| 489 file.write('// Copyright (c) 2011 The Chromium Authors. All rights reserved.\n
') | 489 file.write('// Copyright (c) 2011 The Chromium Authors. All rights reserved.\n
') |
| 490 file.write('// Use of this source code is governed by a BSD-style license that
can be\n') | 490 file.write('// Use of this source code is governed by a BSD-style license that
can be\n') |
| 491 file.write('// found in the LICENSE file.\n') | 491 file.write('// found in the LICENSE file.\n') |
| 492 file.write('\n') | 492 file.write('\n') |
| 493 file.write('// This file is automatically generated.\n') | 493 file.write('// This file is automatically generated.\n') |
| 494 file.write('\n') | 494 file.write('\n') |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 747 for [return_type, names, arguments] in functions: | 747 for [return_type, names, arguments] in functions: |
| 748 file.write(' if (strcmp(name, "%s") == 0)\n' % names[0]) | 748 file.write(' if (strcmp(name, "%s") == 0)\n' % names[0]) |
| 749 file.write(' return reinterpret_cast<void*>(Mock_%s);\n' % names[0]) | 749 file.write(' return reinterpret_cast<void*>(Mock_%s);\n' % names[0]) |
| 750 # Always return a non-NULL pointer like some EGL implementations do. | 750 # Always return a non-NULL pointer like some EGL implementations do. |
| 751 file.write(' return reinterpret_cast<void*>(&MockInvalidFunction);\n') | 751 file.write(' return reinterpret_cast<void*>(&MockInvalidFunction);\n') |
| 752 file.write('}\n'); | 752 file.write('}\n'); |
| 753 | 753 |
| 754 file.write('\n') | 754 file.write('\n') |
| 755 file.write('} // namespace gfx\n') | 755 file.write('} // namespace gfx\n') |
| 756 | 756 |
| 757 |
| 757 def ParseExtensionFunctionsFromHeader(header_file): | 758 def ParseExtensionFunctionsFromHeader(header_file): |
| 758 """Parse a C extension header file and return a map from extension names to | 759 """Parse a C extension header file and return a map from extension names to |
| 759 a list of functions. | 760 a list of functions. |
| 760 | 761 |
| 761 Args: | 762 Args: |
| 762 header_file: Line-iterable C header file. | 763 header_file: Line-iterable C header file. |
| 763 Returns: | 764 Returns: |
| 764 Map of extension name => functions. | 765 Map of extension name => functions. |
| 765 """ | 766 """ |
| 766 extension_start = re.compile(r'#define ([A-Z]+_[A-Z]+_[a-zA-Z]\w+) 1') | 767 extension_start = re.compile(r'#define ([A-Z]+_[A-Z]+_[a-zA-Z]\w+) 1') |
| (...skipping 16 matching lines...) Expand all Loading... |
| 783 if match: | 784 if match: |
| 784 current_extension = match.group(1) | 785 current_extension = match.group(1) |
| 785 current_extension_depth = macro_depth | 786 current_extension_depth = macro_depth |
| 786 assert current_extension not in extensions, \ | 787 assert current_extension not in extensions, \ |
| 787 "Duplicate extension: " + current_extension | 788 "Duplicate extension: " + current_extension |
| 788 match = extension_function.match(line) | 789 match = extension_function.match(line) |
| 789 if match and current_extension and not typedef.match(line): | 790 if match and current_extension and not typedef.match(line): |
| 790 extensions[current_extension].append(match.group(1)) | 791 extensions[current_extension].append(match.group(1)) |
| 791 return extensions | 792 return extensions |
| 792 | 793 |
| 794 |
| 793 def GetExtensionFunctions(extension_headers): | 795 def GetExtensionFunctions(extension_headers): |
| 794 """Parse extension functions from a list of header files. | 796 """Parse extension functions from a list of header files. |
| 795 | 797 |
| 796 Args: | 798 Args: |
| 797 extension_headers: List of header file names. | 799 extension_headers: List of header file names. |
| 798 Returns: | 800 Returns: |
| 799 Map of extension name => list of functions. | 801 Map of extension name => list of functions. |
| 800 """ | 802 """ |
| 801 extensions = {} | 803 extensions = {} |
| 802 for header in extension_headers: | 804 for header in extension_headers: |
| 803 extensions.update(ParseExtensionFunctionsFromHeader(open(header))) | 805 extensions.update(ParseExtensionFunctionsFromHeader(open(header))) |
| 804 return extensions | 806 return extensions |
| 805 | 807 |
| 808 |
| 806 def GetFunctionToExtensionMap(extensions): | 809 def GetFunctionToExtensionMap(extensions): |
| 807 """Construct map from a function names to extensions which define the | 810 """Construct map from a function names to extensions which define the |
| 808 function. | 811 function. |
| 809 | 812 |
| 810 Args: | 813 Args: |
| 811 extensions: Map of extension name => functions. | 814 extensions: Map of extension name => functions. |
| 812 Returns: | 815 Returns: |
| 813 Map of function name => extension name. | 816 Map of function name => extension name. |
| 814 """ | 817 """ |
| 815 function_to_extension = {} | 818 function_to_extension = {} |
| 816 for extension, functions in extensions.items(): | 819 for extension, functions in extensions.items(): |
| 817 for function in functions: | 820 for function in functions: |
| 818 assert function not in function_to_extension, \ | 821 assert function not in function_to_extension, \ |
| 819 "Duplicate function: " + function | 822 "Duplicate function: " + function |
| 820 function_to_extension[function] = extension | 823 function_to_extension[function] = extension |
| 821 return function_to_extension | 824 return function_to_extension |
| 822 | 825 |
| 826 |
| 823 def LooksLikeExtensionFunction(function): | 827 def LooksLikeExtensionFunction(function): |
| 824 """Heuristic to see if a function name is consistent with extension function | 828 """Heuristic to see if a function name is consistent with extension function |
| 825 naming.""" | 829 naming.""" |
| 826 vendor = re.match(r'\w+?([A-Z][A-Z]+)$', function) | 830 vendor = re.match(r'\w+?([A-Z][A-Z]+)$', function) |
| 827 return vendor is not None and not vendor.group(1) in ['GL', 'API', 'DC'] | 831 return vendor is not None and not vendor.group(1) in ['GL', 'API', 'DC'] |
| 828 | 832 |
| 833 |
| 829 def GetUsedExtensionFunctions(functions, extension_headers): | 834 def GetUsedExtensionFunctions(functions, extension_headers): |
| 830 """Determine which functions belong to extensions. | 835 """Determine which functions belong to extensions. |
| 831 | 836 |
| 832 Args: | 837 Args: |
| 833 functions: List of (return type, function names, arguments). | 838 functions: List of (return type, function names, arguments). |
| 834 extension_headers: List of header file names. | 839 extension_headers: List of header file names. |
| 835 Returns: | 840 Returns: |
| 836 List of (extension name, [function name alternatives]) sorted with least | 841 List of (extension name, [function name alternatives]) sorted with least |
| 837 preferred extensions first. | 842 preferred extensions first. |
| 838 """ | 843 """ |
| (...skipping 17 matching lines...) Expand all Loading... |
| 856 def ExtensionSortKey(name): | 861 def ExtensionSortKey(name): |
| 857 # Prefer ratified extensions and EXTs. | 862 # Prefer ratified extensions and EXTs. |
| 858 preferences = ['_ARB_', '_OES_', '_EXT_', ''] | 863 preferences = ['_ARB_', '_OES_', '_EXT_', ''] |
| 859 for i, category in enumerate(preferences): | 864 for i, category in enumerate(preferences): |
| 860 if category in name: | 865 if category in name: |
| 861 return -i | 866 return -i |
| 862 used_extension_functions = sorted(used_extension_functions.items(), | 867 used_extension_functions = sorted(used_extension_functions.items(), |
| 863 key = lambda item: ExtensionSortKey(item[0])) | 868 key = lambda item: ExtensionSortKey(item[0])) |
| 864 return used_extension_functions | 869 return used_extension_functions |
| 865 | 870 |
| 871 |
| 866 def main(argv): | 872 def main(argv): |
| 867 """This is the main function.""" | 873 """This is the main function.""" |
| 868 | 874 |
| 869 if len(argv) >= 1: | 875 if len(argv) >= 1: |
| 870 dir = argv[0] | 876 dir = argv[0] |
| 871 else: | 877 else: |
| 872 dir = '.' | 878 dir = '.' |
| 873 | 879 |
| 874 for [functions, set_name, extension_headers] in FUNCTION_SETS: | 880 for [functions, set_name, extension_headers] in FUNCTION_SETS: |
| 875 used_extension_functions = GetUsedExtensionFunctions( | 881 used_extension_functions = GetUsedExtensionFunctions( |
| 876 functions, extension_headers) | 882 functions, extension_headers) |
| 877 | 883 |
| 878 header_file = open( | 884 header_file = open( |
| 879 os.path.join(dir, 'gl_bindings_autogen_%s.h' % set_name), 'wb') | 885 os.path.join(dir, 'gl_bindings_autogen_%s.h' % set_name), 'wb') |
| 880 GenerateHeader(header_file, functions, set_name, used_extension_functions) | 886 GenerateHeader(header_file, functions, set_name, used_extension_functions) |
| 881 header_file.close() | 887 header_file.close() |
| 882 | 888 |
| 883 source_file = open( | 889 source_file = open( |
| 884 os.path.join(dir, 'gl_bindings_autogen_%s.cc' % set_name), 'wb') | 890 os.path.join(dir, 'gl_bindings_autogen_%s.cc' % set_name), 'wb') |
| 885 GenerateSource(source_file, functions, set_name, used_extension_functions) | 891 GenerateSource(source_file, functions, set_name, used_extension_functions) |
| 886 source_file.close() | 892 source_file.close() |
| 887 | 893 |
| 888 source_file = open(os.path.join(dir, 'gl_bindings_autogen_mock.cc'), 'wb') | 894 source_file = open(os.path.join(dir, 'gl_bindings_autogen_mock.cc'), 'wb') |
| 889 GenerateMockSource(source_file, GL_FUNCTIONS) | 895 GenerateMockSource(source_file, GL_FUNCTIONS) |
| 890 source_file.close() | 896 source_file.close() |
| 897 return 0 |
| 891 | 898 |
| 892 | 899 |
| 893 if __name__ == '__main__': | 900 if __name__ == '__main__': |
| 894 main(sys.argv[1:]) | 901 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |