xref: /aosp_15_r20/external/angle/scripts/registry_xml.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1#!/usr/bin/python3
2#
3# Copyright 2018 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# registry_xml.py:
8#   Parses information from Khronos registry files..
9
10# List of supported extensions. Add to this list to enable new extensions
11# available in gl.xml.
12
13import difflib
14import os
15import sys
16import xml.etree.ElementTree as etree
17
18from enum import Enum
19
20khronos_xml_inputs = [
21    '../third_party/EGL-Registry/src/api/egl.xml',
22    '../third_party/OpenCL-Docs/src/xml/cl.xml',
23    '../third_party/OpenGL-Registry/src/xml/gl.xml',
24    '../third_party/OpenGL-Registry/src/xml/glx.xml',
25    '../third_party/OpenGL-Registry/src/xml/wgl.xml',
26]
27
28angle_xml_inputs = [
29    'gl_angle_ext.xml',
30    'egl_angle_ext.xml',
31    'registry_xml.py',
32]
33
34xml_inputs = sorted(khronos_xml_inputs + angle_xml_inputs)
35
36# Notes on categories of extensions:
37# 'Requestable' extensions are extensions that can be enabled with ANGLE_request_extension
38# 'ES-Only' extensions are always implicitly enabled.
39# 'Toggleable' extensions are like 'Requestable' except they can be also disabled.
40# 'ANGLE' extensions are extensions that are not yet officially upstreamed to Khronos.
41# We document those extensions in gl_angle_ext.xml instead of the canonical gl.xml.
42
43angle_toggleable_extensions = [
44    "GL_ANGLE_texture_rectangle",
45]
46
47angle_requestable_extensions = [
48    "GL_ANGLE_base_vertex_base_instance",
49    "GL_ANGLE_base_vertex_base_instance_shader_builtin",
50    "GL_ANGLE_blob_cache",
51    "GL_ANGLE_clip_cull_distance",
52    "GL_ANGLE_compressed_texture_etc",
53    "GL_ANGLE_copy_texture_3d",
54    "GL_ANGLE_framebuffer_multisample",
55    "GL_ANGLE_get_image",
56    "GL_ANGLE_get_tex_level_parameter",
57    "GL_ANGLE_logic_op",
58    "GL_ANGLE_lossy_etc_decode",
59    "GL_ANGLE_memory_object_flags",
60    "GL_ANGLE_memory_object_fuchsia",
61    "GL_ANGLE_memory_size",
62    "GL_ANGLE_multi_draw",
63    "GL_ANGLE_multiview_multisample",
64    "GL_ANGLE_polygon_mode",
65    "GL_ANGLE_provoking_vertex",
66    "GL_ANGLE_read_only_depth_stencil_feedback_loops",
67    "GL_ANGLE_renderability_validation",
68    "GL_ANGLE_robust_fragment_shader_output",
69    "GL_ANGLE_semaphore_fuchsia",
70    "GL_ANGLE_shader_pixel_local_storage",
71    "GL_ANGLE_shader_pixel_local_storage_coherent",
72    "GL_ANGLE_stencil_texturing",
73    "GL_ANGLE_texture_compression_dxt3",
74    "GL_ANGLE_texture_compression_dxt5",
75    "GL_ANGLE_texture_external_update",
76    "GL_ANGLE_texture_multisample",
77    "GL_ANGLE_vulkan_image",
78    "GL_ANGLE_yuv_internal_format",
79    "GL_CHROMIUM_color_buffer_float_rgb",
80    "GL_CHROMIUM_color_buffer_float_rgba",
81    "GL_CHROMIUM_lose_context",
82    "GL_CHROMIUM_sync_query",
83]
84
85gles_requestable_extensions = [
86    "GL_ANGLE_framebuffer_blit",
87    "GL_ANGLE_instanced_arrays",
88    "GL_ANGLE_pack_reverse_row_order",
89    "GL_ANGLE_texture_usage",
90    "GL_APPLE_clip_distance",
91    "GL_ARB_sync",
92    "GL_ARM_rgba8",
93    "GL_ARM_shader_framebuffer_fetch",
94    "GL_ARM_shader_framebuffer_fetch_depth_stencil",
95    "GL_EXT_base_instance",
96    "GL_EXT_blend_func_extended",
97    "GL_EXT_blend_minmax",
98    "GL_EXT_buffer_storage",
99    "GL_EXT_clear_texture",
100    "GL_EXT_clip_control",
101    "GL_EXT_clip_cull_distance",
102    "GL_EXT_color_buffer_float",
103    "GL_EXT_color_buffer_half_float",
104    "GL_EXT_compressed_ETC1_RGB8_sub_texture",
105    "GL_EXT_conservative_depth",
106    "GL_EXT_copy_image",
107    "GL_EXT_depth_clamp",
108    "GL_EXT_disjoint_timer_query",
109    "GL_EXT_draw_buffers",
110    "GL_EXT_draw_buffers_indexed",
111    "GL_EXT_draw_elements_base_vertex",
112    "GL_EXT_EGL_image_array",
113    "GL_EXT_EGL_image_external_wrap_modes",
114    "GL_EXT_EGL_image_storage",
115    "GL_EXT_EGL_image_storage_compression",
116    "GL_EXT_external_buffer",
117    "GL_EXT_float_blend",
118    "GL_EXT_frag_depth",
119    "GL_EXT_geometry_shader",
120    "GL_EXT_gpu_shader5",
121    "GL_EXT_instanced_arrays",
122    "GL_EXT_map_buffer_range",
123    "GL_EXT_memory_object",
124    "GL_EXT_memory_object_fd",
125    "GL_EXT_multi_draw_indirect",
126    "GL_EXT_multisampled_render_to_texture",
127    "GL_EXT_multisampled_render_to_texture2",
128    "GL_EXT_occlusion_query_boolean",
129    "GL_EXT_polygon_offset_clamp",
130    "GL_EXT_protected_textures",
131    "GL_EXT_pvrtc_sRGB",
132    "GL_EXT_read_format_bgra",
133    "GL_EXT_render_snorm",
134    "GL_EXT_semaphore",
135    "GL_EXT_semaphore_fd",
136    "GL_EXT_separate_depth_stencil",
137    "GL_EXT_separate_shader_objects",
138    "GL_EXT_shader_framebuffer_fetch",
139    "GL_EXT_shader_framebuffer_fetch_non_coherent",
140    "GL_EXT_shader_io_blocks",
141    "GL_EXT_shader_non_constant_global_initializers",
142    "GL_EXT_shader_texture_lod",
143    "GL_EXT_shadow_samplers",
144    "GL_EXT_sRGB",
145    "GL_EXT_tessellation_shader",
146    "GL_EXT_texture_border_clamp",
147    "GL_EXT_texture_buffer",
148    "GL_EXT_texture_compression_astc_decode_mode",
149    "GL_EXT_texture_compression_astc_decode_mode_rgb9e5",
150    "GL_EXT_texture_compression_bptc",
151    "GL_EXT_texture_compression_dxt1",
152    "GL_EXT_texture_compression_rgtc",
153    "GL_EXT_texture_compression_s3tc",
154    "GL_EXT_texture_compression_s3tc_srgb",
155    "GL_EXT_texture_cube_map_array",
156    "GL_EXT_texture_filter_anisotropic",
157    "GL_EXT_texture_filter_minmax",
158    "GL_EXT_texture_format_BGRA8888",
159    "GL_EXT_texture_mirror_clamp_to_edge",
160    "GL_EXT_texture_norm16",
161    "GL_EXT_texture_query_lod",
162    "GL_EXT_texture_rg",
163    "GL_EXT_texture_shadow_lod",
164    "GL_EXT_texture_sRGB_R8",
165    "GL_EXT_texture_sRGB_RG8",
166    "GL_EXT_texture_storage",
167    "GL_EXT_texture_storage_compression",
168    "GL_EXT_texture_type_2_10_10_10_REV",
169    "GL_EXT_unpack_subimage",
170    "GL_EXT_YUV_target",
171    "GL_IMG_texture_compression_pvrtc",
172    "GL_IMG_texture_compression_pvrtc2",
173    "GL_KHR_parallel_shader_compile",
174    "GL_KHR_texture_compression_astc_hdr",
175    "GL_KHR_texture_compression_astc_ldr",
176    "GL_KHR_texture_compression_astc_sliced_3d",
177    "GL_MESA_framebuffer_flip_y",
178    "GL_NV_depth_buffer_float2",
179    "GL_NV_EGL_stream_consumer_external",
180    "GL_NV_framebuffer_blit",
181    "GL_NV_pack_subimage",
182    "GL_NV_pixel_buffer_object",
183    "GL_NV_polygon_mode",
184    "GL_NV_read_depth",
185    "GL_NV_read_depth_stencil",
186    "GL_NV_read_stencil",
187    "GL_NV_shader_noperspective_interpolation",
188    "GL_OES_compressed_EAC_R11_signed_texture",
189    "GL_OES_compressed_EAC_R11_unsigned_texture",
190    "GL_OES_compressed_EAC_RG11_signed_texture",
191    "GL_OES_compressed_EAC_RG11_unsigned_texture",
192    "GL_OES_compressed_ETC1_RGB8_texture",
193    "GL_OES_compressed_ETC2_punchthroughA_RGBA8_texture",
194    "GL_OES_compressed_ETC2_punchthroughA_sRGB8_alpha_texture",
195    "GL_OES_compressed_ETC2_RGB8_texture",
196    "GL_OES_compressed_ETC2_RGBA8_texture",
197    "GL_OES_compressed_ETC2_sRGB8_alpha8_texture",
198    "GL_OES_compressed_ETC2_sRGB8_texture",
199    "GL_OES_compressed_paletted_texture",
200    "GL_OES_copy_image",
201    "GL_OES_depth_texture_cube_map",
202    "GL_OES_draw_buffers_indexed",
203    "GL_OES_draw_elements_base_vertex",
204    "GL_OES_EGL_image",
205    "GL_OES_EGL_image_external",
206    "GL_OES_EGL_image_external_essl3",
207    "GL_OES_element_index_uint",
208    "GL_OES_fbo_render_mipmap",
209    "GL_OES_geometry_shader",
210    "GL_OES_get_program_binary",
211    "GL_OES_gpu_shader5",
212    "GL_OES_mapbuffer",
213    "GL_OES_required_internalformat",
214    "GL_OES_rgb8_rgba8",
215    "GL_OES_sample_shading",
216    "GL_OES_sample_variables",
217    "GL_OES_shader_image_atomic",
218    "GL_OES_shader_io_blocks",
219    "GL_OES_shader_multisample_interpolation",
220    "GL_OES_standard_derivatives",
221    "GL_OES_tessellation_shader",
222    "GL_OES_texture_3D",
223    "GL_OES_texture_border_clamp",
224    "GL_OES_texture_buffer",
225    "GL_OES_texture_compression_astc",
226    "GL_OES_texture_cube_map_array",
227    "GL_OES_texture_float",
228    "GL_OES_texture_float_linear",
229    "GL_OES_texture_half_float",
230    "GL_OES_texture_half_float_linear",
231    "GL_OES_texture_npot",
232    "GL_OES_texture_stencil8",
233    "GL_OES_texture_storage_multisample_2d_array",
234    "GL_OES_vertex_array_object",
235    "GL_OES_vertex_half_float",
236    "GL_OES_vertex_type_10_10_10_2",
237    "GL_OVR_multiview",
238    "GL_OVR_multiview2",
239    "GL_QCOM_framebuffer_foveated",
240    "GL_QCOM_render_shared_exponent",
241    "GL_QCOM_shading_rate",
242    "GL_QCOM_texture_foveated",
243    "GL_QCOM_tiled_rendering",
244    "GL_WEBGL_video_texture",
245]
246
247angle_es_only_extensions = [
248    "GL_ANGLE_client_arrays",
249    "GL_ANGLE_get_serialized_context_string",
250    "GL_ANGLE_program_binary",
251    "GL_ANGLE_program_binary_readiness_query",
252    "GL_ANGLE_program_cache_control",
253    "GL_ANGLE_relaxed_vertex_attribute_type",
254    "GL_ANGLE_request_extension",
255    "GL_ANGLE_rgbx_internal_format",
256    "GL_ANGLE_robust_client_memory",
257    "GL_ANGLE_robust_resource_initialization",
258    "GL_ANGLE_shader_binary",
259    "GL_ANGLE_webgl_compatibility",
260    "GL_CHROMIUM_bind_generates_resource",
261    "GL_CHROMIUM_bind_uniform_location",
262    "GL_CHROMIUM_copy_compressed_texture",
263    "GL_CHROMIUM_copy_texture",
264    "GL_CHROMIUM_framebuffer_mixed_samples",
265]
266
267gles_es_only_extensions = [
268    "GL_AMD_performance_monitor",
269    "GL_ANDROID_extension_pack_es31a",
270    "GL_ANGLE_depth_texture",
271    "GL_ANGLE_translated_shader_source",
272    "GL_EXT_debug_label",
273    "GL_EXT_debug_marker",
274    "GL_EXT_discard_framebuffer",
275    "GL_EXT_multisample_compatibility",
276    "GL_EXT_primitive_bounding_box",
277    "GL_EXT_robustness",
278    "GL_EXT_sRGB_write_control",
279    "GL_EXT_texture_format_sRGB_override",
280    "GL_EXT_texture_sRGB_decode",
281    "GL_KHR_blend_equation_advanced",
282    "GL_KHR_blend_equation_advanced_coherent",
283    "GL_KHR_debug",
284    "GL_KHR_no_error",
285    "GL_KHR_robust_buffer_access_behavior",
286    "GL_KHR_robustness",
287    "GL_NV_fence",
288    "GL_NV_robustness_video_memory_purge",
289    "GL_OES_depth24",
290    "GL_OES_depth32",
291    "GL_OES_depth_texture",
292    "GL_OES_EGL_sync",
293    "GL_OES_packed_depth_stencil",
294    "GL_OES_primitive_bounding_box",
295    "GL_OES_surfaceless_context",
296]
297
298# ES1 (Possibly the min set of extensions needed by Android)
299gles1_extensions = [
300    "GL_OES_blend_subtract",
301    "GL_OES_draw_texture",
302    "GL_OES_framebuffer_object",
303    "GL_OES_matrix_palette",
304    "GL_OES_point_size_array",
305    "GL_OES_point_sprite",
306    "GL_OES_query_matrix",
307    "GL_OES_texture_cube_map",
308    "GL_OES_texture_mirrored_repeat",
309]
310
311
312def check_sorted(name, l):
313    unidiff = difflib.unified_diff(l, sorted(l, key=str.casefold), 'unsorted', 'sorted')
314    diff_lines = list(unidiff)
315    assert not diff_lines, '\n\nPlease sort "%s":\n%s' % (name, '\n'.join(diff_lines))
316
317
318angle_extensions = angle_requestable_extensions + angle_es_only_extensions + angle_toggleable_extensions
319gles_extensions = gles_requestable_extensions + gles_es_only_extensions
320supported_extensions = sorted(angle_extensions + gles1_extensions + gles_extensions)
321
322assert len(supported_extensions) == len(set(supported_extensions)), 'Duplicates in extension list'
323check_sorted('angle_requestable_extensions', angle_requestable_extensions)
324check_sorted('angle_es_only_extensions', angle_es_only_extensions)
325check_sorted('angle_toggleable_extensions', angle_toggleable_extensions)
326check_sorted('gles_requestable_extensions', gles_requestable_extensions)
327check_sorted('gles_es_only_extensions', gles_es_only_extensions)
328check_sorted('gles_extensions', gles1_extensions)
329
330supported_egl_extensions = [
331    "EGL_ANDROID_blob_cache",
332    "EGL_ANDROID_create_native_client_buffer",
333    "EGL_ANDROID_framebuffer_target",
334    "EGL_ANDROID_get_frame_timestamps",
335    "EGL_ANDROID_get_native_client_buffer",
336    "EGL_ANDROID_native_fence_sync",
337    "EGL_ANDROID_presentation_time",
338    "EGL_ANGLE_create_surface_swap_interval",
339    "EGL_ANGLE_d3d_share_handle_client_buffer",
340    "EGL_ANGLE_device_creation",
341    "EGL_ANGLE_device_d3d",
342    "EGL_ANGLE_device_d3d11",
343    "EGL_ANGLE_device_d3d9",
344    "EGL_ANGLE_display_semaphore_share_group",
345    "EGL_ANGLE_display_texture_share_group",
346    "EGL_ANGLE_external_context_and_surface",
347    "EGL_ANGLE_feature_control",
348    "EGL_ANGLE_ggp_stream_descriptor",
349    "EGL_ANGLE_metal_create_context_ownership_identity",
350    "EGL_ANGLE_metal_shared_event_sync",
351    "EGL_ANGLE_no_error",
352    "EGL_ANGLE_power_preference",
353    "EGL_ANGLE_prepare_swap_buffers",
354    "EGL_ANGLE_program_cache_control",
355    "EGL_ANGLE_query_surface_pointer",
356    "EGL_ANGLE_stream_producer_d3d_texture",
357    "EGL_ANGLE_surface_d3d_texture_2d_share_handle",
358    "EGL_ANGLE_swap_with_frame_token",
359    "EGL_ANGLE_sync_control_rate",
360    "EGL_ANGLE_vulkan_image",
361    "EGL_ANGLE_wait_until_work_scheduled",
362    "EGL_ANGLE_window_fixed_size",
363    "EGL_CHROMIUM_sync_control",
364    "EGL_EXT_create_context_robustness",
365    "EGL_EXT_device_query",
366    "EGL_EXT_gl_colorspace_bt2020_hlg",
367    "EGL_EXT_gl_colorspace_bt2020_linear",
368    "EGL_EXT_gl_colorspace_bt2020_pq",
369    "EGL_EXT_gl_colorspace_display_p3",
370    "EGL_EXT_gl_colorspace_display_p3_linear",
371    "EGL_EXT_gl_colorspace_display_p3_passthrough",
372    "EGL_EXT_gl_colorspace_scrgb",
373    "EGL_EXT_gl_colorspace_scrgb_linear",
374    "EGL_EXT_image_dma_buf_import",
375    "EGL_EXT_image_dma_buf_import_modifiers",
376    "EGL_EXT_image_gl_colorspace",
377    "EGL_EXT_pixel_format_float",
378    "EGL_EXT_platform_base",
379    "EGL_EXT_platform_device",
380    "EGL_EXT_protected_content",
381    "EGL_IMG_context_priority",
382    "EGL_KHR_debug",
383    "EGL_KHR_fence_sync",
384    "EGL_KHR_gl_colorspace",
385    "EGL_KHR_image",
386    "EGL_KHR_lock_surface3",
387    "EGL_KHR_mutable_render_buffer",
388    "EGL_KHR_no_config_context",
389    "EGL_KHR_partial_update",
390    "EGL_KHR_reusable_sync",
391    "EGL_KHR_stream",
392    "EGL_KHR_stream_consumer_gltexture",
393    "EGL_KHR_surfaceless_context",
394    "EGL_KHR_swap_buffers_with_damage",
395    "EGL_KHR_wait_sync",
396    "EGL_NV_post_sub_buffer",
397    "EGL_NV_stream_consumer_gltexture_yuv",
398]
399
400check_sorted('supported_egl_extensions', supported_egl_extensions)
401
402supported_cl_extensions = [
403    # Since OpenCL 1.1
404    "cl_khr_byte_addressable_store",
405    "cl_khr_global_int32_base_atomics",
406    "cl_khr_global_int32_extended_atomics",
407    "cl_khr_local_int32_base_atomics",
408    "cl_khr_local_int32_extended_atomics",
409
410    # OpenCL 2.0 - 2.2
411    "cl_khr_3d_image_writes",
412    "cl_khr_depth_images",
413    "cl_khr_image2d_from_buffer",
414
415    # Optional
416    "cl_khr_extended_versioning",
417    "cl_khr_fp64",
418    "cl_khr_icd",
419    "cl_khr_int64_base_atomics",
420    "cl_khr_int64_extended_atomics",
421]
422
423# Strip these suffixes from Context entry point names. NV is excluded (for now).
424strip_suffixes = ["AMD", "ANDROID", "ANGLE", "CHROMIUM", "EXT", "KHR", "OES", "OVR", "QCOM"]
425check_sorted('strip_suffixes', strip_suffixes)
426
427# The EGL_ANGLE_explicit_context extension is generated differently from other extensions.
428# Toggle generation here.
429support_EGL_ANGLE_explicit_context = True
430
431# Group names that appear in command/param, but not present in groups/group
432unsupported_enum_group_names = {
433    'GetMultisamplePNameNV',
434    'BufferPNameARB',
435    'BufferPointerNameARB',
436    'VertexAttribPointerPropertyARB',
437    'VertexAttribPropertyARB',
438    'FenceParameterNameNV',
439    'FenceConditionNV',
440    'BufferPointerNameARB',
441    'MatrixIndexPointerTypeARB',
442    'PointParameterNameARB',
443    'ClampColorTargetARB',
444    'ClampColorModeARB',
445}
446
447# Versions (major, minor). Note that GLES intentionally places 1.0 last.
448GLES_VERSIONS = [(2, 0), (3, 0), (3, 1), (3, 2), (1, 0)]
449EGL_VERSIONS = [(1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5)]
450CL_VERSIONS = [(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2), (3, 0)]
451
452
453# API types
454class apis:
455    GL = 'GL'
456    GLES = 'GLES'
457    WGL = 'WGL'
458    GLX = 'GLX'
459    EGL = 'EGL'
460    CL = 'CL'
461
462# For GLenum types
463api_enums = {apis.GL: 'BigGLEnum', apis.GLES: 'GLESEnum'}
464default_enum_group_name = 'AllEnums'
465
466
467def script_relative(path):
468    return os.path.join(os.path.dirname(sys.argv[0]), path)
469
470
471def path_to(folder, file):
472    return os.path.join(script_relative(".."), "src", folder, file)
473
474
475def strip_api_prefix(cmd_name):
476    return cmd_name.lstrip("cwegl")
477
478
479def find_xml_input(xml_file):
480    for found_xml in xml_inputs:
481        if found_xml == xml_file or found_xml.endswith('/' + xml_file):
482            return found_xml
483    raise Exception('Could not find XML input: ' + xml_file)
484
485
486def get_cmd_name(command_node):
487    proto = command_node.find('proto')
488    cmd_name = proto.find('name').text
489    return cmd_name
490
491
492class CommandNames:
493
494    def __init__(self):
495        self.command_names = {}
496
497    def get_commands(self, version):
498        return self.command_names[version]
499
500    def get_all_commands(self):
501        cmd_names = []
502        # Combine all the version lists into a single list
503        for version, version_cmd_names in sorted(self.command_names.items()):
504            cmd_names += version_cmd_names
505
506        return cmd_names
507
508    def add_commands(self, version, commands):
509        # Add key if it doesn't exist
510        if version not in self.command_names:
511            self.command_names[version] = []
512        # Add the commands that aren't duplicates
513        self.command_names[version] += commands
514
515
516class RegistryXML:
517
518    def __init__(self, xml_file, ext_file=None):
519        tree = etree.parse(script_relative(find_xml_input(xml_file)))
520        self.root = tree.getroot()
521        if (ext_file):
522            self._AppendANGLEExts(find_xml_input(ext_file))
523        self.all_commands = self.root.findall('commands/command')
524        self.all_cmd_names = CommandNames()
525        self.commands = {}
526
527    def _AppendANGLEExts(self, ext_file):
528        angle_ext_tree = etree.parse(script_relative(ext_file))
529        angle_ext_root = angle_ext_tree.getroot()
530
531        insertion_point = self.root.findall("./types")[0]
532        for t in angle_ext_root.iter('types'):
533            insertion_point.extend(t)
534
535        insertion_point = self.root.findall("./commands")[0]
536        for command in angle_ext_root.iter('commands'):
537            insertion_point.extend(command)
538
539        insertion_point = self.root.findall("./extensions")[0]
540        for extension in angle_ext_root.iter('extensions'):
541            insertion_point.extend(extension)
542
543        insertion_point = self.root
544        for enums in angle_ext_root.iter('enums'):
545            insertion_point.append(enums)
546
547    def AddCommands(self, feature_name, annotation):
548        xpath = ".//feature[@name='%s']//command" % feature_name
549        commands = [cmd.attrib['name'] for cmd in self.root.findall(xpath)]
550
551        # Remove commands that have already been processed
552        current_cmds = self.all_cmd_names.get_all_commands()
553        commands = [cmd for cmd in commands if cmd not in current_cmds]
554
555        self.all_cmd_names.add_commands(annotation, commands)
556        self.commands[annotation] = commands
557
558    def _ClassifySupport(self, extension):
559        supported = extension.attrib['supported']
560        # Desktop GL extensions exposed in ANGLE GLES for Chrome.
561        if extension.attrib['name'] in ['GL_ARB_sync', 'GL_NV_robustness_video_memory_purge']:
562            supported += "|gles2"
563        if 'gles2' in supported:
564            return 'gl2ext'
565        elif 'gles1' in supported:
566            return 'glext'
567        elif 'egl' in supported:
568            return 'eglext'
569        elif 'wgl' in supported:
570            return 'wglext'
571        elif 'glx' in supported:
572            return 'glxext'
573        elif 'cl' in supported:
574            return 'clext'
575        else:
576            assert False, 'Cannot classify support for %s: %s' % (extension.attrib['name'],
577                                                                  supported)
578            return 'unknown'
579
580    def AddExtensionCommands(self, supported_extensions, apis):
581        # Use a first step to run through the extensions so we can generate them
582        # in sorted order.
583        self.ext_data = {}
584        self.ext_dupes = {}
585        ext_annotations = {}
586
587        for extension in self.root.findall("extensions/extension"):
588            extension_name = extension.attrib['name']
589            if not extension_name in supported_extensions:
590                continue
591
592            ext_annotations[extension_name] = self._ClassifySupport(extension)
593
594            ext_cmd_names = []
595
596            # There's an extra step here to filter out 'api=gl' extensions. This
597            # is necessary for handling KHR extensions, which have separate entry
598            # point signatures (without the suffix) for desktop GL. Note that this
599            # extra step is necessary because of Etree's limited Xpath support.
600            for require in extension.findall('require'):
601                if 'api' in require.attrib and require.attrib['api'] not in apis:
602                    continue
603
604                # A special case for EXT_texture_storage
605                filter_out_comment = "Supported only if GL_EXT_direct_state_access is supported"
606                if 'comment' in require.attrib and require.attrib['comment'] == filter_out_comment:
607                    continue
608
609                extension_commands = require.findall('command')
610                ext_cmd_names += [command.attrib['name'] for command in extension_commands]
611
612            self.ext_data[extension_name] = sorted(ext_cmd_names)
613
614        for extension_name, ext_cmd_names in sorted(self.ext_data.items()):
615
616            # Detect and filter duplicate extensions.
617            dupes = []
618            for ext_cmd in ext_cmd_names:
619                if ext_cmd in self.all_cmd_names.get_all_commands():
620                    dupes.append(ext_cmd)
621
622            for dupe in dupes:
623                ext_cmd_names.remove(dupe)
624
625            self.ext_data[extension_name] = sorted(ext_cmd_names)
626            self.ext_dupes[extension_name] = dupes
627            self.all_cmd_names.add_commands(ext_annotations[extension_name], ext_cmd_names)
628
629    def GetEnums(self, override_prefix=None):
630        cmd_names = []
631        for cmd in self.all_cmd_names.get_all_commands():
632            stripped = strip_api_prefix(cmd)
633            prefix = override_prefix or cmd[:(len(cmd) - len(stripped))]
634            cmd_names.append(
635                ('%s%s' % (prefix.upper(), stripped), '%s%s' % (prefix.lower(), stripped)))
636        return cmd_names
637
638
639class EntryPoints:
640
641    def __init__(self, api, xml, commands):
642        self.api = api
643        self._cmd_info = []
644
645        for command_node in xml.all_commands:
646            cmd_name = get_cmd_name(command_node)
647
648            if api == apis.WGL:
649                cmd_name = cmd_name if cmd_name.startswith('wgl') else 'wgl' + cmd_name
650
651            if cmd_name not in commands:
652                continue
653
654            param_text = ["".join(param.itertext()) for param in command_node.findall('param')]
655
656            # Treat (void) as ()
657            if len(param_text) == 1 and param_text[0].strip() == 'void':
658                param_text = []
659
660            proto = command_node.find('proto')
661            proto_text = "".join(proto.itertext())
662
663            self._cmd_info.append((cmd_name, command_node, param_text, proto_text))
664
665    def get_infos(self):
666        return self._cmd_info
667
668
669def GetEGL():
670    egl = RegistryXML('egl.xml', 'egl_angle_ext.xml')
671    for major_version, minor_version in EGL_VERSIONS:
672        version = "%d_%d" % (major_version, minor_version)
673        name_prefix = "EGL_VERSION_"
674        feature_name = "%s%s" % (name_prefix, version)
675        egl.AddCommands(feature_name, version)
676    egl.AddExtensionCommands(supported_egl_extensions, ['egl'])
677    return egl
678
679
680def GetGLES():
681    gles = RegistryXML('gl.xml', 'gl_angle_ext.xml')
682    for major_version, minor_version in GLES_VERSIONS:
683        version = "{}_{}".format(major_version, minor_version)
684        name_prefix = "GL_ES_VERSION_"
685        if major_version == 1:
686            name_prefix = "GL_VERSION_ES_CM_"
687        feature_name = "{}{}".format(name_prefix, version)
688        gles.AddCommands(feature_name, version)
689    gles.AddExtensionCommands(supported_extensions, ['gles2', 'gles1'])
690    return gles
691