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 |