OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """code generator for GL/GLES extension wrangler.""" | 6 """code generator for GL/GLES extension wrangler.""" |
7 | 7 |
8 import optparse | 8 import optparse |
9 import os | 9 import os |
10 import collections | 10 import collections |
11 import re | 11 import re |
| 12 import platform |
12 import sys | 13 import sys |
| 14 from subprocess import call |
| 15 |
| 16 HEADER_PATHS = [ |
| 17 '../../third_party/khronos', |
| 18 '../../third_party/mesa/src/include', |
| 19 '.', |
| 20 '../../gpu', |
| 21 ] |
13 | 22 |
14 """In case there are multiple versions of the same function, one that's listed | 23 """In case there are multiple versions of the same function, one that's listed |
15 first takes priority if its conditions are met. If the function is an extension | 24 first takes priority if its conditions are met. If the function is an extension |
16 function, finding the extension from the extension string is a condition for | 25 function, finding the extension from the extension string is a condition for |
17 binding it. The last version of the function is treated as a fallback option in | 26 binding it. The last version of the function is treated as a fallback option in |
18 case no other versions were bound, so a non-null function pointer in the | 27 case no other versions were bound, so a non-null function pointer in the |
19 bindings does not guarantee that the function is supported. | 28 bindings does not guarantee that the function is supported. |
20 | 29 |
21 Function binding conditions can be specified manually by supplying a versions | 30 Function binding conditions can be specified manually by supplying a versions |
22 array instead of the names array. Each version has the following keys: | 31 array instead of the names array. Each version has the following keys: |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 'GLenum target, GLsizeiptr size, const void* data, GLenum usage', }, | 151 'GLenum target, GLsizeiptr size, const void* data, GLenum usage', }, |
143 { 'return_type': 'void', | 152 { 'return_type': 'void', |
144 'names': ['glBufferSubData'], | 153 'names': ['glBufferSubData'], |
145 'arguments': | 154 'arguments': |
146 'GLenum target, GLintptr offset, GLsizeiptr size, const void* data', }, | 155 'GLenum target, GLintptr offset, GLsizeiptr size, const void* data', }, |
147 { 'return_type': 'GLenum', | 156 { 'return_type': 'GLenum', |
148 'names': ['glCheckFramebufferStatusEXT', | 157 'names': ['glCheckFramebufferStatusEXT', |
149 'glCheckFramebufferStatus'], | 158 'glCheckFramebufferStatus'], |
150 'arguments': 'GLenum target', | 159 'arguments': 'GLenum target', |
151 'logging_code': """ | 160 'logging_code': """ |
152 GL_SERVICE_LOG("GL_RESULT: " << GLES2Util::GetStringEnum(result)); | 161 GL_SERVICE_LOG("GL_RESULT: " << GLEnums::GetStringEnum(result)); |
153 """, }, | 162 """, }, |
154 { 'return_type': 'void', | 163 { 'return_type': 'void', |
155 'names': ['glClear'], | 164 'names': ['glClear'], |
156 'arguments': 'GLbitfield mask', }, | 165 'arguments': 'GLbitfield mask', }, |
157 { 'return_type': 'void', | 166 { 'return_type': 'void', |
158 'versions': [{ 'name': 'glClearBufferfi', | 167 'versions': [{ 'name': 'glClearBufferfi', |
159 'gl_versions': ['gl3', 'gl4', 'es3'] }], | 168 'gl_versions': ['gl3', 'gl4', 'es3'] }], |
160 'arguments': 'GLenum buffer, GLint drawbuffer, const GLfloat depth, ' | 169 'arguments': 'GLenum buffer, GLint drawbuffer, const GLfloat depth, ' |
161 'GLint stencil', }, | 170 'GLint stencil', }, |
162 { 'return_type': 'void', | 171 { 'return_type': 'void', |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 { 'return_type': 'void', | 523 { 'return_type': 'void', |
515 'names': ['glGetBooleanv'], | 524 'names': ['glGetBooleanv'], |
516 'arguments': 'GLenum pname, GLboolean* params', }, | 525 'arguments': 'GLenum pname, GLboolean* params', }, |
517 { 'return_type': 'void', | 526 { 'return_type': 'void', |
518 'names': ['glGetBufferParameteriv'], | 527 'names': ['glGetBufferParameteriv'], |
519 'arguments': 'GLenum target, GLenum pname, GLint* params', }, | 528 'arguments': 'GLenum target, GLenum pname, GLint* params', }, |
520 { 'return_type': 'GLenum', | 529 { 'return_type': 'GLenum', |
521 'names': ['glGetError'], | 530 'names': ['glGetError'], |
522 'arguments': 'void', | 531 'arguments': 'void', |
523 'logging_code': """ | 532 'logging_code': """ |
524 GL_SERVICE_LOG("GL_RESULT: " << GLES2Util::GetStringError(result)); | 533 GL_SERVICE_LOG("GL_RESULT: " << GLEnums::GetStringError(result)); |
525 """, }, | 534 """, }, |
526 { 'return_type': 'void', | 535 { 'return_type': 'void', |
527 'names': ['glGetFenceivNV'], | 536 'names': ['glGetFenceivNV'], |
528 'arguments': 'GLuint fence, GLenum pname, GLint* params', }, | 537 'arguments': 'GLuint fence, GLenum pname, GLint* params', }, |
529 { 'return_type': 'void', | 538 { 'return_type': 'void', |
530 'names': ['glGetFloatv'], | 539 'names': ['glGetFloatv'], |
531 'arguments': 'GLenum pname, GLfloat* params', }, | 540 'arguments': 'GLenum pname, GLfloat* params', }, |
532 { 'return_type': 'GLint', | 541 { 'return_type': 'GLint', |
533 'versions': [{ 'name': 'glGetFragDataLocation', | 542 'versions': [{ 'name': 'glGetFragDataLocation', |
534 'gl_versions': ['gl3', 'gl4', 'es3'] }], | 543 'gl_versions': ['gl3', 'gl4', 'es3'] }], |
(...skipping 1146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1681 ], | 1690 ], |
1682 [ | 1691 [ |
1683 'EGL_ANGLE_d3d_share_handle_client_buffer', | 1692 'EGL_ANGLE_d3d_share_handle_client_buffer', |
1684 'EGL_ANGLE_surface_d3d_texture_2d_share_handle', | 1693 'EGL_ANGLE_surface_d3d_texture_2d_share_handle', |
1685 ], | 1694 ], |
1686 ], | 1695 ], |
1687 [WGL_FUNCTIONS, 'wgl', ['GL/wglext.h'], []], | 1696 [WGL_FUNCTIONS, 'wgl', ['GL/wglext.h'], []], |
1688 [GLX_FUNCTIONS, 'glx', ['GL/glx.h', 'GL/glxext.h'], []], | 1697 [GLX_FUNCTIONS, 'glx', ['GL/glx.h', 'GL/glxext.h'], []], |
1689 ] | 1698 ] |
1690 | 1699 |
| 1700 GLES2_HEADERS_WITH_ENUMS = [ |
| 1701 'GLES2/gl2.h', |
| 1702 'GLES2/gl2ext.h', |
| 1703 'GLES2/gl2chromium.h', |
| 1704 'GLES2/gl2extchromium.h', |
| 1705 'GLES3/gl3.h', |
| 1706 ] |
| 1707 |
| 1708 SELF_LOCATION = os.path.dirname(os.path.abspath(__file__)) |
| 1709 |
| 1710 LICENSE_AND_HEADER = """\ |
| 1711 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 1712 // Use of this source code is governed by a BSD-style license that can be |
| 1713 // found in the LICENSE file. |
| 1714 // |
| 1715 // This file is auto-generated from |
| 1716 // ui/gl/generate_bindings.py |
| 1717 // It's formatted by clang-format using chromium coding style: |
| 1718 // clang-format -i -style=chromium filename |
| 1719 // DO NOT EDIT! |
| 1720 |
| 1721 """ |
1691 | 1722 |
1692 def GenerateHeader(file, functions, set_name, used_extensions): | 1723 def GenerateHeader(file, functions, set_name, used_extensions): |
1693 """Generates gl_bindings_autogen_x.h""" | 1724 """Generates gl_bindings_autogen_x.h""" |
1694 | 1725 |
1695 # Write file header. | 1726 # Write file header. |
1696 file.write( | 1727 file.write(LICENSE_AND_HEADER + |
1697 """// Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1728 """ |
1698 // Use of this source code is governed by a BSD-style license that can be | |
1699 // found in the LICENSE file. | |
1700 | |
1701 // This file is automatically generated. | |
1702 | 1729 |
1703 #ifndef UI_GFX_GL_GL_BINDINGS_AUTOGEN_%(name)s_H_ | 1730 #ifndef UI_GFX_GL_GL_BINDINGS_AUTOGEN_%(name)s_H_ |
1704 #define UI_GFX_GL_GL_BINDINGS_AUTOGEN_%(name)s_H_ | 1731 #define UI_GFX_GL_GL_BINDINGS_AUTOGEN_%(name)s_H_ |
1705 | 1732 |
1706 namespace gfx { | 1733 namespace gfx { |
1707 | 1734 |
1708 class GLContext; | 1735 class GLContext; |
1709 | 1736 |
1710 """ % {'name': set_name.upper()}) | 1737 """ % {'name': set_name.upper()}) |
1711 | 1738 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1756 | 1783 |
1757 file.write('\n') | 1784 file.write('\n') |
1758 file.write('#endif // UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' % | 1785 file.write('#endif // UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' % |
1759 set_name.upper()) | 1786 set_name.upper()) |
1760 | 1787 |
1761 | 1788 |
1762 def GenerateAPIHeader(file, functions, set_name): | 1789 def GenerateAPIHeader(file, functions, set_name): |
1763 """Generates gl_bindings_api_autogen_x.h""" | 1790 """Generates gl_bindings_api_autogen_x.h""" |
1764 | 1791 |
1765 # Write file header. | 1792 # Write file header. |
1766 file.write( | 1793 file.write(LICENSE_AND_HEADER) |
1767 """// Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
1768 // Use of this source code is governed by a BSD-style license that can be | |
1769 // found in the LICENSE file. | |
1770 | |
1771 // This file is automatically generated. | |
1772 | |
1773 """ % {'name': set_name.upper()}) | |
1774 | 1794 |
1775 # Write API declaration. | 1795 # Write API declaration. |
1776 for func in functions: | 1796 for func in functions: |
1777 file.write(' %s %sFn(%s) override;\n' % | 1797 file.write(' %s %sFn(%s) override;\n' % |
1778 (func['return_type'], func['known_as'], func['arguments'])) | 1798 (func['return_type'], func['known_as'], func['arguments'])) |
1779 | 1799 |
1780 file.write('\n') | 1800 file.write('\n') |
1781 | 1801 |
1782 | 1802 |
1783 def GenerateMockHeader(file, functions, set_name): | 1803 def GenerateMockHeader(file, functions, set_name): |
1784 """Generates gl_mock_autogen_x.h""" | 1804 """Generates gl_mock_autogen_x.h""" |
1785 | 1805 |
1786 # Write file header. | 1806 # Write file header. |
1787 file.write( | 1807 file.write(LICENSE_AND_HEADER) |
1788 """// Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
1789 // Use of this source code is governed by a BSD-style license that can be | |
1790 // found in the LICENSE file. | |
1791 | |
1792 // This file is automatically generated. | |
1793 | |
1794 """ % {'name': set_name.upper()}) | |
1795 | 1808 |
1796 # Write API declaration. | 1809 # Write API declaration. |
1797 for func in functions: | 1810 for func in functions: |
1798 args = func['arguments'] | 1811 args = func['arguments'] |
1799 if args == 'void': | 1812 if args == 'void': |
1800 args = '' | 1813 args = '' |
1801 arg_count = 0 | 1814 arg_count = 0 |
1802 if len(args): | 1815 if len(args): |
1803 arg_count = func['arguments'].count(',') + 1 | 1816 arg_count = func['arguments'].count(',') + 1 |
1804 file.write(' MOCK_METHOD%d(%s, %s(%s));\n' % | 1817 file.write(' MOCK_METHOD%d(%s, %s(%s));\n' % |
1805 (arg_count, func['known_as'][2:], func['return_type'], args)) | 1818 (arg_count, func['known_as'][2:], func['return_type'], args)) |
1806 | 1819 |
1807 file.write('\n') | 1820 file.write('\n') |
1808 | 1821 |
1809 | 1822 |
1810 def GenerateSource(file, functions, set_name, used_extensions): | 1823 def GenerateSource(file, functions, set_name, used_extensions): |
1811 """Generates gl_bindings_autogen_x.cc""" | 1824 """Generates gl_bindings_autogen_x.cc""" |
1812 | 1825 |
| 1826 set_header_name = "ui/gl/gl_" + set_name.lower() + "_api_implementation.h" |
| 1827 include_list = [ 'base/debug/trace_event.h', |
| 1828 'ui/gl/gl_enums.h', |
| 1829 'ui/gl/gl_bindings.h', |
| 1830 'ui/gl/gl_context.h', |
| 1831 'ui/gl/gl_implementation.h', |
| 1832 'ui/gl/gl_version_info.h', |
| 1833 set_header_name ] |
| 1834 includes_string = "\n".join(["#include \"{0}\"".format(h) |
| 1835 for h in sorted(include_list)]) |
| 1836 |
1813 # Write file header. | 1837 # Write file header. |
1814 file.write( | 1838 file.write(LICENSE_AND_HEADER + |
1815 """// Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1839 """ |
1816 // Use of this source code is governed by a BSD-style license that can be | |
1817 // found in the LICENSE file. | |
1818 | |
1819 // This file is automatically generated. | |
1820 | 1840 |
1821 #include <string> | 1841 #include <string> |
1822 #include "base/debug/trace_event.h" | |
1823 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | |
1824 #include "ui/gl/gl_bindings.h" | |
1825 #include "ui/gl/gl_context.h" | |
1826 #include "ui/gl/gl_implementation.h" | |
1827 #include "ui/gl/gl_version_info.h" | |
1828 #include "ui/gl/gl_%s_api_implementation.h" | |
1829 | 1842 |
1830 using gpu::gles2::GLES2Util; | 1843 %s |
1831 | 1844 |
1832 namespace gfx { | 1845 namespace gfx { |
1833 """ % set_name.lower()) | 1846 """ % includes_string) |
1834 | 1847 |
1835 file.write('\n') | 1848 file.write('\n') |
1836 file.write('static bool g_debugBindingsInitialized;\n') | 1849 file.write('static bool g_debugBindingsInitialized;\n') |
1837 file.write('Driver%s g_driver_%s;\n' % (set_name.upper(), set_name.lower())) | 1850 file.write('Driver%s g_driver_%s;\n' % (set_name.upper(), set_name.lower())) |
1838 file.write('\n') | 1851 file.write('\n') |
1839 | 1852 |
1840 # Write stub functions that take the place of some functions before a context | 1853 # Write stub functions that take the place of some functions before a context |
1841 # is initialized. This is done to provide clear asserts on debug build and to | 1854 # is initialized. This is done to provide clear asserts on debug build and to |
1842 # avoid crashing in case of a bug on release build. | 1855 # avoid crashing in case of a bug on release build. |
1843 file.write('\n') | 1856 file.write('\n') |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1938 # Don't make the last possible binding conditional on anything else but | 1951 # Don't make the last possible binding conditional on anything else but |
1939 # that the function isn't already bound to avoid verbose specification | 1952 # that the function isn't already bound to avoid verbose specification |
1940 # of functions which have both ARB and core versions with the same name, | 1953 # of functions which have both ARB and core versions with the same name, |
1941 # and to be able to bind to mock extension functions in unit tests which | 1954 # and to be able to bind to mock extension functions in unit tests which |
1942 # call InitializeDynamicGLBindings with a stub context that doesn't have | 1955 # call InitializeDynamicGLBindings with a stub context that doesn't have |
1943 # extensions in its extension string. | 1956 # extensions in its extension string. |
1944 # TODO(oetuaho@nvidia.com): Get rid of the fallback. | 1957 # TODO(oetuaho@nvidia.com): Get rid of the fallback. |
1945 # http://crbug.com/325668 | 1958 # http://crbug.com/325668 |
1946 if cond != '' and not last_version: | 1959 if cond != '' and not last_version: |
1947 if not first_version: | 1960 if not first_version: |
1948 file.write(' if (!fn.%sFn && (%s))\n ' % (known_as, cond)) | 1961 file.write(' if (!fn.%sFn && (%s)) {\n ' % (known_as, cond)) |
1949 else: | 1962 else: |
1950 file.write(' if (%s)\n ' % cond) | 1963 file.write(' if (%s) {\n ' % cond) |
1951 elif not first_version: | 1964 elif not first_version: |
1952 file.write(' if (!fn.%sFn)\n ' % known_as) | 1965 file.write(' if (!fn.%sFn) {\n ' % known_as) |
1953 WriteFuncBinding(file, known_as, version['name']) | 1966 WriteFuncBinding(file, known_as, version['name']) |
| 1967 file.write('}\n') |
1954 i += 1 | 1968 i += 1 |
1955 first_version = False | 1969 first_version = False |
1956 | 1970 |
1957 for func in functions: | 1971 for func in functions: |
1958 unique_names = set([version['name'] for version in func['versions']]) | 1972 unique_names = set([version['name'] for version in func['versions']]) |
1959 if len(unique_names) > 1: | 1973 if len(unique_names) > 1: |
1960 file.write('\n') | 1974 file.write('\n') |
1961 file.write(' fn.%sFn = 0;\n' % func['known_as']) | 1975 file.write(' fn.%sFn = 0;\n' % func['known_as']) |
1962 file.write(' debug_fn.%sFn = 0;\n' % func['known_as']) | 1976 file.write(' debug_fn.%sFn = 0;\n' % func['known_as']) |
1963 WriteConditionalFuncBinding(file, func) | 1977 WriteConditionalFuncBinding(file, func) |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1995 log_argument_names) | 2009 log_argument_names) |
1996 log_argument_names = re.sub( | 2010 log_argument_names = re.sub( |
1997 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', | 2011 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', |
1998 log_argument_names) | 2012 log_argument_names) |
1999 log_argument_names = re.sub( | 2013 log_argument_names = re.sub( |
2000 r'CONSTVOID_([a-zA-Z0-9_]+)', | 2014 r'CONSTVOID_([a-zA-Z0-9_]+)', |
2001 r'static_cast<const void*>(\1)', log_argument_names) | 2015 r'static_cast<const void*>(\1)', log_argument_names) |
2002 log_argument_names = re.sub( | 2016 log_argument_names = re.sub( |
2003 r'CONSTCHAR_([a-zA-Z0-9_]+)', r'\1', log_argument_names) | 2017 r'CONSTCHAR_([a-zA-Z0-9_]+)', r'\1', log_argument_names) |
2004 log_argument_names = re.sub( | 2018 log_argument_names = re.sub( |
2005 r'GLenum_([a-zA-Z0-9_]+)', r'GLES2Util::GetStringEnum(\1)', | 2019 r'GLenum_([a-zA-Z0-9_]+)', r'GLEnums::GetStringEnum(\1)', |
2006 log_argument_names) | 2020 log_argument_names) |
2007 log_argument_names = re.sub( | 2021 log_argument_names = re.sub( |
2008 r'GLboolean_([a-zA-Z0-9_]+)', r'GLES2Util::GetStringBool(\1)', | 2022 r'GLboolean_([a-zA-Z0-9_]+)', r'GLEnums::GetStringBool(\1)', |
2009 log_argument_names) | 2023 log_argument_names) |
2010 log_argument_names = log_argument_names.replace(',', ' << ", " <<') | 2024 log_argument_names = log_argument_names.replace(',', ' << ", " <<') |
2011 if argument_names == 'void' or argument_names == '': | 2025 if argument_names == 'void' or argument_names == '': |
2012 argument_names = '' | 2026 argument_names = '' |
2013 log_argument_names = '' | 2027 log_argument_names = '' |
2014 else: | 2028 else: |
2015 log_argument_names = " << " + log_argument_names | 2029 log_argument_names = " << " + log_argument_names |
2016 function_name = func['known_as'] | 2030 function_name = func['known_as'] |
2017 if return_type == 'void': | 2031 if return_type == 'void': |
2018 file.write(' GL_SERVICE_LOG("%s" << "(" %s << ")");\n' % | 2032 file.write(' GL_SERVICE_LOG("%s" << "(" %s << ")");\n' % |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2144 'return_type': func['return_type'], | 2158 'return_type': func['return_type'], |
2145 'arguments': func['arguments'], | 2159 'arguments': func['arguments'], |
2146 'known_as': func['known_as'] | 2160 'known_as': func['known_as'] |
2147 }) | 2161 }) |
2148 return uniquely_named_functions | 2162 return uniquely_named_functions |
2149 | 2163 |
2150 | 2164 |
2151 def GenerateMockBindingsHeader(file, functions): | 2165 def GenerateMockBindingsHeader(file, functions): |
2152 """Headers for functions that invoke MockGLInterface members""" | 2166 """Headers for functions that invoke MockGLInterface members""" |
2153 | 2167 |
2154 file.write( | 2168 file.write(LICENSE_AND_HEADER) |
2155 """// Copyright (c) 2014 The Chromium Authors. All rights reserved. | |
2156 // Use of this source code is governed by a BSD-style license that can be | |
2157 // found in the LICENSE file. | |
2158 | |
2159 // This file is automatically generated. | |
2160 | |
2161 """) | |
2162 uniquely_named_functions = GetUniquelyNamedFunctions(functions) | 2169 uniquely_named_functions = GetUniquelyNamedFunctions(functions) |
2163 | 2170 |
2164 for key in sorted(uniquely_named_functions.iterkeys()): | 2171 for key in sorted(uniquely_named_functions.iterkeys()): |
2165 func = uniquely_named_functions[key] | 2172 func = uniquely_named_functions[key] |
2166 file.write('static %s GL_BINDING_CALL Mock_%s(%s);\n' % | 2173 file.write('static %s GL_BINDING_CALL Mock_%s(%s);\n' % |
2167 (func['return_type'], func['name'], func['arguments'])) | 2174 (func['return_type'], func['name'], func['arguments'])) |
2168 | 2175 |
2169 | 2176 |
2170 def GenerateMockBindingsSource(file, functions): | 2177 def GenerateMockBindingsSource(file, functions): |
2171 """Generates functions that invoke MockGLInterface members and a | 2178 """Generates functions that invoke MockGLInterface members and a |
2172 GetGLProcAddress function that returns addresses to those functions.""" | 2179 GetGLProcAddress function that returns addresses to those functions.""" |
2173 | 2180 |
2174 file.write( | 2181 file.write(LICENSE_AND_HEADER + |
2175 """// Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2182 """ |
2176 // Use of this source code is governed by a BSD-style license that can be | |
2177 // found in the LICENSE file. | |
2178 | |
2179 // This file is automatically generated. | |
2180 | 2183 |
2181 #include <string.h> | 2184 #include <string.h> |
2182 | 2185 |
2183 #include "ui/gl/gl_mock.h" | 2186 #include "ui/gl/gl_mock.h" |
2184 | 2187 |
2185 namespace gfx { | 2188 namespace gfx { |
2186 | 2189 |
2187 // This is called mainly to prevent the compiler combining the code of mock | 2190 // This is called mainly to prevent the compiler combining the code of mock |
2188 // functions with identical contents, so that their function pointers will be | 2191 // functions with identical contents, so that their function pointers will be |
2189 // different. | 2192 // different. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2231 name = uniquely_named_functions[key]['name'] | 2234 name = uniquely_named_functions[key]['name'] |
2232 file.write(' if (strcmp(name, "%s") == 0)\n' % name) | 2235 file.write(' if (strcmp(name, "%s") == 0)\n' % name) |
2233 file.write(' return reinterpret_cast<void*>(Mock_%s);\n' % name) | 2236 file.write(' return reinterpret_cast<void*>(Mock_%s);\n' % name) |
2234 # Always return a non-NULL pointer like some EGL implementations do. | 2237 # Always return a non-NULL pointer like some EGL implementations do. |
2235 file.write(' return reinterpret_cast<void*>(&MockInvalidFunction);\n') | 2238 file.write(' return reinterpret_cast<void*>(&MockInvalidFunction);\n') |
2236 file.write('}\n') | 2239 file.write('}\n') |
2237 | 2240 |
2238 file.write('\n') | 2241 file.write('\n') |
2239 file.write('} // namespace gfx\n') | 2242 file.write('} // namespace gfx\n') |
2240 | 2243 |
| 2244 def GenerateEnumUtils(out_file, input_filenames): |
| 2245 enum_re = re.compile(r'\#define\s+(GL_[a-zA-Z0-9_]+)\s+([0-9A-Fa-fx]+)') |
| 2246 dict = {} |
| 2247 for fname in input_filenames: |
| 2248 lines = open(fname).readlines() |
| 2249 for line in lines: |
| 2250 m = enum_re.match(line) |
| 2251 if m: |
| 2252 name = m.group(1) |
| 2253 value = m.group(2) |
| 2254 if len(value) <= 10: |
| 2255 if not value in dict: |
| 2256 dict[value] = name |
| 2257 # check our own _CHROMIUM macro conflicts with khronos GL headers. |
| 2258 elif dict[value] != name and (name.endswith('_CHROMIUM') or |
| 2259 dict[value].endswith('_CHROMIUM')): |
| 2260 raise RunTimeError("code collision: %s and %s have the same code %s" |
| 2261 % (dict[value], name, value)) |
| 2262 |
| 2263 out_file.write(LICENSE_AND_HEADER) |
| 2264 out_file.write("static const GLEnums::EnumToString " |
| 2265 "enum_to_string_table[] = {\n") |
| 2266 for value in dict: |
| 2267 out_file.write(' { %s, "%s", },\n' % (value, dict[value])) |
| 2268 out_file.write("""}; |
| 2269 |
| 2270 const GLEnums::EnumToString* const GLEnums::enum_to_string_table_ = |
| 2271 enum_to_string_table; |
| 2272 const size_t GLEnums::enum_to_string_table_len_ = |
| 2273 sizeof(enum_to_string_table) / sizeof(enum_to_string_table[0]); |
| 2274 |
| 2275 """) |
| 2276 |
2241 | 2277 |
2242 def ParseExtensionFunctionsFromHeader(header_file): | 2278 def ParseExtensionFunctionsFromHeader(header_file): |
2243 """Parse a C extension header file and return a map from extension names to | 2279 """Parse a C extension header file and return a map from extension names to |
2244 a list of functions. | 2280 a list of functions. |
2245 | 2281 |
2246 Args: | 2282 Args: |
2247 header_file: Line-iterable C header file. | 2283 header_file: Line-iterable C header file. |
2248 Returns: | 2284 Returns: |
2249 Map of extension name => functions. | 2285 Map of extension name => functions. |
2250 """ | 2286 """ |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2351 raise RuntimeError('%s looks like an extension function but does not ' | 2387 raise RuntimeError('%s looks like an extension function but does not ' |
2352 'belong to any of the known extensions.' % name) | 2388 'belong to any of the known extensions.' % name) |
2353 | 2389 |
2354 # Add extensions that do not have any functions. | 2390 # Add extensions that do not have any functions. |
2355 used_extensions.update(extra_extensions) | 2391 used_extensions.update(extra_extensions) |
2356 | 2392 |
2357 return used_extensions | 2393 return used_extensions |
2358 | 2394 |
2359 | 2395 |
2360 def ResolveHeader(header, header_paths): | 2396 def ResolveHeader(header, header_paths): |
2361 paths = header_paths.split(':') | 2397 for path in header_paths: |
2362 | |
2363 for path in paths: | |
2364 result = os.path.join(path, header) | 2398 result = os.path.join(path, header) |
2365 if not os.path.isabs(path): | 2399 if not os.path.isabs(path): |
2366 result = os.path.relpath(os.path.join(os.getcwd(), result), os.getcwd()) | 2400 result = os.path.abspath(os.path.join(SELF_LOCATION, result)) |
2367 if os.path.exists(result): | 2401 if os.path.exists(result): |
2368 # Always use forward slashes as path separators. Otherwise backslashes | 2402 # Always use forward slashes as path separators. Otherwise backslashes |
2369 # may be incorrectly interpreted as escape characters. | 2403 # may be incorrectly interpreted as escape characters. |
2370 return result.replace(os.path.sep, '/') | 2404 return result.replace(os.path.sep, '/') |
2371 | 2405 |
2372 raise Exception('Header %s not found.' % header) | 2406 raise Exception('Header %s not found.' % header) |
2373 | 2407 |
2374 | 2408 |
2375 def main(argv): | 2409 def main(argv): |
2376 """This is the main function.""" | 2410 """This is the main function.""" |
2377 | 2411 |
2378 parser = optparse.OptionParser() | 2412 parser = optparse.OptionParser() |
2379 parser.add_option('--inputs', action='store_true') | 2413 parser.add_option('--inputs', action='store_true') |
2380 parser.add_option('--header-paths') | |
2381 parser.add_option('--verify-order', action='store_true') | 2414 parser.add_option('--verify-order', action='store_true') |
2382 | 2415 |
2383 options, args = parser.parse_args(argv) | 2416 options, args = parser.parse_args(argv) |
2384 | 2417 |
2385 if options.inputs: | 2418 if options.inputs: |
2386 for [_, _, headers, _] in FUNCTION_SETS: | 2419 for [_, _, headers, _] in FUNCTION_SETS: |
2387 for header in headers: | 2420 for header in headers: |
2388 print ResolveHeader(header, options.header_paths) | 2421 print ResolveHeader(header, HEADER_PATHS) |
2389 return 0 | 2422 return 0 |
2390 | 2423 |
2391 directory = '.' | 2424 directory = SELF_LOCATION |
2392 if len(args) >= 1: | 2425 if len(args) >= 1: |
2393 directory = args[0] | 2426 directory = args[0] |
2394 | 2427 |
| 2428 def ClangFormat(filename): |
| 2429 formatter = "clang-format" |
| 2430 if platform.system() == "Windows": |
| 2431 formatter += ".bat" |
| 2432 call([formatter, "-i", "-style=chromium", filename]) |
| 2433 |
2395 for [functions, set_name, extension_headers, extensions] in FUNCTION_SETS: | 2434 for [functions, set_name, extension_headers, extensions] in FUNCTION_SETS: |
2396 # Function names can be specified in two ways (list of unique names or list | 2435 # Function names can be specified in two ways (list of unique names or list |
2397 # of versions with different binding conditions). Fill in the data to the | 2436 # of versions with different binding conditions). Fill in the data to the |
2398 # versions list in case it is missing, so that can be used from here on: | 2437 # versions list in case it is missing, so that can be used from here on: |
2399 for func in functions: | 2438 for func in functions: |
2400 assert 'versions' in func or 'names' in func, 'Function with no names' | 2439 assert 'versions' in func or 'names' in func, 'Function with no names' |
2401 if 'versions' not in func: | 2440 if 'versions' not in func: |
2402 func['versions'] = [{'name': n} for n in func['names']] | 2441 func['versions'] = [{'name': n} for n in func['names']] |
2403 # Use the first version's name unless otherwise specified | 2442 # Use the first version's name unless otherwise specified |
2404 if 'known_as' not in func: | 2443 if 'known_as' not in func: |
2405 func['known_as'] = func['versions'][0]['name'] | 2444 func['known_as'] = func['versions'][0]['name'] |
2406 # Make sure that 'names' is not accidentally used instead of 'versions' | 2445 # Make sure that 'names' is not accidentally used instead of 'versions' |
2407 if 'names' in func: | 2446 if 'names' in func: |
2408 del func['names'] | 2447 del func['names'] |
2409 | 2448 |
2410 # Check function names in each set is sorted in alphabetical order. | 2449 # Check function names in each set is sorted in alphabetical order. |
2411 for index in range(len(functions) - 1): | 2450 for index in range(len(functions) - 1): |
2412 func_name = functions[index]['known_as'] | 2451 func_name = functions[index]['known_as'] |
2413 next_func_name = functions[index + 1]['known_as'] | 2452 next_func_name = functions[index + 1]['known_as'] |
2414 if func_name.lower() > next_func_name.lower(): | 2453 if func_name.lower() > next_func_name.lower(): |
2415 raise Exception( | 2454 raise Exception( |
2416 'function %s is not in alphabetical order' % next_func_name) | 2455 'function %s is not in alphabetical order' % next_func_name) |
2417 if options.verify_order: | 2456 if options.verify_order: |
2418 continue | 2457 continue |
2419 | 2458 |
2420 extension_headers = [ResolveHeader(h, options.header_paths) | 2459 extension_headers = [ResolveHeader(h, HEADER_PATHS) |
2421 for h in extension_headers] | 2460 for h in extension_headers] |
2422 used_extensions = FillExtensionsFromHeaders( | 2461 used_extensions = FillExtensionsFromHeaders( |
2423 functions, extension_headers, extensions) | 2462 functions, extension_headers, extensions) |
2424 | 2463 |
2425 header_file = open( | 2464 header_file = open( |
2426 os.path.join(directory, 'gl_bindings_autogen_%s.h' % set_name), 'wb') | 2465 os.path.join(directory, 'gl_bindings_autogen_%s.h' % set_name), 'wb') |
2427 GenerateHeader(header_file, functions, set_name, used_extensions) | 2466 GenerateHeader(header_file, functions, set_name, used_extensions) |
2428 header_file.close() | 2467 header_file.close() |
| 2468 ClangFormat(header_file.name) |
2429 | 2469 |
2430 header_file = open( | 2470 header_file = open( |
2431 os.path.join(directory, 'gl_bindings_api_autogen_%s.h' % set_name), | 2471 os.path.join(directory, 'gl_bindings_api_autogen_%s.h' % set_name), |
2432 'wb') | 2472 'wb') |
2433 GenerateAPIHeader(header_file, functions, set_name) | 2473 GenerateAPIHeader(header_file, functions, set_name) |
2434 header_file.close() | 2474 header_file.close() |
| 2475 ClangFormat(header_file.name) |
2435 | 2476 |
2436 source_file = open( | 2477 source_file = open( |
2437 os.path.join(directory, 'gl_bindings_autogen_%s.cc' % set_name), 'wb') | 2478 os.path.join(directory, 'gl_bindings_autogen_%s.cc' % set_name), 'wb') |
2438 GenerateSource(source_file, functions, set_name, used_extensions) | 2479 GenerateSource(source_file, functions, set_name, used_extensions) |
2439 source_file.close() | 2480 source_file.close() |
| 2481 ClangFormat(source_file.name) |
2440 | 2482 |
2441 if not options.verify_order: | 2483 if not options.verify_order: |
2442 header_file = open( | 2484 header_file = open( |
2443 os.path.join(directory, 'gl_mock_autogen_gl.h'), 'wb') | 2485 os.path.join(directory, 'gl_mock_autogen_gl.h'), 'wb') |
2444 GenerateMockHeader(header_file, GL_FUNCTIONS, 'gl') | 2486 GenerateMockHeader(header_file, GL_FUNCTIONS, 'gl') |
2445 header_file.close() | 2487 header_file.close() |
| 2488 ClangFormat(header_file.name) |
2446 | 2489 |
2447 header_file = open(os.path.join(directory, 'gl_bindings_autogen_mock.h'), | 2490 header_file = open(os.path.join(directory, 'gl_bindings_autogen_mock.h'), |
2448 'wb') | 2491 'wb') |
2449 GenerateMockBindingsHeader(header_file, GL_FUNCTIONS) | 2492 GenerateMockBindingsHeader(header_file, GL_FUNCTIONS) |
2450 header_file.close() | 2493 header_file.close() |
| 2494 ClangFormat(header_file.name) |
2451 | 2495 |
2452 source_file = open(os.path.join(directory, 'gl_bindings_autogen_mock.cc'), | 2496 source_file = open(os.path.join(directory, 'gl_bindings_autogen_mock.cc'), |
2453 'wb') | 2497 'wb') |
2454 GenerateMockBindingsSource(source_file, GL_FUNCTIONS) | 2498 GenerateMockBindingsSource(source_file, GL_FUNCTIONS) |
2455 source_file.close() | 2499 source_file.close() |
| 2500 ClangFormat(source_file.name) |
| 2501 |
| 2502 enum_header_filenames = [ResolveHeader(h, HEADER_PATHS) |
| 2503 for h in GLES2_HEADERS_WITH_ENUMS] |
| 2504 header_file = open(os.path.join(directory, |
| 2505 'gl_enums_implementation_autogen.h'), |
| 2506 'wb') |
| 2507 GenerateEnumUtils(header_file, enum_header_filenames) |
| 2508 header_file.close() |
| 2509 ClangFormat(header_file.name) |
2456 return 0 | 2510 return 0 |
2457 | 2511 |
2458 | 2512 |
2459 if __name__ == '__main__': | 2513 if __name__ == '__main__': |
2460 sys.exit(main(sys.argv[1:])) | 2514 sys.exit(main(sys.argv[1:])) |
OLD | NEW |