~mmach/netext73/webkit2gtk

« back to all changes in this revision

Viewing changes to Source/ThirdParty/ANGLE/scripts/gen_gl_enum_utils.py

  • Committer: mmach
  • Date: 2023-06-16 17:21:37 UTC
  • Revision ID: netbit73@gmail.com-20230616172137-2rqx6yr96ga9g3kp
1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
#
 
3
# Copyright 2019 The ANGLE Project Authors. All rights reserved.
 
4
# Use of this source code is governed by a BSD-style license that can be
 
5
# found in the LICENSE file.
 
6
#
 
7
# gen_gl_enum_utils.py:
 
8
#   Generates GLenum value to string mapping for ANGLE
 
9
#   NOTE: don't run this script directly. Run scripts/run_code_generation.py.
 
10
 
 
11
import sys
 
12
import os
 
13
from datetime import date
 
14
 
 
15
import registry_xml
 
16
 
 
17
template_gl_enums_header = """// GENERATED FILE - DO NOT EDIT.
 
18
// Generated by {script_name} using data from {data_source_name}.
 
19
//
 
20
// Copyright {year} The ANGLE Project Authors. All rights reserved.
 
21
// Use of this source code is governed by a BSD-style license that can be
 
22
// found in the LICENSE file.
 
23
//
 
24
// gl_enum_utils_autogen.h:
 
25
//   mapping of GLenum value to string.
 
26
 
 
27
# ifndef LIBANGLE_GL_ENUM_UTILS_AUTOGEN_H_
 
28
# define LIBANGLE_GL_ENUM_UTILS_AUTOGEN_H_
 
29
 
 
30
namespace gl
 
31
{{
 
32
enum class GLenumGroup
 
33
{{
 
34
    {gl_enum_groups}
 
35
}};
 
36
}}  // namespace gl
 
37
 
 
38
# endif  // LIBANGLE_GL_ENUM_UTILS_AUTOGEN_H_
 
39
"""
 
40
 
 
41
template_gl_enums_source = """// GENERATED FILE - DO NOT EDIT.
 
42
// Generated by {script_name} using data from {data_source_name}.
 
43
//
 
44
// Copyright {year} The ANGLE Project Authors. All rights reserved.
 
45
// Use of this source code is governed by a BSD-style license that can be
 
46
// found in the LICENSE file.
 
47
//
 
48
// gl_enum_utils_autogen.cpp:
 
49
//   mapping of GLenum value to string.
 
50
 
 
51
#include "libANGLE/gl_enum_utils_autogen.h"
 
52
 
 
53
#include "libANGLE/gl_enum_utils.h"
 
54
 
 
55
#include <sstream>
 
56
 
 
57
#include "common/bitset_utils.h"
 
58
 
 
59
namespace gl
 
60
{{
 
61
const char *GLenumToString(GLenumGroup enumGroup, unsigned int value)
 
62
{{
 
63
    switch (enumGroup)
 
64
    {{
 
65
        {gl_enums_value_to_string_table}
 
66
        default:
 
67
            return kUnknownGLenumString;
 
68
    }}
 
69
}}
 
70
 
 
71
 
 
72
std::string GLbitfieldToString(GLenumGroup enumGroup, unsigned int value)
 
73
{{
 
74
    std::stringstream st;
 
75
 
 
76
    const angle::BitSet<32> bitSet(value);
 
77
    bool first = true;
 
78
    for (const auto index : bitSet)
 
79
    {{
 
80
        if (!first)
 
81
        {{
 
82
            st << " | ";
 
83
        }}
 
84
        first = false;
 
85
 
 
86
        unsigned int mask = 1u << index;
 
87
        OutputGLenumString(st, enumGroup, mask);
 
88
    }}
 
89
 
 
90
    return st.str();
 
91
}}
 
92
}}  // namespace gl
 
93
 
 
94
"""
 
95
 
 
96
template_enum_group_case = """case GLenumGroup::{group_name}: {{
 
97
    switch (value) {{
 
98
        {inner_group_cases}
 
99
        default:
 
100
            return kUnknownGLenumString;
 
101
    }}
 
102
}}
 
103
"""
 
104
 
 
105
template_enum_value_to_string_case = """case {value}: return {name};"""
 
106
 
 
107
exclude_gl_enums = {
 
108
    'GL_NO_ERROR', 'GL_TIMEOUT_IGNORED', 'GL_INVALID_INDEX', 'GL_VERSION_ES_CL_1_0',
 
109
    'GL_VERSION_ES_CM_1_1', 'GL_VERSION_ES_CL_1_1'
 
110
}
 
111
exclude_gl_enum_groups = {'SpecialNumbers'}
 
112
 
 
113
 
 
114
def dump_value_to_string_mapping(gl_enum_in_groups, exporting_enums):
 
115
    exporting_groups = list()
 
116
    for group_name, inner_mapping in gl_enum_in_groups.iteritems():
 
117
        string_value_pairs = list(
 
118
            filter(lambda x: x[0] in exporting_enums, inner_mapping.iteritems()))
 
119
        if not string_value_pairs:
 
120
            continue
 
121
 
 
122
        # sort according values
 
123
        string_value_pairs.sort(key=lambda x: (x[1], x[0]))
 
124
 
 
125
        # remove all duplicate values from the pairs list
 
126
        # some value may have more than one GLenum mapped to them, such as:
 
127
        #     GL_DRAW_FRAMEBUFFER_BINDING and GL_FRAMEBUFFER_BINDING
 
128
        #     GL_BLEND_EQUATION_RGB and GL_BLEND_EQUATION
 
129
        # it is safe to output either one of them, for simplity here just
 
130
        # choose the shorter one which comes first in the sorted list
 
131
        exporting_string_value_pairs = list()
 
132
        for index, pair in enumerate(string_value_pairs):
 
133
            if index == 0 or pair[1] != string_value_pairs[index - 1][1]:
 
134
                exporting_string_value_pairs.append(pair)
 
135
 
 
136
        inner_code_block = "\n".join([
 
137
            template_enum_value_to_string_case.format(
 
138
                value='0x%X' % value,
 
139
                name='"%s"' % name,
 
140
            ) for name, value in exporting_string_value_pairs
 
141
        ])
 
142
 
 
143
        exporting_groups.append((group_name, inner_code_block))
 
144
 
 
145
    return "\n".join([
 
146
        template_enum_group_case.format(
 
147
            group_name=group_name,
 
148
            inner_group_cases=inner_code_block,
 
149
        ) for group_name, inner_code_block in sorted(exporting_groups, key=lambda x: x[0])
 
150
    ])
 
151
 
 
152
 
 
153
def main(header_output_path, source_output_path):
 
154
    xml = registry_xml.RegistryXML('gl.xml', 'gl_angle_ext.xml')
 
155
 
 
156
    # build a map from GLenum name to its value
 
157
    all_gl_enums = dict()
 
158
    for enums_node in xml.root.findall('enums'):
 
159
        for enum in enums_node.findall('enum'):
 
160
            name = enum.attrib['name']
 
161
            value = int(enum.attrib['value'], base=16)
 
162
            all_gl_enums[name] = value
 
163
 
 
164
    # Parse groups of GLenums to build a {group, name} -> value mapping.
 
165
    gl_enum_in_groups = dict()
 
166
    enums_has_group = set()
 
167
    for enums_group_node in xml.root.findall('groups/group'):
 
168
        group_name = enums_group_node.attrib['name']
 
169
        if group_name in exclude_gl_enum_groups:
 
170
            continue
 
171
 
 
172
        if group_name not in gl_enum_in_groups:
 
173
            gl_enum_in_groups[group_name] = dict()
 
174
 
 
175
        for enum_node in enums_group_node.findall('enum'):
 
176
            enum_name = enum_node.attrib['name']
 
177
            enums_has_group.add(enum_name)
 
178
            gl_enum_in_groups[group_name][enum_name] = all_gl_enums[enum_name]
 
179
 
 
180
    # Find relevant GLenums according to enabled APIs and extensions.
 
181
    exporting_enums = set()
 
182
    # export all the apis
 
183
    xpath = "./feature[@api='gles2']/require/enum"
 
184
    for enum_tag in xml.root.findall(xpath):
 
185
        enum_name = enum_tag.attrib['name']
 
186
        if enum_name not in exclude_gl_enums:
 
187
            exporting_enums.add(enum_name)
 
188
 
 
189
    for extension in registry_xml.supported_extensions:
 
190
        xpath = "./extensions/extension[@name='%s']/require/enum" % extension
 
191
        for enum_tag in xml.root.findall(xpath):
 
192
            enum_name = enum_tag.attrib['name']
 
193
            if enum_name not in exclude_gl_enums:
 
194
                exporting_enums.add(enum_name)
 
195
 
 
196
    # For enums that do not have a group, add them to a default group
 
197
    default_group_name = registry_xml.default_enum_group_name
 
198
    gl_enum_in_groups[default_group_name] = dict()
 
199
    default_group = gl_enum_in_groups[default_group_name]
 
200
    for enum_name in exporting_enums:
 
201
        if enum_name not in enums_has_group:
 
202
            default_group[enum_name] = all_gl_enums[enum_name]
 
203
 
 
204
    # Write GLenum groups into the header file.
 
205
    header_content = template_gl_enums_header.format(
 
206
        script_name=os.path.basename(sys.argv[0]),
 
207
        data_source_name="gl.xml and gl_angle_ext.xml",
 
208
        year=date.today().year,
 
209
        gl_enum_groups=',\n'.join(sorted(gl_enum_in_groups.iterkeys())))
 
210
 
 
211
    header_output_path = registry_xml.script_relative(header_output_path)
 
212
    with open(header_output_path, 'w') as f:
 
213
        f.write(header_content)
 
214
 
 
215
    # Write mapping to source file
 
216
    gl_enums_value_to_string_table = dump_value_to_string_mapping(gl_enum_in_groups,
 
217
                                                                  exporting_enums)
 
218
    source_content = template_gl_enums_source.format(
 
219
        script_name=os.path.basename(sys.argv[0]),
 
220
        data_source_name="gl.xml and gl_angle_ext.xml",
 
221
        year=date.today().year,
 
222
        gl_enums_value_to_string_table=gl_enums_value_to_string_table,
 
223
    )
 
224
 
 
225
    source_output_path = registry_xml.script_relative(source_output_path)
 
226
    with open(source_output_path, 'w') as f:
 
227
        f.write(source_content)
 
228
 
 
229
    return 0
 
230
 
 
231
 
 
232
if __name__ == '__main__':
 
233
    inputs = [
 
234
        'gl.xml',
 
235
        'gl_angle_ext.xml',
 
236
        'registry_xml.py',
 
237
    ]
 
238
 
 
239
    gl_enum_utils_autogen_base_path = '../src/libANGLE/gl_enum_utils_autogen'
 
240
    outputs = [
 
241
        gl_enum_utils_autogen_base_path + '.h',
 
242
        gl_enum_utils_autogen_base_path + '.cpp',
 
243
    ]
 
244
 
 
245
    if len(sys.argv) > 1:
 
246
        if sys.argv[1] == 'inputs':
 
247
            print ','.join(inputs)
 
248
        elif sys.argv[1] == 'outputs':
 
249
            print ','.join(outputs)
 
250
    else:
 
251
        sys.exit(
 
252
            main(
 
253
                registry_xml.script_relative(outputs[0]),
 
254
                registry_xml.script_relative(outputs[1])))