| #!/usr/bin/python3 | |
| # Copyright 2017 The ANGLE Project Authors. All rights reserved. | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| # | |
| # gen_proc_table.py: | |
| # Code generation for entry point loading tables. | |
| # NOTE: don't run this script directly. Run scripts/run_code_generation.py. | |
| import os | |
| import sys | |
| import registry_xml | |
| out_file_name_gles = "../src/libGLESv2/egl_stubs_getprocaddress_autogen.cpp" | |
| out_file_name_cl = "../src/libGLESv2/proc_table_cl_autogen.cpp" | |
| out_file_name_cl_map = "../src/libOpenCL/libOpenCL_autogen.map" | |
| template_cpp = """// GENERATED FILE - DO NOT EDIT. | |
| // Generated by {script_name} using data from {data_source_name}. | |
| // | |
| // Copyright 2019 The ANGLE Project Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // | |
| // getProcAddress loader table: | |
| // Mapping from a string entry point name to function address. | |
| // | |
| {includes} | |
| #define P(FUNC) reinterpret_cast<{cast}>(FUNC) | |
| namespace {namespace} | |
| {{ | |
| namespace | |
| {{ | |
| struct ProcEntry | |
| {{ | |
| const char *name; | |
| __eglMustCastToProperFunctionPointerType func; | |
| }}; | |
| bool CompareProc(const ProcEntry &a, const char *b) | |
| {{ | |
| return strcmp(a.name, b) < 0; | |
| }} | |
| // clang-format off | |
| const ProcEntry g_procTable[] = {{ | |
| {proc_data} | |
| }}; | |
| // clang-format on | |
| }} // anonymous namespace | |
| __eglMustCastToProperFunctionPointerType GetProcAddress(Thread *thread, const char *procname) | |
| {{ | |
| if (procname == nullptr) | |
| {{ | |
| return nullptr; | |
| }} | |
| const ProcEntry *entry = | |
| std::lower_bound(std::begin(g_procTable), std::end(g_procTable), procname, CompareProc); | |
| thread->setSuccess(); | |
| if (entry == std::end(g_procTable) || strcmp(entry->name, procname) != 0) | |
| {{ | |
| return nullptr; | |
| }} | |
| return entry->func; | |
| }} | |
| }} // namespace {namespace} | |
| """ | |
| # FOR OPENCL | |
| template_map_cpp = """// GENERATED FILE - DO NOT EDIT. | |
| // Generated by {script_name} using data from {data_source_name}. | |
| // | |
| // Copyright 2021 The ANGLE Project Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // | |
| // proc_table: | |
| // Mapping from a string entry point name to function address. | |
| // | |
| {includes} | |
| #define P(FUNC) reinterpret_cast<{cast}>(FUNC) | |
| namespace {namespace} | |
| {{ | |
| const ProcTable &GetProcTable() | |
| {{ | |
| static angle::base::NoDestructor<ProcTable> sProcTable( | |
| {{{proc_data}}}); | |
| return *sProcTable; | |
| }} | |
| }} // namespace {namespace} | |
| """ | |
| # FOR OPENCL | |
| template_map = """/* GENERATED FILE - DO NOT EDIT. | |
| * Generated by {script_name} using data from {data_source_name}. | |
| * | |
| * Copyright 2021 The ANGLE Project Authors. All rights reserved. | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| * | |
| * symbol version map: Maps versions to entry point names for a shared library. | |
| */ | |
| {symbol_maps} | |
| """ | |
| includes_gles = """#include "libANGLE/Thread.h" | |
| #include "libGLESv2/entry_points_egl_autogen.h" | |
| #include "libGLESv2/entry_points_egl_ext_autogen.h" | |
| #include "libGLESv2/entry_points_gles_1_0_autogen.h" | |
| #include "libGLESv2/entry_points_gles_2_0_autogen.h" | |
| #include "libGLESv2/entry_points_gles_3_0_autogen.h" | |
| #include "libGLESv2/entry_points_gles_3_1_autogen.h" | |
| #include "libGLESv2/entry_points_gles_3_2_autogen.h" | |
| #include "libGLESv2/entry_points_gles_ext_autogen.h" | |
| #if defined(ANGLE_ENABLE_EXPLICIT_CONTEXT) | |
| #include "libGLESv2/entry_points_gles_ext_explicit_context_autogen.h" | |
| #endif // defined(ANGLE_ENABLE_EXPLICIT_CONTEXT) | |
| #include "platform/PlatformMethods.h" | |
| #include <iterator> | |
| """ | |
| includes_cl = """#include "libGLESv2/proc_table_cl.h" | |
| #include "libGLESv2/entry_points_cl_autogen.h" | |
| #include "anglebase/no_destructor.h" | |
| // Using fully qualified entry point identifiers to make sure that missing entry points would not | |
| // pick up the global declarations of OpenCL | |
| """ | |
| sys.path.append('../src/libANGLE/renderer') | |
| def _get_annotations(versions): | |
| return ["%d_%d" % version for version in versions] | |
| def main(): | |
| # auto_script parameters. | |
| if len(sys.argv) > 1: | |
| inputs = [source for source in registry_xml.xml_inputs] | |
| outputs = [out_file_name_gles, out_file_name_cl, out_file_name_cl_map] | |
| if sys.argv[1] == 'inputs': | |
| print(','.join(inputs)) | |
| elif sys.argv[1] == 'outputs': | |
| print(','.join(outputs)) | |
| else: | |
| print('Invalid script parameters') | |
| return 1 | |
| return 0 | |
| glesxml = registry_xml.RegistryXML('gl.xml', 'gl_angle_ext.xml') | |
| for annotation in _get_annotations(registry_xml.GLES_VERSIONS): | |
| name_prefix = "GL_ES_VERSION_" | |
| if annotation[0] == '1': | |
| name_prefix = "GL_VERSION_ES_CM_" | |
| feature_name = "{}{}".format(name_prefix, annotation) | |
| glesxml.AddCommands(feature_name, annotation) | |
| glesxml.AddExtensionCommands(registry_xml.supported_extensions, ['gles2', 'gles1']) | |
| gles_data = glesxml.all_cmd_names.get_all_commands() | |
| eglxml = registry_xml.RegistryXML('egl.xml', 'egl_angle_ext.xml') | |
| for annotation in _get_annotations(registry_xml.EGL_VERSIONS): | |
| name_prefix = "EGL_VERSION_" | |
| feature_name = "{}{}".format(name_prefix, annotation) | |
| eglxml.AddCommands(feature_name, annotation) | |
| eglxml.AddExtensionCommands(registry_xml.supported_egl_extensions, ['gles2', 'gles1']) | |
| gles_data.extend(eglxml.all_cmd_names.get_all_commands()) | |
| gles_data.append("ANGLEGetDisplayPlatform") | |
| gles_data.append("ANGLEResetDisplayPlatform") | |
| gles_data = set(gles_data) | |
| all_functions = {} | |
| for function in gles_data: | |
| if function.startswith("gl"): | |
| all_functions[function] = {"function": "GL_" + function[2:]} | |
| all_functions[function + "ContextANGLE"] = { | |
| "function": "GL_" + function[2:] + "ContextANGLE", | |
| "defines": ["ANGLE_ENABLE_EXPLICIT_CONTEXT"] | |
| } | |
| elif function.startswith("egl"): | |
| all_functions[function] = {"function": "EGL_" + function[3:]} | |
| else: | |
| all_functions[function] = {"function": function} | |
| proc_data = [] | |
| for func, angle_func in sorted(all_functions.items()): | |
| defines = angle_func.get("defines", []) | |
| for define in defines: | |
| proc_data.append('#if defined(%s)' % (define)) | |
| proc_data.append(' {"%s", P(%s)},' % (func, angle_func['function'])) | |
| for define in defines: | |
| proc_data.append('#endif // defined(%s)' % (define)) | |
| with open(out_file_name_gles, 'w') as out_file: | |
| output_cpp = template_cpp.format( | |
| script_name=os.path.basename(sys.argv[0]), | |
| data_source_name="gl.xml, gl_angle_ext.xml, egl.xml, egl_angle_ext.xml", | |
| includes=includes_gles, | |
| cast="__eglMustCastToProperFunctionPointerType", | |
| namespace="egl", | |
| proc_data="\n".join(proc_data), | |
| num_procs="std::size(g_procTable)") | |
| out_file.write(output_cpp) | |
| out_file.close() | |
| # libCL proc table | |
| clxml = registry_xml.RegistryXML('cl.xml') | |
| symbol_maps = [] | |
| symbol_map_dependency = "" | |
| for major_version, minor_version in registry_xml.CL_VERSIONS: | |
| name_prefix = "CL_VERSION_" | |
| annotation = "%d_%d" % (major_version, minor_version) | |
| feature_name = "%s%s" % (name_prefix, annotation) | |
| clxml.AddCommands(feature_name, annotation) | |
| symbol_version = "OPENCL_%d.%d" % (major_version, minor_version) | |
| symbol_maps += ["\n%s {\n global:" % symbol_version] | |
| symbol_maps += [' %s;' % cmd for cmd in clxml.commands[annotation]] | |
| if not symbol_map_dependency: | |
| symbol_maps += [" local:\n *;\n};"] | |
| else: | |
| symbol_maps += ["} %s;" % symbol_map_dependency] | |
| symbol_map_dependency = symbol_version | |
| clxml.AddExtensionCommands(registry_xml.supported_cl_extensions, ['cl']) | |
| cl_commands = clxml.all_cmd_names.get_all_commands() | |
| proc_data = ['{"%s", P(::cl::%s)}' % (cmd, cmd) for cmd in cl_commands] | |
| with open(out_file_name_cl, 'w') as out_file: | |
| output_cpp = template_map_cpp.format( | |
| script_name=os.path.basename(sys.argv[0]), | |
| data_source_name="cl.xml", | |
| includes=includes_cl, | |
| cast="void *", | |
| namespace="cl", | |
| proc_data=",\n ".join(proc_data)) | |
| out_file.write(output_cpp) | |
| out_file.close() | |
| with open(out_file_name_cl_map, 'w') as out_file: | |
| output_map = template_map.format( | |
| script_name=os.path.basename(sys.argv[0]), | |
| data_source_name="cl.xml", | |
| symbol_maps="\n".join(symbol_maps)) | |
| out_file.write(output_map) | |
| out_file.close() | |
| return 0 | |
| if __name__ == '__main__': | |
| sys.exit(main()) |