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.
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.
13
from datetime import date
17
template_gl_enums_header = """// GENERATED FILE - DO NOT EDIT.
18
// Generated by {script_name} using data from {data_source_name}.
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.
24
// gl_enum_utils_autogen.h:
25
// mapping of GLenum value to string.
27
# ifndef LIBANGLE_GL_ENUM_UTILS_AUTOGEN_H_
28
# define LIBANGLE_GL_ENUM_UTILS_AUTOGEN_H_
32
enum class GLenumGroup
38
# endif // LIBANGLE_GL_ENUM_UTILS_AUTOGEN_H_
41
template_gl_enums_source = """// GENERATED FILE - DO NOT EDIT.
42
// Generated by {script_name} using data from {data_source_name}.
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.
48
// gl_enum_utils_autogen.cpp:
49
// mapping of GLenum value to string.
51
#include "libANGLE/gl_enum_utils_autogen.h"
53
#include "libANGLE/gl_enum_utils.h"
57
#include "common/bitset_utils.h"
61
const char *GLenumToString(GLenumGroup enumGroup, unsigned int value)
65
{gl_enums_value_to_string_table}
67
return kUnknownGLenumString;
72
std::string GLbitfieldToString(GLenumGroup enumGroup, unsigned int value)
76
const angle::BitSet<32> bitSet(value);
78
for (const auto index : bitSet)
86
unsigned int mask = 1u << index;
87
OutputGLenumString(st, enumGroup, mask);
96
template_enum_group_case = """case GLenumGroup::{group_name}: {{
100
return kUnknownGLenumString;
105
template_enum_value_to_string_case = """case {value}: return {name};"""
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'
111
exclude_gl_enum_groups = {'SpecialNumbers'}
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:
122
# sort according values
123
string_value_pairs.sort(key=lambda x: (x[1], x[0]))
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)
136
inner_code_block = "\n".join([
137
template_enum_value_to_string_case.format(
138
value='0x%X' % value,
140
) for name, value in exporting_string_value_pairs
143
exporting_groups.append((group_name, inner_code_block))
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])
153
def main(header_output_path, source_output_path):
154
xml = registry_xml.RegistryXML('gl.xml', 'gl_angle_ext.xml')
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
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:
172
if group_name not in gl_enum_in_groups:
173
gl_enum_in_groups[group_name] = dict()
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]
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)
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)
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]
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())))
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)
215
# Write mapping to source file
216
gl_enums_value_to_string_table = dump_value_to_string_mapping(gl_enum_in_groups,
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,
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)
232
if __name__ == '__main__':
239
gl_enum_utils_autogen_base_path = '../src/libANGLE/gl_enum_utils_autogen'
241
gl_enum_utils_autogen_base_path + '.h',
242
gl_enum_utils_autogen_base_path + '.cpp',
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)
253
registry_xml.script_relative(outputs[0]),
254
registry_xml.script_relative(outputs[1])))