Chromium Code Reviews| 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 platform |
| 13 import sys | 13 import sys |
| 14 from subprocess import call | 14 from subprocess import call |
| 15 from collections import namedtuple | 15 from collections import namedtuple |
| 16 | 16 |
| 17 HEADER_PATHS = [ | 17 HEADER_PATHS = [ |
| 18 '../../third_party/khronos', | 18 '../../third_party/khronos', |
| 19 '../../third_party/mesa/src/include', | 19 '../../third_party/mesa/src/include', |
| 20 '.', | 20 '.', |
| 21 '../../gpu', | 21 '../../gpu', |
| 22 ] | 22 ] |
| 23 | 23 |
| 24 UNCONDITIONALLY_BOUND_EXTENSIONS = set([ | 24 UNCONDITIONALLY_BOUND_EXTENSIONS = set([ |
| 25 'WGL_ARB_extensions_string', | 25 'WGL_ARB_extensions_string', |
| 26 'WGL_EXT_extensions_string', | 26 'WGL_EXT_extensions_string', |
| 27 'GL_CHROMIUM_gles_depth_binding_hack', # crbug.com/448206 | 27 'GL_CHROMIUM_gles_depth_binding_hack', # crbug.com/448206 |
| 28 'GL_CHROMIUM_glgetstringi_hack', # crbug.com/470396 | 28 'GL_CHROMIUM_glgetstringi_hack', # crbug.com/470396 |
| 29 'GL_CHROMIUM_EGL_KHR_fence_sync_bind_always_504758_hack', # crbug.com/504758 | |
|
Ken Russell (switch to Gerrit)
2015/06/26 17:06:49
That's a mouthful. Is it really worth embedding th
no sievers
2015/06/26 17:51:29
Yea sorry that was my overly explicit suggestion,
| |
| 29 ]) | 30 ]) |
| 30 | 31 |
| 31 """Function binding conditions can be specified manually by supplying a versions | 32 """Function binding conditions can be specified manually by supplying a versions |
| 32 array instead of the names array. Each version has the following keys: | 33 array instead of the names array. Each version has the following keys: |
| 33 name: Mandatory. Name of the function. Multiple versions can have the same | 34 name: Mandatory. Name of the function. Multiple versions can have the same |
| 34 name but different conditions. | 35 name but different conditions. |
| 35 extensions: Extra Extensions for which the function is bound. Only needed | 36 extensions: Extra Extensions for which the function is bound. Only needed |
| 36 in some cases where the extension cannot be parsed from the | 37 in some cases where the extension cannot be parsed from the |
| 37 headers. | 38 headers. |
| 38 | 39 |
| (...skipping 1156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1195 'arguments': 'EGLenum api', }, | 1196 'arguments': 'EGLenum api', }, |
| 1196 { 'return_type': 'EGLBoolean', | 1197 { 'return_type': 'EGLBoolean', |
| 1197 'names': ['eglBindTexImage'], | 1198 'names': ['eglBindTexImage'], |
| 1198 'arguments': 'EGLDisplay dpy, EGLSurface surface, EGLint buffer', }, | 1199 'arguments': 'EGLDisplay dpy, EGLSurface surface, EGLint buffer', }, |
| 1199 { 'return_type': 'EGLBoolean', | 1200 { 'return_type': 'EGLBoolean', |
| 1200 'names': ['eglChooseConfig'], | 1201 'names': ['eglChooseConfig'], |
| 1201 'arguments': 'EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, ' | 1202 'arguments': 'EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, ' |
| 1202 'EGLint config_size, EGLint* num_config', }, | 1203 'EGLint config_size, EGLint* num_config', }, |
| 1203 { 'return_type': 'EGLint', | 1204 { 'return_type': 'EGLint', |
| 1204 'versions': [{ 'name': 'eglClientWaitSyncKHR', | 1205 'versions': [{ 'name': 'eglClientWaitSyncKHR', |
| 1205 'extensions': ['EGL_KHR_fence_sync'] }], | 1206 'extensions': [ |
| 1207 'EGL_KHR_fence_sync', | |
| 1208 'GL_CHROMIUM_EGL_KHR_fence_sync_bind_always_504758_hack' | |
| 1209 ] }], | |
| 1206 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, ' | 1210 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, ' |
| 1207 'EGLTimeKHR timeout' }, | 1211 'EGLTimeKHR timeout' }, |
| 1208 { 'return_type': 'EGLBoolean', | 1212 { 'return_type': 'EGLBoolean', |
| 1209 'names': ['eglCopyBuffers'], | 1213 'names': ['eglCopyBuffers'], |
| 1210 'arguments': | 1214 'arguments': |
| 1211 'EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target', }, | 1215 'EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target', }, |
| 1212 { 'return_type': 'EGLContext', | 1216 { 'return_type': 'EGLContext', |
| 1213 'names': ['eglCreateContext'], | 1217 'names': ['eglCreateContext'], |
| 1214 'arguments': 'EGLDisplay dpy, EGLConfig config, EGLContext share_context, ' | 1218 'arguments': 'EGLDisplay dpy, EGLConfig config, EGLContext share_context, ' |
| 1215 'const EGLint* attrib_list', }, | 1219 'const EGLint* attrib_list', }, |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1227 'const EGLint* attrib_list', }, | 1231 'const EGLint* attrib_list', }, |
| 1228 { 'return_type': 'EGLSurface', | 1232 { 'return_type': 'EGLSurface', |
| 1229 'names': ['eglCreatePbufferSurface'], | 1233 'names': ['eglCreatePbufferSurface'], |
| 1230 'arguments': 'EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list', }, | 1234 'arguments': 'EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list', }, |
| 1231 { 'return_type': 'EGLSurface', | 1235 { 'return_type': 'EGLSurface', |
| 1232 'names': ['eglCreatePixmapSurface'], | 1236 'names': ['eglCreatePixmapSurface'], |
| 1233 'arguments': 'EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, ' | 1237 'arguments': 'EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, ' |
| 1234 'const EGLint* attrib_list', }, | 1238 'const EGLint* attrib_list', }, |
| 1235 { 'return_type': 'EGLSyncKHR', | 1239 { 'return_type': 'EGLSyncKHR', |
| 1236 'versions': [{ 'name': 'eglCreateSyncKHR', | 1240 'versions': [{ 'name': 'eglCreateSyncKHR', |
| 1237 'extensions': ['EGL_KHR_fence_sync'] }], | 1241 'extensions': [ |
| 1242 'EGL_KHR_fence_sync', | |
| 1243 'GL_CHROMIUM_EGL_KHR_fence_sync_bind_always_504758_hack' | |
| 1244 ] }], | |
| 1238 'arguments': 'EGLDisplay dpy, EGLenum type, const EGLint* attrib_list' }, | 1245 'arguments': 'EGLDisplay dpy, EGLenum type, const EGLint* attrib_list' }, |
| 1239 { 'return_type': 'EGLSurface', | 1246 { 'return_type': 'EGLSurface', |
| 1240 'names': ['eglCreateWindowSurface'], | 1247 'names': ['eglCreateWindowSurface'], |
| 1241 'arguments': 'EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, ' | 1248 'arguments': 'EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, ' |
| 1242 'const EGLint* attrib_list', }, | 1249 'const EGLint* attrib_list', }, |
| 1243 { 'return_type': 'EGLBoolean', | 1250 { 'return_type': 'EGLBoolean', |
| 1244 'names': ['eglDestroyContext'], | 1251 'names': ['eglDestroyContext'], |
| 1245 'arguments': 'EGLDisplay dpy, EGLContext ctx', }, | 1252 'arguments': 'EGLDisplay dpy, EGLContext ctx', }, |
| 1246 { 'return_type': 'EGLBoolean', | 1253 { 'return_type': 'EGLBoolean', |
| 1247 'versions': [{ 'name' : 'eglDestroyImageKHR', | 1254 'versions': [{ 'name' : 'eglDestroyImageKHR', |
| 1248 'extensions': ['EGL_KHR_image_base'] }], | 1255 'extensions': ['EGL_KHR_image_base'] }], |
| 1249 'arguments': 'EGLDisplay dpy, EGLImageKHR image' }, | 1256 'arguments': 'EGLDisplay dpy, EGLImageKHR image' }, |
| 1250 { 'return_type': 'EGLBoolean', | 1257 { 'return_type': 'EGLBoolean', |
| 1251 'names': ['eglDestroySurface'], | 1258 'names': ['eglDestroySurface'], |
| 1252 'arguments': 'EGLDisplay dpy, EGLSurface surface', }, | 1259 'arguments': 'EGLDisplay dpy, EGLSurface surface', }, |
| 1253 { 'return_type': 'EGLBoolean', | 1260 { 'return_type': 'EGLBoolean', |
| 1254 'versions': [{ 'name': 'eglDestroySyncKHR', | 1261 'versions': [{ 'name': 'eglDestroySyncKHR', |
| 1255 'extensions': ['EGL_KHR_fence_sync'] }], | 1262 'extensions': [ |
| 1263 'EGL_KHR_fence_sync', | |
| 1264 'GL_CHROMIUM_EGL_KHR_fence_sync_bind_always_504758_hack' | |
| 1265 ] }], | |
| 1256 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync' }, | 1266 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync' }, |
| 1257 { 'return_type': 'EGLBoolean', | 1267 { 'return_type': 'EGLBoolean', |
| 1258 'names': ['eglGetConfigAttrib'], | 1268 'names': ['eglGetConfigAttrib'], |
| 1259 'arguments': | 1269 'arguments': |
| 1260 'EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value', }, | 1270 'EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value', }, |
| 1261 { 'return_type': 'EGLBoolean', | 1271 { 'return_type': 'EGLBoolean', |
| 1262 'names': ['eglGetConfigs'], | 1272 'names': ['eglGetConfigs'], |
| 1263 'arguments': 'EGLDisplay dpy, EGLConfig* configs, EGLint config_size, ' | 1273 'arguments': 'EGLDisplay dpy, EGLConfig* configs, EGLint config_size, ' |
| 1264 'EGLint* num_config', }, | 1274 'EGLint* num_config', }, |
| 1265 { 'return_type': 'EGLContext', | 1275 { 'return_type': 'EGLContext', |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1281 'known_as': 'eglGetPlatformDisplayEXT', | 1291 'known_as': 'eglGetPlatformDisplayEXT', |
| 1282 'versions': [{ 'name': 'eglGetPlatformDisplayEXT', | 1292 'versions': [{ 'name': 'eglGetPlatformDisplayEXT', |
| 1283 'client_extensions': ['EGL_EXT_platform_base'], }], | 1293 'client_extensions': ['EGL_EXT_platform_base'], }], |
| 1284 'arguments': 'EGLenum platform, void* native_display, ' | 1294 'arguments': 'EGLenum platform, void* native_display, ' |
| 1285 'const EGLint* attrib_list', }, | 1295 'const EGLint* attrib_list', }, |
| 1286 { 'return_type': '__eglMustCastToProperFunctionPointerType', | 1296 { 'return_type': '__eglMustCastToProperFunctionPointerType', |
| 1287 'names': ['eglGetProcAddress'], | 1297 'names': ['eglGetProcAddress'], |
| 1288 'arguments': 'const char* procname', }, | 1298 'arguments': 'const char* procname', }, |
| 1289 { 'return_type': 'EGLBoolean', | 1299 { 'return_type': 'EGLBoolean', |
| 1290 'versions': [{ 'name': 'eglGetSyncAttribKHR', | 1300 'versions': [{ 'name': 'eglGetSyncAttribKHR', |
| 1291 'extensions': ['EGL_KHR_fence_sync'] }], | 1301 'extensions': [ |
| 1302 'EGL_KHR_fence_sync', | |
| 1303 'GL_CHROMIUM_EGL_KHR_fence_sync_bind_always_504758_hack' | |
| 1304 ] }], | |
| 1292 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, ' | 1305 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, ' |
| 1293 'EGLint* value' }, | 1306 'EGLint* value' }, |
| 1294 { 'return_type': 'EGLBoolean', | 1307 { 'return_type': 'EGLBoolean', |
| 1295 'names': ['eglGetSyncValuesCHROMIUM'], | 1308 'names': ['eglGetSyncValuesCHROMIUM'], |
| 1296 'arguments': | 1309 'arguments': |
| 1297 'EGLDisplay dpy, EGLSurface surface, ' | 1310 'EGLDisplay dpy, EGLSurface surface, ' |
| 1298 'EGLuint64CHROMIUM* ust, EGLuint64CHROMIUM* msc, ' | 1311 'EGLuint64CHROMIUM* ust, EGLuint64CHROMIUM* msc, ' |
| 1299 'EGLuint64CHROMIUM* sbc', }, | 1312 'EGLuint64CHROMIUM* sbc', }, |
| 1300 { 'return_type': 'EGLBoolean', | 1313 { 'return_type': 'EGLBoolean', |
| 1301 'names': ['eglInitialize'], | 1314 'names': ['eglInitialize'], |
| (...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1898 first_version = False | 1911 first_version = False |
| 1899 | 1912 |
| 1900 # TODO(jmadill): make more robust | 1913 # TODO(jmadill): make more robust |
| 1901 def IsClientExtensionFunc(func): | 1914 def IsClientExtensionFunc(func): |
| 1902 assert len(func['versions']) > 0 | 1915 assert len(func['versions']) > 0 |
| 1903 if 'client_extensions' in func['versions'][0]: | 1916 if 'client_extensions' in func['versions'][0]: |
| 1904 assert len(func['versions']) == 1 | 1917 assert len(func['versions']) == 1 |
| 1905 return True | 1918 return True |
| 1906 return False | 1919 return False |
| 1907 | 1920 |
| 1908 if set_name == 'egl': | 1921 file.write("}\n\n"); |
| 1909 file.write("""std::string client_extensions(GetClientExtensions()); | |
| 1910 client_extensions += " "; | |
| 1911 ALLOW_UNUSED_LOCAL(client_extensions); | |
| 1912 | |
| 1913 """) | |
| 1914 for extension in sorted(used_client_extensions): | |
| 1915 # Extra space at the end of the extension name is intentional, | |
| 1916 # it is used as a separator | |
| 1917 file.write( | |
| 1918 ' ext.b_%s = client_extensions.find("%s ") != std::string::npos;\n' % | |
| 1919 (extension, extension)) | |
| 1920 for func in functions: | |
| 1921 if not 'static_binding' in func and IsClientExtensionFunc(func): | |
| 1922 file.write('\n') | |
| 1923 file.write(' debug_fn.%sFn = 0;\n' % func['known_as']) | |
| 1924 WriteConditionalFuncBinding(file, func) | |
| 1925 | 1922 |
| 1926 if set_name == 'gl': | 1923 if set_name == 'gl': |
| 1927 # Write the deferred bindings for GL that need a current context and depend | 1924 file.write("""\ |
| 1928 # on GL_VERSION and GL_EXTENSIONS. | 1925 void DriverGL::InitializeDynamicBindings( |
| 1929 file.write('}\n\n') | 1926 GLContext* context) { |
| 1930 file.write("""void DriverGL::InitializeDynamicBindings(GLContext* context) { | |
| 1931 DCHECK(context && context->IsCurrent(NULL)); | 1927 DCHECK(context && context->IsCurrent(NULL)); |
| 1932 const GLVersionInfo* ver = context->GetVersionInfo(); | 1928 const GLVersionInfo* ver = context->GetVersionInfo(); |
| 1933 ALLOW_UNUSED_LOCAL(ver); | 1929 ALLOW_UNUSED_LOCAL(ver); |
| 1934 std::string extensions = context->GetExtensions() + " "; | 1930 std::string extensions = context->GetExtensions() + " "; |
| 1935 ALLOW_UNUSED_LOCAL(extensions); | 1931 ALLOW_UNUSED_LOCAL(extensions); |
| 1936 | 1932 |
| 1937 """) | 1933 """) |
| 1934 elif set_name == 'egl': | |
| 1935 file.write("""\ | |
| 1936 void DriverEGL::InitializeExtensionBindings() { | |
| 1937 std::string client_extensions(GetClientExtensions()); | |
| 1938 client_extensions += " "; | |
| 1939 ALLOW_UNUSED_LOCAL(client_extensions); | |
| 1940 | |
| 1941 """) | |
| 1938 else: | 1942 else: |
| 1939 file.write("""std::string extensions(GetPlatformExtensions()); | 1943 file.write("""\ |
| 1944 void Driver%s::InitializeExtensionBindings() { | |
| 1945 std::string extensions(GetPlatformExtensions()); | |
| 1946 extensions += " "; | |
| 1947 ALLOW_UNUSED_LOCAL(extensions); | |
| 1948 | |
| 1949 """ % (set_name.upper(),)) | |
| 1950 | |
| 1951 def OutputExtensionBindings(extension_var, extensions, extension_funcs): | |
| 1952 # Extra space at the end of the extension name is intentional, | |
| 1953 # it is used as a separator | |
| 1954 for extension in extensions: | |
| 1955 file.write(' ext.b_%s = %s.find("%s ") != std::string::npos;\n' % | |
| 1956 (extension, extension_var, extension)) | |
| 1957 | |
| 1958 for func in extension_funcs: | |
| 1959 if not 'static_binding' in func: | |
| 1960 file.write('\n') | |
| 1961 file.write(' debug_fn.%sFn = 0;\n' % func['known_as']) | |
| 1962 WriteConditionalFuncBinding(file, func) | |
| 1963 | |
| 1964 OutputExtensionBindings( | |
| 1965 'client_extensions', | |
| 1966 sorted(used_client_extensions), | |
| 1967 [ f for f in functions if IsClientExtensionFunc(f) ]) | |
| 1968 | |
| 1969 if set_name == 'egl': | |
| 1970 file.write("""\ | |
| 1971 std::string extensions(GetPlatformExtensions()); | |
| 1940 extensions += " "; | 1972 extensions += " "; |
| 1941 ALLOW_UNUSED_LOCAL(extensions); | 1973 ALLOW_UNUSED_LOCAL(extensions); |
| 1942 | 1974 |
| 1943 """) | 1975 """) |
| 1944 | 1976 |
| 1945 for extension in sorted(used_extensions): | 1977 OutputExtensionBindings( |
| 1946 # Extra space at the end of the extension name is intentional, it is used | 1978 'extensions', |
| 1947 # as a separator | 1979 sorted(used_extensions), |
| 1948 file.write(' ext.b_%s = extensions.find("%s ") != std::string::npos;\n' % | 1980 [ f for f in functions if not IsClientExtensionFunc(f) ]) |
| 1949 (extension, extension)) | |
| 1950 | |
| 1951 for func in functions: | |
| 1952 if not 'static_binding' in func and not IsClientExtensionFunc(func): | |
| 1953 file.write('\n') | |
| 1954 file.write(' debug_fn.%sFn = 0;\n' % func['known_as']) | |
| 1955 WriteConditionalFuncBinding(file, func) | |
| 1956 | 1981 |
| 1957 # Some new function pointers have been added, so update them in debug bindings | 1982 # Some new function pointers have been added, so update them in debug bindings |
| 1958 file.write('\n') | 1983 file.write('\n') |
| 1959 file.write(' if (g_debugBindingsInitialized)\n') | 1984 file.write(' if (g_debugBindingsInitialized)\n') |
| 1960 file.write(' InitializeDebugBindings();\n') | 1985 file.write(' InitializeDebugBindings();\n') |
| 1961 file.write('}\n') | 1986 file.write('}\n') |
| 1962 file.write('\n') | 1987 file.write('\n') |
| 1963 | 1988 |
| 1964 # Write logging wrappers for each function. | 1989 # Write logging wrappers for each function. |
| 1965 file.write('extern "C" {\n') | 1990 file.write('extern "C" {\n') |
| (...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2607 'gl_enums_implementation_autogen.h'), | 2632 'gl_enums_implementation_autogen.h'), |
| 2608 'wb') | 2633 'wb') |
| 2609 GenerateEnumUtils(header_file, enum_header_filenames) | 2634 GenerateEnumUtils(header_file, enum_header_filenames) |
| 2610 header_file.close() | 2635 header_file.close() |
| 2611 ClangFormat(header_file.name) | 2636 ClangFormat(header_file.name) |
| 2612 return 0 | 2637 return 0 |
| 2613 | 2638 |
| 2614 | 2639 |
| 2615 if __name__ == '__main__': | 2640 if __name__ == '__main__': |
| 2616 sys.exit(main(sys.argv[1:])) | 2641 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |