1#!python
2# Copyright 2017 The ANGLE Project Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5#
6# gen_proc_table.py:
7#  Code generation for entry point loading tables.
8#  NOTE: don't run this script directly. Run scripts/run_code_generation.py.
9
10import sys
11from datetime import date
12import registry_xml
13
14out_file_name_gles = "../src/libGLESv2/proc_table_egl_autogen.cpp"
15out_file_name_gl = "../src/libGL/proc_table_wgl_autogen.cpp"
16
17# The EGL_ANGLE_explicit_context extension is generated differently from other extensions.
18# Toggle generation here.
19# Only for GLES
20support_egl_ANGLE_explicit_context = True
21
22strip_suffixes = ["ANGLE", "EXT", "KHR", "OES", "CHROMIUM", "OVR"]
23
24template_cpp = """// GENERATED FILE - DO NOT EDIT.
25// Generated by {script_name} using data from {data_source_name}.
26//
27// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
28// Use of this source code is governed by a BSD-style license that can be
29// found in the LICENSE file.
30//
31// getProcAddress loader table:
32//   Mapping from a string entry point name to function address.
33//
34
35{includes}
36#define P(FUNC) reinterpret_cast<{cast}>(FUNC)
37
38namespace {namespace}
39{{
40ProcEntry g_procTable[] = {{
41{proc_data}
42}};
43
44size_t g_numProcs = {num_procs};
45}}  // namespace {namespace}
46"""
47
48includes_gles = """#include "libGLESv2/proc_table_egl.h"
49
50#include "libGLESv2/entry_points_egl.h"
51#include "libGLESv2/entry_points_egl_ext.h"
52#include "libGLESv2/entry_points_gles_1_0_autogen.h"
53#include "libGLESv2/entry_points_gles_2_0_autogen.h"
54#include "libGLESv2/entry_points_gles_3_0_autogen.h"
55#include "libGLESv2/entry_points_gles_3_1_autogen.h"
56#include "libGLESv2/entry_points_gles_3_2_autogen.h"
57#include "libGLESv2/entry_points_gles_ext_autogen.h"
58#include "platform/Platform.h"
59"""
60
61includes_gl = """#include "libGL/proc_table_wgl.h"
62
63#include "libGL/entry_points_wgl.h"
64#include "libGL/entry_points_gl_1_0_autogen.h"
65#include "libGL/entry_points_gl_1_1_autogen.h"
66#include "libGL/entry_points_gl_1_2_autogen.h"
67#include "libGL/entry_points_gl_1_3_autogen.h"
68#include "libGL/entry_points_gl_1_4_autogen.h"
69#include "libGL/entry_points_gl_1_5_autogen.h"
70#include "libGL/entry_points_gl_2_0_autogen.h"
71#include "libGL/entry_points_gl_2_1_autogen.h"
72#include "libGL/entry_points_gl_3_0_autogen.h"
73#include "libGL/entry_points_gl_3_1_autogen.h"
74#include "libGL/entry_points_gl_3_2_autogen.h"
75#include "libGL/entry_points_gl_3_3_autogen.h"
76#include "libGL/entry_points_gl_4_0_autogen.h"
77#include "libGL/entry_points_gl_4_1_autogen.h"
78#include "libGL/entry_points_gl_4_2_autogen.h"
79#include "libGL/entry_points_gl_4_3_autogen.h"
80#include "libGL/entry_points_gl_4_4_autogen.h"
81#include "libGL/entry_points_gl_4_5_autogen.h"
82#include "libGL/entry_points_gl_4_6_autogen.h"
83#include "platform/Platform.h"
84"""
85
86sys.path.append('../src/libANGLE/renderer')
87import angle_format
88
89
90def main():
91
92    # auto_script parameters.
93    if len(sys.argv) > 1:
94        inputs = [source for source in registry_xml.xml_inputs]
95        outputs = [out_file_name_gles, out_file_name_gl]
96        if sys.argv[1] == 'inputs':
97            print ','.join(inputs)
98        elif sys.argv[1] == 'outputs':
99            print ','.join(outputs)
100        else:
101            print('Invalid script parameters')
102            return 1
103        return 0
104
105    glesxml = registry_xml.RegistryXML('gl.xml', 'gl_angle_ext.xml')
106
107    for annotation in ["2_0", "3_0", "3_1", "1_0"]:
108
109        name_prefix = "GL_ES_VERSION_"
110        if annotation[0] == '1':
111            name_prefix = "GL_VERSION_ES_CM_"
112        feature_name = "{}{}".format(name_prefix, annotation)
113        glesxml.AddCommands(feature_name, annotation)
114
115    glesxml.AddExtensionCommands(registry_xml.supported_extensions, ['gles2', 'gles1'])
116
117    # Also don't add GLES extension commands to libGL proc table
118    extension_commands = []
119    for extension_name, ext_cmd_names in sorted(glesxml.ext_data.iteritems()):
120        extension_commands.extend(glesxml.ext_data[extension_name])
121    for name in extension_commands:
122        name_no_suffix = name
123        for suffix in strip_suffixes:
124            if name_no_suffix.endswith(suffix):
125                name_no_suffix = name_no_suffix[0:-len(suffix)]
126
127    gles_data = glesxml.all_cmd_names.get_all_commands()
128
129    eglxml = registry_xml.RegistryXML('egl.xml', 'egl_angle_ext.xml')
130
131    for annotation in ["1_0", "1_1", "1_2", "1_3", "1_4", "1_5"]:
132
133        name_prefix = "EGL_VERSION_"
134        feature_name = "{}{}".format(name_prefix, annotation)
135        eglxml.AddCommands(feature_name, annotation)
136
137    eglxml.AddExtensionCommands(registry_xml.supported_egl_extensions, ['gles2', 'gles1'])
138
139    gles_data.extend(eglxml.all_cmd_names.get_all_commands())
140
141    gles_data.append("ANGLEGetDisplayPlatform")
142    gles_data.append("ANGLEResetDisplayPlatform")
143
144    all_functions = {}
145
146    for function in gles_data:
147        if function.startswith("gl"):
148            all_functions[function] = "gl::" + function[2:]
149            # Special handling for EGL_ANGLE_explicit_context extension
150            if support_egl_ANGLE_explicit_context:
151                all_functions[function + "ContextANGLE"] = "gl::" + function[2:] + "ContextANGLE"
152        elif function.startswith("egl"):
153            all_functions[function] = "EGL_" + function[3:]
154        else:
155            all_functions[function] = function
156
157    proc_data = [('    {"%s", P(%s)}' % (func, angle_func))
158                 for func, angle_func in sorted(all_functions.iteritems())]
159
160    with open(out_file_name_gles, 'w') as out_file:
161        output_cpp = template_cpp.format(
162            script_name=sys.argv[0],
163            data_source_name="gl.xml, gl_angle_ext.xml, egl.xml, egl_angle_ext.xml",
164            copyright_year=date.today().year,
165            includes=includes_gles,
166            cast="__eglMustCastToProperFunctionPointerType",
167            namespace="egl",
168            proc_data=",\n".join(proc_data),
169            num_procs=len(proc_data))
170        out_file.write(output_cpp)
171        out_file.close()
172
173    # libGL proc table
174    glxml = registry_xml.RegistryXML('gl.xml')
175
176    for annotation in [
177            "1_0", "1_1", "1_2", "1_3", "1_4", "1_5", "2_0", "2_1", "3_0", "3_1", "3_2", "3_3",
178            "4_0", "4_1", "4_2", "4_3", "4_4", "4_5", "4_6"
179    ]:
180
181        name_prefix = "GL_VERSION_"
182        feature_name = "{}{}".format(name_prefix, annotation)
183        glxml.AddCommands(feature_name, annotation)
184
185    gl_data = [cmd for cmd in glxml.all_cmd_names.get_all_commands()]
186
187    wglxml = registry_xml.RegistryXML('wgl.xml')
188
189    for annotation in ["1_0"]:
190
191        name_prefix = "WGL_VERSION_"
192        feature_name = "{}{}".format(name_prefix, annotation)
193        wglxml.AddCommands(feature_name, annotation)
194
195    gl_commands = wglxml.all_cmd_names.get_all_commands()
196    gl_data.extend([cmd if cmd[:3] == 'wgl' else 'wgl' + cmd for cmd in gl_commands])
197
198    all_functions = {}
199
200    for function in gl_data:
201        if function.startswith("gl"):
202            all_functions[function] = "gl::" + function[2:]
203        else:
204            all_functions[function] = function
205
206    proc_data = [('    {"%s", P(%s)}' % (func, angle_func))
207                 for func, angle_func in sorted(all_functions.iteritems())]
208
209    with open(out_file_name_gl, 'w') as out_file:
210        output_cpp = template_cpp.format(
211            script_name=sys.argv[0],
212            data_source_name="gl.xml, wgl.xml",
213            copyright_year=date.today().year,
214            includes=includes_gl,
215            cast="PROC",
216            namespace="wgl",
217            proc_data=",\n".join(proc_data),
218            num_procs=len(proc_data))
219        out_file.write(output_cpp)
220        out_file.close()
221    return 0
222
223
224if __name__ == '__main__':
225    sys.exit(main())
226