Edit

kc3-lang/angle/scripts/generate_entry_points.py

Branch :

  • Show log

    Commit

  • Author : Brandon Schade
    Date : 2020-01-27 13:37:29
    Hash : 0a6e118d
    Message : Change g_Mutex from std::mutex to std::recursive_mutex When running flatland on android-10.0.0_r21 (Pixel 3), libgui's ~EglImage calls eglTerminate which grabs angle's EGL entry point mutex. The path continues to libvulkan where eventually another egl call happens (eglDestroyImageKHR) and it will attempt to take the mutex at the entry point again. So we try to get the mutex multiple times from the same thread. Change this mutex to a recursive_mutex to allow for this re-entry of EGL calls Tests: android-10.0.0_r21/frameworks/native/cmds/flatland Bug: angleproject:4354 Change-Id: If8a817df45e9f58d5f06884510350e17d7127fa9 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2029218 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Cody Northrop <cnorthrop@google.com>

  • scripts/generate_entry_points.py
  • #!/usr/bin/python2
    #
    # 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.
    #
    # generate_entry_points.py:
    #   Generates the OpenGL bindings and entry point layers for ANGLE.
    #   NOTE: don't run this script directly. Run scripts/run_code_generation.py.
    
    import sys, os, pprint, json
    from datetime import date
    import registry_xml
    
    # List of GLES1 extensions for which we don't need to add Context.h decls.
    gles1_no_context_decl_extensions = [
        "GL_OES_framebuffer_object",
    ]
    
    # This is a list of exceptions for entry points which don't want to have
    # the EVENT macro. This is required for some debug marker entry points.
    no_event_marker_exceptions_list = sorted([
        "glPushGroupMarkerEXT",
        "glPopGroupMarkerEXT",
        "glInsertEventMarkerEXT",
    ])
    
    # Strip these suffixes from Context entry point names. NV is excluded (for now).
    strip_suffixes = ["ANGLE", "EXT", "KHR", "OES", "CHROMIUM", "OVR"]
    
    template_entry_point_header = """// GENERATED FILE - DO NOT EDIT.
    // Generated by {script_name} using data from {data_source_name}.
    //
    // Copyright {year} 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.
    //
    // entry_points_{annotation_lower}_autogen.h:
    //   Defines the {comment} entry points.
    
    #ifndef {lib}_ENTRY_POINTS_{annotation_upper}_AUTOGEN_H_
    #define {lib}_ENTRY_POINTS_{annotation_upper}_AUTOGEN_H_
    
    {includes}
    
    namespace gl
    {{
    {entry_points}
    }}  // namespace gl
    
    #endif  // {lib}_ENTRY_POINTS_{annotation_upper}_AUTOGEN_H_
    """
    
    template_entry_point_source = """// GENERATED FILE - DO NOT EDIT.
    // Generated by {script_name} using data from {data_source_name}.
    //
    // Copyright {year} 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.
    //
    // entry_points_{annotation_lower}_autogen.cpp:
    //   Defines the {comment} entry points.
    
    {includes}
    
    namespace gl
    {{
    {entry_points}}}  // namespace gl
    """
    
    template_entry_points_enum_header = """// GENERATED FILE - DO NOT EDIT.
    // Generated by {script_name} using data from {data_source_name}.
    //
    // Copyright {year} 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.
    //
    // entry_points_enum_autogen.h:
    //   Defines the {lib} entry points enumeration.
    
    #ifndef LIBANGLE_ENTRYPOINTSENUM_AUTOGEN_H_
    #define LIBANGLE_ENTRYPOINTSENUM_AUTOGEN_H_
    
    namespace gl
    {{
    enum class EntryPoint
    {{
    {entry_points_list}
    }};
    
    const char *GetEntryPointName(EntryPoint ep);
    }}  // namespace gl
    #endif  // LIBANGLE_ENTRY_POINTS_ENUM_AUTOGEN_H_
    """
    
    template_entry_points_name_case = """        case EntryPoint::{enum}:
                return "gl{enum}";"""
    
    template_entry_points_enum_source = """// GENERATED FILE - DO NOT EDIT.
    // Generated by {script_name} using data from {data_source_name}.
    //
    // Copyright {year} 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.
    //
    // entry_points_enum_autogen.cpp:
    //   Helper methods for the {lib} entry points enumeration.
    
    #include "libANGLE/entry_points_enum_autogen.h"
    
    #include "common/debug.h"
    
    namespace gl
    {{
    const char *GetEntryPointName(EntryPoint ep)
    {{
        switch (ep)
        {{
    {entry_points_name_cases}
            default:
                UNREACHABLE();
                return "error";
        }}
    }}
    }}  // namespace gl
    """
    
    template_lib_entry_point_source = """// GENERATED FILE - DO NOT EDIT.
    // Generated by {script_name} using data from {data_source_name}.
    //
    // Copyright {year} 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.
    //
    // {lib_name}.cpp: Implements the exported {lib_description} functions.
    
    {includes}
    extern "C" {{
    {entry_points}
    }} // extern "C"
    """
    
    template_entry_point_decl = """ANGLE_EXPORT {return_type}GL_APIENTRY {name}{explicit_context_suffix}({explicit_context_param}{explicit_context_comma}{params});"""
    
    template_entry_point_no_return = """void GL_APIENTRY {name}{explicit_context_suffix}({explicit_context_param}{explicit_context_comma}{params})
    {{
        Context *context = {context_getter};
        {event_comment}EVENT("gl{name}", "context = %d{comma_if_needed}{format_params}", CID(context){comma_if_needed}{pass_params});
    
        if (context)
        {{{assert_explicit_context}{packed_gl_enum_conversions}
            std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
            bool isCallValid = (context->skipValidation() || Validate{name}({validate_params}));
            if (isCallValid)
            {{
                context->{name_lower_no_suffix}({internal_params});
            }}
            ANGLE_CAPTURE({name}, isCallValid, {validate_params});
        }}
    }}
    """
    
    template_entry_point_with_return = """{return_type}GL_APIENTRY {name}{explicit_context_suffix}({explicit_context_param}{explicit_context_comma}{params})
    {{
        Context *context = {context_getter};
        {event_comment}EVENT("gl{name}", "context = %d{comma_if_needed}{format_params}", CID(context){comma_if_needed}{pass_params});
    
        {return_type} returnValue;
        if (context)
        {{{assert_explicit_context}{packed_gl_enum_conversions}
            std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
            bool isCallValid = (context->skipValidation() || Validate{name}({validate_params}));
            if (isCallValid)
            {{
                returnValue = context->{name_lower_no_suffix}({internal_params});
            }}
            else
            {{
                returnValue = GetDefaultReturnValue<EntryPoint::{name}, {return_type}>();
            }}
            ANGLE_CAPTURE({name}, isCallValid, {validate_params}, returnValue);
        }}
        else
        {{
            returnValue = GetDefaultReturnValue<EntryPoint::{name}, {return_type}>();
        }}
        return returnValue;
    }}
    """
    
    context_header = """// GENERATED FILE - DO NOT EDIT.
    // Generated by {script_name} using data from {data_source_name}.
    //
    // Copyright {year} 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.
    //
    // Context_{annotation_lower}_autogen.h: Creates a macro for interfaces in Context.
    
    #ifndef ANGLE_CONTEXT_{annotation_upper}_AUTOGEN_H_
    #define ANGLE_CONTEXT_{annotation_upper}_AUTOGEN_H_
    
    #define ANGLE_{annotation_upper}_CONTEXT_API \\
    {interface}
    
    #endif // ANGLE_CONTEXT_API_{version}_AUTOGEN_H_
    """
    
    context_decl_format = """    {return_type} {name_lower_no_suffix}({internal_params}); \\"""
    
    libgles_entry_point_def = """{return_type}GL_APIENTRY gl{name}{explicit_context_suffix}({explicit_context_param}{explicit_context_comma}{params})
    {{
        return gl::{name}{explicit_context_suffix}({explicit_context_internal_param}{explicit_context_comma}{internal_params});
    }}
    """
    
    template_glext_explicit_context_inc = """// GENERATED FILE - DO NOT EDIT.
    // Generated by {script_name} using data from {data_source_name}.
    //
    // Copyright {year} 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.
    //
    // gl{version}ext_explicit_context_autogen.inc:
    //   Function declarations for the EGL_ANGLE_explicit_context extension
    
    {function_pointers}
    #ifdef GL_GLEXT_PROTOTYPES
    {function_prototypes}
    #endif
    """
    
    template_glext_function_pointer = """typedef {return_type}(GL_APIENTRYP PFN{name_upper}{explicit_context_suffix_upper}PROC)({explicit_context_param}{explicit_context_comma}{params});"""
    template_glext_function_prototype = """{apicall} {return_type}GL_APIENTRY {name}{explicit_context_suffix}({explicit_context_param}{explicit_context_comma}{params});"""
    
    template_validation_header = """// GENERATED FILE - DO NOT EDIT.
    // Generated by {script_name} using data from {data_source_name}.
    //
    // Copyright {year} 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.
    //
    // validation{annotation}_autogen.h:
    //   Validation functions for the OpenGL {comment} entry points.
    
    #ifndef LIBANGLE_VALIDATION_{annotation}_AUTOGEN_H_
    #define LIBANGLE_VALIDATION_{annotation}_AUTOGEN_H_
    
    #include "common/PackedEnums.h"
    
    namespace gl
    {{
    class Context;
    
    {prototypes}
    }}  // namespace gl
    
    #endif  // LIBANGLE_VALIDATION_{annotation}_AUTOGEN_H_
    """
    
    template_capture_header = """// GENERATED FILE - DO NOT EDIT.
    // Generated by {script_name} using data from {data_source_name}.
    //
    // Copyright {year} 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.
    //
    // capture_gles_{annotation}_autogen.h:
    //   Capture functions for the OpenGL ES {comment} entry points.
    
    #ifndef LIBANGLE_CAPTURE_GLES_{annotation}_AUTOGEN_H_
    #define LIBANGLE_CAPTURE_GLES_{annotation}_AUTOGEN_H_
    
    #include "common/PackedEnums.h"
    #include "libANGLE/FrameCapture.h"
    
    namespace gl
    {{
    {prototypes}
    }}  // namespace gl
    
    #endif  // LIBANGLE_CAPTURE_GLES_{annotation}_AUTOGEN_H_
    """
    
    template_capture_source = """// GENERATED FILE - DO NOT EDIT.
    // Generated by {script_name} using data from {data_source_name}.
    //
    // Copyright {year} 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.
    //
    // capture_gles_{annotation_with_dash}_autogen.cpp:
    //   Capture functions for the OpenGL ES {comment} entry points.
    
    #include "libANGLE/capture_gles_{annotation_with_dash}_autogen.h"
    
    #include "libANGLE/Context.h"
    #include "libANGLE/FrameCapture.h"
    #include "libANGLE/gl_enum_utils.h"
    #include "libANGLE/validation{annotation_no_dash}.h"
    
    using namespace angle;
    
    namespace gl
    {{
    {capture_methods}
    }}  // namespace gl
    """
    
    template_capture_method_with_return_value = """
    CallCapture Capture{short_name}({params_with_type}, {return_value_type_original} returnValue)
    {{
        ParamBuffer paramBuffer;
    
        {parameter_captures}
    
        ParamCapture returnValueCapture("returnValue", ParamType::T{return_value_type_custom});
        InitParamValue(ParamType::T{return_value_type_custom}, returnValue, &returnValueCapture.value);
        paramBuffer.addReturnValue(std::move(returnValueCapture));
    
        return CallCapture(gl::EntryPoint::{short_name}, std::move(paramBuffer));
    }}
    """
    
    template_capture_method_no_return_value = """
    CallCapture Capture{short_name}({params_with_type})
    {{
        ParamBuffer paramBuffer;
    
        {parameter_captures}
    
        return CallCapture(gl::EntryPoint::{short_name}, std::move(paramBuffer));
    }}
    """
    
    template_parameter_capture_value = """paramBuffer.addValueParam("{name}", ParamType::T{type}, {name});"""
    
    template_parameter_capture_gl_enum = """paramBuffer.addEnumParam("{name}", GLenumGroup::{group}, ParamType::T{type}, {name});"""
    
    template_parameter_capture_pointer = """
        ParamCapture {name}Param("{name}", ParamType::T{type});
        InitParamValue(ParamType::T{type}, {name}, &{name}Param.value);
        {capture_name}({params}, &{name}Param);
        paramBuffer.addParam(std::move({name}Param));
    """
    
    template_parameter_capture_pointer_func = """void {name}({params});"""
    
    template_capture_replay_source = """// GENERATED FILE - DO NOT EDIT.
    // Generated by {script_name} using data from {data_source_name}.
    //
    // Copyright {year} 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.
    //
    // frame_capture_replay_autogen.cpp:
    //   Util function to dispatch captured GL calls through Context and replay them.
    
    #include "angle_gl.h"
    
    #include "common/debug.h"
    #include "common/debug.h"
    #include "libANGLE/Context.h"
    #include "libANGLE/Context.inl.h"
    #include "libANGLE/FrameCapture.h"
    
    using namespace gl;
    
    namespace angle
    {{
    
    void FrameCapture::ReplayCall(gl::Context *context,
                                  ReplayContext *replayContext,
                                  const CallCapture &call)
    {{
        const ParamBuffer &params = call.params;
        switch (call.entryPoint)
        {{
            {call_replay_cases}
            default:
                UNREACHABLE();
        }}
    }}
    
    }}  // namespace angle
    
    """
    
    template_capture_replay_call_case = """case gl::EntryPoint::{entry_point}:
        context->{context_call}({param_value_access});break;"""
    
    static_cast_to_dict = {
        "GLintptr": "unsigned long long",
        "GLsizeiptr": "unsigned long long",
        "GLuint64": "unsigned long long",
    }
    
    reinterpret_cast_to_dict = {
        "GLsync": "uintptr_t",
        "GLDEBUGPROC": "uintptr_t",
        "GLDEBUGPROCKHR": "uintptr_t",
        "GLeglImageOES": "uintptr_t",
    }
    
    format_dict = {
        "GLbitfield": "%s",
        "GLboolean": "%s",
        "GLbyte": "%d",
        "GLclampx": "0x%X",
        "GLDEBUGPROC": "0x%016\" PRIxPTR \"",
        "GLDEBUGPROCKHR": "0x%016\" PRIxPTR \"",
        "GLdouble": "%f",
        "GLeglImageOES": "0x%016\" PRIxPTR \"",
        "GLenum": "%s",
        "GLfixed": "0x%X",
        "GLfloat": "%f",
        "GLint": "%d",
        "GLintptr": "%llu",
        "GLshort": "%d",
        "GLsizei": "%d",
        "GLsizeiptr": "%llu",
        "GLsync": "0x%016\" PRIxPTR \"",
        "GLubyte": "%d",
        "GLuint": "%u",
        "GLuint64": "%llu",
        "GLushort": "%u",
        "int": "%d",
        # WGL specific types
        "BOOL": "%u",
        "DWORD": "0x%016\" PRIxPTR \"",
        "FLOAT": "%f",
        "HDC": "0x%016\" PRIxPTR \"",
        "HENHMETAFILE": "0x%016\" PRIxPTR \"",
        "HGLRC": "0x%016\" PRIxPTR \"",
        "LPCSTR": "0x%016\" PRIxPTR \"",
        "LPGLYPHMETRICSFLOAT": "0x%016\" PRIxPTR \"",
        "UINT": "%u",
    }
    
    template_header_includes = """#include <GLES{major}/gl{major}{minor}.h>
    #include <export.h>"""
    
    template_sources_includes = """#include "libGLESv2/entry_points_{header_version}_autogen.h"
    
    #include "libANGLE/Context.h"
    #include "libANGLE/Context.inl.h"
    #include "libANGLE/capture_{header_version}_autogen.h"
    #include "libANGLE/gl_enum_utils.h"
    #include "libANGLE/validation{validation_header_version}.h"
    #include "libANGLE/entry_points_utils.h"
    #include "libGLESv2/global_state.h"
    """
    
    template_header_includes_gl32 = """#include <export.h>
    #include "angle_gl.h"
    
    """
    
    template_sources_includes_gl32 = """#include "libGL/entry_points_{}_autogen.h"
    
    #include "libANGLE/Context.h"
    #include "libANGLE/Context.inl.h"
    #include "libANGLE/gl_enum_utils.h"
    #include "libANGLE/validationEGL.h"
    #include "libANGLE/validationES.h"
    #include "libANGLE/validationES1.h"
    #include "libANGLE/validationES2.h"
    #include "libANGLE/validationES3.h"
    #include "libANGLE/validationES31.h"
    #include "libANGLE/validationES32.h"
    #include "libANGLE/validationESEXT.h"
    #include "libANGLE/validationGL{}{}_autogen.h"
    #include "libANGLE/entry_points_utils.h"
    #include "libGLESv2/global_state.h"
    """
    
    template_event_comment = """// Don't run the EVENT() macro on the EXT_debug_marker entry points.
        // It can interfere with the debug events being set by the caller.
        // """
    
    template_capture_proto = "angle::CallCapture Capture%s(%s);"
    
    template_validation_proto = "bool Validate%s(%s);"
    
    template_windows_def_file = """; GENERATED FILE - DO NOT EDIT.
    ; Generated by {script_name} using data from {data_source_name}.
    ;
    ; Copyright {year} 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.
    LIBRARY {lib}
    EXPORTS
    {exports}
    """
    
    template_frame_capture_utils_header = """// GENERATED FILE - DO NOT EDIT.
    // Generated by {script_name} using data from {data_source_name}.
    //
    // Copyright {year} 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.
    //
    // frame_capture_utils_autogen.h:
    //   ANGLE Frame capture types and helper functions.
    
    #ifndef LIBANGLE_FRAME_CAPTURE_UTILS_AUTOGEN_H_
    #define LIBANGLE_FRAME_CAPTURE_UTILS_AUTOGEN_H_
    
    #include "common/PackedEnums.h"
    
    namespace angle
    {{
    enum class ParamType
    {{
        {param_types}
    }};
    
    constexpr uint32_t kParamTypeCount = {param_type_count};
    
    union ParamValue
    {{
        {param_union_values}
    }};
    
    template <ParamType PType, typename T>
    T GetParamVal(const ParamValue &value);
    
    {get_param_val_specializations}
    
    template <ParamType PType, typename T>
    T GetParamVal(const ParamValue &value)
    {{
        UNREACHABLE();
        return T();
    }}
    
    template <typename T>
    T AccessParamValue(ParamType paramType, const ParamValue &value)
    {{
        switch (paramType)
        {{
    {access_param_value_cases}
        }}
    }}
    
    template <ParamType PType, typename T>
    void SetParamVal(T valueIn, ParamValue *valueOut);
    
    {set_param_val_specializations}
    
    template <ParamType PType, typename T>
    void SetParamVal(T valueIn, ParamValue *valueOut)
    {{
        UNREACHABLE();
    }}
    
    template <typename T>
    void InitParamValue(ParamType paramType, T valueIn, ParamValue *valueOut)
    {{
        switch (paramType)
        {{
    {init_param_value_cases}
        }}
    }}
    
    void WriteParamTypeToStream(std::ostream &os, ParamType paramType, const ParamValue& paramValue);
    const char *ParamTypeToString(ParamType paramType);
    
    enum class ResourceIDType
    {{
        {resource_id_types}
    }};
    
    ResourceIDType GetResourceIDTypeFromParamType(ParamType paramType);
    const char *GetResourceIDTypeName(ResourceIDType resourceIDType);
    }}  // namespace angle
    
    #endif  // LIBANGLE_FRAME_CAPTURE_UTILS_AUTOGEN_H_
    """
    
    template_frame_capture_utils_source = """// GENERATED FILE - DO NOT EDIT.
    // Generated by {script_name} using data from {data_source_name}.
    //
    // Copyright {year} 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.
    //
    // frame_capture_utils_autogen.cpp:
    //   ANGLE Frame capture types and helper functions.
    
    #include "libANGLE/frame_capture_utils_autogen.h"
    
    #include "libANGLE/FrameCapture.h"
    
    namespace angle
    {{
    void WriteParamTypeToStream(std::ostream &os, ParamType paramType, const ParamValue& paramValue)
    {{
        switch (paramType)
        {{
    {write_param_type_to_stream_cases}
            default:
                os << "unknown";
                break;
        }}
    }}
    
    const char *ParamTypeToString(ParamType paramType)
    {{
        switch (paramType)
        {{
    {param_type_to_string_cases}
            default:
                UNREACHABLE();
                return "unknown";
        }}
    }}
    
    ResourceIDType GetResourceIDTypeFromParamType(ParamType paramType)
    {{
        switch (paramType)
        {{
    {param_type_resource_id_cases}
            default:
                return ResourceIDType::InvalidEnum;
        }}
    }}
    
    const char *GetResourceIDTypeName(ResourceIDType resourceIDType)
    {{
        switch (resourceIDType)
        {{
    {resource_id_type_name_cases}
            default:
                UNREACHABLE();
                return "GetResourceIDTypeName error";
        }}
    }}
    }}  // namespace angle
    """
    
    template_get_param_val_specialization = """template <>
    inline {type} GetParamVal<ParamType::T{enum}, {type}>(const ParamValue &value)
    {{
        return value.{union_name};
    }}"""
    
    template_access_param_value_case = """        case ParamType::T{enum}:
        return GetParamVal<ParamType::T{enum}, T>(value);"""
    
    template_set_param_val_specialization = """template <>
    inline void SetParamVal<ParamType::T{enum}>({type} valueIn, ParamValue *valueOut)
    {{
        valueOut->{union_name} = valueIn;
    }}"""
    
    template_init_param_value_case = """        case ParamType::T{enum}:
                SetParamVal<ParamType::T{enum}>(valueIn, valueOut);
                break;"""
    
    template_write_param_type_to_stream_case = """        case ParamType::T{enum}:
                WriteParamValueToStream<ParamType::T{enum}>(os, paramValue.{union_name});
                break;"""
    
    template_param_type_to_string_case = """        case ParamType::T{enum}:
                return "{type}";"""
    
    template_param_type_to_resource_id_type_case = """        case ParamType::T{enum}:
                return ResourceIDType::{resource_id_type};"""
    
    template_resource_id_type_name_case = """        case ResourceIDType::{resource_id_type}:
                return "{resource_id_type}";"""
    
    
    def script_relative(path):
        return os.path.join(os.path.dirname(sys.argv[0]), path)
    
    
    def format_entry_point_decl(cmd_name, proto, params, is_explicit_context):
        comma_if_needed = ", " if len(params) > 0 else ""
        return template_entry_point_decl.format(
            name=cmd_name[2:],
            return_type=proto[:-len(cmd_name)],
            params=", ".join(params),
            comma_if_needed=comma_if_needed,
            explicit_context_suffix="ContextANGLE" if is_explicit_context else "",
            explicit_context_param="GLeglContext ctx" if is_explicit_context else "",
            explicit_context_comma=", " if is_explicit_context and len(params) > 0 else "")
    
    
    def type_name_sep_index(param):
        space = param.rfind(" ")
        pointer = param.rfind("*")
        return max(space, pointer)
    
    
    def just_the_type(param):
        if "*" in param:
            return param[:type_name_sep_index(param) + 1]
        return param[:type_name_sep_index(param)]
    
    
    def just_the_name(param):
        return param[type_name_sep_index(param) + 1:]
    
    
    def make_param(param_type, param_name):
        return param_type + " " + param_name
    
    
    def just_the_type_packed(param, entry):
        name = just_the_name(param)
        if entry.has_key(name):
            return entry[name]
        else:
            return just_the_type(param)
    
    
    def just_the_name_packed(param, reserved_set):
        name = just_the_name(param)
        if name in reserved_set:
            return name + 'Packed'
        else:
            return name
    
    
    def param_print_argument(command_node, param):
        name_only = just_the_name(param)
        type_only = just_the_type(param)
    
        if "*" in param:
            return "(uintptr_t)" + name_only
    
        if type_only in reinterpret_cast_to_dict:
            return "(" + reinterpret_cast_to_dict[type_only] + ")" + name_only
    
        if type_only in static_cast_to_dict:
            return "static_cast<" + static_cast_to_dict[type_only] + ">(" + name_only + ")"
    
        if type_only == "GLboolean":
            return "GLbooleanToString(%s)" % (name_only,)
    
        if type_only == "GLbitfield":
            group_name = find_gl_enum_group_in_command(command_node, name_only)
            return "GLbitfieldToString(GLenumGroup::%s, %s).c_str()" % (group_name, name_only)
    
        if type_only == "GLenum":
            group_name = find_gl_enum_group_in_command(command_node, name_only)
            return "GLenumToString(GLenumGroup::%s, %s)" % (group_name, name_only)
    
        return name_only
    
    
    def param_format_string(param):
        if "*" in param:
            return param + " = 0x%016\" PRIxPTR \""
        else:
            type_only = just_the_type(param)
            if type_only not in format_dict:
                raise Exception(type_only + " is not a known type in 'format_dict'")
    
            return param + " = " + format_dict[type_only]
    
    
    def default_return_value(cmd_name, return_type):
        if return_type == "void":
            return ""
        return "GetDefaultReturnValue<EntryPoint::" + cmd_name[2:] + ", " + return_type + ">()"
    
    
    def get_context_getter_function(cmd_name, is_explicit_context):
        if is_explicit_context:
            return "static_cast<gl::Context *>(ctx)"
    
        lost_context_acceptable_cmds = [
            "glGetError",
            "glGetSync",
            "glGetQueryObjecti",
            "glGetProgramiv",
            "glGetGraphicsResetStatus",
            "glGetShaderiv",
        ]
        for context_lost_entry_pont in lost_context_acceptable_cmds:
            if cmd_name.startswith(context_lost_entry_pont):
                return "GetGlobalContext()"
        return "GetValidGlobalContext()"
    
    
    def strip_suffix(name):
        for suffix in strip_suffixes:
            if name.endswith(suffix):
                name = name[0:-len(suffix)]
        return name
    
    
    def find_gl_enum_group_in_command(command_node, param_name):
        group_name = None
        for param_node in command_node.findall('./param'):
            if param_node.find('./name').text == param_name:
                group_name = param_node.attrib.get('group', None)
                break
    
        if group_name is None or group_name in registry_xml.unsupported_enum_group_names:
            group_name = registry_xml.default_enum_group_name
    
        return group_name
    
    
    def get_packed_enums(cmd_packed_gl_enums, cmd_name):
        # Always strip the suffix when querying packed enums.
        return cmd_packed_gl_enums.get(strip_suffix(cmd_name), {})
    
    
    def format_entry_point_def(command_node, cmd_name, proto, params, is_explicit_context,
                               cmd_packed_gl_enums):
        packed_gl_enums = get_packed_enums(cmd_packed_gl_enums, cmd_name)
        internal_params = [just_the_name_packed(param, packed_gl_enums) for param in params]
        packed_gl_enum_conversions = []
        for param in params:
            name = just_the_name(param)
            if name in packed_gl_enums:
                internal_name = name + "Packed"
                internal_type = packed_gl_enums[name]
                packed_gl_enum_conversions += [
                    "\n        " + internal_type + " " + internal_name + " = FromGL<" + internal_type +
                    ">(" + name + ");"
                ]
    
        pass_params = [param_print_argument(command_node, param) for param in params]
        format_params = [param_format_string(param) for param in params]
        return_type = proto[:-len(cmd_name)]
        default_return = default_return_value(cmd_name, return_type.strip())
        event_comment = template_event_comment if cmd_name in no_event_marker_exceptions_list else ""
        name_lower_no_suffix = strip_suffix(cmd_name[2:3].lower() + cmd_name[3:])
    
        format_params = {
            "name":
                cmd_name[2:],
            "name_lower_no_suffix":
                name_lower_no_suffix,
            "return_type":
                return_type,
            "params":
                ", ".join(params),
            "internal_params":
                ", ".join(internal_params),
            "packed_gl_enum_conversions":
                "".join(packed_gl_enum_conversions),
            "pass_params":
                ", ".join(pass_params),
            "comma_if_needed":
                ", " if len(params) > 0 else "",
            "validate_params":
                ", ".join(["context"] + internal_params),
            "format_params":
                ", ".join(format_params),
            "context_getter":
                get_context_getter_function(cmd_name, is_explicit_context),
            "event_comment":
                event_comment,
            "explicit_context_suffix":
                "ContextANGLE" if is_explicit_context else "",
            "explicit_context_param":
                "GLeglContext ctx" if is_explicit_context else "",
            "explicit_context_comma":
                ", " if is_explicit_context and len(params) > 0 else "",
            "assert_explicit_context":
                "\nASSERT(context == GetValidGlobalContext());" if is_explicit_context else ""
        }
    
        if return_type.strip() == "void":
            return template_entry_point_no_return.format(**format_params)
        else:
            return template_entry_point_with_return.format(**format_params)
    
    
    def get_capture_param_type_name(param_type):
    
        pointer_count = param_type.count("*")
        is_const = "const" in param_type.split()
    
        param_type = param_type.replace("*", "").strip()
        param_type = " ".join([param for param in param_type.split() if param != "const"])
    
        if is_const:
            param_type += "Const"
        for x in range(pointer_count):
            param_type += "Pointer"
    
        return param_type
    
    
    def format_capture_method(command, cmd_name, proto, params, all_param_types, capture_pointer_funcs,
                              cmd_packed_gl_enums):
    
        packed_gl_enums = get_packed_enums(cmd_packed_gl_enums, cmd_name)
    
        params_with_type = get_internal_params(
            cmd_name, ["const State &glState", "bool isCallValid"] + params, cmd_packed_gl_enums)
        params_just_name = ", ".join(
            ["glState", "isCallValid"] +
            [just_the_name_packed(param, packed_gl_enums) for param in params])
    
        parameter_captures = []
        for param in params:
    
            param_name = just_the_name_packed(param, packed_gl_enums)
            param_type = just_the_type_packed(param, packed_gl_enums).strip()
    
            pointer_count = param_type.count("*")
            param_type = get_capture_param_type_name(param_type)
    
            if pointer_count > 0:
                params = params_just_name
                capture_name = "Capture%s_%s" % (cmd_name[2:], param_name)
                capture = template_parameter_capture_pointer.format(
                    name=param_name, type=param_type, capture_name=capture_name, params=params)
    
                capture_pointer_func = template_parameter_capture_pointer_func.format(
                    name=capture_name, params=params_with_type + ", angle::ParamCapture *paramCapture")
                capture_pointer_funcs += [capture_pointer_func]
            elif param_type in ('GLenum', 'GLbitfield'):
                gl_enum_group = find_gl_enum_group_in_command(command, param_name)
                capture = template_parameter_capture_gl_enum.format(
                    name=param_name, type=param_type, group=gl_enum_group)
            else:
                capture = template_parameter_capture_value.format(name=param_name, type=param_type)
    
            all_param_types.add(param_type)
    
            parameter_captures += [capture]
    
        return_type = proto[:-len(cmd_name)].strip()
    
        format_args = {
            "full_name": cmd_name,
            "short_name": cmd_name[2:],
            "params_with_type": params_with_type,
            "params_just_name": params_just_name,
            "parameter_captures": "\n    ".join(parameter_captures),
            "return_value_type_original": return_type,
            "return_value_type_custom": get_capture_param_type_name(return_type)
        }
    
        if return_type == "void":
            return template_capture_method_no_return_value.format(**format_args)
        else:
            return template_capture_method_with_return_value.format(**format_args)
    
    
    def get_internal_params(cmd_name, params, cmd_packed_gl_enums):
        packed_gl_enums = get_packed_enums(cmd_packed_gl_enums, cmd_name)
        return ", ".join([
            make_param(
                just_the_type_packed(param, packed_gl_enums),
                just_the_name_packed(param, packed_gl_enums)) for param in params
        ])
    
    
    def format_context_decl(cmd_name, proto, params, template, cmd_packed_gl_enums):
        internal_params = get_internal_params(cmd_name, params, cmd_packed_gl_enums)
    
        return_type = proto[:-len(cmd_name)]
        name_lower_no_suffix = cmd_name[2:3].lower() + cmd_name[3:]
        name_lower_no_suffix = strip_suffix(name_lower_no_suffix)
    
        return template.format(
            return_type=return_type,
            name_lower_no_suffix=name_lower_no_suffix,
            internal_params=internal_params)
    
    
    def format_libgles_entry_point_def(cmd_name, proto, params, is_explicit_context):
        internal_params = [just_the_name(param) for param in params]
        return_type = proto[:-len(cmd_name)]
    
        return libgles_entry_point_def.format(
            name=cmd_name[2:],
            return_type=return_type,
            params=", ".join(params),
            internal_params=", ".join(internal_params),
            explicit_context_suffix="ContextANGLE" if is_explicit_context else "",
            explicit_context_param="GLeglContext ctx" if is_explicit_context else "",
            explicit_context_comma=", " if is_explicit_context and len(params) > 0 else "",
            explicit_context_internal_param="ctx" if is_explicit_context else "")
    
    
    def format_validation_proto(cmd_name, params, cmd_packed_gl_enums):
        internal_params = get_internal_params(cmd_name, ["Context *context"] + params,
                                              cmd_packed_gl_enums)
        return template_validation_proto % (cmd_name[2:], internal_params)
    
    
    def format_capture_proto(cmd_name, proto, params, cmd_packed_gl_enums):
        internal_params = get_internal_params(
            cmd_name, ["const State &glState", "bool isCallValid"] + params, cmd_packed_gl_enums)
        return_type = proto[:-len(cmd_name)].strip()
        if return_type != "void":
            internal_params += ", %s returnValue" % return_type
        return template_capture_proto % (cmd_name[2:], internal_params)
    
    
    def path_to(folder, file):
        return os.path.join(script_relative(".."), "src", folder, file)
    
    
    def get_entry_points(all_commands, commands, is_explicit_context, is_wgl, all_param_types,
                         cmd_packed_gl_enums):
        decls = []
        defs = []
        export_defs = []
        validation_protos = []
        capture_protos = []
        capture_methods = []
        capture_pointer_funcs = []
    
        for command in all_commands:
            proto = command.find('proto')
            cmd_name = proto.find('name').text
    
            if is_wgl:
                cmd_name = cmd_name if cmd_name[:3] == 'wgl' else 'wgl' + cmd_name
    
            if cmd_name not in commands:
                continue
    
            param_text = ["".join(param.itertext()) for param in command.findall('param')]
            proto_text = "".join(proto.itertext())
            decls.append(
                format_entry_point_decl(cmd_name, proto_text, param_text, is_explicit_context))
            defs.append(
                format_entry_point_def(command, cmd_name, proto_text, param_text, is_explicit_context,
                                       cmd_packed_gl_enums))
    
            export_defs.append(
                format_libgles_entry_point_def(cmd_name, proto_text, param_text, is_explicit_context))
    
            validation_protos.append(
                format_validation_proto(cmd_name, param_text, cmd_packed_gl_enums))
            capture_protos.append(
                format_capture_proto(cmd_name, proto_text, param_text, cmd_packed_gl_enums))
            capture_methods.append(
                format_capture_method(command, cmd_name, proto_text, param_text, all_param_types,
                                      capture_pointer_funcs, cmd_packed_gl_enums))
    
        return decls, defs, export_defs, validation_protos, capture_protos, capture_methods, capture_pointer_funcs
    
    
    def get_decls(formatter, all_commands, gles_commands, already_included, cmd_packed_gl_enums):
        decls = []
        for command in all_commands:
            proto = command.find('proto')
            cmd_name = proto.find('name').text
    
            if cmd_name not in gles_commands:
                continue
    
            name_no_suffix = strip_suffix(cmd_name)
            if name_no_suffix in already_included:
                continue
    
            param_text = ["".join(param.itertext()) for param in command.findall('param')]
            proto_text = "".join(proto.itertext())
            decls.append(
                format_context_decl(cmd_name, proto_text, param_text, formatter, cmd_packed_gl_enums))
    
        return decls
    
    
    def get_glext_decls(all_commands, gles_commands, version, is_explicit_context):
        glext_ptrs = []
        glext_protos = []
        is_gles1 = False
    
        if (version == ""):
            is_gles1 = True
    
        for command in all_commands:
            proto = command.find('proto')
            cmd_name = proto.find('name').text
    
            if cmd_name not in gles_commands:
                continue
    
            param_text = ["".join(param.itertext()) for param in command.findall('param')]
            proto_text = "".join(proto.itertext())
    
            return_type = proto_text[:-len(cmd_name)]
            params = ", ".join(param_text)
    
            format_params = {
                "apicall": "GL_API" if is_gles1 else "GL_APICALL",
                "name": cmd_name,
                "name_upper": cmd_name.upper(),
                "return_type": return_type,
                "params": params,
                "explicit_context_comma": ", " if is_explicit_context and len(params) > 0 else "",
                "explicit_context_suffix": "ContextANGLE" if is_explicit_context else "",
                "explicit_context_suffix_upper": "CONTEXTANGLE" if is_explicit_context else "",
                "explicit_context_param": "GLeglContext ctx" if is_explicit_context else ""
            }
    
            glext_ptrs.append(template_glext_function_pointer.format(**format_params))
            glext_protos.append(template_glext_function_prototype.format(**format_params))
    
        return glext_ptrs, glext_protos
    
    
    def write_file(annotation, comment, template, entry_points, suffix, includes, lib, file):
        content = template.format(
            script_name=os.path.basename(sys.argv[0]),
            data_source_name=file,
            year=date.today().year,
            annotation_lower=annotation.lower(),
            annotation_upper=annotation.upper(),
            comment=comment,
            lib=lib.upper(),
            includes=includes,
            entry_points=entry_points)
    
        path = path_to(lib, "entry_points_{}_autogen.{}".format(annotation.lower(), suffix))
    
        with open(path, "w") as out:
            out.write(content)
            out.close()
    
    
    def write_export_files(entry_points, includes, source, lib_name, lib_description):
        content = template_lib_entry_point_source.format(
            script_name=os.path.basename(sys.argv[0]),
            data_source_name=source,
            year=date.today().year,
            lib_name=lib_name,
            lib_description=lib_description,
            includes=includes,
            entry_points=entry_points)
    
        path = path_to(lib_name, "{}_autogen.cpp".format(lib_name))
    
        with open(path, "w") as out:
            out.write(content)
            out.close()
    
    
    def write_context_api_decls(template, decls, api):
        for ver in decls['core'].keys():
            interface_lines = []
    
            for i in decls['core'][ver]:
                interface_lines.append(i)
    
            annotation = '{}_{}_{}'.format(api, ver[0], ver[1])
            version = '{}_{}'.format(ver[0], ver[1])
    
            content = template.format(
                annotation_lower=annotation.lower(),
                annotation_upper=annotation.upper(),
                script_name=os.path.basename(sys.argv[0]),
                data_source_name="gl.xml",
                year=date.today().year,
                version=version,
                interface="\n".join(interface_lines))
    
            path = path_to("libANGLE", "Context_%s_autogen.h" % annotation.lower())
    
            with open(path, "w") as out:
                out.write(content)
                out.close()
    
        if 'exts' in decls.keys():
            interface_lines = []
            for annotation in decls['exts'].keys():
                interface_lines.append("\\\n    /* " + annotation + " */ \\\n\\")
    
                for extname in sorted(decls['exts'][annotation].keys()):
                    interface_lines.append("    /* " + extname + " */ \\")
                    interface_lines.extend(decls['exts'][annotation][extname])
    
            content = template.format(
                annotation_lower='gles_ext',
                annotation_upper='GLES_EXT',
                script_name=os.path.basename(sys.argv[0]),
                data_source_name="gl.xml",
                year=date.today().year,
                version='EXT',
                interface="\n".join(interface_lines))
    
            path = path_to("libANGLE", "Context_gles_ext_autogen.h")
    
            with open(path, "w") as out:
                out.write(content)
                out.close()
    
    
    def write_glext_explicit_context_inc(version, ptrs, protos):
        possible_versions = ["31", "32"]
        folder_version = version if version not in possible_versions else "3"
    
        content = template_glext_explicit_context_inc.format(
            script_name=os.path.basename(sys.argv[0]),
            data_source_name="gl.xml and gl_angle_ext.xml",
            year=date.today().year,
            version=version,
            function_pointers=ptrs,
            function_prototypes=protos)
    
        path = os.path.join(
            script_relative(".."), "include", "GLES{}".format(folder_version),
            "gl{}ext_explicit_context_autogen.inc".format(version))
    
        with open(path, "w") as out:
            out.write(content)
            out.close()
    
    
    def write_validation_header(annotation, comment, protos, source):
        content = template_validation_header.format(
            script_name=os.path.basename(sys.argv[0]),
            data_source_name=source,
            year=date.today().year,
            annotation=annotation,
            comment=comment,
            prototypes="\n".join(protos))
    
        path = path_to("libANGLE", "validation%s_autogen.h" % annotation)
    
        with open(path, "w") as out:
            out.write(content)
            out.close()
    
    
    def write_capture_header(annotation, comment, protos, capture_pointer_funcs):
        content = template_capture_header.format(
            script_name=os.path.basename(sys.argv[0]),
            data_source_name="gl.xml and gl_angle_ext.xml",
            year=date.today().year,
            annotation=annotation,
            comment=comment,
            prototypes="\n".join(["\n// Method Captures\n"] + protos + ["\n// Parameter Captures\n"] +
                                 capture_pointer_funcs))
    
        path = path_to("libANGLE", "capture_gles_%s_autogen.h" % annotation)
    
        with open(path, "w") as out:
            out.write(content)
            out.close()
    
    
    def write_capture_source(annotation_with_dash, annotation_no_dash, comment, capture_methods):
        content = template_capture_source.format(
            script_name=os.path.basename(sys.argv[0]),
            data_source_name="gl.xml and gl_angle_ext.xml",
            year=date.today().year,
            annotation_with_dash=annotation_with_dash,
            annotation_no_dash=annotation_no_dash,
            comment=comment,
            capture_methods="\n".join(capture_methods))
    
        path = path_to("libANGLE", "capture_gles_%s_autogen.cpp" % annotation_with_dash)
    
        with open(path, "w") as out:
            out.write(content)
            out.close()
    
    
    def is_packed_enum_param_type(param_type):
        return param_type[0:2] != "GL" and "void" not in param_type
    
    
    def get_gl_pointer_type(param_type):
    
        if "ConstPointerPointer" in param_type:
            return "const " + param_type.replace("ConstPointerPointer", "") + " * const *"
    
        if "ConstPointer" in param_type:
            return "const " + param_type.replace("ConstPointer", "") + " *"
    
        if "PointerPointer" in param_type:
            return param_type.replace("PointerPointer", "") + " **"
    
        if "Pointer" in param_type:
            return param_type.replace("Pointer", "") + " *"
    
        return param_type
    
    
    def get_param_type_type(param_type):
    
        if is_packed_enum_param_type(param_type):
            param_type = "gl::" + param_type
    
        return get_gl_pointer_type(param_type)
    
    
    def get_gl_param_type_type(param_type):
        if not is_packed_enum_param_type(param_type):
            return get_gl_pointer_type(param_type)
        else:
            base_type = param_type.replace("Pointer", "").replace("Const", "")
            if base_type[-2:] == "ID":
                replace_type = "GLuint"
            else:
                replace_type = "GLenum"
            param_type = param_type.replace(base_type, replace_type)
            return get_gl_pointer_type(param_type)
    
    
    def get_param_type_union_name(param_type):
        return param_type + "Val"
    
    
    def format_param_type_union_type(param_type):
        return "%s %s;" % (get_param_type_type(param_type), get_param_type_union_name(param_type))
    
    
    def format_get_param_val_specialization(param_type):
        return template_get_param_val_specialization.format(
            enum=param_type,
            type=get_param_type_type(param_type),
            union_name=get_param_type_union_name(param_type))
    
    
    def format_access_param_value_case(param_type):
        return template_access_param_value_case.format(enum=param_type)
    
    
    def format_set_param_val_specialization(param_type):
        return template_set_param_val_specialization.format(
            enum=param_type,
            type=get_param_type_type(param_type),
            union_name=get_param_type_union_name(param_type))
    
    
    def format_init_param_value_case(param_type):
        return template_init_param_value_case.format(enum=param_type)
    
    
    def format_write_param_type_to_stream_case(param_type):
        return template_write_param_type_to_stream_case.format(
            enum=param_type, union_name=get_param_type_union_name(param_type))
    
    
    def get_resource_id_types(all_param_types):
        return [t[:-2] for t in filter(lambda t: t.endswith("ID"), all_param_types)]
    
    
    def format_resource_id_types(all_param_types):
        resource_id_types = get_resource_id_types(all_param_types)
        resource_id_types += ["EnumCount", "InvalidEnum = EnumCount"]
        resource_id_types = ",\n    ".join(resource_id_types)
        return resource_id_types
    
    
    def write_capture_helper_header(all_param_types):
    
        param_types = "\n    ".join(["T%s," % t for t in all_param_types])
        param_union_values = "\n    ".join([format_param_type_union_type(t) for t in all_param_types])
        get_param_val_specializations = "\n\n".join(
            [format_get_param_val_specialization(t) for t in all_param_types])
        access_param_value_cases = "\n".join(
            [format_access_param_value_case(t) for t in all_param_types])
        set_param_val_specializations = "\n\n".join(
            [format_set_param_val_specialization(t) for t in all_param_types])
        init_param_value_cases = "\n".join([format_init_param_value_case(t) for t in all_param_types])
        resource_id_types = format_resource_id_types(all_param_types)
    
        content = template_frame_capture_utils_header.format(
            script_name=os.path.basename(sys.argv[0]),
            data_source_name="gl.xml and gl_angle_ext.xml",
            year=date.today().year,
            param_types=param_types,
            param_type_count=len(all_param_types),
            param_union_values=param_union_values,
            get_param_val_specializations=get_param_val_specializations,
            access_param_value_cases=access_param_value_cases,
            set_param_val_specializations=set_param_val_specializations,
            init_param_value_cases=init_param_value_cases,
            resource_id_types=resource_id_types)
    
        path = path_to("libANGLE", "frame_capture_utils_autogen.h")
    
        with open(path, "w") as out:
            out.write(content)
            out.close()
    
    
    def format_param_type_to_string_case(param_type):
        return template_param_type_to_string_case.format(
            enum=param_type, type=get_gl_param_type_type(param_type))
    
    
    def get_resource_id_type_from_param_type(param_type):
        if param_type.endswith("ConstPointer"):
            return param_type.replace("ConstPointer", "")[:-2]
        if param_type.endswith("Pointer"):
            return param_type.replace("Pointer", "")[:-2]
        return param_type[:-2]
    
    
    def format_param_type_to_resource_id_type_case(param_type):
        return template_param_type_to_resource_id_type_case.format(
            enum=param_type, resource_id_type=get_resource_id_type_from_param_type(param_type))
    
    
    def format_param_type_resource_id_cases(all_param_types):
        id_types = filter(
            lambda t: t.endswith("ID") or t.endswith("IDConstPointer") or t.endswith("IDPointer"),
            all_param_types)
        return "\n".join([format_param_type_to_resource_id_type_case(t) for t in id_types])
    
    
    def format_resource_id_type_name_case(resource_id_type):
        return template_resource_id_type_name_case.format(resource_id_type=resource_id_type)
    
    
    def write_capture_helper_source(all_param_types):
    
        write_param_type_to_stream_cases = "\n".join(
            [format_write_param_type_to_stream_case(t) for t in all_param_types])
        param_type_to_string_cases = "\n".join(
            [format_param_type_to_string_case(t) for t in all_param_types])
    
        param_type_resource_id_cases = format_param_type_resource_id_cases(all_param_types)
    
        resource_id_types = get_resource_id_types(all_param_types)
        resource_id_type_name_cases = "\n".join(
            [format_resource_id_type_name_case(t) for t in resource_id_types])
    
        content = template_frame_capture_utils_source.format(
            script_name=os.path.basename(sys.argv[0]),
            data_source_name="gl.xml and gl_angle_ext.xml",
            year=date.today().year,
            write_param_type_to_stream_cases=write_param_type_to_stream_cases,
            param_type_to_string_cases=param_type_to_string_cases,
            param_type_resource_id_cases=param_type_resource_id_cases,
            resource_id_type_name_cases=resource_id_type_name_cases)
    
        path = path_to("libANGLE", "frame_capture_utils_autogen.cpp")
    
        with open(path, "w") as out:
            out.write(content)
            out.close()
    
    
    def get_command_params_text(command_node, cmd_name):
        param_text_list = list()
        for param_node in command_node.findall('param'):
            param_text_list.append("".join(param_node.itertext()))
        return param_text_list
    
    
    def is_get_pointer_command(command_name):
        return command_name.endswith('Pointerv') and command_name.startswith('glGet')
    
    
    def format_capture_replay_param_access(command_name, param_text_list, cmd_packed_gl_enums):
        param_access_strs = list()
        cmd_packed_enums = get_packed_enums(cmd_packed_gl_enums, command_name)
        for i, param_text in enumerate(param_text_list):
            param_type = just_the_type_packed(param_text, cmd_packed_enums)
            param_name = just_the_name_packed(param_text, cmd_packed_enums)
    
            pointer_count = param_type.count('*')
            is_const = 'const' in param_type
            if pointer_count == 0:
                param_template = 'params.getParam("{name}", ParamType::T{enum_type}, {index}).value.{enum_type}Val'
            elif pointer_count == 1 and is_const:
                param_template = 'replayContext->getAsConstPointer<{type}>(params.getParam("{name}", ParamType::T{enum_type}, {index}))'
            elif pointer_count == 2 and is_const:
                param_template = 'replayContext->getAsPointerConstPointer<{type}>(params.getParam("{name}", ParamType::T{enum_type}, {index}))'
            elif pointer_count == 1 or (pointer_count == 2 and is_get_pointer_command(command_name)):
                param_template = 'replayContext->getReadBufferPointer<{type}>(params.getParam("{name}", ParamType::T{enum_type}, {index}))'
            else:
                assert False, "Not supported param type %s" % param_type
    
            param_access_strs.append(
                param_template.format(
                    index=i,
                    name=param_name,
                    type=param_type,
                    enum_type=get_capture_param_type_name(param_type)))
        return ",".join(param_access_strs)
    
    
    def format_capture_replay_call_case(command_to_param_types_mapping, cmd_packed_gl_enums):
        call_str_list = list()
        for command_name, cmd_param_texts in sorted(command_to_param_types_mapping.items()):
            entry_point_name = command_name[2:]  # strip the 'gl' prefix
    
            call_str_list.append(
                template_capture_replay_call_case.format(
                    entry_point=entry_point_name,
                    param_value_access=format_capture_replay_param_access(
                        command_name, cmd_param_texts, cmd_packed_gl_enums),
                    context_call=entry_point_name[0].lower() + entry_point_name[1:],
                ))
    
        return '\n'.join(call_str_list)
    
    
    def write_capture_replay_source(all_commands_nodes, gles_command_names, cmd_packed_gl_enums):
        all_commands_names = set(gles_command_names)
    
        command_to_param_types_mapping = dict()
        for command_node in all_commands_nodes:
            command_name = command_node.find('proto').find('name').text
            if command_name not in all_commands_names:
                continue
    
            command_to_param_types_mapping[command_name] = get_command_params_text(
                command_node, command_name)
    
        call_replay_cases = format_capture_replay_call_case(command_to_param_types_mapping,
                                                            cmd_packed_gl_enums)
    
        source_content = template_capture_replay_source.format(
            script_name=os.path.basename(sys.argv[0]),
            data_source_name="gl.xml and gl_angle_ext.xml",
            year=date.today().year,
            call_replay_cases=call_replay_cases,
        )
        source_file_path = registry_xml.script_relative(
            "../src/libANGLE/frame_capture_replay_autogen.cpp")
        with open(source_file_path, 'w') as f:
            f.write(source_content)
    
    
    def write_windows_def_file(data_source_name, lib, libexport, folder, exports):
    
        content = template_windows_def_file.format(
            script_name=os.path.basename(sys.argv[0]),
            data_source_name=data_source_name,
            exports="\n".join(exports),
            year=date.today().year,
            lib=libexport)
    
        path = path_to(folder, "%s_autogen.def" % lib)
    
        with open(path, "w") as out:
            out.write(content)
            out.close()
    
    
    def get_exports(commands, fmt=None):
        if fmt:
            return ["    %s" % fmt(cmd) for cmd in sorted(commands)]
        else:
            return ["    %s" % cmd for cmd in sorted(commands)]
    
    
    # Get EGL exports
    def get_egl_exports():
    
        egl = registry_xml.RegistryXML('egl.xml', 'egl_angle_ext.xml')
        exports = []
    
        capser = lambda fn: "EGL_" + fn[3:]
    
        for major, minor in [[1, 0], [1, 1], [1, 2], [1, 3], [1, 4], [1, 5]]:
            annotation = "{}_{}".format(major, minor)
            name_prefix = "EGL_VERSION_"
    
            feature_name = "{}{}".format(name_prefix, annotation)
    
            egl.AddCommands(feature_name, annotation)
    
            commands = egl.commands[annotation]
    
            if len(commands) == 0:
                continue
    
            exports.append("\n    ; EGL %d.%d" % (major, minor))
            exports += get_exports(commands, capser)
    
        egl.AddExtensionCommands(registry_xml.supported_egl_extensions, ['egl'])
    
        for extension_name, ext_cmd_names in sorted(egl.ext_data.iteritems()):
    
            if len(ext_cmd_names) == 0:
                continue
    
            exports.append("\n    ; %s" % extension_name)
            exports += get_exports(ext_cmd_names, capser)
    
        return exports
    
    
    def main():
    
        # auto_script parameters.
        if len(sys.argv) > 1:
            inputs = ['entry_point_packed_gl_enums.json'] + registry_xml.xml_inputs
            outputs = [
                '../src/libANGLE/Context_gl_1_0_autogen.h',
                '../src/libANGLE/Context_gl_1_1_autogen.h',
                '../src/libANGLE/Context_gl_1_2_autogen.h',
                '../src/libANGLE/Context_gl_1_3_autogen.h',
                '../src/libANGLE/Context_gl_1_4_autogen.h',
                '../src/libANGLE/Context_gl_1_5_autogen.h',
                '../src/libANGLE/Context_gl_2_0_autogen.h',
                '../src/libANGLE/Context_gl_2_1_autogen.h',
                '../src/libANGLE/Context_gl_3_0_autogen.h',
                '../src/libANGLE/Context_gl_3_1_autogen.h',
                '../src/libANGLE/Context_gl_3_2_autogen.h',
                '../src/libANGLE/Context_gl_3_3_autogen.h',
                '../src/libANGLE/Context_gl_4_0_autogen.h',
                '../src/libANGLE/Context_gl_4_1_autogen.h',
                '../src/libANGLE/Context_gl_4_2_autogen.h',
                '../src/libANGLE/Context_gl_4_3_autogen.h',
                '../src/libANGLE/Context_gl_4_4_autogen.h',
                '../src/libANGLE/Context_gl_4_5_autogen.h',
                '../src/libANGLE/Context_gl_4_6_autogen.h',
                '../src/libANGLE/Context_gles_1_0_autogen.h',
                '../src/libANGLE/Context_gles_2_0_autogen.h',
                '../src/libANGLE/Context_gles_3_0_autogen.h',
                '../src/libANGLE/Context_gles_3_1_autogen.h',
                '../src/libANGLE/Context_gles_3_2_autogen.h',
                '../src/libANGLE/Context_gles_ext_autogen.h',
                '../src/libANGLE/capture_gles_1_0_autogen.cpp',
                '../src/libANGLE/capture_gles_1_0_autogen.h',
                '../src/libANGLE/capture_gles_2_0_autogen.cpp',
                '../src/libANGLE/capture_gles_2_0_autogen.h',
                '../src/libANGLE/capture_gles_3_0_autogen.cpp',
                '../src/libANGLE/capture_gles_3_0_autogen.h',
                '../src/libANGLE/capture_gles_3_1_autogen.cpp',
                '../src/libANGLE/capture_gles_3_1_autogen.h',
                '../src/libANGLE/capture_gles_3_2_autogen.cpp',
                '../src/libANGLE/capture_gles_3_2_autogen.h',
                '../src/libANGLE/capture_gles_ext_autogen.cpp',
                '../src/libANGLE/capture_gles_ext_autogen.h',
                '../src/libANGLE/frame_capture_replay_autogen.cpp',
                '../src/libANGLE/frame_capture_utils_autogen.cpp',
                '../src/libANGLE/frame_capture_utils_autogen.h',
                '../src/libANGLE/entry_points_enum_autogen.cpp',
                '../src/libANGLE/entry_points_enum_autogen.h',
                '../src/libANGLE/validationES1_autogen.h',
                '../src/libANGLE/validationES2_autogen.h',
                '../src/libANGLE/validationES31_autogen.h',
                '../src/libANGLE/validationES32_autogen.h',
                '../src/libANGLE/validationES3_autogen.h',
                '../src/libANGLE/validationESEXT_autogen.h',
                '../src/libANGLE/validationGL1_autogen.h',
                '../src/libANGLE/validationGL2_autogen.h',
                '../src/libANGLE/validationGL3_autogen.h',
                '../src/libANGLE/validationGL4_autogen.h',
                '../src/libANGLE/validationGL11_autogen.h',
                '../src/libANGLE/validationGL12_autogen.h',
                '../src/libANGLE/validationGL13_autogen.h',
                '../src/libANGLE/validationGL14_autogen.h',
                '../src/libANGLE/validationGL15_autogen.h',
                '../src/libANGLE/validationGL21_autogen.h',
                '../src/libANGLE/validationGL31_autogen.h',
                '../src/libANGLE/validationGL32_autogen.h',
                '../src/libANGLE/validationGL33_autogen.h',
                '../src/libANGLE/validationGL41_autogen.h',
                '../src/libANGLE/validationGL42_autogen.h',
                '../src/libANGLE/validationGL43_autogen.h',
                '../src/libANGLE/validationGL44_autogen.h',
                '../src/libANGLE/validationGL45_autogen.h',
                '../src/libANGLE/validationGL46_autogen.h',
                '../src/libGLESv2/entry_points_gles_1_0_autogen.cpp',
                '../src/libGLESv2/entry_points_gles_1_0_autogen.h',
                '../src/libGLESv2/entry_points_gles_2_0_autogen.cpp',
                '../src/libGLESv2/entry_points_gles_2_0_autogen.h',
                '../src/libGLESv2/entry_points_gles_3_0_autogen.cpp',
                '../src/libGLESv2/entry_points_gles_3_0_autogen.h',
                '../src/libGLESv2/entry_points_gles_3_1_autogen.cpp',
                '../src/libGLESv2/entry_points_gles_3_1_autogen.h',
                '../src/libGLESv2/entry_points_gles_3_2_autogen.cpp',
                '../src/libGLESv2/entry_points_gles_3_2_autogen.h',
                '../src/libGLESv2/entry_points_gles_ext_autogen.cpp',
                '../src/libGLESv2/entry_points_gles_ext_autogen.h',
                '../src/libGLESv2/libGLESv2_autogen.cpp',
                '../src/libGLESv2/libGLESv2_autogen.def',
                '../src/libGLESv2/libGLESv2_no_capture_autogen.def',
                '../src/libGLESv2/libGLESv2_with_capture_autogen.def',
                '../src/libGL/entry_points_gl_1_0_autogen.cpp',
                '../src/libGL/entry_points_gl_1_0_autogen.h',
                '../src/libGL/entry_points_gl_1_1_autogen.cpp',
                '../src/libGL/entry_points_gl_1_1_autogen.h',
                '../src/libGL/entry_points_gl_1_2_autogen.cpp',
                '../src/libGL/entry_points_gl_1_2_autogen.h',
                '../src/libGL/entry_points_gl_1_3_autogen.cpp',
                '../src/libGL/entry_points_gl_1_3_autogen.h',
                '../src/libGL/entry_points_gl_1_4_autogen.cpp',
                '../src/libGL/entry_points_gl_1_4_autogen.h',
                '../src/libGL/entry_points_gl_1_5_autogen.cpp',
                '../src/libGL/entry_points_gl_1_5_autogen.h',
                '../src/libGL/entry_points_gl_2_0_autogen.cpp',
                '../src/libGL/entry_points_gl_2_0_autogen.h',
                '../src/libGL/entry_points_gl_2_1_autogen.cpp',
                '../src/libGL/entry_points_gl_2_1_autogen.h',
                '../src/libGL/entry_points_gl_3_0_autogen.cpp',
                '../src/libGL/entry_points_gl_3_0_autogen.h',
                '../src/libGL/entry_points_gl_3_1_autogen.cpp',
                '../src/libGL/entry_points_gl_3_1_autogen.h',
                '../src/libGL/entry_points_gl_3_2_autogen.cpp',
                '../src/libGL/entry_points_gl_3_2_autogen.h',
                '../src/libGL/entry_points_gl_3_3_autogen.cpp',
                '../src/libGL/entry_points_gl_3_3_autogen.h',
                '../src/libGL/entry_points_gl_4_0_autogen.cpp',
                '../src/libGL/entry_points_gl_4_0_autogen.h',
                '../src/libGL/entry_points_gl_4_1_autogen.cpp',
                '../src/libGL/entry_points_gl_4_1_autogen.h',
                '../src/libGL/entry_points_gl_4_2_autogen.cpp',
                '../src/libGL/entry_points_gl_4_2_autogen.h',
                '../src/libGL/entry_points_gl_4_3_autogen.cpp',
                '../src/libGL/entry_points_gl_4_3_autogen.h',
                '../src/libGL/entry_points_gl_4_4_autogen.cpp',
                '../src/libGL/entry_points_gl_4_4_autogen.h',
                '../src/libGL/entry_points_gl_4_5_autogen.cpp',
                '../src/libGL/entry_points_gl_4_5_autogen.h',
                '../src/libGL/entry_points_gl_4_6_autogen.cpp',
                '../src/libGL/entry_points_gl_4_6_autogen.h',
                '../src/libGL/libGL_autogen.cpp',
                '../src/libGL/libGL_autogen.def',
            ]
    
            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
    
        with open(script_relative('entry_point_packed_gl_enums.json')) as f:
            cmd_packed_gl_enums = json.loads(f.read())
    
        glesdecls = {}
        glesdecls['core'] = {}
        glesdecls['exts'] = {}
        for ver in [(1, 0), (2, 0), (3, 0), (3, 1), (3, 2)]:
            glesdecls['core'][ver] = []
        for ver in ['GLES1 Extensions', 'GLES2+ Extensions', 'ANGLE Extensions']:
            glesdecls['exts'][ver] = {}
    
        libgles_ep_defs = []
        libgles_ep_exports = []
    
        xml = registry_xml.RegistryXML('gl.xml', 'gl_angle_ext.xml')
    
        # Stores core commands to keep track of duplicates
        all_commands_no_suffix = []
        all_commands_with_suffix = []
        all_gles_param_types = set()
    
        # First run through the main GLES entry points.  Since ES2+ is the primary use
        # case, we go through those first and then add ES1-only APIs at the end.
        versions = [[2, 0], [3, 0], [3, 1], [3, 2], [1, 0]]
        for major_version, minor_version in versions:
            version = "{}_{}".format(major_version, minor_version)
            annotation = "GLES_{}".format(version)
            name_prefix = "GL_ES_VERSION_"
    
            if major_version == 1:
                name_prefix = "GL_VERSION_ES_CM_"
    
            comment = version.replace("_", ".")
            feature_name = "{}{}".format(name_prefix, version)
    
            xml.AddCommands(feature_name, version)
    
            gles_commands = xml.commands[version]
            all_commands = xml.all_commands
            all_commands_no_suffix.extend(xml.commands[version])
            all_commands_with_suffix.extend(xml.commands[version])
    
            decls, defs, libgles_defs, validation_protos, capture_protos, capture_methods, capture_pointer_funcs = get_entry_points(
                all_commands, gles_commands, False, False, all_gles_param_types, cmd_packed_gl_enums)
    
            # Write the version as a comment before the first EP.
            libgles_defs.insert(0, "\n// OpenGL ES %s" % comment)
            libgles_ep_exports.append("\n    ; OpenGL ES %s" % comment)
    
            libgles_ep_defs += libgles_defs
            libgles_ep_exports += get_exports(gles_commands)
    
            major_if_not_one = major_version if major_version != 1 else ""
            minor_if_not_zero = minor_version if minor_version != 0 else ""
    
            header_includes = template_header_includes.format(
                major=major_if_not_one, minor=minor_if_not_zero)
    
            # We include the platform.h header since it undefines the conflicting MemoryBarrier macro.
            if major_version == 3 and minor_version == 1:
                header_includes += "\n#include \"common/platform.h\"\n"
    
            version_annotation = "%s%s" % (major_version, minor_if_not_zero)
            source_includes = template_sources_includes.format(
                header_version=annotation.lower(), validation_header_version="ES" + version_annotation)
    
            write_file(annotation, "GLES " + comment, template_entry_point_header, "\n".join(decls),
                       "h", header_includes, "libGLESv2", "gl.xml")
            write_file(annotation, "GLES " + comment, template_entry_point_source, "\n".join(defs),
                       "cpp", source_includes, "libGLESv2", "gl.xml")
    
            glesdecls['core'][(major_version, minor_version)] = get_decls(
                context_decl_format, all_commands, gles_commands, [], cmd_packed_gl_enums)
    
            validation_annotation = "ES%s%s" % (major_version, minor_if_not_zero)
            write_validation_header(validation_annotation, "ES %s" % comment, validation_protos,
                                    "gl.xml and gl_angle_ext.xml")
    
            write_capture_header(version, comment, capture_protos, capture_pointer_funcs)
            write_capture_source(version, validation_annotation, comment, capture_methods)
    
        # After we finish with the main entry points, we process the extensions.
        extension_defs = []
        extension_decls = []
        extension_commands = []
    
        # Accumulated validation prototypes.
        ext_validation_protos = []
        ext_capture_protos = []
        ext_capture_methods = []
        ext_capture_param_funcs = []
    
        for gles1ext in registry_xml.gles1_extensions:
            glesdecls['exts']['GLES1 Extensions'][gles1ext] = []
        for glesext in registry_xml.gles_extensions:
            glesdecls['exts']['GLES2+ Extensions'][glesext] = []
        for angle_ext in registry_xml.angle_extensions:
            glesdecls['exts']['ANGLE Extensions'][angle_ext] = []
    
        xml.AddExtensionCommands(registry_xml.supported_extensions, ['gles2', 'gles1'])
    
        for extension_name, ext_cmd_names in sorted(xml.ext_data.iteritems()):
            extension_commands.extend(xml.ext_data[extension_name])
    
            # Detect and filter duplicate extensions.
            decls, defs, libgles_defs, validation_protos, capture_protos, capture_methods, capture_param_funcs = get_entry_points(
                xml.all_commands, ext_cmd_names, False, False, all_gles_param_types,
                cmd_packed_gl_enums)
    
            # Avoid writing out entry points defined by a prior extension.
            for dupe in xml.ext_dupes[extension_name]:
                msg = "// {} is already defined.\n".format(dupe[2:])
                defs.append(msg)
    
            # Write the extension name as a comment before the first EP.
            comment = "\n// {}".format(extension_name)
            defs.insert(0, comment)
            decls.insert(0, comment)
            libgles_defs.insert(0, comment)
            libgles_ep_exports.append("\n    ; %s" % extension_name)
    
            extension_defs += defs
            extension_decls += decls
    
            ext_validation_protos += [comment] + validation_protos
            ext_capture_protos += [comment] + capture_protos
            ext_capture_methods += capture_methods
            ext_capture_param_funcs += capture_param_funcs
    
            libgles_ep_defs += libgles_defs
            libgles_ep_exports += get_exports(ext_cmd_names)
    
            if (extension_name in registry_xml.gles1_extensions and
                    extension_name not in gles1_no_context_decl_extensions):
                glesdecls['exts']['GLES1 Extensions'][extension_name] = get_decls(
                    context_decl_format, all_commands, ext_cmd_names, all_commands_no_suffix,
                    cmd_packed_gl_enums)
            if extension_name in registry_xml.gles_extensions:
                glesdecls['exts']['GLES2+ Extensions'][extension_name] = get_decls(
                    context_decl_format, all_commands, ext_cmd_names, all_commands_no_suffix,
                    cmd_packed_gl_enums)
            if extension_name in registry_xml.angle_extensions:
                glesdecls['exts']['ANGLE Extensions'][extension_name] = get_decls(
                    context_decl_format, all_commands, ext_cmd_names, all_commands_no_suffix,
                    cmd_packed_gl_enums)
    
        for name in extension_commands:
            all_commands_with_suffix.append(name)
            all_commands_no_suffix.append(strip_suffix(name))
    
        # Special handling for EGL_ANGLE_explicit_context extension
        if registry_xml.support_EGL_ANGLE_explicit_context:
            comment = "\n// EGL_ANGLE_explicit_context"
            extension_defs.append(comment)
            extension_decls.append(comment)
            libgles_ep_defs.append(comment)
    
            cmds = xml.all_cmd_names.get_all_commands()
    
            # Get the explicit context entry points
            decls, defs, libgles_defs, validation_protos, capture_protos, capture_methods, capture_param_funcs = get_entry_points(
                xml.all_commands, cmds, True, False, all_gles_param_types, cmd_packed_gl_enums)
    
            # Append the explicit context entry points
            extension_decls += decls
            extension_defs += defs
            libgles_ep_defs += libgles_defs
    
            libgles_ep_exports.append("\n    ; EGL_ANGLE_explicit_context")
            libgles_ep_exports += get_exports(cmds, lambda x: "%sContextANGLE" % x)
    
            # Generate .inc files for extension function pointers and declarations
            for major, minor in versions:
                annotation = "{}_{}".format(major, minor)
    
                major_if_not_one = major if major != 1 else ""
                minor_if_not_zero = minor if minor != 0 else ""
                version = "{}{}".format(major_if_not_one, minor_if_not_zero)
    
                glext_ptrs, glext_protos = get_glext_decls(all_commands,
                                                           xml.all_cmd_names.get_commands(annotation),
                                                           version, True)
    
                glext_ext_ptrs = []
                glext_ext_protos = []
    
                # Append extensions for 1.0 and 2.0
                if (annotation == "1_0"):
                    glext_ext_ptrs, glext_ext_protos = get_glext_decls(
                        all_commands, xml.all_cmd_names.get_commands("glext"), version, True)
                elif (annotation == "2_0"):
                    glext_ext_ptrs, glext_ext_protos = get_glext_decls(
                        all_commands, xml.all_cmd_names.get_commands("gl2ext"), version, True)
    
                glext_ptrs += glext_ext_ptrs
                glext_protos += glext_ext_protos
    
                write_glext_explicit_context_inc(version, "\n".join(glext_ptrs),
                                                 "\n".join(glext_protos))
    
        # Now we generate entry points for the desktop implementation
        gldecls = {}
        gldecls['core'] = {}
        for ver in [(1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 0), (2, 1), (3, 0), (3, 1),
                    (3, 2), (3, 3), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6)]:
            gldecls['core'][ver] = []
    
        libgl_ep_defs = []
        libgl_ep_exports = []
    
        glxml = registry_xml.RegistryXML('gl.xml')
    
        for major_version, minor_version in [[1, 0], [1, 1], [1, 2], [1, 3], [1, 4], [1, 5], [2, 0],
                                             [2, 1], [3, 0], [3, 1], [3, 2], [3, 3], [4, 0], [4, 1],
                                             [4, 2], [4, 3], [4, 4], [4, 5], [4, 6]]:
            version = "{}_{}".format(major_version, minor_version)
            annotation = "GL_{}".format(version)
            name_prefix = "GL_VERSION_"
    
            comment = version.replace("_", ".")
            feature_name = "{}{}".format(name_prefix, version)
    
            glxml.AddCommands(feature_name, version)
    
            all_libgl_commands = glxml.commands[version]
    
            just_libgl_commands = [
                cmd for cmd in all_libgl_commands if cmd not in all_commands_no_suffix
            ]
            just_libgl_commands_suffix = [
                cmd for cmd in all_libgl_commands if cmd not in all_commands_with_suffix
            ]
    
            all_commands32 = glxml.all_commands
    
            # Validation duplicates handled with suffix
            _, _, _, validation_protos32, _, _, _ = get_entry_points(
                all_commands32, just_libgl_commands_suffix, False, False, all_gles_param_types,
                cmd_packed_gl_enums)
            decls_gl, defs_gl, libgl_defs, _, _, _, _ = get_entry_points(
                all_commands32, all_libgl_commands, False, False, all_gles_param_types,
                cmd_packed_gl_enums)
    
            # Write the version as a comment before the first EP.
            libgl_defs.insert(0, "\n// GL %s" % comment)
            libgl_ep_exports.append("\n    ; GL %s" % comment)
    
            libgl_ep_defs += libgl_defs
            libgl_ep_exports += get_exports(all_libgl_commands)
    
            minor_if_not_zero = minor_version if minor_version != 0 else ""
    
            header_includes = template_header_includes_gl32
            source_includes = template_sources_includes_gl32.format(annotation.lower(), major_version,
                                                                    minor_if_not_zero)
    
            # Entry point files
            write_file(annotation, "GL " + comment, template_entry_point_header, "\n".join(decls_gl),
                       "h", header_includes, "libGL", "gl.xml")
            write_file(annotation, "GL " + comment, template_entry_point_source, "\n".join(defs_gl),
                       "cpp", source_includes, "libGL", "gl.xml")
    
            gldecls['core'][(major_version, minor_version)] = get_decls(
                context_decl_format, all_commands32, just_libgl_commands, all_commands_no_suffix,
                cmd_packed_gl_enums)
    
            # Validation files
            validation_annotation = "GL%s%s" % (major_version, minor_if_not_zero)
            write_validation_header(validation_annotation, "%s" % comment, validation_protos32,
                                    "gl.xml and wgl.xml")
    
        # WGL
        wglxml = registry_xml.RegistryXML('wgl.xml')
    
        name_prefix = "WGL_VERSION_"
        version = "1_0"
        comment = version.replace("_", ".")
        feature_name = "{}{}".format(name_prefix, version)
        wglxml.AddCommands(feature_name, version)
        wgl_commands = wglxml.commands[version]
        all_commands32.extend(wglxml.all_commands)
    
        wgl_commands = [cmd if cmd[:3] == 'wgl' else 'wgl' + cmd for cmd in wgl_commands]
    
        wgl_param_types = set()
        decls_wgl, defs_wgl, wgl_defs, validation_protos_wgl, _, _, _ = get_entry_points(
            all_commands32, wgl_commands, False, True, wgl_param_types, {})
    
        # Write the version as a comment before the first EP.
        libgl_ep_exports.append("\n    ; WGL %s" % comment)
    
        # Other versions of these functions are used
        wgl_commands.remove("wglUseFontBitmaps")
        wgl_commands.remove("wglUseFontOutlines")
    
        libgl_ep_exports += get_exports(wgl_commands)
    
        header_includes = template_header_includes.format(major="", minor="")
        header_includes += """
        #include <GLES/glext.h>
        #include <GLES2/gl2.h>
        #include <GLES2/gl2ext.h>
        #include <GLES3/gl32.h>
        """
    
        source_includes = template_sources_includes.format(
            header_version="gles_ext", validation_header_version="ESEXT")
        source_includes += """
        #include "libANGLE/capture_gles_1_0_autogen.h"
        #include "libANGLE/capture_gles_2_0_autogen.h"
        #include "libANGLE/capture_gles_3_0_autogen.h"
        #include "libANGLE/capture_gles_3_1_autogen.h"
        #include "libANGLE/capture_gles_3_2_autogen.h"
        #include "libANGLE/validationES1.h"
        #include "libANGLE/validationES2.h"
        #include "libANGLE/validationES3.h"
        #include "libANGLE/validationES31.h"
        #include "libANGLE/validationES32.h"
        """
    
        write_file("gles_ext", "GLES extension", template_entry_point_header,
                   "\n".join([item for item in extension_decls]), "h", header_includes, "libGLESv2",
                   "gl.xml and gl_angle_ext.xml")
        write_file("gles_ext", "GLES extension", template_entry_point_source,
                   "\n".join([item for item in extension_defs]), "cpp", source_includes, "libGLESv2",
                   "gl.xml and gl_angle_ext.xml")
    
        write_validation_header("ESEXT", "ES extension", ext_validation_protos,
                                "gl.xml and gl_angle_ext.xml")
        write_capture_header("ext", "extension", ext_capture_protos, ext_capture_param_funcs)
        write_capture_source("ext", "ESEXT", "extension", ext_capture_methods)
    
        write_context_api_decls(context_header, glesdecls, "gles")
        write_context_api_decls(context_header, gldecls, "gl")
    
        # Entry point enum
        cmd_names = ["Invalid"] + [cmd[2:] for cmd in xml.all_cmd_names.get_all_commands()]
        gl_cmd_names = [cmd[2:] for cmd in glxml.all_cmd_names.get_all_commands()]
        cmd_names.extend([cmd for cmd in gl_cmd_names if cmd not in cmd_names])
        sorted_cmd_names = sorted(cmd_names)
    
        entry_points_enum_header = template_entry_points_enum_header.format(
            script_name=os.path.basename(sys.argv[0]),
            data_source_name="gl.xml and gl_angle_ext.xml",
            year=date.today().year,
            lib="GL/GLES",
            entry_points_list=",\n".join(["    " + cmd for cmd in sorted_cmd_names]))
    
        entry_points_enum_header_path = path_to("libANGLE", "entry_points_enum_autogen.h")
        with open(entry_points_enum_header_path, "w") as out:
            out.write(entry_points_enum_header)
            out.close()
    
        entry_points_cases = [
            template_entry_points_name_case.format(enum=cmd) for cmd in sorted_cmd_names
        ]
        entry_points_enum_source = template_entry_points_enum_source.format(
            script_name=os.path.basename(sys.argv[0]),
            data_source_name="gl.xml and gl_angle_ext.xml",
            year=date.today().year,
            lib="GL/GLES",
            entry_points_name_cases="\n".join(entry_points_cases))
    
        entry_points_enum_source_path = path_to("libANGLE", "entry_points_enum_autogen.cpp")
        with open(entry_points_enum_source_path, "w") as out:
            out.write(entry_points_enum_source)
            out.close()
    
        source_includes = """
        #include "angle_gl.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"
    
        #include "common/event_tracer.h"
        """
    
        write_export_files("\n".join([item for item in libgles_ep_defs]), source_includes,
                           "gl.xml and gl_angle_ext.xml", "libGLESv2", "OpenGL ES")
    
        source_includes = """
        #include "angle_gl.h"
    
        #include "libGL/entry_points_gl_1_0_autogen.h"
        #include "libGL/entry_points_gl_1_1_autogen.h"
        #include "libGL/entry_points_gl_1_2_autogen.h"
        #include "libGL/entry_points_gl_1_3_autogen.h"
        #include "libGL/entry_points_gl_1_4_autogen.h"
        #include "libGL/entry_points_gl_1_5_autogen.h"
        #include "libGL/entry_points_gl_2_0_autogen.h"
        #include "libGL/entry_points_gl_2_1_autogen.h"
        #include "libGL/entry_points_gl_3_0_autogen.h"
        #include "libGL/entry_points_gl_3_1_autogen.h"
        #include "libGL/entry_points_gl_3_2_autogen.h"
        #include "libGL/entry_points_gl_3_3_autogen.h"
        #include "libGL/entry_points_gl_4_0_autogen.h"
        #include "libGL/entry_points_gl_4_1_autogen.h"
        #include "libGL/entry_points_gl_4_2_autogen.h"
        #include "libGL/entry_points_gl_4_3_autogen.h"
        #include "libGL/entry_points_gl_4_4_autogen.h"
        #include "libGL/entry_points_gl_4_5_autogen.h"
        #include "libGL/entry_points_gl_4_6_autogen.h"
    
        #include "common/event_tracer.h"
        """
    
        write_export_files("\n".join([item for item in libgl_ep_defs]), source_includes,
                           "gl.xml and wgl.xml", "libGL", "Windows GL")
    
        libgles_ep_exports += get_egl_exports()
    
        everything = "Khronos and ANGLE XML files"
    
        for lib in ["libGLESv2" + suffix for suffix in ["", "_no_capture", "_with_capture"]]:
            write_windows_def_file(everything, lib, lib, "libGLESv2", libgles_ep_exports)
        write_windows_def_file(everything, "libGL", "openGL32", "libGL", libgl_ep_exports)
    
        all_gles_param_types = sorted(all_gles_param_types)
        write_capture_helper_header(all_gles_param_types)
        write_capture_helper_source(all_gles_param_types)
        write_capture_replay_source(xml.all_commands, all_commands_no_suffix, cmd_packed_gl_enums)
    
    
    if __name__ == '__main__':
        sys.exit(main())