pub const ext = @import("ext.zig");
const gstgl = @This();

const std = @import("std");
const compat = @import("compat");
const gstvideo = @import("gstvideo1");
const gstbase = @import("gstbase1");
const gst = @import("gst1");
const gobject = @import("gobject2");
const glib = @import("glib2");
const gmodule = @import("gmodule2");
/// `gstgl.GLBaseFilter` handles the nitty gritty details of retrieving an OpenGL
/// context.  It also provided some wrappers around `gstbase.BaseTransform`'s
/// ``start``, ``stop`` and ``set_caps`` virtual methods that ensure an OpenGL
/// context is available and current in the calling thread.
pub const GLBaseFilter = extern struct {
    pub const Parent = gstbase.BaseTransform;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLBaseFilterClass;
    f_parent: gstbase.BaseTransform,
    /// the currently configured `gstgl.GLDisplay`
    f_display: ?*gstgl.GLDisplay,
    /// the currently configured `gstgl.GLContext`
    f_context: ?*gstgl.GLContext,
    /// the currently configured input `gst.Caps`
    f_in_caps: ?*gst.Caps,
    /// the currently configured output `gst.Caps`
    f_out_caps: ?*gst.Caps,
    f__padding: [4]*anyopaque,
    f_priv: ?*gstgl.GLBaseFilterPrivate,

    pub const virtual_methods = struct {
        /// called in the GL thread when caps are set on `filter`.
        ///               Note: this will also be called when changing OpenGL contexts
        ///               where `gstbase.BaseTransform.signals.set_caps` may not.
        pub const gl_set_caps = struct {
            pub fn call(p_class: anytype, p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_incaps: *gst.Caps, p_outcaps: *gst.Caps) c_int {
                return gobject.ext.as(GLBaseFilter.Class, p_class).f_gl_set_caps.?(gobject.ext.as(GLBaseFilter, p_filter), p_incaps, p_outcaps);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_incaps: *gst.Caps, p_outcaps: *gst.Caps) callconv(.c) c_int) void {
                gobject.ext.as(GLBaseFilter.Class, p_class).f_gl_set_caps = @ptrCast(p_implementation);
            }
        };

        /// called in the GL thread to setup the element GL state.
        pub const gl_start = struct {
            pub fn call(p_class: anytype, p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(GLBaseFilter.Class, p_class).f_gl_start.?(gobject.ext.as(GLBaseFilter, p_filter));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) c_int) void {
                gobject.ext.as(GLBaseFilter.Class, p_class).f_gl_start = @ptrCast(p_implementation);
            }
        };

        /// called in the GL thread to setup the element GL state.
        pub const gl_stop = struct {
            pub fn call(p_class: anytype, p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) void {
                return gobject.ext.as(GLBaseFilter.Class, p_class).f_gl_stop.?(gobject.ext.as(GLBaseFilter, p_filter));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) void) void {
                gobject.ext.as(GLBaseFilter.Class, p_class).f_gl_stop = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        pub const context = struct {
            pub const name = "context";

            pub const Type = ?*gstgl.GLContext;
        };
    };

    pub const signals = struct {};

    extern fn gst_gl_base_filter_find_gl_context(p_filter: *GLBaseFilter) c_int;
    pub const findGlContext = gst_gl_base_filter_find_gl_context;

    extern fn gst_gl_base_filter_get_gl_context(p_filter: *GLBaseFilter) ?*gstgl.GLContext;
    pub const getGlContext = gst_gl_base_filter_get_gl_context;

    extern fn gst_gl_base_filter_get_type() usize;
    pub const getGObjectType = gst_gl_base_filter_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLBaseFilter) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLBaseFilter) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLBaseFilter, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Opaque `gstgl.GLBaseMemoryAllocator` struct
pub const GLBaseMemoryAllocator = extern struct {
    pub const Parent = gst.Allocator;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLBaseMemoryAllocatorClass;
    f_parent: gst.Allocator,
    f_fallback_mem_copy: ?gst.MemoryCopyFunction,
    f__padding: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// a `gstgl.GLBaseMemoryAllocatorAllocFunction`
        pub const alloc = struct {
            pub fn call(p_class: anytype, p_allocator: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_params: *gstgl.GLAllocationParams) ?*gstgl.GLBaseMemory {
                return gobject.ext.as(GLBaseMemoryAllocator.Class, p_class).f_alloc.?(gobject.ext.as(GLBaseMemoryAllocator, p_allocator), p_params);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_allocator: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_params: *gstgl.GLAllocationParams) callconv(.c) ?*gstgl.GLBaseMemory) void {
                gobject.ext.as(GLBaseMemoryAllocator.Class, p_class).f_alloc = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_gl_base_memory_allocator_get_type() usize;
    pub const getGObjectType = gst_gl_base_memory_allocator_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLBaseMemoryAllocator) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLBaseMemoryAllocator) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLBaseMemoryAllocator, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gstgl.GLBaseMixer` handles the nitty gritty details of retrieving an OpenGL
/// context.  It provides some virtual methods to know when the OpenGL context
/// is available and is not available within this element.
pub const GLBaseMixer = extern struct {
    pub const Parent = gstvideo.VideoAggregator;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLBaseMixerClass;
    /// parent `gstvideo.VideoAggregator`
    f_parent: gstvideo.VideoAggregator,
    /// the currently configured `gstgl.GLDisplay`
    f_display: ?*gstgl.GLDisplay,
    /// the currently configured `gstgl.GLContext`
    f_context: ?*gstgl.GLContext,
    f__padding: [4]*anyopaque,
    f_priv: ?*gstgl.GLBaseMixerPrivate,

    pub const virtual_methods = struct {
        /// called in the GL thread to setup the element GL state.
        pub const gl_start = struct {
            pub fn call(p_class: anytype, p_mix: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(GLBaseMixer.Class, p_class).f_gl_start.?(gobject.ext.as(GLBaseMixer, p_mix));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_mix: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) c_int) void {
                gobject.ext.as(GLBaseMixer.Class, p_class).f_gl_start = @ptrCast(p_implementation);
            }
        };

        /// called in the GL thread to setup the element GL state.
        pub const gl_stop = struct {
            pub fn call(p_class: anytype, p_mix: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) void {
                return gobject.ext.as(GLBaseMixer.Class, p_class).f_gl_stop.?(gobject.ext.as(GLBaseMixer, p_mix));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_mix: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) void) void {
                gobject.ext.as(GLBaseMixer.Class, p_class).f_gl_stop = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        /// The `gstgl.GLContext` in use by this `gstgl.GLBaseMixer`
        pub const context = struct {
            pub const name = "context";

            pub const Type = ?*gstgl.GLContext;
        };
    };

    pub const signals = struct {};

    extern fn gst_gl_base_mixer_get_gl_context(p_mix: *GLBaseMixer) ?*gstgl.GLContext;
    pub const getGlContext = gst_gl_base_mixer_get_gl_context;

    extern fn gst_gl_base_mixer_get_type() usize;
    pub const getGObjectType = gst_gl_base_mixer_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLBaseMixer) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLBaseMixer) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLBaseMixer, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLBaseMixerPad = extern struct {
    pub const Parent = gstvideo.VideoAggregatorPad;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLBaseMixerPadClass;
    /// parent `gstvideo.VideoAggregatorPad`
    f_parent: gstvideo.VideoAggregatorPad,
    f__padding: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_gl_base_mixer_pad_get_type() usize;
    pub const getGObjectType = gst_gl_base_mixer_pad_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLBaseMixerPad) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLBaseMixerPad) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLBaseMixerPad, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gstgl.GLBaseSrc` handles the nitty gritty details of retrieving an OpenGL
/// context. It also provided some wrappers around `gstbase.BaseSrc`'s ``start`` and
/// ``stop`` virtual methods that ensure an OpenGL context is available and
/// current in the calling thread.
pub const GLBaseSrc = extern struct {
    pub const Parent = gstbase.PushSrc;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLBaseSrcClass;
    f_parent: gstbase.PushSrc,
    /// the currently configured `gstgl.GLDisplay`
    f_display: ?*gstgl.GLDisplay,
    /// the currently configured `gstgl.GLContext`
    f_context: ?*gstgl.GLContext,
    /// the currently configured output `gstvideo.VideoInfo`
    f_out_info: gstvideo.VideoInfo,
    /// the currently configured output `gst.Caps`
    f_out_caps: ?*gst.Caps,
    /// the total running time
    f_running_time: gst.ClockTime,
    f__padding: [4]*anyopaque,
    f_priv: ?*gstgl.GLBaseSrcPrivate,

    pub const virtual_methods = struct {
        /// called in the GL thread to fill the current video texture.
        pub const fill_gl_memory = struct {
            pub fn call(p_class: anytype, p_src: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_mem: *gstgl.GLMemory) c_int {
                return gobject.ext.as(GLBaseSrc.Class, p_class).f_fill_gl_memory.?(gobject.ext.as(GLBaseSrc, p_src), p_mem);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_src: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_mem: *gstgl.GLMemory) callconv(.c) c_int) void {
                gobject.ext.as(GLBaseSrc.Class, p_class).f_fill_gl_memory = @ptrCast(p_implementation);
            }
        };

        /// called in the GL thread to setup the element GL state.
        pub const gl_start = struct {
            pub fn call(p_class: anytype, p_src: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(GLBaseSrc.Class, p_class).f_gl_start.?(gobject.ext.as(GLBaseSrc, p_src));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_src: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) c_int) void {
                gobject.ext.as(GLBaseSrc.Class, p_class).f_gl_start = @ptrCast(p_implementation);
            }
        };

        /// called in the GL thread to setup the element GL state.
        pub const gl_stop = struct {
            pub fn call(p_class: anytype, p_src: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) void {
                return gobject.ext.as(GLBaseSrc.Class, p_class).f_gl_stop.?(gobject.ext.as(GLBaseSrc, p_src));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_src: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) void) void {
                gobject.ext.as(GLBaseSrc.Class, p_class).f_gl_stop = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        pub const timestamp_offset = struct {
            pub const name = "timestamp-offset";

            pub const Type = i64;
        };
    };

    pub const signals = struct {};

    extern fn gst_gl_base_src_get_type() usize;
    pub const getGObjectType = gst_gl_base_src_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLBaseSrc) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLBaseSrc) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLBaseSrc, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Opaque `gstgl.GLBufferAllocator` struct
pub const GLBufferAllocator = extern struct {
    pub const Parent = gstgl.GLBaseMemoryAllocator;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLBufferAllocatorClass;
    f_parent: gstgl.GLBaseMemoryAllocator,
    f__padding: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_gl_buffer_allocator_get_type() usize;
    pub const getGObjectType = gst_gl_buffer_allocator_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLBufferAllocator) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLBufferAllocator) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLBufferAllocator, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// a `gstgl.GLBufferPool` is an object that allocates buffers with `gstgl.GLBaseMemory`
///
/// A `gstgl.GLBufferPool` is created with `gstgl.GLBufferPool.new`
///
/// `gstgl.GLBufferPool` implements the VideoMeta buffer pool option
/// `GST_BUFFER_POOL_OPTION_VIDEO_META`, the VideoAligment buffer pool option
/// `GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT` as well as the OpenGL specific
/// `GST_BUFFER_POOL_OPTION_GL_SYNC_META` buffer pool option.
pub const GLBufferPool = extern struct {
    pub const Parent = gst.BufferPool;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLBufferPoolClass;
    f_bufferpool: gst.BufferPool,
    f_context: ?*gstgl.GLContext,
    f_priv: ?*gstgl.GLBufferPoolPrivate,
    f__padding: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_gl_buffer_pool_new(p_context: *gstgl.GLContext) *gstgl.GLBufferPool;
    pub const new = gst_gl_buffer_pool_new;

    /// The returned `gstgl.GLAllocationParams` will by `NULL` before the first successful
    /// call to `gst.BufferPool.setConfig`.  Subsequent successful calls to
    /// `gst.BufferPool.setConfig` will cause this function to return a new
    /// `gstgl.GLAllocationParams` which may or may not contain the same information.
    extern fn gst_gl_buffer_pool_get_gl_allocation_params(p_pool: *GLBufferPool) ?*gstgl.GLAllocationParams;
    pub const getGlAllocationParams = gst_gl_buffer_pool_get_gl_allocation_params;

    extern fn gst_gl_buffer_pool_get_type() usize;
    pub const getGObjectType = gst_gl_buffer_pool_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLBufferPool) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLBufferPool) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLBufferPool, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gstgl.GLColorConvert` is an object that converts between color spaces and/or
/// formats using OpenGL Shaders.
///
/// A `gstgl.GLColorConvert` can be created with `gstgl.GLColorConvert.new`, the
/// configuration negotiated with `gstgl.GLColorConvert.transformCaps` and the
/// conversion performed with `gstgl.GLColorConvert.perform`.
///
/// The glcolorconvertelement provides a GStreamer element that uses
/// `gstgl.GLColorConvert` to convert between video formats and color spaces.
pub const GLColorConvert = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLColorConvertClass;
    f_parent: gst.Object,
    f_context: ?*gstgl.GLContext,
    f_in_info: gstvideo.VideoInfo,
    f_out_info: gstvideo.VideoInfo,
    f_initted: c_int,
    f_passthrough: c_int,
    f_inbuf: ?*gst.Buffer,
    f_outbuf: ?*gst.Buffer,
    f_fbo: ?*gstgl.GLFramebuffer,
    f_shader: ?*gstgl.GLShader,
    f_priv: ?*gstgl.GLColorConvertPrivate,
    f__reserved: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Provides an implementation of `gstbase.BaseTransformClass.virtual_methods.fixate_caps`
    extern fn gst_gl_color_convert_fixate_caps(p_context: *gstgl.GLContext, p_direction: gst.PadDirection, p_caps: *gst.Caps, p_other: *gst.Caps) *gst.Caps;
    pub const fixateCaps = gst_gl_color_convert_fixate_caps;

    extern fn gst_gl_color_convert_swizzle_shader_string(p_context: *gstgl.GLContext) [*:0]u8;
    pub const swizzleShaderString = gst_gl_color_convert_swizzle_shader_string;

    /// Provides an implementation of `gstbase.BaseTransformClass.virtual_methods.transform_caps`
    extern fn gst_gl_color_convert_transform_caps(p_context: *gstgl.GLContext, p_direction: gst.PadDirection, p_caps: *gst.Caps, p_filter: *gst.Caps) *gst.Caps;
    pub const transformCaps = gst_gl_color_convert_transform_caps;

    /// The returned glsl function has declaration:
    ///
    /// `vec3 yuv_to_rgb (vec3 rgb, vec3 offset, vec3 ycoeff, vec3 ucoeff, vec3 vcoeff);`
    ///
    /// The Y component is placed in the 0th index of the returned value, The U component in the
    /// 1st, and the V component in the 2nd.  offset, ycoeff, ucoeff, and vcoeff are the
    /// specific coefficients and offset used for the conversion.
    extern fn gst_gl_color_convert_yuv_to_rgb_shader_string(p_context: *gstgl.GLContext) [*:0]u8;
    pub const yuvToRgbShaderString = gst_gl_color_convert_yuv_to_rgb_shader_string;

    extern fn gst_gl_color_convert_new(p_context: *gstgl.GLContext) *gstgl.GLColorConvert;
    pub const new = gst_gl_color_convert_new;

    /// Provides an implementation of `gstbase.BaseTransformClass.virtual_methods.decide_allocation`
    extern fn gst_gl_color_convert_decide_allocation(p_convert: *GLColorConvert, p_query: *gst.Query) c_int;
    pub const decideAllocation = gst_gl_color_convert_decide_allocation;

    /// Converts the data contained by `inbuf` using the formats specified by the
    /// `gst.Caps` passed to `gstgl.GLColorConvert.setCaps`
    extern fn gst_gl_color_convert_perform(p_convert: *GLColorConvert, p_inbuf: *gst.Buffer) ?*gst.Buffer;
    pub const perform = gst_gl_color_convert_perform;

    /// Initializes `convert` with the information required for conversion.
    extern fn gst_gl_color_convert_set_caps(p_convert: *GLColorConvert, p_in_caps: *gst.Caps, p_out_caps: *gst.Caps) c_int;
    pub const setCaps = gst_gl_color_convert_set_caps;

    extern fn gst_gl_color_convert_get_type() usize;
    pub const getGObjectType = gst_gl_color_convert_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLColorConvert) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLColorConvert) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLColorConvert, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gstgl.GLContext` wraps an OpenGL context object in a uniform API.  As a result
/// of the limitation on OpenGL context, this object is not thread safe unless
/// specified and must only be activated in a single thread.
///
/// Environment variables:
/// - `GST_GL_API`: select which OpenGL API to create and OpenGL context for.
///                 Depending on the platform, the available values are
///                 'opengl', 'opengl3' (core profile), and 'gles2'.  See the
///                 the `gstgl.GLAPI` enumeration for more details.
/// - `GST_GL_PLATFORM`: select which OpenGL platform to create an OpenGL
///                      context with.  Depending on the platform and the
///                      dependencies available build-time, the available values
///                      are, 'glx', 'egl', 'cgl', 'wgl', and 'eagl'
/// - `GST_GL_CONFIG`: select the configuration used for creating the OpenGL
///                    context and OpenGL surface.  Written out as a GstStructure
///                    that has been serialized to string.  e.g.
///                    `GST_GL_CONFIG="gst-gl-context-config,red-size=8,green-size=8,blue-size=8,alpha-size=8,depth-size=16"`.
///                    Not all platforms will support the same level of
///                    functionality.
pub const GLContext = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLContextClass;
    f_parent: gst.Object,
    f_display: ?*gstgl.GLDisplay,
    f_window: ?*gstgl.GLWindow,
    /// a list of OpenGL function pointers
    f_gl_vtable: ?*gstgl.GLFuncs,
    f_priv: ?*gstgl.GLContextPrivate,
    f__reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// (De)activate the OpenGL context represented by this `context`.
        ///
        /// In OpenGL terms, calls eglMakeCurrent or similar with this context and the
        /// currently set window.  See `gstgl.GLContext.setWindow` for details.
        pub const activate = struct {
            pub fn call(p_class: anytype, p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_activate: c_int) c_int {
                return gobject.ext.as(GLContext.Class, p_class).f_activate.?(gobject.ext.as(GLContext, p_context), p_activate);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_activate: c_int) callconv(.c) c_int) void {
                gobject.ext.as(GLContext.Class, p_class).f_activate = @ptrCast(p_implementation);
            }
        };

        /// Check for an OpenGL `feature` being supported.
        ///
        /// Note: Most features require that the context be created before it is
        /// possible to determine their existence and so will fail if that is not the
        /// case.
        pub const check_feature = struct {
            pub fn call(p_class: anytype, p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_feature: [*:0]const u8) c_int {
                return gobject.ext.as(GLContext.Class, p_class).f_check_feature.?(gobject.ext.as(GLContext, p_context), p_feature);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_feature: [*:0]const u8) callconv(.c) c_int) void {
                gobject.ext.as(GLContext.Class, p_class).f_check_feature = @ptrCast(p_implementation);
            }
        };

        /// choose a format for the framebuffer
        pub const choose_format = struct {
            pub fn call(p_class: anytype, p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_error: ?*?*glib.Error) c_int {
                return gobject.ext.as(GLContext.Class, p_class).f_choose_format.?(gobject.ext.as(GLContext, p_context), p_error);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_error: ?*?*glib.Error) callconv(.c) c_int) void {
                gobject.ext.as(GLContext.Class, p_class).f_choose_format = @ptrCast(p_implementation);
            }
        };

        /// create the OpenGL context
        pub const create_context = struct {
            pub fn call(p_class: anytype, p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_gl_api: gstgl.GLAPI, p_other_context: *gstgl.GLContext, p_error: ?*?*glib.Error) c_int {
                return gobject.ext.as(GLContext.Class, p_class).f_create_context.?(gobject.ext.as(GLContext, p_context), p_gl_api, p_other_context, p_error);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_gl_api: gstgl.GLAPI, p_other_context: *gstgl.GLContext, p_error: ?*?*glib.Error) callconv(.c) c_int) void {
                gobject.ext.as(GLContext.Class, p_class).f_create_context = @ptrCast(p_implementation);
            }
        };

        /// destroy the OpenGL context
        pub const destroy_context = struct {
            pub fn call(p_class: anytype, p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) void {
                return gobject.ext.as(GLContext.Class, p_class).f_destroy_context.?(gobject.ext.as(GLContext, p_context));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) void) void {
                gobject.ext.as(GLContext.Class, p_class).f_destroy_context = @ptrCast(p_implementation);
            }
        };

        /// Retrieve the OpenGL configuration for this context.  The context must
        /// have been successfully created for this function to return a valid value.
        ///
        /// Not all implementations currently support retrieving the config and will
        /// return `NULL` when not supported.
        pub const get_config = struct {
            pub fn call(p_class: anytype, p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) ?*gst.Structure {
                return gobject.ext.as(GLContext.Class, p_class).f_get_config.?(gobject.ext.as(GLContext, p_context));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) ?*gst.Structure) void {
                gobject.ext.as(GLContext.Class, p_class).f_get_config = @ptrCast(p_implementation);
            }
        };

        /// Get the currently enabled OpenGL api.
        ///
        /// The currently available API may be limited by the `gstgl.GLDisplay` in use and/or
        /// the `gstgl.GLWindow` chosen.
        pub const get_gl_api = struct {
            pub fn call(p_class: anytype, p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) gstgl.GLAPI {
                return gobject.ext.as(GLContext.Class, p_class).f_get_gl_api.?(gobject.ext.as(GLContext, p_context));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) gstgl.GLAPI) void {
                gobject.ext.as(GLContext.Class, p_class).f_get_gl_api = @ptrCast(p_implementation);
            }
        };

        /// Gets the backing OpenGL context used by `context`.
        pub const get_gl_context = struct {
            pub fn call(p_class: anytype, p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) usize {
                return gobject.ext.as(GLContext.Class, p_class).f_get_gl_context.?(gobject.ext.as(GLContext, p_context));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) usize) void {
                gobject.ext.as(GLContext.Class, p_class).f_get_gl_context = @ptrCast(p_implementation);
            }
        };

        /// Gets the OpenGL platform that used by `context`.
        pub const get_gl_platform = struct {
            pub fn call(p_class: anytype, p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) gstgl.GLPlatform {
                return gobject.ext.as(GLContext.Class, p_class).f_get_gl_platform.?(gobject.ext.as(GLContext, p_context));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) gstgl.GLPlatform) void {
                gobject.ext.as(GLContext.Class, p_class).f_get_gl_platform = @ptrCast(p_implementation);
            }
        };

        /// Get the version of the OpenGL platform (GLX, EGL, etc) used.  Only valid
        /// after a call to `gstgl.GLContext.create`.
        pub const get_gl_platform_version = struct {
            pub fn call(p_class: anytype, p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_major: *c_int, p_minor: *c_int) void {
                return gobject.ext.as(GLContext.Class, p_class).f_get_gl_platform_version.?(gobject.ext.as(GLContext, p_context), p_major, p_minor);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_major: *c_int, p_minor: *c_int) callconv(.c) void) void {
                gobject.ext.as(GLContext.Class, p_class).f_get_gl_platform_version = @ptrCast(p_implementation);
            }
        };

        /// Set the OpenGL configuration for this context.  The context must not
        /// have been created for this function to succeed.  Setting a `NULL`
        /// `config` has the affect of removing any specific configuration request.
        ///
        /// Not all implementations currently support retrieving the config and this
        /// function will return FALSE when not supported.
        ///
        /// Note that calling this function may cause a subsequent
        /// `gstgl.GLContext.create` to fail if `config` could not be matched with
        /// the platform-specific configuration.
        ///
        /// Note that the actual config used may be differ from the requested values.
        pub const request_config = struct {
            pub fn call(p_class: anytype, p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_gl_config: ?*gst.Structure) c_int {
                return gobject.ext.as(GLContext.Class, p_class).f_request_config.?(gobject.ext.as(GLContext, p_context), p_gl_config);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_gl_config: ?*gst.Structure) callconv(.c) c_int) void {
                gobject.ext.as(GLContext.Class, p_class).f_request_config = @ptrCast(p_implementation);
            }
        };

        /// Swap the front and back buffers on the window attached to `context`.
        /// This will display the frame on the next refresh cycle.
        pub const swap_buffers = struct {
            pub fn call(p_class: anytype, p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) void {
                return gobject.ext.as(GLContext.Class, p_class).f_swap_buffers.?(gobject.ext.as(GLContext, p_context));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_context: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) void) void {
                gobject.ext.as(GLContext.Class, p_class).f_swap_buffers = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {};

    /// A default implementation of the various GetProcAddress functions that looks
    /// for `name` in the OpenGL shared libraries or in the current process.
    ///
    /// See also: `gstgl.GLContext.getProcAddress`
    extern fn gst_gl_context_default_get_proc_address(p_gl_api: gstgl.GLAPI, p_name: [*:0]const u8) ?*anyopaque;
    pub const defaultGetProcAddress = gst_gl_context_default_get_proc_address;

    /// See also `gstgl.GLContext.activate`.
    extern fn gst_gl_context_get_current() ?*gstgl.GLContext;
    pub const getCurrent = gst_gl_context_get_current;

    /// If an error occurs, `major` and `minor` are not modified and `GST_GL_API_NONE` is
    /// returned.
    extern fn gst_gl_context_get_current_gl_api(p_platform: gstgl.GLPlatform, p_major: ?*c_uint, p_minor: ?*c_uint) gstgl.GLAPI;
    pub const getCurrentGlApi = gst_gl_context_get_current_gl_api;

    extern fn gst_gl_context_get_current_gl_context(p_context_type: gstgl.GLPlatform) usize;
    pub const getCurrentGlContext = gst_gl_context_get_current_gl_context;

    /// Attempts to use the `context_type` specific GetProcAddress implementations
    /// to retrieve `name`.
    ///
    /// See also `gstgl.GLContext.getProcAddress`.
    extern fn gst_gl_context_get_proc_address_with_platform(p_context_type: gstgl.GLPlatform, p_gl_api: gstgl.GLAPI, p_name: [*:0]const u8) ?*anyopaque;
    pub const getProcAddressWithPlatform = gst_gl_context_get_proc_address_with_platform;

    /// Create a new `gstgl.GLContext` with the specified `display`
    extern fn gst_gl_context_new(p_display: *gstgl.GLDisplay) *gstgl.GLContext;
    pub const new = gst_gl_context_new;

    /// Wraps an existing OpenGL context into a `gstgl.GLContext`.
    ///
    /// Note: The caller is responsible for ensuring that the OpenGL context
    /// represented by `handle` stays alive while the returned `gstgl.GLContext` is
    /// active.
    ///
    /// `context_type` must not be `GST_GL_PLATFORM_NONE` or `GST_GL_PLATFORM_ANY`
    ///
    /// `available_apis` must not be `GST_GL_API_NONE` or `GST_GL_API_ANY`
    extern fn gst_gl_context_new_wrapped(p_display: *gstgl.GLDisplay, p_handle: usize, p_context_type: gstgl.GLPlatform, p_available_apis: gstgl.GLAPI) ?*gstgl.GLContext;
    pub const newWrapped = gst_gl_context_new_wrapped;

    /// (De)activate the OpenGL context represented by this `context`.
    ///
    /// In OpenGL terms, calls eglMakeCurrent or similar with this context and the
    /// currently set window.  See `gstgl.GLContext.setWindow` for details.
    extern fn gst_gl_context_activate(p_context: *GLContext, p_activate: c_int) c_int;
    pub const activate = gst_gl_context_activate;

    /// Note: This will always fail for two wrapped `gstgl.GLContext`'s
    extern fn gst_gl_context_can_share(p_context: *GLContext, p_other_context: *gstgl.GLContext) c_int;
    pub const canShare = gst_gl_context_can_share;

    /// Check for an OpenGL `feature` being supported.
    ///
    /// Note: Most features require that the context be created before it is
    /// possible to determine their existence and so will fail if that is not the
    /// case.
    extern fn gst_gl_context_check_feature(p_context: *GLContext, p_feature: [*:0]const u8) c_int;
    pub const checkFeature = gst_gl_context_check_feature;

    /// Must be called with `context` current.
    extern fn gst_gl_context_check_framebuffer_status(p_context: *GLContext, p_fbo_target: c_uint) c_int;
    pub const checkFramebufferStatus = gst_gl_context_check_framebuffer_status;

    extern fn gst_gl_context_check_gl_version(p_context: *GLContext, p_api: gstgl.GLAPI, p_maj: c_int, p_min: c_int) c_int;
    pub const checkGlVersion = gst_gl_context_check_gl_version;

    /// Unbind the current framebuffer
    extern fn gst_gl_context_clear_framebuffer(p_context: *GLContext) void;
    pub const clearFramebuffer = gst_gl_context_clear_framebuffer;

    /// Clear's the currently set shader from the GL state machine.
    ///
    /// Note: must be called in the GL thread.
    extern fn gst_gl_context_clear_shader(p_context: *GLContext) void;
    pub const clearShader = gst_gl_context_clear_shader;

    /// Creates an OpenGL context with the specified `other_context` as a context
    /// to share shareable OpenGL objects with.  See the OpenGL specification for
    /// what is shared between OpenGL contexts.
    ///
    /// Since 1.20, the configuration can be overriden with the environment variable
    /// `GST_GL_CONFIG` which is a stringified `gst.Structure` as would be returned
    /// from `gstgl.GLContext.getConfig`.  If `GST_GL_CONFIG` is not set, then the
    /// config will be chosen from `other_context` by calling
    /// `gstgl.GLContext.getConfig` on `other_context`.  Otherwise, a default
    /// configuration is used.
    ///
    /// Calling `gstgl.GLContext.requestConfig`) before calling
    /// `gstgl.GLContext.create` will override the config from `other_context` but
    /// will not override the `GST_GL_CONFIG` environment variable.
    ///
    /// If an error occurs, and `error` is not `NULL`, then `error` will contain
    /// details of the error and `FALSE` will be returned.
    ///
    /// Should only be called once.
    extern fn gst_gl_context_create(p_context: *GLContext, p_other_context: ?*gstgl.GLContext, p_error: ?*?*glib.Error) c_int;
    pub const create = gst_gl_context_create;

    /// Destroys an OpenGL context.
    ///
    /// Should only be called after `gstgl.GLContext.create` has been successfully
    /// called for this context.
    extern fn gst_gl_context_destroy(p_context: *GLContext) void;
    pub const destroy = gst_gl_context_destroy;

    /// Fills `context`'s info (version, extensions, vtable, etc) from the GL
    /// context in the current thread.  Typically used with wrapped contexts to
    /// allow wrapped contexts to be used as regular `gstgl.GLContext`'s.
    extern fn gst_gl_context_fill_info(p_context: *GLContext, p_error: ?*?*glib.Error) c_int;
    pub const fillInfo = gst_gl_context_fill_info;

    /// Retrieve the OpenGL configuration for this context.  The context must
    /// have been successfully created for this function to return a valid value.
    ///
    /// Not all implementations currently support retrieving the config and will
    /// return `NULL` when not supported.
    extern fn gst_gl_context_get_config(p_context: *GLContext) ?*gst.Structure;
    pub const getConfig = gst_gl_context_get_config;

    extern fn gst_gl_context_get_display(p_context: *GLContext) *gstgl.GLDisplay;
    pub const getDisplay = gst_gl_context_get_display;

    /// Get the currently enabled OpenGL api.
    ///
    /// The currently available API may be limited by the `gstgl.GLDisplay` in use and/or
    /// the `gstgl.GLWindow` chosen.
    extern fn gst_gl_context_get_gl_api(p_context: *GLContext) gstgl.GLAPI;
    pub const getGlApi = gst_gl_context_get_gl_api;

    /// Gets the backing OpenGL context used by `context`.
    extern fn gst_gl_context_get_gl_context(p_context: *GLContext) usize;
    pub const getGlContext = gst_gl_context_get_gl_context;

    /// Gets the OpenGL platform that used by `context`.
    extern fn gst_gl_context_get_gl_platform(p_context: *GLContext) gstgl.GLPlatform;
    pub const getGlPlatform = gst_gl_context_get_gl_platform;

    /// Get the version of the OpenGL platform (GLX, EGL, etc) used.  Only valid
    /// after a call to `gstgl.GLContext.create`.
    extern fn gst_gl_context_get_gl_platform_version(p_context: *GLContext, p_major: *c_int, p_minor: *c_int) void;
    pub const getGlPlatformVersion = gst_gl_context_get_gl_platform_version;

    /// Returns the OpenGL version implemented by `context`.  See
    /// `gstgl.GLContext.getGlApi` for retrieving the OpenGL api implemented by
    /// `context`.
    extern fn gst_gl_context_get_gl_version(p_context: *GLContext, p_maj: *c_int, p_min: *c_int) void;
    pub const getGlVersion = gst_gl_context_get_gl_version;

    /// Get a function pointer to a specified opengl function, `name`.  If the the
    /// specific function does not exist, NULL is returned instead.
    ///
    /// Platform specific functions (names starting 'egl', 'glX', 'wgl', etc) can also
    /// be retrieved using this method.
    ///
    /// Note: This function may return valid function pointers that may not be valid
    /// to call in `context`.  The caller is responsible for ensuring that the
    /// returned function is a valid function to call in `context` by either checking
    /// the OpenGL API and version or for an appropriate OpenGL extension.
    ///
    /// Note: On success, you need to cast the returned function pointer to the
    /// correct type to be able to call it correctly.  On 32-bit Windows, this will
    /// include the `GSTGLAPI` identifier to use the correct calling convention.
    /// e.g.
    ///
    /// ```
    /// void (GSTGLAPI *PFN_glGetIntegerv) (GLenum name, GLint * ret)
    /// ```
    extern fn gst_gl_context_get_proc_address(p_context: *GLContext, p_name: [*:0]const u8) ?*anyopaque;
    pub const getProcAddress = gst_gl_context_get_proc_address;

    extern fn gst_gl_context_get_thread(p_context: *GLContext) ?*glib.Thread;
    pub const getThread = gst_gl_context_get_thread;

    extern fn gst_gl_context_get_window(p_context: *GLContext) ?*gstgl.GLWindow;
    pub const getWindow = gst_gl_context_get_window;

    extern fn gst_gl_context_is_shared(p_context: *GLContext) c_int;
    pub const isShared = gst_gl_context_is_shared;

    /// Set the OpenGL configuration for this context.  The context must not
    /// have been created for this function to succeed.  Setting a `NULL`
    /// `config` has the affect of removing any specific configuration request.
    ///
    /// Not all implementations currently support retrieving the config and this
    /// function will return FALSE when not supported.
    ///
    /// Note that calling this function may cause a subsequent
    /// `gstgl.GLContext.create` to fail if `config` could not be matched with
    /// the platform-specific configuration.
    ///
    /// Note that the actual config used may be differ from the requested values.
    extern fn gst_gl_context_request_config(p_context: *GLContext, p_gl_config: ?*gst.Structure) c_int;
    pub const requestConfig = gst_gl_context_request_config;

    /// Will internally set `context` as shared with `share`
    extern fn gst_gl_context_set_shared_with(p_context: *GLContext, p_share: *gstgl.GLContext) void;
    pub const setSharedWith = gst_gl_context_set_shared_with;

    /// Set's the current window on `context` to `window`.  The window can only be
    /// changed before `gstgl.GLContext.create` has been called and the `window` is not
    /// already running.
    extern fn gst_gl_context_set_window(p_context: *GLContext, p_window: *gstgl.GLWindow) c_int;
    pub const setWindow = gst_gl_context_set_window;

    extern fn gst_gl_context_supports_glsl_profile_version(p_context: *GLContext, p_version: gstgl.GLSLVersion, p_profile: gstgl.GLSLProfile) c_int;
    pub const supportsGlslProfileVersion = gst_gl_context_supports_glsl_profile_version;

    extern fn gst_gl_context_supports_precision(p_context: *GLContext, p_version: gstgl.GLSLVersion, p_profile: gstgl.GLSLProfile) c_int;
    pub const supportsPrecision = gst_gl_context_supports_precision;

    extern fn gst_gl_context_supports_precision_highp(p_context: *GLContext, p_version: gstgl.GLSLVersion, p_profile: gstgl.GLSLProfile) c_int;
    pub const supportsPrecisionHighp = gst_gl_context_supports_precision_highp;

    /// Swap the front and back buffers on the window attached to `context`.
    /// This will display the frame on the next refresh cycle.
    extern fn gst_gl_context_swap_buffers(p_context: *GLContext) void;
    pub const swapBuffers = gst_gl_context_swap_buffers;

    /// Execute `func` in the OpenGL thread of `context` with `data`
    ///
    /// MT-safe
    extern fn gst_gl_context_thread_add(p_context: *GLContext, p_func: gstgl.GLContextThreadFunc, p_data: ?*anyopaque) void;
    pub const threadAdd = gst_gl_context_thread_add;

    extern fn gst_gl_context_get_type() usize;
    pub const getGObjectType = gst_gl_context_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLContext) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLContext) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLContext, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gstgl.GLDisplay` represents a connection to the underlying windowing system.
/// Elements are required to make use of `gst.Context` to share and propagate
/// a `gstgl.GLDisplay`.
///
/// There are a number of environment variables that influence the choice of
/// platform and window system specific functionality.
/// - GST_GL_WINDOW influences the window system to use.  Common values are
///   'x11', 'wayland', 'surfaceless', 'win32' or 'cocoa'.
/// - GST_GL_PLATFORM influences the OpenGL platform to use.  Common values are
///   'egl', 'glx', 'wgl' or 'cgl'.
/// - GST_GL_API influences the OpenGL API requested by the OpenGL platform.
///   Common values are 'opengl', 'opengl3' and 'gles2'.
///
/// > Certain window systems require a special function to be called to
/// > initialize threading support.  As this GStreamer GL library does not preclude
/// > concurrent access to the windowing system, it is strongly advised that
/// > applications ensure that threading support has been initialized before any
/// > other toolkit/library functionality is accessed.  Failure to do so could
/// > result in sudden application abortion during execution.  The most notably
/// > example of such a function is X11's XInitThreads\().
pub const GLDisplay = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLDisplayClass;
    f_object: gst.Object,
    f_type: gstgl.GLDisplayType,
    f_windows: ?*glib.List,
    f_main_context: ?*glib.MainContext,
    f_main_loop: ?*glib.MainLoop,
    f_event_source: ?*glib.Source,
    f_priv: ?*gstgl.GLDisplayPrivate,

    pub const virtual_methods = struct {
        pub const create_window = struct {
            pub fn call(p_class: anytype, p_display: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) ?*gstgl.GLWindow {
                return gobject.ext.as(GLDisplay.Class, p_class).f_create_window.?(gobject.ext.as(GLDisplay, p_display));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_display: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) ?*gstgl.GLWindow) void {
                gobject.ext.as(GLDisplay.Class, p_class).f_create_window = @ptrCast(p_implementation);
            }
        };

        pub const get_handle = struct {
            pub fn call(p_class: anytype, p_display: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) usize {
                return gobject.ext.as(GLDisplay.Class, p_class).f_get_handle.?(gobject.ext.as(GLDisplay, p_display));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_display: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) usize) void {
                gobject.ext.as(GLDisplay.Class, p_class).f_get_handle = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {
        /// Overrides the `GstGLContext` creation mechanism.
        /// It can be called in any thread and it is emitted with
        /// display's object lock held.
        pub const create_context = struct {
            pub const name = "create-context";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_context: *gstgl.GLContext, P_Data) callconv(.c) ?*gstgl.GLContext, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(GLDisplay, p_instance))),
                    gobject.signalLookup("create-context", GLDisplay.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    extern fn gst_gl_display_new() *gstgl.GLDisplay;
    pub const new = gst_gl_display_new;

    /// Will always return a `gstgl.GLDisplay` of a single type.  This differs from
    /// `gstgl.GLDisplay.new` and the seemingly equivalent call
    /// gst_gl_display_new_with_type (GST_GL_DISPLAY_TYPE_ANY) in that the latter
    /// may return NULL.
    extern fn gst_gl_display_new_with_type(p_type: gstgl.GLDisplayType) ?*gstgl.GLDisplay;
    pub const newWithType = gst_gl_display_new_with_type;

    extern fn gst_gl_display_add_context(p_display: *GLDisplay, p_context: *gstgl.GLContext) c_int;
    pub const addContext = gst_gl_display_add_context;

    /// It requires the display's object lock to be held.
    extern fn gst_gl_display_create_context(p_display: *GLDisplay, p_other_context: ?*gstgl.GLContext, p_p_context: **gstgl.GLContext, p_error: ?*?*glib.Error) c_int;
    pub const createContext = gst_gl_display_create_context;

    extern fn gst_gl_display_create_window(p_display: *GLDisplay) ?*gstgl.GLWindow;
    pub const createWindow = gst_gl_display_create_window;

    /// Ensures that the display has a valid GL context for the current thread. If
    /// `context` already contains a valid context, this does nothing.
    extern fn gst_gl_display_ensure_context(p_display: *GLDisplay, p_other_context: ?*gstgl.GLContext, p_context: ?**gstgl.GLContext, p_error: ?*?*glib.Error) c_int;
    pub const ensureContext = gst_gl_display_ensure_context;

    /// limit the use of OpenGL to the requested `gl_api`.  This is intended to allow
    /// application and elements to request a specific set of OpenGL API's based on
    /// what they support.  See `gstgl.GLContext.getGlApi` for the retrieving the
    /// API supported by a `gstgl.GLContext`.
    extern fn gst_gl_display_filter_gl_api(p_display: *GLDisplay, p_gl_api: gstgl.GLAPI) void;
    pub const filterGlApi = gst_gl_display_filter_gl_api;

    /// Execute `compare_func` over the list of windows stored by `display`.  The
    /// first argument to `compare_func` is the `gstgl.GLWindow` being checked and the
    /// second argument is `data`.
    extern fn gst_gl_display_find_window(p_display: *GLDisplay, p_data: ?*anyopaque, p_compare_func: glib.CompareFunc) ?*gstgl.GLWindow;
    pub const findWindow = gst_gl_display_find_window;

    /// see `gstgl.GLDisplay.filterGlApi` for what the returned value represents
    extern fn gst_gl_display_get_gl_api(p_display: *GLDisplay) gstgl.GLAPI;
    pub const getGlApi = gst_gl_display_get_gl_api;

    extern fn gst_gl_display_get_gl_api_unlocked(p_display: *GLDisplay) gstgl.GLAPI;
    pub const getGlApiUnlocked = gst_gl_display_get_gl_api_unlocked;

    extern fn gst_gl_display_get_gl_context_for_thread(p_display: *GLDisplay, p_thread: *glib.Thread) ?*gstgl.GLContext;
    pub const getGlContextForThread = gst_gl_display_get_gl_context_for_thread;

    extern fn gst_gl_display_get_handle(p_display: *GLDisplay) usize;
    pub const getHandle = gst_gl_display_get_handle;

    extern fn gst_gl_display_get_handle_type(p_display: *GLDisplay) gstgl.GLDisplayType;
    pub const getHandleType = gst_gl_display_get_handle_type;

    /// Must be called with the object lock held.
    extern fn gst_gl_display_remove_context(p_display: *GLDisplay, p_context: *gstgl.GLContext) void;
    pub const removeContext = gst_gl_display_remove_context;

    extern fn gst_gl_display_remove_window(p_display: *GLDisplay, p_window: *gstgl.GLWindow) c_int;
    pub const removeWindow = gst_gl_display_remove_window;

    /// Execute `compare_func` over the list of windows stored by `display`.  The
    /// first argument to `compare_func` is the `gstgl.GLWindow` being checked and the
    /// second argument is `data`.
    extern fn gst_gl_display_retrieve_window(p_display: *GLDisplay, p_data: ?*anyopaque, p_compare_func: glib.CompareFunc) ?*gstgl.GLWindow;
    pub const retrieveWindow = gst_gl_display_retrieve_window;

    extern fn gst_gl_display_get_type() usize;
    pub const getGObjectType = gst_gl_display_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLDisplay) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLDisplay) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLDisplay, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gstgl.GLFilter` helps to implement simple OpenGL filter elements taking a
/// single input and producing a single output with a `gstgl.GLFramebuffer`
pub const GLFilter = extern struct {
    pub const Parent = gstgl.GLBaseFilter;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLFilterClass;
    f_parent: gstgl.GLBaseFilter,
    /// the video info for input buffers
    f_in_info: gstvideo.VideoInfo,
    /// the video info for output buffers
    f_out_info: gstvideo.VideoInfo,
    /// The texture target of the input buffers (usually 2D)
    f_in_texture_target: gstgl.GLTextureTarget,
    /// The texture target of the output buffers (usually 2D)
    f_out_texture_target: gstgl.GLTextureTarget,
    /// the output `gst.Caps`
    f_out_caps: ?*gst.Caps,
    /// `gstgl.GLFramebuffer` object used for transformations (only for subclass usage)
    f_fbo: ?*gstgl.GLFramebuffer,
    f_gl_result: c_int,
    f_inbuf: ?*gst.Buffer,
    f_outbuf: ?*gst.Buffer,
    f_default_shader: ?*gstgl.GLShader,
    f_valid_attributes: c_int,
    f_vao: c_uint,
    f_vbo_indices: c_uint,
    f_vertex_buffer: c_uint,
    f_draw_attr_position_loc: c_int,
    f_draw_attr_texture_loc: c_int,
    f__padding: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// perform operations on the input and output buffers.  In general,
        ///          you should avoid using this method if at all possible. One valid
        ///          use-case for using this is keeping previous buffers for future calculations.
        ///          Note: If `filter` exists, then `filter_texture` is not run
        pub const filter = struct {
            pub fn call(p_class: anytype, p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_inbuf: *gst.Buffer, p_outbuf: *gst.Buffer) c_int {
                return gobject.ext.as(GLFilter.Class, p_class).f_filter.?(gobject.ext.as(GLFilter, p_filter), p_inbuf, p_outbuf);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_inbuf: *gst.Buffer, p_outbuf: *gst.Buffer) callconv(.c) c_int) void {
                gobject.ext.as(GLFilter.Class, p_class).f_filter = @ptrCast(p_implementation);
            }
        };

        /// Calls filter_texture vfunc with correctly mapped `GstGLMemorys`
        pub const filter_texture = struct {
            pub fn call(p_class: anytype, p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_input: *gstgl.GLMemory, p_output: *gstgl.GLMemory) c_int {
                return gobject.ext.as(GLFilter.Class, p_class).f_filter_texture.?(gobject.ext.as(GLFilter, p_filter), p_input, p_output);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_input: *gstgl.GLMemory, p_output: *gstgl.GLMemory) callconv(.c) c_int) void {
                gobject.ext.as(GLFilter.Class, p_class).f_filter_texture = @ptrCast(p_implementation);
            }
        };

        /// perform initialization when the Framebuffer object is created
        pub const init_fbo = struct {
            pub fn call(p_class: anytype, p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(GLFilter.Class, p_class).f_init_fbo.?(gobject.ext.as(GLFilter, p_filter));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) c_int) void {
                gobject.ext.as(GLFilter.Class, p_class).f_init_fbo = @ptrCast(p_implementation);
            }
        };

        /// mirror from `gstbase.BaseTransform`
        pub const set_caps = struct {
            pub fn call(p_class: anytype, p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_incaps: *gst.Caps, p_outcaps: *gst.Caps) c_int {
                return gobject.ext.as(GLFilter.Class, p_class).f_set_caps.?(gobject.ext.as(GLFilter, p_filter), p_incaps, p_outcaps);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_incaps: *gst.Caps, p_outcaps: *gst.Caps) callconv(.c) c_int) void {
                gobject.ext.as(GLFilter.Class, p_class).f_set_caps = @ptrCast(p_implementation);
            }
        };

        /// Perform sub-class specific modifications of the
        ///   caps to be processed between upload on input and before download for output.
        pub const transform_internal_caps = struct {
            pub fn call(p_class: anytype, p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_direction: gst.PadDirection, p_caps: *gst.Caps, p_filter_caps: *gst.Caps) *gst.Caps {
                return gobject.ext.as(GLFilter.Class, p_class).f_transform_internal_caps.?(gobject.ext.as(GLFilter, p_filter), p_direction, p_caps, p_filter_caps);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_direction: gst.PadDirection, p_caps: *gst.Caps, p_filter_caps: *gst.Caps) callconv(.c) *gst.Caps) void {
                gobject.ext.as(GLFilter.Class, p_class).f_transform_internal_caps = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_gl_filter_add_rgba_pad_templates(p_klass: *gstgl.GLFilterClass) void;
    pub const addRgbaPadTemplates = gst_gl_filter_add_rgba_pad_templates;

    /// Render a fullscreen quad using the current GL state.  The only GL state this
    /// modifies is the necessary vertex/index buffers and, if necessary, a
    /// Vertex Array Object for drawing a fullscreen quad.  Framebuffer state,
    /// any shaders, viewport state, etc must be setup by the caller.
    extern fn gst_gl_filter_draw_fullscreen_quad(p_filter: *GLFilter) void;
    pub const drawFullscreenQuad = gst_gl_filter_draw_fullscreen_quad;

    /// Calls filter_texture vfunc with correctly mapped `GstGLMemorys`
    extern fn gst_gl_filter_filter_texture(p_filter: *GLFilter, p_input: *gst.Buffer, p_output: *gst.Buffer) c_int;
    pub const filterTexture = gst_gl_filter_filter_texture;

    /// Transforms `input` into `output` using `func` on through FBO.
    extern fn gst_gl_filter_render_to_target(p_filter: *GLFilter, p_input: *gstgl.GLMemory, p_output: *gstgl.GLMemory, p_func: gstgl.GLFilterRenderFunc, p_data: ?*anyopaque) c_int;
    pub const renderToTarget = gst_gl_filter_render_to_target;

    /// Transforms `input` into `output` using `shader` with a FBO.
    ///
    /// See also: `gstgl.GLFilter.renderToTarget`
    extern fn gst_gl_filter_render_to_target_with_shader(p_filter: *GLFilter, p_input: *gstgl.GLMemory, p_output: *gstgl.GLMemory, p_shader: *gstgl.GLShader) void;
    pub const renderToTargetWithShader = gst_gl_filter_render_to_target_with_shader;

    extern fn gst_gl_filter_get_type() usize;
    pub const getGObjectType = gst_gl_filter_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLFilter) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLFilter) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLFilter, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A `gstgl.GLFramebuffer` represents and holds an OpenGL framebuffer object with
/// it's associated attachments.
///
/// A `gstgl.GLFramebuffer` can be created with `gstgl.GLFramebuffer.new` or
/// `gstgl.GLFramebuffer.newWithDefaultDepth` and bound with
/// `gstgl.GLFramebuffer.bind`.  Other resources can be bound with
/// `gstgl.GLFramebuffer.attach`
///
/// Note: OpenGL framebuffers are not shareable resources so cannot be used
/// between multiple OpenGL contexts.
pub const GLFramebuffer = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLFramebufferClass;
    f_object: gst.Object,
    f_context: ?*gstgl.GLContext,
    f_fbo_id: c_uint,
    f_attachments: ?*glib.Array,
    f__padding: [4]*anyopaque,
    f_priv: ?*gstgl.GLFramebufferPrivate,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// This function will internally create an OpenGL framebuffer object and must
    /// be called on `context`'s OpenGL thread.
    extern fn gst_gl_framebuffer_new(p_context: *gstgl.GLContext) *gstgl.GLFramebuffer;
    pub const new = gst_gl_framebuffer_new;

    /// This function will internally create an OpenGL framebuffer object and must
    /// be called on `context`'s OpenGL thread.
    extern fn gst_gl_framebuffer_new_with_default_depth(p_context: *gstgl.GLContext, p_width: c_uint, p_height: c_uint) *gstgl.GLFramebuffer;
    pub const newWithDefaultDepth = gst_gl_framebuffer_new_with_default_depth;

    /// attach `mem` to `attachment_point`
    ///
    /// Must be called with the same OpenGL context current that `fb` was created
    /// with.
    extern fn gst_gl_framebuffer_attach(p_fb: *GLFramebuffer, p_attachment_point: c_uint, p_mem: *gstgl.GLBaseMemory) void;
    pub const attach = gst_gl_framebuffer_attach;

    /// Bind `fb` into the current thread
    ///
    /// Must be called with the same OpenGL context current that `fb` was created
    /// with.
    extern fn gst_gl_framebuffer_bind(p_fb: *GLFramebuffer) void;
    pub const bind = gst_gl_framebuffer_bind;

    /// Perform the steps necessary to have the output of a glDraw* command in
    /// `func` update the contents of `mem`.
    ///
    /// Note: this function does not map `mem` for writing with OpenGL and that must
    /// be done manually by the caller using any of the mapping functions such as
    /// `gst.Memory.map` with the map flags `GST_MAP_WRITE` | `GST_MAP_GL`.
    ///
    /// Must be called with the same OpenGL context current that `fb` was created
    /// with.
    extern fn gst_gl_framebuffer_draw_to_texture(p_fb: *GLFramebuffer, p_mem: *gstgl.GLMemory, p_func: gstgl.GLFramebufferFunc, p_user_data: ?*anyopaque) c_int;
    pub const drawToTexture = gst_gl_framebuffer_draw_to_texture;

    /// Retrieve the effective dimensions from the current attachments attached to
    /// `fb`.
    extern fn gst_gl_framebuffer_get_effective_dimensions(p_fb: *GLFramebuffer, p_width: ?*c_uint, p_height: ?*c_uint) void;
    pub const getEffectiveDimensions = gst_gl_framebuffer_get_effective_dimensions;

    extern fn gst_gl_framebuffer_get_id(p_fb: *GLFramebuffer) c_uint;
    pub const getId = gst_gl_framebuffer_get_id;

    extern fn gst_gl_framebuffer_get_type() usize;
    pub const getGObjectType = gst_gl_framebuffer_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLFramebuffer) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLFramebuffer) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLFramebuffer, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Opaque `gstgl.GLMemoryAllocator` struct
pub const GLMemoryAllocator = extern struct {
    pub const Parent = gstgl.GLBaseMemoryAllocator;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLMemoryAllocatorClass;
    f_parent: gstgl.GLBaseMemoryAllocator,
    f__padding: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_gl_memory_allocator_get_default(p_context: *gstgl.GLContext) *gstgl.GLMemoryAllocator;
    pub const getDefault = gst_gl_memory_allocator_get_default;

    extern fn gst_gl_memory_allocator_get_type() usize;
    pub const getGObjectType = gst_gl_memory_allocator_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLMemoryAllocator) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLMemoryAllocator) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLMemoryAllocator, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Opaque `gstgl.GLMemoryPBOAllocator` struct
pub const GLMemoryPBOAllocator = extern struct {
    pub const Parent = gstgl.GLMemoryAllocator;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLMemoryPBOAllocatorClass;
    f_parent: gstgl.GLMemoryAllocator,
    f__padding: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_gl_memory_pbo_allocator_get_type() usize;
    pub const getGObjectType = gst_gl_memory_pbo_allocator_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLMemoryPBOAllocator) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLMemoryPBOAllocator) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLMemoryPBOAllocator, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gstgl.GLMixer` helps implement an element that operates on RGBA textures.
pub const GLMixer = extern struct {
    pub const Parent = gstgl.GLBaseMixer;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLMixerClass;
    f_parent: gstgl.GLBaseMixer,
    /// the configured output `gst.Caps`
    f_out_caps: ?*gst.Caps,
    f_priv: ?*gstgl.GLMixerPrivate,
    f__padding: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// Perform operations on the input buffers to produce an
        /// output buffer.
        pub const process_buffers = struct {
            pub fn call(p_class: anytype, p_mix: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_outbuf: *gst.Buffer) c_int {
                return gobject.ext.as(GLMixer.Class, p_class).f_process_buffers.?(gobject.ext.as(GLMixer, p_mix), p_outbuf);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_mix: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_outbuf: *gst.Buffer) callconv(.c) c_int) void {
                gobject.ext.as(GLMixer.Class, p_class).f_process_buffers = @ptrCast(p_implementation);
            }
        };

        /// Perform processing required and call `gstgl.GLMixerClass.signals.process_textures``process_textures`.
        /// Intended for use within implementations of
        /// `gstgl.GLMixerClass.signals.process_buffers``process_buffers`.
        pub const process_textures = struct {
            pub fn call(p_class: anytype, p_mix: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_out_tex: *gstgl.GLMemory) c_int {
                return gobject.ext.as(GLMixer.Class, p_class).f_process_textures.?(gobject.ext.as(GLMixer, p_mix), p_out_tex);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_mix: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_out_tex: *gstgl.GLMemory) callconv(.c) c_int) void {
                gobject.ext.as(GLMixer.Class, p_class).f_process_textures = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_gl_mixer_get_framebuffer(p_mix: *GLMixer) *gstgl.GLFramebuffer;
    pub const getFramebuffer = gst_gl_mixer_get_framebuffer;

    /// Perform processing required and call `gstgl.GLMixerClass.signals.process_textures``process_textures`.
    /// Intended for use within implementations of
    /// `gstgl.GLMixerClass.signals.process_buffers``process_buffers`.
    extern fn gst_gl_mixer_process_textures(p_mix: *GLMixer, p_outbuf: *gst.Buffer) c_int;
    pub const processTextures = gst_gl_mixer_process_textures;

    extern fn gst_gl_mixer_get_type() usize;
    pub const getGObjectType = gst_gl_mixer_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLMixer) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLMixer) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLMixer, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLMixerPad = extern struct {
    pub const Parent = gstgl.GLBaseMixerPad;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLMixerPadClass;
    /// parent `gstgl.GLBaseMixerPad`
    f_parent: gstgl.GLBaseMixerPad,
    /// the current input texture for this pad
    f_current_texture: c_uint,
    f__padding: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_gl_mixer_pad_get_type() usize;
    pub const getGObjectType = gst_gl_mixer_pad_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLMixerPad) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLMixerPad) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLMixerPad, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Opaque `gstgl.GLOverlayCompositor` object
pub const GLOverlayCompositor = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLOverlayCompositorClass;
    f_parent: gst.Object,
    f_context: ?*gstgl.GLContext,
    f_last_window_width: c_uint,
    f_last_window_height: c_uint,
    f_overlays: ?*glib.List,
    f_shader: ?*gstgl.GLShader,
    f_position_attrib: c_int,
    f_texcoord_attrib: c_int,
    f__padding: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {
        pub const yinvert = struct {
            pub const name = "yinvert";

            pub const Type = c_int;
        };
    };

    pub const signals = struct {};

    extern fn gst_gl_overlay_compositor_add_caps(p_caps: *gst.Caps) *gst.Caps;
    pub const addCaps = gst_gl_overlay_compositor_add_caps;

    extern fn gst_gl_overlay_compositor_new(p_context: *gstgl.GLContext) *gstgl.GLOverlayCompositor;
    pub const new = gst_gl_overlay_compositor_new;

    extern fn gst_gl_overlay_compositor_draw_overlays(p_compositor: *GLOverlayCompositor) void;
    pub const drawOverlays = gst_gl_overlay_compositor_draw_overlays;

    extern fn gst_gl_overlay_compositor_free_overlays(p_compositor: *GLOverlayCompositor) void;
    pub const freeOverlays = gst_gl_overlay_compositor_free_overlays;

    extern fn gst_gl_overlay_compositor_upload_overlays(p_compositor: *GLOverlayCompositor, p_buf: *gst.Buffer) void;
    pub const uploadOverlays = gst_gl_overlay_compositor_upload_overlays;

    extern fn gst_gl_overlay_compositor_get_type() usize;
    pub const getGObjectType = gst_gl_overlay_compositor_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLOverlayCompositor) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLOverlayCompositor) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLOverlayCompositor, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Opaque `gstgl.GLRenderbufferAllocator` struct
pub const GLRenderbufferAllocator = extern struct {
    pub const Parent = gstgl.GLBaseMemoryAllocator;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLRenderbufferAllocatorClass;
    f_parent: gstgl.GLBaseMemoryAllocator,
    f__padding: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_gl_renderbuffer_allocator_get_type() usize;
    pub const getGObjectType = gst_gl_renderbuffer_allocator_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLRenderbufferAllocator) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLRenderbufferAllocator) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLRenderbufferAllocator, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gstgl.GLSLStage` holds and represents a single OpenGL shader stage.
pub const GLSLStage = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLSLStageClass;
    f_parent: gst.Object,
    f_context: ?*gstgl.GLContext,
    f_priv: ?*gstgl.GLSLStagePrivate,
    f__padding: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_glsl_stage_new(p_context: *gstgl.GLContext, p_type: c_uint) *gstgl.GLSLStage;
    pub const new = gst_glsl_stage_new;

    extern fn gst_glsl_stage_new_default_fragment(p_context: *gstgl.GLContext) *gstgl.GLSLStage;
    pub const newDefaultFragment = gst_glsl_stage_new_default_fragment;

    extern fn gst_glsl_stage_new_default_vertex(p_context: *gstgl.GLContext) *gstgl.GLSLStage;
    pub const newDefaultVertex = gst_glsl_stage_new_default_vertex;

    extern fn gst_glsl_stage_new_with_string(p_context: *gstgl.GLContext, p_type: c_uint, p_version: gstgl.GLSLVersion, p_profile: gstgl.GLSLProfile, p_str: [*:0]const u8) *gstgl.GLSLStage;
    pub const newWithString = gst_glsl_stage_new_with_string;

    extern fn gst_glsl_stage_new_with_strings(p_context: *gstgl.GLContext, p_type: c_uint, p_version: gstgl.GLSLVersion, p_profile: gstgl.GLSLProfile, p_n_strings: c_int, p_str: [*][*:0]const u8) *gstgl.GLSLStage;
    pub const newWithStrings = gst_glsl_stage_new_with_strings;

    extern fn gst_glsl_stage_compile(p_stage: *GLSLStage, p_error: ?*?*glib.Error) c_int;
    pub const compile = gst_glsl_stage_compile;

    extern fn gst_glsl_stage_get_handle(p_stage: *GLSLStage) c_uint;
    pub const getHandle = gst_glsl_stage_get_handle;

    extern fn gst_glsl_stage_get_profile(p_stage: *GLSLStage) gstgl.GLSLProfile;
    pub const getProfile = gst_glsl_stage_get_profile;

    extern fn gst_glsl_stage_get_shader_type(p_stage: *GLSLStage) c_uint;
    pub const getShaderType = gst_glsl_stage_get_shader_type;

    extern fn gst_glsl_stage_get_version(p_stage: *GLSLStage) gstgl.GLSLVersion;
    pub const getVersion = gst_glsl_stage_get_version;

    /// Replaces the current shader string with `str`.
    extern fn gst_glsl_stage_set_strings(p_stage: *GLSLStage, p_version: gstgl.GLSLVersion, p_profile: gstgl.GLSLProfile, p_n_strings: c_int, p_str: [*][*:0]const u8) c_int;
    pub const setStrings = gst_glsl_stage_set_strings;

    extern fn gst_glsl_stage_get_type() usize;
    pub const getGObjectType = gst_glsl_stage_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLSLStage) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLSLStage) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLSLStage, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLShader = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLShaderClass;
    f_parent: gst.Object,
    f_context: ?*gstgl.GLContext,
    f_priv: ?*gstgl.GLShaderPrivate,
    f__padding: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {
        pub const linked = struct {
            pub const name = "linked";

            pub const Type = c_int;
        };
    };

    pub const signals = struct {};

    extern fn gst_gl_shader_string_fragment_external_oes_get_default(p_context: *gstgl.GLContext, p_version: gstgl.GLSLVersion, p_profile: gstgl.GLSLProfile) [*:0]u8;
    pub const stringFragmentExternalOesGetDefault = gst_gl_shader_string_fragment_external_oes_get_default;

    extern fn gst_gl_shader_string_fragment_get_default(p_context: *gstgl.GLContext, p_version: gstgl.GLSLVersion, p_profile: gstgl.GLSLProfile) [*:0]u8;
    pub const stringFragmentGetDefault = gst_gl_shader_string_fragment_get_default;

    /// Generates a shader string that defines the precision of float types in
    /// GLSL shaders.  This is particularly needed for fragment shaders in a
    /// GLSL ES context where there is no default precision specified.
    ///
    /// Practically, this will return the string 'precision mediump float'
    /// or 'precision highp float' depending on if high precision floats are
    /// determined to be supported.
    extern fn gst_gl_shader_string_get_highest_precision(p_context: *gstgl.GLContext, p_version: gstgl.GLSLVersion, p_profile: gstgl.GLSLProfile) [*:0]const u8;
    pub const stringGetHighestPrecision = gst_gl_shader_string_get_highest_precision;

    /// Note: must be called in the GL thread
    extern fn gst_gl_shader_new(p_context: *gstgl.GLContext) *gstgl.GLShader;
    pub const new = gst_gl_shader_new;

    /// Note: must be called in the GL thread
    extern fn gst_gl_shader_new_default(p_context: *gstgl.GLContext, p_error: ?*?*glib.Error) ?*gstgl.GLShader;
    pub const newDefault = gst_gl_shader_new_default;

    /// Each stage will attempt to be compiled and attached to `shader`.  Then
    /// the shader will be linked. On error, `NULL` will be returned and `error` will
    /// contain the details of the error.
    ///
    /// Note: must be called in the GL thread
    extern fn gst_gl_shader_new_link_with_stages(p_context: *gstgl.GLContext, p_error: **glib.Error, ...) *gstgl.GLShader;
    pub const newLinkWithStages = gst_gl_shader_new_link_with_stages;

    /// Each stage will attempt to be compiled and attached to `shader`.  On error,
    /// `NULL` will be returned and `error` will contain the details of the error.
    ///
    /// Note: must be called in the GL thread
    extern fn gst_gl_shader_new_with_stages(p_context: *gstgl.GLContext, p_error: **glib.Error, ...) *gstgl.GLShader;
    pub const newWithStages = gst_gl_shader_new_with_stages;

    /// Attaches `stage` to `shader`.  `stage` must have been successfully compiled
    /// with `gstgl.GLSLStage.compile`.
    ///
    /// Note: must be called in the GL thread
    extern fn gst_gl_shader_attach(p_shader: *GLShader, p_stage: *gstgl.GLSLStage) c_int;
    pub const attach = gst_gl_shader_attach;

    /// Attaches `stage` to `shader`.  `stage` must have been successfully compiled
    /// with `gstgl.GLSLStage.compile`.
    ///
    /// Note: must be called in the GL thread
    extern fn gst_gl_shader_attach_unlocked(p_shader: *GLShader, p_stage: *gstgl.GLSLStage) c_int;
    pub const attachUnlocked = gst_gl_shader_attach_unlocked;

    /// Bind attribute `name` to the specified location `index` using
    /// ``glBindAttributeLocation``.
    extern fn gst_gl_shader_bind_attribute_location(p_shader: *GLShader, p_index: c_uint, p_name: [*:0]const u8) void;
    pub const bindAttributeLocation = gst_gl_shader_bind_attribute_location;

    /// Bind attribute `name` to the specified location `index` using
    /// ``glBindFragDataLocation``.
    extern fn gst_gl_shader_bind_frag_data_location(p_shader: *GLShader, p_index: c_uint, p_name: [*:0]const u8) void;
    pub const bindFragDataLocation = gst_gl_shader_bind_frag_data_location;

    /// Compiles `stage` and attaches it to `shader`.
    ///
    /// Note: must be called in the GL thread
    extern fn gst_gl_shader_compile_attach_stage(p_shader: *GLShader, p_stage: *gstgl.GLSLStage, p_error: ?*?*glib.Error) c_int;
    pub const compileAttachStage = gst_gl_shader_compile_attach_stage;

    /// Detaches `stage` from `shader`.  `stage` must have been successfully attached
    /// to `shader` with `gstgl.GLShader.attach` or `gstgl.GLShader.attachUnlocked`.
    ///
    /// Note: must be called in the GL thread
    extern fn gst_gl_shader_detach(p_shader: *GLShader, p_stage: *gstgl.GLSLStage) void;
    pub const detach = gst_gl_shader_detach;

    /// Detaches `stage` from `shader`.  `stage` must have been successfully attached
    /// to `shader` with `gstgl.GLShader.attach` or `gstgl.GLShader.attachUnlocked`.
    ///
    /// Note: must be called in the GL thread
    extern fn gst_gl_shader_detach_unlocked(p_shader: *GLShader, p_stage: *gstgl.GLSLStage) void;
    pub const detachUnlocked = gst_gl_shader_detach_unlocked;

    extern fn gst_gl_shader_get_attribute_location(p_shader: *GLShader, p_name: [*:0]const u8) c_int;
    pub const getAttributeLocation = gst_gl_shader_get_attribute_location;

    extern fn gst_gl_shader_get_program_handle(p_shader: *GLShader) c_int;
    pub const getProgramHandle = gst_gl_shader_get_program_handle;

    /// Note: must be called in the GL thread
    extern fn gst_gl_shader_is_linked(p_shader: *GLShader) c_int;
    pub const isLinked = gst_gl_shader_is_linked;

    /// Links the current list of `gstgl.GLSLStage`'s in `shader`.
    ///
    /// Note: must be called in the GL thread
    extern fn gst_gl_shader_link(p_shader: *GLShader, p_error: ?*?*glib.Error) c_int;
    pub const link = gst_gl_shader_link;

    /// Releases the shader and stages.
    ///
    /// Note: must be called in the GL thread
    extern fn gst_gl_shader_release(p_shader: *GLShader) void;
    pub const release = gst_gl_shader_release;

    /// Releases the shader and stages.
    ///
    /// Note: must be called in the GL thread
    extern fn gst_gl_shader_release_unlocked(p_shader: *GLShader) void;
    pub const releaseUnlocked = gst_gl_shader_release_unlocked;

    /// Perform ``glUniform1f`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_1f(p_shader: *GLShader, p_name: [*:0]const u8, p_value: f32) void;
    pub const setUniform1f = gst_gl_shader_set_uniform_1f;

    /// Perform ``glUniform1fv`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_1fv(p_shader: *GLShader, p_name: [*:0]const u8, p_count: c_uint, p_value: [*]const f32) void;
    pub const setUniform1fv = gst_gl_shader_set_uniform_1fv;

    /// Perform ``glUniform1i`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_1i(p_shader: *GLShader, p_name: [*:0]const u8, p_value: c_int) void;
    pub const setUniform1i = gst_gl_shader_set_uniform_1i;

    /// Perform ``glUniform1iv`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_1iv(p_shader: *GLShader, p_name: [*:0]const u8, p_count: c_uint, p_value: [*]const c_int) void;
    pub const setUniform1iv = gst_gl_shader_set_uniform_1iv;

    /// Perform ``glUniform2f`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_2f(p_shader: *GLShader, p_name: [*:0]const u8, p_v0: f32, p_v1: f32) void;
    pub const setUniform2f = gst_gl_shader_set_uniform_2f;

    /// Perform ``glUniform2fv`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_2fv(p_shader: *GLShader, p_name: [*:0]const u8, p_count: c_uint, p_value: [*]const f32) void;
    pub const setUniform2fv = gst_gl_shader_set_uniform_2fv;

    /// Perform ``glUniform2i`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_2i(p_shader: *GLShader, p_name: [*:0]const u8, p_v0: c_int, p_v1: c_int) void;
    pub const setUniform2i = gst_gl_shader_set_uniform_2i;

    /// Perform ``glUniform2iv`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_2iv(p_shader: *GLShader, p_name: [*:0]const u8, p_count: c_uint, p_value: [*]const c_int) void;
    pub const setUniform2iv = gst_gl_shader_set_uniform_2iv;

    /// Perform ``glUniform3f`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_3f(p_shader: *GLShader, p_name: [*:0]const u8, p_v0: f32, p_v1: f32, p_v2: f32) void;
    pub const setUniform3f = gst_gl_shader_set_uniform_3f;

    /// Perform ``glUniform3fv`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_3fv(p_shader: *GLShader, p_name: [*:0]const u8, p_count: c_uint, p_value: [*]const f32) void;
    pub const setUniform3fv = gst_gl_shader_set_uniform_3fv;

    /// Perform ``glUniform3i`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_3i(p_shader: *GLShader, p_name: [*:0]const u8, p_v0: c_int, p_v1: c_int, p_v2: c_int) void;
    pub const setUniform3i = gst_gl_shader_set_uniform_3i;

    /// Perform ``glUniform3iv`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_3iv(p_shader: *GLShader, p_name: [*:0]const u8, p_count: c_uint, p_value: [*]const c_int) void;
    pub const setUniform3iv = gst_gl_shader_set_uniform_3iv;

    /// Perform ``glUniform4f`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_4f(p_shader: *GLShader, p_name: [*:0]const u8, p_v0: f32, p_v1: f32, p_v2: f32, p_v3: f32) void;
    pub const setUniform4f = gst_gl_shader_set_uniform_4f;

    /// Perform ``glUniform4fv`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_4fv(p_shader: *GLShader, p_name: [*:0]const u8, p_count: c_uint, p_value: [*]const f32) void;
    pub const setUniform4fv = gst_gl_shader_set_uniform_4fv;

    /// Perform ``glUniform4i`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_4i(p_shader: *GLShader, p_name: [*:0]const u8, p_v0: c_int, p_v1: c_int, p_v2: c_int, p_v3: c_int) void;
    pub const setUniform4i = gst_gl_shader_set_uniform_4i;

    /// Perform ``glUniform4iv`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_4iv(p_shader: *GLShader, p_name: [*:0]const u8, p_count: c_uint, p_value: [*]const c_int) void;
    pub const setUniform4iv = gst_gl_shader_set_uniform_4iv;

    /// Perform ``glUniformMatrix2fv`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_matrix_2fv(p_shader: *GLShader, p_name: [*:0]const u8, p_count: c_int, p_transpose: c_int, p_value: *const f32) void;
    pub const setUniformMatrix2fv = gst_gl_shader_set_uniform_matrix_2fv;

    /// Perform ``glUniformMatrix2x3fv`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_matrix_2x3fv(p_shader: *GLShader, p_name: [*:0]const u8, p_count: c_int, p_transpose: c_int, p_value: *const f32) void;
    pub const setUniformMatrix2x3fv = gst_gl_shader_set_uniform_matrix_2x3fv;

    /// Perform ``glUniformMatrix2x4fv`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_matrix_2x4fv(p_shader: *GLShader, p_name: [*:0]const u8, p_count: c_int, p_transpose: c_int, p_value: *const f32) void;
    pub const setUniformMatrix2x4fv = gst_gl_shader_set_uniform_matrix_2x4fv;

    /// Perform ``glUniformMatrix3fv`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_matrix_3fv(p_shader: *GLShader, p_name: [*:0]const u8, p_count: c_int, p_transpose: c_int, p_value: *const f32) void;
    pub const setUniformMatrix3fv = gst_gl_shader_set_uniform_matrix_3fv;

    /// Perform ``glUniformMatrix3x2fv`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_matrix_3x2fv(p_shader: *GLShader, p_name: [*:0]const u8, p_count: c_int, p_transpose: c_int, p_value: *const f32) void;
    pub const setUniformMatrix3x2fv = gst_gl_shader_set_uniform_matrix_3x2fv;

    /// Perform ``glUniformMatrix3x4fv`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_matrix_3x4fv(p_shader: *GLShader, p_name: [*:0]const u8, p_count: c_int, p_transpose: c_int, p_value: *const f32) void;
    pub const setUniformMatrix3x4fv = gst_gl_shader_set_uniform_matrix_3x4fv;

    /// Perform ``glUniformMatrix4fv`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_matrix_4fv(p_shader: *GLShader, p_name: [*:0]const u8, p_count: c_int, p_transpose: c_int, p_value: *const f32) void;
    pub const setUniformMatrix4fv = gst_gl_shader_set_uniform_matrix_4fv;

    /// Perform ``glUniformMatrix4x2fv`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_matrix_4x2fv(p_shader: *GLShader, p_name: [*:0]const u8, p_count: c_int, p_transpose: c_int, p_value: *const f32) void;
    pub const setUniformMatrix4x2fv = gst_gl_shader_set_uniform_matrix_4x2fv;

    /// Perform ``glUniformMatrix4x3fv`` for `name` on `shader`
    extern fn gst_gl_shader_set_uniform_matrix_4x3fv(p_shader: *GLShader, p_name: [*:0]const u8, p_count: c_int, p_transpose: c_int, p_value: *const f32) void;
    pub const setUniformMatrix4x3fv = gst_gl_shader_set_uniform_matrix_4x3fv;

    /// Mark's `shader` as being used for the next GL draw command.
    ///
    /// Note: must be called in the GL thread and `shader` must have been linked.
    extern fn gst_gl_shader_use(p_shader: *GLShader) void;
    pub const use = gst_gl_shader_use;

    extern fn gst_gl_shader_get_type() usize;
    pub const getGObjectType = gst_gl_shader_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLShader) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLShader) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLShader, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gstgl.GLUpload` is an object that uploads data from system memory into GL textures.
///
/// A `gstgl.GLUpload` can be created with `gstgl.GLUpload.new`
pub const GLUpload = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLUploadClass;
    f_parent: gst.Object,
    f_context: ?*gstgl.GLContext,
    f_priv: ?*gstgl.GLUploadPrivate,
    f__reserved: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_gl_upload_get_input_template_caps() *gst.Caps;
    pub const getInputTemplateCaps = gst_gl_upload_get_input_template_caps;

    extern fn gst_gl_upload_new(p_context: *gstgl.GLContext) *gstgl.GLUpload;
    pub const new = gst_gl_upload_new;

    /// Fixate the `othercaps` based on the information of the `caps`.
    extern fn gst_gl_upload_fixate_caps(p_upload: *GLUpload, p_direction: gst.PadDirection, p_caps: *gst.Caps, p_othercaps: *gst.Caps) *gst.Caps;
    pub const fixateCaps = gst_gl_upload_fixate_caps;

    extern fn gst_gl_upload_get_caps(p_upload: *GLUpload, p_in_caps: ?**gst.Caps, p_out_caps: ?**gst.Caps) void;
    pub const getCaps = gst_gl_upload_get_caps;

    /// Uploads `buffer` using the transformation specified by
    /// `gstgl.GLUpload.setCaps` creating a new `gst.Buffer` in `outbuf_ptr`.
    extern fn gst_gl_upload_perform_with_buffer(p_upload: *GLUpload, p_buffer: *gst.Buffer, p_outbuf_ptr: **gst.Buffer) gstgl.GLUploadReturn;
    pub const performWithBuffer = gst_gl_upload_perform_with_buffer;

    /// Adds the required allocation parameters to support uploading.
    extern fn gst_gl_upload_propose_allocation(p_upload: *GLUpload, p_decide_query: ?*gst.Query, p_query: *gst.Query) void;
    pub const proposeAllocation = gst_gl_upload_propose_allocation;

    /// Initializes `upload` with the information required for upload.
    extern fn gst_gl_upload_set_caps(p_upload: *GLUpload, p_in_caps: *gst.Caps, p_out_caps: *gst.Caps) c_int;
    pub const setCaps = gst_gl_upload_set_caps;

    extern fn gst_gl_upload_set_context(p_upload: *GLUpload, p_context: *gstgl.GLContext) void;
    pub const setContext = gst_gl_upload_set_context;

    extern fn gst_gl_upload_transform_caps(p_upload: *GLUpload, p_context: *gstgl.GLContext, p_direction: gst.PadDirection, p_caps: *gst.Caps, p_filter: *gst.Caps) *gst.Caps;
    pub const transformCaps = gst_gl_upload_transform_caps;

    extern fn gst_gl_upload_get_type() usize;
    pub const getGObjectType = gst_gl_upload_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLUpload) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLUpload) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLUpload, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Convert stereoscopic/multiview video using fragment shaders.
pub const GLViewConvert = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLViewConvertClass;
    f_object: gst.Object,
    f_context: ?*gstgl.GLContext,
    f_shader: ?*gstgl.GLShader,
    f_input_mode_override: gstvideo.VideoMultiviewMode,
    f_input_flags_override: gstvideo.VideoMultiviewFlags,
    f_output_mode_override: gstvideo.VideoMultiviewMode,
    f_output_flags_override: gstvideo.VideoMultiviewFlags,
    f_downmix_mode: gstgl.GLStereoDownmix,
    f_in_info: gstvideo.VideoInfo,
    f_out_info: gstvideo.VideoInfo,
    f_from_texture_target: gstgl.GLTextureTarget,
    f_to_texture_target: gstgl.GLTextureTarget,
    f_caps_passthrough: c_int,
    f_initted: c_int,
    f_reconfigure: c_int,
    f_fbo: ?*gstgl.GLFramebuffer,
    f_priv: ?*gstgl.GLViewConvertPrivate,
    f__padding: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {
        pub const downmix_mode = struct {
            pub const name = "downmix-mode";

            pub const Type = gstgl.GLStereoDownmix;
        };

        pub const input_flags_override = struct {
            pub const name = "input-flags-override";

            pub const Type = gstvideo.VideoMultiviewFlags;
        };

        pub const input_mode_override = struct {
            pub const name = "input-mode-override";

            pub const Type = gstvideo.VideoMultiviewMode;
        };

        pub const output_flags_override = struct {
            pub const name = "output-flags-override";

            pub const Type = gstvideo.VideoMultiviewFlags;
        };

        pub const output_mode_override = struct {
            pub const name = "output-mode-override";

            pub const Type = gstvideo.VideoMultiviewMode;
        };
    };

    pub const signals = struct {};

    extern fn gst_gl_view_convert_new() *gstgl.GLViewConvert;
    pub const new = gst_gl_view_convert_new;

    /// Provides an implementation of `gstbase.BaseTransformClass.virtual_methods.fixate_caps`
    extern fn gst_gl_view_convert_fixate_caps(p_viewconvert: *GLViewConvert, p_direction: gst.PadDirection, p_caps: *gst.Caps, p_othercaps: *gst.Caps) *gst.Caps;
    pub const fixateCaps = gst_gl_view_convert_fixate_caps;

    /// Retrieve the processed output buffer placing the output in `outbuf_ptr`.
    extern fn gst_gl_view_convert_get_output(p_viewconvert: *GLViewConvert, p_outbuf_ptr: **gst.Buffer) gst.FlowReturn;
    pub const getOutput = gst_gl_view_convert_get_output;

    /// Converts the data contained by `inbuf` using the formats specified by the
    /// `gst.Caps` passed to `gstgl.GLViewConvert.setCaps`
    extern fn gst_gl_view_convert_perform(p_viewconvert: *GLViewConvert, p_inbuf: *gst.Buffer) ?*gst.Buffer;
    pub const perform = gst_gl_view_convert_perform;

    /// Reset `viewconvert` to the default state.  Further operation will require
    /// setting the caps with `gstgl.GLViewConvert.setCaps`.
    extern fn gst_gl_view_convert_reset(p_viewconvert: *GLViewConvert) void;
    pub const reset = gst_gl_view_convert_reset;

    /// Initializes `viewconvert` with the information required for conversion.
    extern fn gst_gl_view_convert_set_caps(p_viewconvert: *GLViewConvert, p_in_caps: *gst.Caps, p_out_caps: *gst.Caps) c_int;
    pub const setCaps = gst_gl_view_convert_set_caps;

    /// Set `context` on `viewconvert`
    extern fn gst_gl_view_convert_set_context(p_viewconvert: *GLViewConvert, p_context: *gstgl.GLContext) void;
    pub const setContext = gst_gl_view_convert_set_context;

    /// Submit `input` to be processed by `viewconvert`
    extern fn gst_gl_view_convert_submit_input_buffer(p_viewconvert: *GLViewConvert, p_is_discont: c_int, p_input: *gst.Buffer) gst.FlowReturn;
    pub const submitInputBuffer = gst_gl_view_convert_submit_input_buffer;

    /// Provides an implementation of `gstbase.BaseTransformClass.virtual_methods.transform_caps`
    extern fn gst_gl_view_convert_transform_caps(p_viewconvert: *GLViewConvert, p_direction: gst.PadDirection, p_caps: *gst.Caps, p_filter: *gst.Caps) *gst.Caps;
    pub const transformCaps = gst_gl_view_convert_transform_caps;

    extern fn gst_gl_view_convert_get_type() usize;
    pub const getGObjectType = gst_gl_view_convert_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLViewConvert) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLViewConvert) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLViewConvert, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GstGLWindow represents a window that elements can render into.  A window can
/// either be a user visible window (onscreen) or hidden (offscreen).
pub const GLWindow = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gstgl.GLWindowClass;
    f_parent: gst.Object,
    f_lock: glib.Mutex,
    f_display: ?*gstgl.GLDisplay,
    f_context_ref: gobject.WeakRef,
    f_is_drawing: c_int,
    f_draw: ?gstgl.GLWindowCB,
    f_draw_data: ?*anyopaque,
    f_draw_notify: ?glib.DestroyNotify,
    f_close: ?gstgl.GLWindowCB,
    f_close_data: ?*anyopaque,
    f_close_notify: ?glib.DestroyNotify,
    f_resize: ?gstgl.GLWindowResizeCB,
    f_resize_data: ?*anyopaque,
    f_resize_notify: ?glib.DestroyNotify,
    f_queue_resize: c_int,
    f_main_context: ?*glib.MainContext,
    f_priv: ?*gstgl.GLWindowPrivate,
    f__reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// close the connection to the display
        pub const close = struct {
            pub fn call(p_class: anytype, p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) void {
                return gobject.ext.as(GLWindow.Class, p_class).f_close.?(gobject.ext.as(GLWindow, p_window));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) void) void {
                gobject.ext.as(GLWindow.Class, p_class).f_close = @ptrCast(p_implementation);
            }
        };

        /// Checks if `window` controls the GL viewport.
        pub const controls_viewport = struct {
            pub fn call(p_class: anytype, p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(GLWindow.Class, p_class).f_controls_viewport.?(gobject.ext.as(GLWindow, p_window));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) c_int) void {
                gobject.ext.as(GLWindow.Class, p_class).f_controls_viewport = @ptrCast(p_implementation);
            }
        };

        /// Redraw the window contents.  Implementations should invoke the draw callback.
        pub const draw = struct {
            pub fn call(p_class: anytype, p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) void {
                return gobject.ext.as(GLWindow.Class, p_class).f_draw.?(gobject.ext.as(GLWindow, p_window));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) void) void {
                gobject.ext.as(GLWindow.Class, p_class).f_draw = @ptrCast(p_implementation);
            }
        };

        /// Gets the current windowing system display connection
        pub const get_display = struct {
            pub fn call(p_class: anytype, p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) usize {
                return gobject.ext.as(GLWindow.Class, p_class).f_get_display.?(gobject.ext.as(GLWindow, p_window));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) usize) void {
                gobject.ext.as(GLWindow.Class, p_class).f_get_display = @ptrCast(p_implementation);
            }
        };

        /// Gets the current window handle that this `gstgl.GLWindow` is
        ///                     rendering into.  This may return a different value to
        ///                     what is passed into `set_window_handle`
        pub const get_window_handle = struct {
            pub fn call(p_class: anytype, p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) usize {
                return gobject.ext.as(GLWindow.Class, p_class).f_get_window_handle.?(gobject.ext.as(GLWindow, p_window));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) usize) void {
                gobject.ext.as(GLWindow.Class, p_class).f_get_window_handle = @ptrCast(p_implementation);
            }
        };

        /// Tell a `window` that it should handle events from the window system. These
        /// events are forwarded upstream as navigation events. In some window systems
        /// events are not propagated in the window hierarchy if a client is listening
        /// for them. This method allows you to disable events handling completely
        /// from the `window`.
        pub const handle_events = struct {
            pub fn call(p_class: anytype, p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_handle_events: c_int) void {
                return gobject.ext.as(GLWindow.Class, p_class).f_handle_events.?(gobject.ext.as(GLWindow, p_window), p_handle_events);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_handle_events: c_int) callconv(.c) void) void {
                gobject.ext.as(GLWindow.Class, p_class).f_handle_events = @ptrCast(p_implementation);
            }
        };

        /// Query whether `window` has output surface or not
        pub const has_output_surface = struct {
            pub fn call(p_class: anytype, p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(GLWindow.Class, p_class).f_has_output_surface.?(gobject.ext.as(GLWindow, p_window));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) c_int) void {
                gobject.ext.as(GLWindow.Class, p_class).f_has_output_surface = @ptrCast(p_implementation);
            }
        };

        /// open the connection to the display
        pub const open = struct {
            pub fn call(p_class: anytype, p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_error: ?*?*glib.Error) c_int {
                return gobject.ext.as(GLWindow.Class, p_class).f_open.?(gobject.ext.as(GLWindow, p_window), p_error);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_error: ?*?*glib.Error) callconv(.c) c_int) void {
                gobject.ext.as(GLWindow.Class, p_class).f_open = @ptrCast(p_implementation);
            }
        };

        /// Queue resizing of `window`.
        pub const queue_resize = struct {
            pub fn call(p_class: anytype, p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) void {
                return gobject.ext.as(GLWindow.Class, p_class).f_queue_resize.?(gobject.ext.as(GLWindow, p_window));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) void) void {
                gobject.ext.as(GLWindow.Class, p_class).f_queue_resize = @ptrCast(p_implementation);
            }
        };

        /// Quit the runloop's execution.
        pub const quit = struct {
            pub fn call(p_class: anytype, p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) void {
                return gobject.ext.as(GLWindow.Class, p_class).f_quit.?(gobject.ext.as(GLWindow, p_window));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) void) void {
                gobject.ext.as(GLWindow.Class, p_class).f_quit = @ptrCast(p_implementation);
            }
        };

        /// Start the execution of the runloop.
        pub const run = struct {
            pub fn call(p_class: anytype, p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) void {
                return gobject.ext.as(GLWindow.Class, p_class).f_run.?(gobject.ext.as(GLWindow, p_window));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) void) void {
                gobject.ext.as(GLWindow.Class, p_class).f_run = @ptrCast(p_implementation);
            }
        };

        /// Invoke `callback` with data on the window thread.  `callback` is guaranteed to
        /// have executed when this function returns.
        pub const send_message = struct {
            pub fn call(p_class: anytype, p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_callback: gstgl.GLWindowCB, p_data: ?*anyopaque) void {
                return gobject.ext.as(GLWindow.Class, p_class).f_send_message.?(gobject.ext.as(GLWindow, p_window), p_callback, p_data);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_callback: gstgl.GLWindowCB, p_data: ?*anyopaque) callconv(.c) void) void {
                gobject.ext.as(GLWindow.Class, p_class).f_send_message = @ptrCast(p_implementation);
            }
        };

        /// Invoke `callback` with `data` on the window thread.  The callback may not
        /// have been executed when this function returns.
        pub const send_message_async = struct {
            pub fn call(p_class: anytype, p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_callback: gstgl.GLWindowCB, p_data: ?*anyopaque, p_destroy: ?glib.DestroyNotify) void {
                return gobject.ext.as(GLWindow.Class, p_class).f_send_message_async.?(gobject.ext.as(GLWindow, p_window), p_callback, p_data, p_destroy);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_callback: gstgl.GLWindowCB, p_data: ?*anyopaque, p_destroy: ?glib.DestroyNotify) callconv(.c) void) void {
                gobject.ext.as(GLWindow.Class, p_class).f_send_message_async = @ptrCast(p_implementation);
            }
        };

        /// Set the preferred width and height of the window.  Implementations are free
        /// to ignore this information.
        pub const set_preferred_size = struct {
            pub fn call(p_class: anytype, p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_width: c_int, p_height: c_int) void {
                return gobject.ext.as(GLWindow.Class, p_class).f_set_preferred_size.?(gobject.ext.as(GLWindow, p_window), p_width, p_height);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_width: c_int, p_height: c_int) callconv(.c) void) void {
                gobject.ext.as(GLWindow.Class, p_class).f_set_preferred_size = @ptrCast(p_implementation);
            }
        };

        /// Tell a `window` that it should render into a specific region of the window
        /// according to the `gstvideo.VideoOverlay` interface.
        pub const set_render_rectangle = struct {
            pub fn call(p_class: anytype, p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_x: c_int, p_y: c_int, p_width: c_int, p_height: c_int) c_int {
                return gobject.ext.as(GLWindow.Class, p_class).f_set_render_rectangle.?(gobject.ext.as(GLWindow, p_window), p_x, p_y, p_width, p_height);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_x: c_int, p_y: c_int, p_width: c_int, p_height: c_int) callconv(.c) c_int) void {
                gobject.ext.as(GLWindow.Class, p_class).f_set_render_rectangle = @ptrCast(p_implementation);
            }
        };

        /// Sets the window that this `window` should render into.  Some implementations
        /// require this to be called with a valid handle before drawing can commence.
        pub const set_window_handle = struct {
            pub fn call(p_class: anytype, p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_handle: usize) void {
                return gobject.ext.as(GLWindow.Class, p_class).f_set_window_handle.?(gobject.ext.as(GLWindow, p_window), p_handle);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_handle: usize) callconv(.c) void) void {
                gobject.ext.as(GLWindow.Class, p_class).f_set_window_handle = @ptrCast(p_implementation);
            }
        };

        /// Present the window to the screen.
        pub const show = struct {
            pub fn call(p_class: anytype, p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) void {
                return gobject.ext.as(GLWindow.Class, p_class).f_show.?(gobject.ext.as(GLWindow, p_window));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_window: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) void) void {
                gobject.ext.as(GLWindow.Class, p_class).f_show = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {
        /// Will be emitted when a key event is received by the GstGLwindow.
        pub const key_event = struct {
            pub const name = "key-event";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_id: [*:0]u8, p_key: [*:0]u8, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(GLWindow, p_instance))),
                    gobject.signalLookup("key-event", GLWindow.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };

        /// Will be emitted when a mouse event is received by the GstGLwindow.
        pub const mouse_event = struct {
            pub const name = "mouse-event";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_id: [*:0]u8, p_button: c_int, p_x: f64, p_y: f64, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(GLWindow, p_instance))),
                    gobject.signalLookup("mouse-event", GLWindow.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };

        /// Will be emitted when a mouse scroll event is received by the GstGLwindow.
        pub const scroll_event = struct {
            pub const name = "scroll-event";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_x: f64, p_y: f64, p_delta_x: f64, p_delta_y: f64, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(GLWindow, p_instance))),
                    gobject.signalLookup("scroll-event", GLWindow.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };

        /// Will be emitted when the window handle has been set into the native
        /// implementation, but before the context is re-activated. By using this
        /// signal, elements can refresh associated resource without relying on
        /// direct handle comparision.
        pub const window_handle_changed = struct {
            pub const name = "window-handle-changed";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(GLWindow, p_instance))),
                    gobject.signalLookup("window-handle-changed", GLWindow.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    extern fn gst_gl_window_new(p_display: *gstgl.GLDisplay) *gstgl.GLWindow;
    pub const new = gst_gl_window_new;

    /// Checks if `window` controls the GL viewport.
    extern fn gst_gl_window_controls_viewport(p_window: *GLWindow) c_int;
    pub const controlsViewport = gst_gl_window_controls_viewport;

    /// Redraw the window contents.  Implementations should invoke the draw callback.
    extern fn gst_gl_window_draw(p_window: *GLWindow) void;
    pub const draw = gst_gl_window_draw;

    extern fn gst_gl_window_get_context(p_window: *GLWindow) *gstgl.GLContext;
    pub const getContext = gst_gl_window_get_context;

    extern fn gst_gl_window_get_display(p_window: *GLWindow) usize;
    pub const getDisplay = gst_gl_window_get_display;

    extern fn gst_gl_window_get_surface_dimensions(p_window: *GLWindow, p_width: *c_uint, p_height: *c_uint) void;
    pub const getSurfaceDimensions = gst_gl_window_get_surface_dimensions;

    extern fn gst_gl_window_get_window_handle(p_window: *GLWindow) usize;
    pub const getWindowHandle = gst_gl_window_get_window_handle;

    /// Tell a `window` that it should handle events from the window system. These
    /// events are forwarded upstream as navigation events. In some window systems
    /// events are not propagated in the window hierarchy if a client is listening
    /// for them. This method allows you to disable events handling completely
    /// from the `window`.
    extern fn gst_gl_window_handle_events(p_window: *GLWindow, p_handle_events: c_int) void;
    pub const handleEvents = gst_gl_window_handle_events;

    /// Query whether `window` has output surface or not
    extern fn gst_gl_window_has_output_surface(p_window: *GLWindow) c_int;
    pub const hasOutputSurface = gst_gl_window_has_output_surface;

    /// Queue resizing of `window`.
    extern fn gst_gl_window_queue_resize(p_window: *GLWindow) void;
    pub const queueResize = gst_gl_window_queue_resize;

    /// Quit the runloop's execution.
    extern fn gst_gl_window_quit(p_window: *GLWindow) void;
    pub const quit = gst_gl_window_quit;

    /// Resize `window` to the given `width` and `height`.
    extern fn gst_gl_window_resize(p_window: *GLWindow, p_width: c_uint, p_height: c_uint) void;
    pub const resize = gst_gl_window_resize;

    /// Start the execution of the runloop.
    extern fn gst_gl_window_run(p_window: *GLWindow) void;
    pub const run = gst_gl_window_run;

    extern fn gst_gl_window_send_key_event(p_window: *GLWindow, p_event_type: [*:0]const u8, p_key_str: [*:0]const u8) void;
    pub const sendKeyEvent = gst_gl_window_send_key_event;

    /// Invoke `callback` with data on the window thread.  `callback` is guaranteed to
    /// have executed when this function returns.
    extern fn gst_gl_window_send_message(p_window: *GLWindow, p_callback: gstgl.GLWindowCB, p_data: ?*anyopaque) void;
    pub const sendMessage = gst_gl_window_send_message;

    /// Invoke `callback` with `data` on the window thread.  The callback may not
    /// have been executed when this function returns.
    extern fn gst_gl_window_send_message_async(p_window: *GLWindow, p_callback: gstgl.GLWindowCB, p_data: ?*anyopaque, p_destroy: ?glib.DestroyNotify) void;
    pub const sendMessageAsync = gst_gl_window_send_message_async;

    extern fn gst_gl_window_send_mouse_event(p_window: *GLWindow, p_event_type: [*:0]const u8, p_button: c_int, p_posx: f64, p_posy: f64) void;
    pub const sendMouseEvent = gst_gl_window_send_mouse_event;

    /// Notify a `window` about a scroll event. A scroll signal holding the event
    /// coordinates will be emitted.
    extern fn gst_gl_window_send_scroll_event(p_window: *GLWindow, p_posx: f64, p_posy: f64, p_delta_x: f64, p_delta_y: f64) void;
    pub const sendScrollEvent = gst_gl_window_send_scroll_event;

    /// Sets the callback called when the window is about to close.
    extern fn gst_gl_window_set_close_callback(p_window: *GLWindow, p_callback: gstgl.GLWindowCB, p_data: ?*anyopaque, p_destroy_notify: ?glib.DestroyNotify) void;
    pub const setCloseCallback = gst_gl_window_set_close_callback;

    /// Sets the draw callback called every time `gstgl.GLWindow.draw` is called
    extern fn gst_gl_window_set_draw_callback(p_window: *GLWindow, p_callback: gstgl.GLWindowCB, p_data: ?*anyopaque, p_destroy_notify: ?glib.DestroyNotify) void;
    pub const setDrawCallback = gst_gl_window_set_draw_callback;

    /// Set the preferred width and height of the window.  Implementations are free
    /// to ignore this information.
    extern fn gst_gl_window_set_preferred_size(p_window: *GLWindow, p_width: c_int, p_height: c_int) void;
    pub const setPreferredSize = gst_gl_window_set_preferred_size;

    /// Tell a `window` that it should render into a specific region of the window
    /// according to the `gstvideo.VideoOverlay` interface.
    extern fn gst_gl_window_set_render_rectangle(p_window: *GLWindow, p_x: c_int, p_y: c_int, p_width: c_int, p_height: c_int) c_int;
    pub const setRenderRectangle = gst_gl_window_set_render_rectangle;

    /// Sets the resize callback called every time a resize of the window occurs.
    extern fn gst_gl_window_set_resize_callback(p_window: *GLWindow, p_callback: gstgl.GLWindowResizeCB, p_data: ?*anyopaque, p_destroy_notify: ?glib.DestroyNotify) void;
    pub const setResizeCallback = gst_gl_window_set_resize_callback;

    /// Sets the window that this `window` should render into.  Some implementations
    /// require this to be called with a valid handle before drawing can commence.
    extern fn gst_gl_window_set_window_handle(p_window: *GLWindow, p_handle: usize) void;
    pub const setWindowHandle = gst_gl_window_set_window_handle;

    /// Present the window to the screen.
    extern fn gst_gl_window_show(p_window: *GLWindow) void;
    pub const show = gst_gl_window_show;

    extern fn gst_gl_window_get_type() usize;
    pub const getGObjectType = gst_gl_window_get_type;

    extern fn g_object_ref(p_self: *gstgl.GLWindow) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstgl.GLWindow) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GLWindow, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLAllocationParams = extern struct {
    /// the size of the struct (including and subclass data)
    f_struct_size: usize,
    /// a `gstgl.GLAllocationParamsCopyFunc`
    f_copy: ?gstgl.GLAllocationParamsCopyFunc,
    /// a `gstgl.GLAllocationParamsFreeFunc`
    f_free: ?gstgl.GLAllocationParamsFreeFunc,
    /// allocation flags
    f_alloc_flags: c_uint,
    /// the allocation size
    f_alloc_size: usize,
    /// the `gst.AllocationParams`
    f_alloc_params: ?*gst.AllocationParams,
    /// a `gstgl.GLContext`
    f_context: ?*gstgl.GLContext,
    /// a `glib.DestroyNotify`
    f_notify: ?glib.DestroyNotify,
    /// argument to call `notify` with
    f_user_data: ?*anyopaque,
    /// the wrapped data pointer
    f_wrapped_data: ?*anyopaque,
    /// the wrapped OpenGL handle
    f_gl_handle: ?*anyopaque,
    f__padding: [4]*anyopaque,

    extern fn gst_gl_allocation_params_copy(p_src: *GLAllocationParams) *gstgl.GLAllocationParams;
    pub const copy = gst_gl_allocation_params_copy;

    /// Copies the dynamically allocated data from `src` to `dest`.  Direct subclasses
    /// should call this function in their own overridden copy function.
    extern fn gst_gl_allocation_params_copy_data(p_src: *GLAllocationParams, p_dest: *gstgl.GLAllocationParams) void;
    pub const copyData = gst_gl_allocation_params_copy_data;

    /// Frees the `gstgl.GLAllocationParams` and all associated data.
    extern fn gst_gl_allocation_params_free(p_params: *GLAllocationParams) void;
    pub const free = gst_gl_allocation_params_free;

    /// Frees the dynamically allocated data in `params`.  Direct subclasses
    /// should call this function in their own overridden free function.
    extern fn gst_gl_allocation_params_free_data(p_params: *GLAllocationParams) void;
    pub const freeData = gst_gl_allocation_params_free_data;

    /// `notify` will be called once for each allocated memory using these `params`
    /// when freeing the memory.
    extern fn gst_gl_allocation_params_init(p_params: *GLAllocationParams, p_struct_size: usize, p_alloc_flags: c_uint, p_copy: gstgl.GLAllocationParamsCopyFunc, p_free: gstgl.GLAllocationParamsFreeFunc, p_context: *gstgl.GLContext, p_alloc_size: usize, p_alloc_params: ?*const gst.AllocationParams, p_wrapped_data: ?*anyopaque, p_gl_handle: ?*anyopaque, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) c_int;
    pub const init = gst_gl_allocation_params_init;

    extern fn gst_gl_allocation_params_get_type() usize;
    pub const getGObjectType = gst_gl_allocation_params_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gstgl.GLAsyncDebug` an opaque structure and should only be accessed through the
/// provided API.
pub const GLAsyncDebug = extern struct {
    f_state_flags: c_uint,
    f_cat: ?*gst.DebugCategory,
    f_level: gst.DebugLevel,
    f_file: ?[*:0]const u8,
    f_function: ?[*:0]const u8,
    f_line: c_int,
    f_object: ?*gobject.Object,
    f_debug_msg: ?[*:0]u8,
    f_callback: ?gstgl.GLAsyncDebugLogGetMessage,
    f_user_data: ?*anyopaque,
    f_notify: ?glib.DestroyNotify,
    f__padding: [4]*anyopaque,

    /// Free with `gstgl.GLAsyncDebug.free`
    extern fn gst_gl_async_debug_new() *gstgl.GLAsyncDebug;
    pub const new = gst_gl_async_debug_new;

    /// Frees `ad`
    extern fn gst_gl_async_debug_free(p_ad: *GLAsyncDebug) void;
    pub const free = gst_gl_async_debug_free;

    /// freeze the debug output.  While frozen, any call to
    /// `gstgl.GLAsyncDebug.outputLogMsg` will not output any messages but
    /// subsequent calls to `gstgl.GLAsyncDebug.storeLogMsg` will overwrite previous
    /// messages.
    extern fn gst_gl_async_debug_freeze(p_ad: *GLAsyncDebug) void;
    pub const freeze = gst_gl_async_debug_freeze;

    /// Initialize `ad`.  Intended for use with `gstgl.GLAsyncDebug`'s that are embedded
    /// in other structs.
    extern fn gst_gl_async_debug_init(p_ad: *GLAsyncDebug) void;
    pub const init = gst_gl_async_debug_init;

    /// Outputs a previously stored debug message.
    extern fn gst_gl_async_debug_output_log_msg(p_ad: *GLAsyncDebug) void;
    pub const outputLogMsg = gst_gl_async_debug_output_log_msg;

    /// Stores a debug message for later output by `gstgl.GLAsyncDebug.outputLogMsg`
    extern fn gst_gl_async_debug_store_log_msg(p_ad: *GLAsyncDebug, p_cat: *gst.DebugCategory, p_level: gst.DebugLevel, p_file: [*:0]const u8, p_function: [*:0]const u8, p_line: c_int, p_object: ?*gobject.Object, p_format: [*:0]const u8, ...) void;
    pub const storeLogMsg = gst_gl_async_debug_store_log_msg;

    /// Stores a debug message for later output by `gstgl.GLAsyncDebug.outputLogMsg`
    extern fn gst_gl_async_debug_store_log_msg_valist(p_ad: *GLAsyncDebug, p_cat: *gst.DebugCategory, p_level: gst.DebugLevel, p_file: [*:0]const u8, p_function: [*:0]const u8, p_line: c_int, p_object: ?*gobject.Object, p_format: [*:0]const u8, p_varargs: std.builtin.VaList) void;
    pub const storeLogMsgValist = gst_gl_async_debug_store_log_msg_valist;

    /// unfreeze the debug output.  See `gstgl.GLAsyncDebug.freeze` for what freezing means
    extern fn gst_gl_async_debug_thaw(p_ad: *GLAsyncDebug) void;
    pub const thaw = gst_gl_async_debug_thaw;

    /// Unset any dynamically allocated data.  Intended for use with
    /// `gstgl.GLAsyncDebug`'s that are embedded in other structs.
    extern fn gst_gl_async_debug_unset(p_ad: *GLAsyncDebug) void;
    pub const unset = gst_gl_async_debug_unset;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The base class for GStreamer GL Filter.
pub const GLBaseFilterClass = extern struct {
    pub const Instance = gstgl.GLBaseFilter;

    f_parent_class: gstbase.BaseTransformClass,
    /// the logical-OR of `gstgl.GLAPI`'s supported by this element
    f_supported_gl_api: gstgl.GLAPI,
    /// called in the GL thread to setup the element GL state.
    f_gl_start: ?*const fn (p_filter: *gstgl.GLBaseFilter) callconv(.c) c_int,
    /// called in the GL thread to setup the element GL state.
    f_gl_stop: ?*const fn (p_filter: *gstgl.GLBaseFilter) callconv(.c) void,
    /// called in the GL thread when caps are set on `filter`.
    ///               Note: this will also be called when changing OpenGL contexts
    ///               where `gstbase.BaseTransform.signals.set_caps` may not.
    f_gl_set_caps: ?*const fn (p_filter: *gstgl.GLBaseFilter, p_incaps: *gst.Caps, p_outcaps: *gst.Caps) callconv(.c) c_int,
    f__padding: [4]*anyopaque,

    pub fn as(p_instance: *GLBaseFilterClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLBaseFilterPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GstGLBaseMemory is a `gst.Memory` subclass providing the basis of support
/// for the mapping of GL buffers.
///
/// Data is uploaded or downloaded from the GPU as is necessary.
pub const GLBaseMemory = extern struct {
    /// the parent object
    f_mem: gst.Memory,
    /// the `gstgl.GLContext` to use for GL operations
    f_context: ?*gstgl.GLContext,
    f_lock: glib.Mutex,
    f_map_flags: gst.MapFlags,
    f_map_count: c_int,
    f_gl_map_count: c_int,
    f_data: ?*anyopaque,
    f_query: ?*gstgl.GLQuery,
    f_alloc_size: usize,
    f_alloc_data: ?*anyopaque,
    f_notify: ?glib.DestroyNotify,
    f_user_data: ?*anyopaque,
    f__padding: [4]*anyopaque,

    extern fn gst_gl_base_memory_alloc(p_allocator: *gstgl.GLBaseMemoryAllocator, p_params: *gstgl.GLAllocationParams) ?*gstgl.GLBaseMemory;
    pub const alloc = gst_gl_base_memory_alloc;

    /// Initializes the GL Base Memory allocator. It is safe to call this function
    /// multiple times.  This must be called before any other GstGLBaseMemory operation.
    extern fn gst_gl_base_memory_init_once() void;
    pub const initOnce = gst_gl_base_memory_init_once;

    /// Note: only intended for subclass usage to allocate the system memory buffer
    /// on demand.  If there is already a non-NULL data pointer in `gl_mem`->data,
    /// then this function imply returns TRUE.
    extern fn gst_gl_base_memory_alloc_data(p_gl_mem: *GLBaseMemory) c_int;
    pub const allocData = gst_gl_base_memory_alloc_data;

    /// Initializes `mem` with the required parameters
    extern fn gst_gl_base_memory_init(p_mem: *GLBaseMemory, p_allocator: *gst.Allocator, p_parent: ?*gst.Memory, p_context: *gstgl.GLContext, p_params: ?*const gst.AllocationParams, p_size: usize, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) void;
    pub const init = gst_gl_base_memory_init;

    extern fn gst_gl_base_memory_memcpy(p_src: *GLBaseMemory, p_dest: *gstgl.GLBaseMemory, p_offset: isize, p_size: isize) c_int;
    pub const memcpy = gst_gl_base_memory_memcpy;

    extern fn gst_gl_base_memory_get_type() usize;
    pub const getGObjectType = gst_gl_base_memory_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLBaseMemoryAllocatorClass = extern struct {
    pub const Instance = gstgl.GLBaseMemoryAllocator;

    /// the parent class
    f_parent_class: gst.AllocatorClass,
    /// a `gstgl.GLBaseMemoryAllocatorAllocFunction`
    f_alloc: ?gstgl.GLBaseMemoryAllocatorAllocFunction,
    /// a `gstgl.GLBaseMemoryAllocatorCreateFunction`
    f_create: ?gstgl.GLBaseMemoryAllocatorCreateFunction,
    /// a `gstgl.GLBaseMemoryAllocatorMapFunction`
    f_map: ?gstgl.GLBaseMemoryAllocatorMapFunction,
    /// a `gstgl.GLBaseMemoryAllocatorUnmapFunction`
    f_unmap: ?gstgl.GLBaseMemoryAllocatorUnmapFunction,
    /// a `gstgl.GLBaseMemoryAllocatorCopyFunction`
    f_copy: ?gstgl.GLBaseMemoryAllocatorCopyFunction,
    /// a `gstgl.GLBaseMemoryAllocatorDestroyFunction`
    f_destroy: ?gstgl.GLBaseMemoryAllocatorDestroyFunction,
    f__padding: [4]*anyopaque,

    pub fn as(p_instance: *GLBaseMemoryAllocatorClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLBaseMixerClass = extern struct {
    pub const Instance = gstgl.GLBaseMixer;

    /// the parent `gstvideo.VideoAggregatorClass`
    f_parent_class: gstvideo.VideoAggregatorClass,
    /// the logical-OR of `gstgl.GLAPI`'s supported by this element
    f_supported_gl_api: gstgl.GLAPI,
    f_gl_start: ?*const fn (p_mix: *gstgl.GLBaseMixer) callconv(.c) c_int,
    f_gl_stop: ?*const fn (p_mix: *gstgl.GLBaseMixer) callconv(.c) void,
    f__padding: [4]*anyopaque,

    pub fn as(p_instance: *GLBaseMixerClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLBaseMixerPadClass = extern struct {
    pub const Instance = gstgl.GLBaseMixerPad;

    /// parent `gstvideo.VideoAggregatorPadClass`
    f_parent_class: gstvideo.VideoAggregatorPadClass,
    f__padding: [4]*anyopaque,

    pub fn as(p_instance: *GLBaseMixerPadClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLBaseMixerPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The base class for GStreamer GL Video sources.
pub const GLBaseSrcClass = extern struct {
    pub const Instance = gstgl.GLBaseSrc;

    f_parent_class: gstbase.PushSrcClass,
    /// the logical-OR of `gstgl.GLAPI`'s supported by this element
    f_supported_gl_api: gstgl.GLAPI,
    /// called in the GL thread to setup the element GL state.
    f_gl_start: ?*const fn (p_src: *gstgl.GLBaseSrc) callconv(.c) c_int,
    /// called in the GL thread to setup the element GL state.
    f_gl_stop: ?*const fn (p_src: *gstgl.GLBaseSrc) callconv(.c) void,
    /// called in the GL thread to fill the current video texture.
    f_fill_gl_memory: ?*const fn (p_src: *gstgl.GLBaseSrc, p_mem: *gstgl.GLMemory) callconv(.c) c_int,
    f__padding: [4]*anyopaque,

    pub fn as(p_instance: *GLBaseSrcClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLBaseSrcPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GstGLBuffer is a `gst.Memory` subclass providing support for the mapping of
/// GL buffers.
///
/// Data is uploaded or downloaded from the GPU as is necessary.
pub const GLBuffer = extern struct {
    /// the parent object
    f_mem: gstgl.GLBaseMemory,
    /// the buffer id for this memory
    f_id: c_uint,
    /// the OpenGL target of this texture for binding purposes
    f_target: c_uint,
    /// the OpenGL usage hints this buffer was created with
    f_usage_hints: c_uint,

    /// Initializes the GL Buffer allocator. It is safe to call this function
    /// multiple times.  This must be called before any other `gstgl.GLBuffer` operation.
    extern fn gst_gl_buffer_init_once() void;
    pub const initOnce = gst_gl_buffer_init_once;

    extern fn gst_gl_buffer_get_type() usize;
    pub const getGObjectType = gst_gl_buffer_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLBufferAllocationParams = extern struct {
    /// parent object
    f_parent: gstgl.GLAllocationParams,
    /// the OpenGL target to bind the buffer to
    f_gl_target: c_uint,
    /// the OpenGL usage hint to create the buffer with
    f_gl_usage: c_uint,
    f__padding: [4]*anyopaque,

    extern fn gst_gl_buffer_allocation_params_new(p_context: *gstgl.GLContext, p_alloc_size: usize, p_alloc_params: ?*const gst.AllocationParams, p_gl_target: c_uint, p_gl_usage: c_uint) *gstgl.GLBufferAllocationParams;
    pub const new = gst_gl_buffer_allocation_params_new;

    extern fn gst_gl_buffer_allocation_params_get_type() usize;
    pub const getGObjectType = gst_gl_buffer_allocation_params_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The `gstgl.GLBufferAllocatorClass` only contains private data
pub const GLBufferAllocatorClass = extern struct {
    pub const Instance = gstgl.GLBufferAllocator;

    f_parent_class: gstgl.GLBaseMemoryAllocatorClass,
    f__padding: [4]*anyopaque,

    pub fn as(p_instance: *GLBufferAllocatorClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The `gstgl.GLBufferPoolClass` structure contains only private data
pub const GLBufferPoolClass = extern struct {
    pub const Instance = gstgl.GLBufferPool;

    f_parent_class: gst.BufferPoolClass,
    f__padding: [4]*anyopaque,

    pub fn as(p_instance: *GLBufferPoolClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLBufferPoolPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The `gstgl.GLColorConvertClass` struct only contains private data
pub const GLColorConvertClass = extern struct {
    pub const Instance = gstgl.GLColorConvert;

    f_object_class: gst.ObjectClass,
    f__padding: [4]*anyopaque,

    pub fn as(p_instance: *GLColorConvertClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLColorConvertPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLContextClass = extern struct {
    pub const Instance = gstgl.GLContext;

    f_parent_class: gst.ObjectClass,
    f_get_current_context: ?*const fn () callconv(.c) usize,
    /// get the backing platform specific OpenGL context
    f_get_gl_context: ?*const fn (p_context: *gstgl.GLContext) callconv(.c) usize,
    /// get the available OpenGL api's that this context can work with
    f_get_gl_api: ?*const fn (p_context: *gstgl.GLContext) callconv(.c) gstgl.GLAPI,
    f_get_gl_platform: ?*const fn (p_context: *gstgl.GLContext) callconv(.c) gstgl.GLPlatform,
    /// get an function pointer to an OpenGL function
    f_get_proc_address: ?*const fn (p_gl_api: gstgl.GLAPI, p_name: [*:0]const u8) callconv(.c) *anyopaque,
    /// call eglMakeCurrent or similar
    f_activate: ?*const fn (p_context: *gstgl.GLContext, p_activate: c_int) callconv(.c) c_int,
    /// choose a format for the framebuffer
    f_choose_format: ?*const fn (p_context: *gstgl.GLContext, p_error: ?*?*glib.Error) callconv(.c) c_int,
    /// create the OpenGL context
    f_create_context: ?*const fn (p_context: *gstgl.GLContext, p_gl_api: gstgl.GLAPI, p_other_context: *gstgl.GLContext, p_error: ?*?*glib.Error) callconv(.c) c_int,
    /// destroy the OpenGL context
    f_destroy_context: ?*const fn (p_context: *gstgl.GLContext) callconv(.c) void,
    /// swap the default framebuffer's front/back buffers
    f_swap_buffers: ?*const fn (p_context: *gstgl.GLContext) callconv(.c) void,
    f_check_feature: ?*const fn (p_context: *gstgl.GLContext, p_feature: [*:0]const u8) callconv(.c) c_int,
    f_get_gl_platform_version: ?*const fn (p_context: *gstgl.GLContext, p_major: *c_int, p_minor: *c_int) callconv(.c) void,
    f_get_config: ?*const fn (p_context: *gstgl.GLContext) callconv(.c) ?*gst.Structure,
    f_request_config: ?*const fn (p_context: *gstgl.GLContext, p_gl_config: ?*gst.Structure) callconv(.c) c_int,
    f__reserved: [2]*anyopaque,

    pub fn as(p_instance: *GLContextClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLContextPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLDisplayClass = extern struct {
    pub const Instance = gstgl.GLDisplay;

    f_object_class: gst.ObjectClass,
    f_get_handle: ?*const fn (p_display: *gstgl.GLDisplay) callconv(.c) usize,
    f_create_window: ?*const fn (p_display: *gstgl.GLDisplay) callconv(.c) ?*gstgl.GLWindow,
    f__padding: [4]*anyopaque,

    pub fn as(p_instance: *GLDisplayClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLDisplayPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLFilterClass = extern struct {
    pub const Instance = gstgl.GLFilter;

    f_parent_class: gstgl.GLBaseFilterClass,
    /// mirror from `gstbase.BaseTransform`
    f_set_caps: ?*const fn (p_filter: *gstgl.GLFilter, p_incaps: *gst.Caps, p_outcaps: *gst.Caps) callconv(.c) c_int,
    /// perform operations on the input and output buffers.  In general,
    ///          you should avoid using this method if at all possible. One valid
    ///          use-case for using this is keeping previous buffers for future calculations.
    ///          Note: If `filter` exists, then `filter_texture` is not run
    f_filter: ?*const fn (p_filter: *gstgl.GLFilter, p_inbuf: *gst.Buffer, p_outbuf: *gst.Buffer) callconv(.c) c_int,
    /// given `in_tex`, transform it into `out_tex`.  Not used
    ///                  if `filter` exists
    f_filter_texture: ?*const fn (p_filter: *gstgl.GLFilter, p_input: *gstgl.GLMemory, p_output: *gstgl.GLMemory) callconv(.c) c_int,
    /// perform initialization when the Framebuffer object is created
    f_init_fbo: ?*const fn (p_filter: *gstgl.GLFilter) callconv(.c) c_int,
    /// Perform sub-class specific modifications of the
    ///   caps to be processed between upload on input and before download for output.
    f_transform_internal_caps: ?*const fn (p_filter: *gstgl.GLFilter, p_direction: gst.PadDirection, p_caps: *gst.Caps, p_filter_caps: *gst.Caps) callconv(.c) *gst.Caps,
    f__padding: [4]*anyopaque,

    pub fn as(p_instance: *GLFilterClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Opaque `gstgl.GLFramebufferClass` struct
pub const GLFramebufferClass = extern struct {
    pub const Instance = gstgl.GLFramebuffer;

    f_object_class: gst.ObjectClass,
    f__padding: [4]*anyopaque,

    pub fn as(p_instance: *GLFramebufferClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLFramebufferPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Structure containing function pointers to OpenGL functions.
///
/// Each field is named exactly the same as the OpenGL function without the
/// `gl` prefix.
pub const GLFuncs = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GstGLMemory is a `gstgl.GLBaseMemory` subclass providing support for the mapping of
/// OpenGL textures.
///
/// `gstgl.GLMemory` is created or wrapped through `gstgl.glBaseMemoryAlloc`
/// with `gstgl.GLVideoAllocationParams`.
///
/// Data is uploaded or downloaded from the GPU as is necessary.
///
/// The `gst.Caps` that is used for `gstgl.GLMemory` based buffers should contain
/// the `GST_CAPS_FEATURE_MEMORY_GL_MEMORY` as a `gst.CapsFeatures` and should
/// contain a 'texture-target' field with one of the `gstgl.GLTextureTarget` values
/// as a string, i.e. some combination of 'texture-target=(string){2D,
/// rectangle, external-oes}'.
pub const GLMemory = extern struct {
    /// the parent `gstgl.GLBaseMemory` object
    f_mem: gstgl.GLBaseMemory,
    /// the GL texture id for this memory
    f_tex_id: c_uint,
    /// the GL texture target for this memory
    f_tex_target: gstgl.GLTextureTarget,
    /// the texture type
    f_tex_format: gstgl.GLFormat,
    /// the texture's `gstvideo.VideoInfo`
    f_info: gstvideo.VideoInfo,
    /// data alignment for system memory mapping
    f_valign: gstvideo.VideoAlignment,
    /// data plane in `info`
    f_plane: c_uint,
    /// GL shader scaling parameters for `valign` and/or width/height
    f_tex_scaling: [2]f32,
    f_texture_wrapped: c_int,
    f_unpack_length: c_uint,
    f_tex_width: c_uint,
    f__padding: [4]*anyopaque,

    /// Initializes the GL Base Texture allocator. It is safe to call this function
    /// multiple times.  This must be called before any other GstGLMemory operation.
    extern fn gst_gl_memory_init_once() void;
    pub const initOnce = gst_gl_memory_init_once;

    extern fn gst_gl_memory_setup_buffer(p_allocator: *gstgl.GLMemoryAllocator, p_buffer: *gst.Buffer, p_params: *gstgl.GLVideoAllocationParams, p_tex_formats: ?[*]gstgl.GLFormat, p_wrapped_data: [*]*anyopaque, p_n_wrapped_pointers: usize) c_int;
    pub const setupBuffer = gst_gl_memory_setup_buffer;

    /// Copies `gl_mem` into the texture specified by `tex_id`.  The format of `tex_id`
    /// is specified by `tex_format`, `width` and `height`.
    extern fn gst_gl_memory_copy_into(p_gl_mem: *GLMemory, p_tex_id: c_uint, p_target: gstgl.GLTextureTarget, p_tex_format: gstgl.GLFormat, p_width: c_int, p_height: c_int) c_int;
    pub const copyInto = gst_gl_memory_copy_into;

    /// Copies the texture in `gstgl.GLMemory` into the texture specified by `tex_id`,
    /// `out_target`, `out_tex_format`, `out_width` and `out_height`.
    extern fn gst_gl_memory_copy_teximage(p_src: *GLMemory, p_tex_id: c_uint, p_out_target: gstgl.GLTextureTarget, p_out_tex_format: gstgl.GLFormat, p_out_width: c_int, p_out_height: c_int) c_int;
    pub const copyTeximage = gst_gl_memory_copy_teximage;

    extern fn gst_gl_memory_get_texture_format(p_gl_mem: *GLMemory) gstgl.GLFormat;
    pub const getTextureFormat = gst_gl_memory_get_texture_format;

    extern fn gst_gl_memory_get_texture_height(p_gl_mem: *GLMemory) c_int;
    pub const getTextureHeight = gst_gl_memory_get_texture_height;

    extern fn gst_gl_memory_get_texture_id(p_gl_mem: *GLMemory) c_uint;
    pub const getTextureId = gst_gl_memory_get_texture_id;

    extern fn gst_gl_memory_get_texture_target(p_gl_mem: *GLMemory) gstgl.GLTextureTarget;
    pub const getTextureTarget = gst_gl_memory_get_texture_target;

    extern fn gst_gl_memory_get_texture_width(p_gl_mem: *GLMemory) c_int;
    pub const getTextureWidth = gst_gl_memory_get_texture_width;

    /// Initializes `mem` with the required parameters.  `info` is assumed to have
    /// already have been modified with `gstvideo.VideoInfo.@"align"`.
    extern fn gst_gl_memory_init(p_mem: *GLMemory, p_allocator: *gst.Allocator, p_parent: ?*gst.Memory, p_context: *gstgl.GLContext, p_target: gstgl.GLTextureTarget, p_tex_format: gstgl.GLFormat, p_params: ?*const gst.AllocationParams, p_info: *const gstvideo.VideoInfo, p_plane: c_uint, p_valign: ?*const gstvideo.VideoAlignment, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) void;
    pub const init = gst_gl_memory_init;

    /// Reads the texture in `gstgl.GLMemory` into `write_pointer` if no buffer is bound
    /// to `GL_PIXEL_PACK_BUFFER`.  Otherwise `write_pointer` is the byte offset into
    /// the currently bound `GL_PIXEL_PACK_BUFFER` buffer to store the result of
    /// glReadPixels.  See the OpenGL specification for glReadPixels for more
    /// details.
    extern fn gst_gl_memory_read_pixels(p_gl_mem: *GLMemory, p_write_pointer: ?*anyopaque) c_int;
    pub const readPixels = gst_gl_memory_read_pixels;

    /// Reads the texture in `read_pointer` into `gl_mem`.
    ///
    /// See `gstgl.GLMemory.readPixels` for what `read_pointer` signifies.
    extern fn gst_gl_memory_texsubimage(p_gl_mem: *GLMemory, p_read_pointer: ?*anyopaque) void;
    pub const texsubimage = gst_gl_memory_texsubimage;

    extern fn gst_gl_memory_get_type() usize;
    pub const getGObjectType = gst_gl_memory_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLMemoryAllocatorClass = extern struct {
    pub const Instance = gstgl.GLMemoryAllocator;

    f_parent_class: gstgl.GLBaseMemoryAllocatorClass,
    /// provide a custom map implementation
    f_map: ?gstgl.GLBaseMemoryAllocatorMapFunction,
    /// provide a custom copy implementation
    f_copy: ?gstgl.GLBaseMemoryAllocatorCopyFunction,
    /// provide a custom unmap implementation
    f_unmap: ?gstgl.GLBaseMemoryAllocatorUnmapFunction,
    f__padding: [4]*anyopaque,

    pub fn as(p_instance: *GLMemoryAllocatorClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gstgl.GLMemoryPBO` is created or wrapped through `gstgl.glBaseMemoryAlloc`
/// with `gstgl.GLVideoAllocationParams`.
///
/// Data is uploaded or downloaded from the GPU as is necessary.
pub const GLMemoryPBO = extern struct {
    f_mem: gstgl.GLMemory,
    f_pbo: ?*gstgl.GLBuffer,
    f__padding: [4]*anyopaque,

    extern fn gst_gl_memory_pbo_init_once() void;
    pub const initOnce = gst_gl_memory_pbo_init_once;

    /// Copies `gl_mem` into the texture specified by `tex_id`.  The format of `tex_id`
    /// is specified by `tex_format`, `width` and `height`.
    ///
    /// If `respecify` is `TRUE`, then the copy is performed in terms of the texture
    /// data.  This is useful for splitting RGBA textures into RG or R textures or
    /// vice versa. The requirement for this to succeed is that the backing texture
    /// data must be the same size, i.e. say a RGBA8 texture is converted into a RG8
    /// texture, then the RG texture must have twice as many pixels available for
    /// output as the RGBA texture.
    ///
    /// Otherwise, if `respecify` is `FALSE`, then the copy is performed per texel
    /// using glCopyTexImage.  See the OpenGL specification for details on the
    /// mappings between texture formats.
    extern fn gst_gl_memory_pbo_copy_into_texture(p_gl_mem: *GLMemoryPBO, p_tex_id: c_uint, p_target: gstgl.GLTextureTarget, p_tex_format: gstgl.GLFormat, p_width: c_int, p_height: c_int, p_stride: c_int, p_respecify: c_int) c_int;
    pub const copyIntoTexture = gst_gl_memory_pbo_copy_into_texture;

    /// Transfer the texture data from the texture into the PBO if necessary.
    extern fn gst_gl_memory_pbo_download_transfer(p_gl_mem: *GLMemoryPBO) void;
    pub const downloadTransfer = gst_gl_memory_pbo_download_transfer;

    /// Transfer the texture data from the PBO into the texture if necessary.
    extern fn gst_gl_memory_pbo_upload_transfer(p_gl_mem: *GLMemoryPBO) void;
    pub const uploadTransfer = gst_gl_memory_pbo_upload_transfer;

    extern fn gst_gl_memory_pbo_get_type() usize;
    pub const getGObjectType = gst_gl_memory_pbo_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Only contains private data
pub const GLMemoryPBOAllocatorClass = extern struct {
    pub const Instance = gstgl.GLMemoryPBOAllocator;

    f_parent_class: gstgl.GLMemoryAllocatorClass,
    f__padding: [4]*anyopaque,

    pub fn as(p_instance: *GLMemoryPBOAllocatorClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLMixerClass = extern struct {
    pub const Instance = gstgl.GLMixer;

    f_parent_class: gstgl.GLBaseMixerClass,
    f_process_buffers: ?*const fn (p_mix: *gstgl.GLMixer, p_outbuf: *gst.Buffer) callconv(.c) c_int,
    f_process_textures: ?*const fn (p_mix: *gstgl.GLMixer, p_out_tex: *gstgl.GLMemory) callconv(.c) c_int,
    f__padding: [4]*anyopaque,

    /// Adds the default RGBA pad templates to this class.  If you have any special
    /// template requirements like a different pad subclass or different supported
    /// caps, you should not call this function and add the pad templates yourself
    /// manually.
    extern fn gst_gl_mixer_class_add_rgba_pad_templates(p_klass: *GLMixerClass) void;
    pub const addRgbaPadTemplates = gst_gl_mixer_class_add_rgba_pad_templates;

    pub fn as(p_instance: *GLMixerClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLMixerPadClass = extern struct {
    pub const Instance = gstgl.GLMixerPad;

    /// parent `gstgl.GLBaseMixerPadClass`
    f_parent_class: gstgl.GLBaseMixerPadClass,
    f__padding: [4]*anyopaque,

    pub fn as(p_instance: *GLMixerPadClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLMixerPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLOverlayCompositorClass = extern struct {
    pub const Instance = gstgl.GLOverlayCompositor;

    f_object_class: gst.ObjectClass,
    f__padding: [4]*anyopaque,

    pub fn as(p_instance: *GLOverlayCompositorClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A `gstgl.GLQuery` represents and holds an OpenGL query object.  Various types of
/// queries can be run or counters retrieved.
pub const GLQuery = extern struct {
    f_context: ?*gstgl.GLContext,
    f_query_type: c_uint,
    f_query_id: c_uint,
    f_supported: c_int,
    f_start_called: c_int,
    f_debug: gstgl.GLAsyncDebug,
    f__padding: [4]*anyopaque,

    /// Performs a GST_QUERY_CONTEXT query of type "gst.gl.local_context" on all
    /// `GstPads` in `element` of `direction` for the local OpenGL context used by
    /// GStreamer elements.
    extern fn gst_gl_query_local_gl_context(p_element: *gst.Element, p_direction: gst.PadDirection, p_context_ptr: **gstgl.GLContext) c_int;
    pub const localGlContext = gst_gl_query_local_gl_context;

    /// Free with `gstgl.GLQuery.free`
    extern fn gst_gl_query_new(p_context: *gstgl.GLContext, p_query_type: gstgl.GLQueryType) *gstgl.GLQuery;
    pub const new = gst_gl_query_new;

    /// Record the result of a counter
    extern fn gst_gl_query_counter(p_query: *GLQuery) void;
    pub const counter = gst_gl_query_counter;

    /// End counting the query
    extern fn gst_gl_query_end(p_query: *GLQuery) void;
    pub const end = gst_gl_query_end;

    /// Frees a `gstgl.GLQuery`
    extern fn gst_gl_query_free(p_query: *GLQuery) void;
    pub const free = gst_gl_query_free;

    extern fn gst_gl_query_init(p_query: *GLQuery, p_context: *gstgl.GLContext, p_query_type: gstgl.GLQueryType) void;
    pub const init = gst_gl_query_init;

    extern fn gst_gl_query_result(p_query: *GLQuery) u64;
    pub const result = gst_gl_query_result;

    /// Start counting the query
    extern fn gst_gl_query_start(p_query: *GLQuery) void;
    pub const start = gst_gl_query_start;

    /// Free any dynamically allocated resources
    extern fn gst_gl_query_unset(p_query: *GLQuery) void;
    pub const unset = gst_gl_query_unset;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GstGLRenderbuffer is a `gstgl.GLBaseMemory` subclass providing support for
/// OpenGL renderbuffers.
///
/// `gstgl.GLRenderbuffer` is created or wrapped through `gstgl.glBaseMemoryAlloc`
/// with `gstgl.GLRenderbufferAllocationParams`.
pub const GLRenderbuffer = extern struct {
    f_mem: gstgl.GLBaseMemory,
    /// the GL texture id for this memory
    f_renderbuffer_id: c_uint,
    /// the texture type
    f_renderbuffer_format: gstgl.GLFormat,
    /// the width
    f_width: c_uint,
    /// the height
    f_height: c_uint,
    f_renderbuffer_wrapped: c_int,
    f__padding: [4]*anyopaque,

    /// Initializes the GL Base Texture allocator. It is safe to call this function
    /// multiple times.  This must be called before any other GstGLRenderbuffer operation.
    extern fn gst_gl_renderbuffer_init_once() void;
    pub const initOnce = gst_gl_renderbuffer_init_once;

    extern fn gst_gl_renderbuffer_get_format(p_gl_mem: *GLRenderbuffer) gstgl.GLFormat;
    pub const getFormat = gst_gl_renderbuffer_get_format;

    extern fn gst_gl_renderbuffer_get_height(p_gl_mem: *GLRenderbuffer) c_int;
    pub const getHeight = gst_gl_renderbuffer_get_height;

    extern fn gst_gl_renderbuffer_get_id(p_gl_mem: *GLRenderbuffer) c_uint;
    pub const getId = gst_gl_renderbuffer_get_id;

    extern fn gst_gl_renderbuffer_get_width(p_gl_mem: *GLRenderbuffer) c_int;
    pub const getWidth = gst_gl_renderbuffer_get_width;

    extern fn gst_gl_renderbuffer_get_type() usize;
    pub const getGObjectType = gst_gl_renderbuffer_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Allocation parameters
pub const GLRenderbufferAllocationParams = extern struct {
    f_parent: gstgl.GLAllocationParams,
    /// the `gstgl.GLFormat`
    f_renderbuffer_format: gstgl.GLFormat,
    /// the width
    f_width: c_uint,
    /// the height
    f_height: c_uint,
    f__padding: [4]*anyopaque,

    extern fn gst_gl_renderbuffer_allocation_params_new(p_context: *gstgl.GLContext, p_alloc_params: ?*const gst.AllocationParams, p_renderbuffer_format: gstgl.GLFormat, p_width: c_uint, p_height: c_uint) *gstgl.GLRenderbufferAllocationParams;
    pub const new = gst_gl_renderbuffer_allocation_params_new;

    extern fn gst_gl_renderbuffer_allocation_params_new_wrapped(p_context: *gstgl.GLContext, p_alloc_params: ?*const gst.AllocationParams, p_renderbuffer_format: gstgl.GLFormat, p_width: c_uint, p_height: c_uint, p_gl_handle: ?*anyopaque, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) *gstgl.GLRenderbufferAllocationParams;
    pub const newWrapped = gst_gl_renderbuffer_allocation_params_new_wrapped;

    extern fn gst_gl_renderbuffer_allocation_params_get_type() usize;
    pub const getGObjectType = gst_gl_renderbuffer_allocation_params_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The `gstgl.GLRenderbufferAllocatorClass` only contains private data
pub const GLRenderbufferAllocatorClass = extern struct {
    pub const Instance = gstgl.GLRenderbufferAllocator;

    f_parent_class: gstgl.GLBaseMemoryAllocatorClass,
    f__padding: [4]*anyopaque,

    pub fn as(p_instance: *GLRenderbufferAllocatorClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Opaque `gstgl.GLSLStageClass` struct
pub const GLSLStageClass = extern struct {
    pub const Instance = gstgl.GLSLStage;

    f_parent: gst.ObjectClass,
    f__padding: [4]*anyopaque,

    pub fn as(p_instance: *GLSLStageClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLSLStagePrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLShaderClass = extern struct {
    pub const Instance = gstgl.GLShader;

    f_parent_class: gst.ObjectClass,

    pub fn as(p_instance: *GLShaderClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLShaderPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gstgl.GLSyncMeta` provides the ability to synchronize the OpenGL command stream
/// with the CPU or with other OpenGL contexts.
pub const GLSyncMeta = extern struct {
    /// the parent `gst.Meta`
    f_parent: gst.Meta,
    /// the `gstgl.GLContext` used to allocate the meta
    f_context: ?*gstgl.GLContext,
    /// a custom data pointer for the implementation
    f_data: ?*anyopaque,
    /// set a sync point in the OpenGL command stream
    f_set_sync: ?*const fn (p_sync: *gstgl.GLSyncMeta, p_context: *gstgl.GLContext) callconv(.c) void,
    /// the same as `set_sync` but called from `context`'s thread
    f_set_sync_gl: ?*const fn (p_sync: *gstgl.GLSyncMeta, p_context: *gstgl.GLContext) callconv(.c) void,
    /// execute a wait on the previously set sync point into the OpenGL command stream
    f_wait: ?*const fn (p_sync: *gstgl.GLSyncMeta, p_context: *gstgl.GLContext) callconv(.c) void,
    /// the same as `wait` but called from `context`'s thread
    f_wait_gl: ?*const fn (p_sync: *gstgl.GLSyncMeta, p_context: *gstgl.GLContext) callconv(.c) void,
    /// wait for the previously set sync point to pass from the CPU
    f_wait_cpu: ?*const fn (p_sync: *gstgl.GLSyncMeta, p_context: *gstgl.GLContext) callconv(.c) void,
    /// the same as `wait_cpu` but called from `context`'s thread
    f_wait_cpu_gl: ?*const fn (p_sync: *gstgl.GLSyncMeta, p_context: *gstgl.GLContext) callconv(.c) void,
    /// copy `data` into a new `gstgl.GLSyncMeta`
    f_copy: ?*const fn (p_src: *gstgl.GLSyncMeta, p_sbuffer: *gst.Buffer, p_dest: *gstgl.GLSyncMeta, p_dbuffer: *gst.Buffer) callconv(.c) void,
    /// free `data`
    f_free: ?*const fn (p_sync: *gstgl.GLSyncMeta, p_context: *gstgl.GLContext) callconv(.c) void,
    /// free `data` in `context`'s thread
    f_free_gl: ?*const fn (p_sync: *gstgl.GLSyncMeta, p_context: *gstgl.GLContext) callconv(.c) void,

    extern fn gst_gl_sync_meta_get_info() *const gst.MetaInfo;
    pub const getInfo = gst_gl_sync_meta_get_info;

    /// Set a sync point to possibly wait on at a later time.
    extern fn gst_gl_sync_meta_set_sync_point(p_sync_meta: *GLSyncMeta, p_context: *gstgl.GLContext) void;
    pub const setSyncPoint = gst_gl_sync_meta_set_sync_point;

    /// Insert a wait into `context`'s command stream ensuring all previous OpenGL
    /// commands before `sync_meta` have completed.
    extern fn gst_gl_sync_meta_wait(p_sync_meta: *GLSyncMeta, p_context: *gstgl.GLContext) void;
    pub const wait = gst_gl_sync_meta_wait;

    /// Perform a wait so that the sync point has passed from the CPU's perspective
    /// What that means, is that all GL operations changing CPU-visible data before
    /// the sync point are now visible.
    extern fn gst_gl_sync_meta_wait_cpu(p_sync_meta: *GLSyncMeta, p_context: *gstgl.GLContext) void;
    pub const waitCpu = gst_gl_sync_meta_wait_cpu;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The `gstgl.GLUploadClass` struct only contains private data
pub const GLUploadClass = extern struct {
    pub const Instance = gstgl.GLUpload;

    f_object_class: gst.ObjectClass,
    f__padding: [4]*anyopaque,

    pub fn as(p_instance: *GLUploadClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLUploadPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLVideoAllocationParams = extern struct {
    /// the parent `gstgl.GLAllocationParams` structure
    f_parent: gstgl.GLAllocationParams,
    /// the `gstvideo.VideoInfo` to allocate
    f_v_info: ?*gstvideo.VideoInfo,
    /// the video plane index to allocate
    f_plane: c_uint,
    /// the `gstvideo.VideoAlignment` to align the system representation to (may be `NULL` for the default)
    f_valign: ?*gstvideo.VideoAlignment,
    /// the `gstgl.GLTextureTarget` to allocate
    f_target: gstgl.GLTextureTarget,
    /// the `gstgl.GLFormat` to allocate
    f_tex_format: gstgl.GLFormat,
    f__padding: [4]*anyopaque,

    extern fn gst_gl_video_allocation_params_new(p_context: *gstgl.GLContext, p_alloc_params: ?*const gst.AllocationParams, p_v_info: *const gstvideo.VideoInfo, p_plane: c_uint, p_valign: ?*const gstvideo.VideoAlignment, p_target: gstgl.GLTextureTarget, p_tex_format: gstgl.GLFormat) *gstgl.GLVideoAllocationParams;
    pub const new = gst_gl_video_allocation_params_new;

    extern fn gst_gl_video_allocation_params_new_wrapped_data(p_context: *gstgl.GLContext, p_alloc_params: ?*const gst.AllocationParams, p_v_info: *const gstvideo.VideoInfo, p_plane: c_uint, p_valign: ?*const gstvideo.VideoAlignment, p_target: gstgl.GLTextureTarget, p_tex_format: gstgl.GLFormat, p_wrapped_data: ?*anyopaque, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) *gstgl.GLVideoAllocationParams;
    pub const newWrappedData = gst_gl_video_allocation_params_new_wrapped_data;

    /// `gl_handle` is defined by the specific OpenGL handle being wrapped
    /// For `gstgl.GLMemory` and `gstgl.GLMemoryPBO` it is an OpenGL texture id.
    /// Other memory types may define it to require a different type of parameter.
    extern fn gst_gl_video_allocation_params_new_wrapped_gl_handle(p_context: *gstgl.GLContext, p_alloc_params: ?*const gst.AllocationParams, p_v_info: *const gstvideo.VideoInfo, p_plane: c_uint, p_valign: ?*const gstvideo.VideoAlignment, p_target: gstgl.GLTextureTarget, p_tex_format: gstgl.GLFormat, p_gl_handle: ?*anyopaque, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) *gstgl.GLVideoAllocationParams;
    pub const newWrappedGlHandle = gst_gl_video_allocation_params_new_wrapped_gl_handle;

    extern fn gst_gl_video_allocation_params_new_wrapped_texture(p_context: *gstgl.GLContext, p_alloc_params: ?*const gst.AllocationParams, p_v_info: *const gstvideo.VideoInfo, p_plane: c_uint, p_valign: ?*const gstvideo.VideoAlignment, p_target: gstgl.GLTextureTarget, p_tex_format: gstgl.GLFormat, p_tex_id: c_uint, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) *gstgl.GLVideoAllocationParams;
    pub const newWrappedTexture = gst_gl_video_allocation_params_new_wrapped_texture;

    /// Copy and set any dynamically allocated resources in `dest_vid`.  Intended
    /// for subclass usage only to chain up at the end of a subclass copy function.
    extern fn gst_gl_video_allocation_params_copy_data(p_src_vid: *GLVideoAllocationParams, p_dest_vid: *gstgl.GLVideoAllocationParams) void;
    pub const copyData = gst_gl_video_allocation_params_copy_data;

    /// Unset and free any dynamically allocated resources.  Intended for subclass
    /// usage only to chain up at the end of a subclass free function.
    extern fn gst_gl_video_allocation_params_free_data(p_params: *GLVideoAllocationParams) void;
    pub const freeData = gst_gl_video_allocation_params_free_data;

    /// Intended for subclass usage
    extern fn gst_gl_video_allocation_params_init_full(p_params: *GLVideoAllocationParams, p_struct_size: usize, p_alloc_flags: c_uint, p_copy: gstgl.GLAllocationParamsCopyFunc, p_free: gstgl.GLAllocationParamsFreeFunc, p_context: *gstgl.GLContext, p_alloc_params: ?*const gst.AllocationParams, p_v_info: *const gstvideo.VideoInfo, p_plane: c_uint, p_valign: ?*const gstvideo.VideoAlignment, p_target: gstgl.GLTextureTarget, p_tex_format: gstgl.GLFormat, p_wrapped_data: ?*anyopaque, p_gl_handle: ?*anyopaque, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) c_int;
    pub const initFull = gst_gl_video_allocation_params_init_full;

    extern fn gst_gl_video_allocation_params_get_type() usize;
    pub const getGObjectType = gst_gl_video_allocation_params_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Opaque `gstgl.GLViewConvertClass` struct
pub const GLViewConvertClass = extern struct {
    pub const Instance = gstgl.GLViewConvert;

    f_object_class: gst.ObjectClass,
    f__padding: [4]*anyopaque,

    pub fn as(p_instance: *GLViewConvertClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLViewConvertPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLWindowClass = extern struct {
    pub const Instance = gstgl.GLWindow;

    /// Parent class
    f_parent_class: gst.ObjectClass,
    /// Gets the current windowing system display connection
    f_get_display: ?*const fn (p_window: *gstgl.GLWindow) callconv(.c) usize,
    /// Set a window handle to render into
    f_set_window_handle: ?*const fn (p_window: *gstgl.GLWindow, p_handle: usize) callconv(.c) void,
    /// Gets the current window handle that this `gstgl.GLWindow` is
    ///                     rendering into.  This may return a different value to
    ///                     what is passed into `set_window_handle`
    f_get_window_handle: ?*const fn (p_window: *gstgl.GLWindow) callconv(.c) usize,
    /// redraw the window with the specified dimensions
    f_draw: ?*const fn (p_window: *gstgl.GLWindow) callconv(.c) void,
    /// run the mainloop
    f_run: ?*const fn (p_window: *gstgl.GLWindow) callconv(.c) void,
    /// send a quit to the mainloop
    f_quit: ?*const fn (p_window: *gstgl.GLWindow) callconv(.c) void,
    /// invoke a function on the window thread.  Required to be reentrant.
    f_send_message: ?*const fn (p_window: *gstgl.GLWindow, p_callback: gstgl.GLWindowCB, p_data: ?*anyopaque) callconv(.c) void,
    /// invoke a function on the window thread. `run` may or may
    ///                      not have been called.  Required to be reentrant.
    f_send_message_async: ?*const fn (p_window: *gstgl.GLWindow, p_callback: gstgl.GLWindowCB, p_data: ?*anyopaque, p_destroy: ?glib.DestroyNotify) callconv(.c) void,
    /// open the connection to the display
    f_open: ?*const fn (p_window: *gstgl.GLWindow, p_error: ?*?*glib.Error) callconv(.c) c_int,
    /// close the connection to the display
    f_close: ?*const fn (p_window: *gstgl.GLWindow) callconv(.c) void,
    /// whether to handle 'extra' events from the windowing system.
    ///                 Basic events like surface moves and resizes are still valid
    ///                 things to listen for.
    f_handle_events: ?*const fn (p_window: *gstgl.GLWindow, p_handle_events: c_int) callconv(.c) void,
    /// request that the window change surface size.  The
    ///                      implementation is free to ignore this information.
    f_set_preferred_size: ?*const fn (p_window: *gstgl.GLWindow, p_width: c_int, p_height: c_int) callconv(.c) void,
    /// request that the window be shown to the user
    f_show: ?*const fn (p_window: *gstgl.GLWindow) callconv(.c) void,
    /// request a rectangle to render into.  See `gstvideo.VideoOverlay`
    f_set_render_rectangle: ?*const fn (p_window: *gstgl.GLWindow, p_x: c_int, p_y: c_int, p_width: c_int, p_height: c_int) callconv(.c) c_int,
    /// request a resize to occur when possible
    f_queue_resize: ?*const fn (p_window: *gstgl.GLWindow) callconv(.c) void,
    /// Whether the window takes care of glViewport setup.
    ///                     and the user does not need to deal with viewports
    f_controls_viewport: ?*const fn (p_window: *gstgl.GLWindow) callconv(.c) c_int,
    /// Whether the window has output surface or not. (Since: 1.18)
    f_has_output_surface: ?*const fn (p_window: *gstgl.GLWindow) callconv(.c) c_int,
    f__reserved: [2]*anyopaque,

    pub fn as(p_instance: *GLWindowClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLWindowPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLBaseMemoryError = enum(c_int) {
    failed = 0,
    old_libs = 1,
    resource_unavailable = 2,
    _,

    extern fn gst_gl_base_memory_error_quark() glib.Quark;
    pub const quark = gst_gl_base_memory_error_quark;

    extern fn gst_gl_base_memory_error_get_type() usize;
    pub const getGObjectType = gst_gl_base_memory_error_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLConfigCaveat = enum(c_int) {
    none = 0,
    slow = 1,
    non_conformant = 2,
    _,

    extern fn gst_gl_config_caveat_to_string(p_caveat: gstgl.GLConfigCaveat) ?[*:0]const u8;
    pub const toString = gst_gl_config_caveat_to_string;

    extern fn gst_gl_config_caveat_get_type() usize;
    pub const getGObjectType = gst_gl_config_caveat_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// OpenGL context errors.
pub const GLContextError = enum(c_int) {
    failed = 0,
    wrong_config = 1,
    wrong_api = 2,
    old_libs = 3,
    create_context = 4,
    resource_unavailable = 5,
    _,

    extern fn gst_gl_context_error_quark() glib.Quark;
    pub const quark = gst_gl_context_error_quark;

    extern fn gst_gl_context_error_get_type() usize;
    pub const getGObjectType = gst_gl_context_error_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLFormat = enum(c_int) {
    luminance = 6409,
    alpha = 6406,
    luminance_alpha = 6410,
    red = 6403,
    r8 = 33321,
    rg = 33319,
    rg8 = 33323,
    rgb = 6407,
    rgb8 = 32849,
    rgb565 = 36194,
    rgb16 = 32852,
    rgba = 6408,
    rgba8 = 32856,
    rgba16 = 32859,
    depth_component16 = 33189,
    depth24_stencil8 = 35056,
    rgb10_a2 = 32857,
    r16 = 33322,
    rg16 = 33324,
    _,

    extern fn gst_gl_format_from_video_info(p_context: *gstgl.GLContext, p_vinfo: *const gstvideo.VideoInfo, p_plane: c_uint) gstgl.GLFormat;
    pub const fromVideoInfo = gst_gl_format_from_video_info;

    extern fn gst_gl_format_is_supported(p_context: *gstgl.GLContext, p_format: gstgl.GLFormat) c_int;
    pub const isSupported = gst_gl_format_is_supported;

    extern fn gst_gl_format_n_components(p_gl_format: gstgl.GLFormat) c_uint;
    pub const nComponents = gst_gl_format_n_components;

    /// Get the unsized format and type from `format` for usage in glReadPixels,
    /// glTex{Sub}Image*, glTexImage* and similar functions.
    extern fn gst_gl_format_type_from_sized_gl_format(p_format: gstgl.GLFormat, p_unsized_format: *gstgl.GLFormat, p_gl_type: *c_uint) void;
    pub const typeFromSizedGlFormat = gst_gl_format_type_from_sized_gl_format;

    extern fn gst_gl_format_type_n_bytes(p_format: c_uint, p_type: c_uint) c_uint;
    pub const typeNBytes = gst_gl_format_type_n_bytes;

    extern fn gst_gl_format_get_type() usize;
    pub const getGObjectType = gst_gl_format_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLQueryType = enum(c_int) {
    none = 0,
    time_elapsed = 1,
    timestamp = 2,
    _,

    extern fn gst_gl_query_type_get_type() usize;
    pub const getGObjectType = gst_gl_query_type_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Compilation stage that caused an error
pub const GLSLError = enum(c_int) {
    compile = 0,
    link = 1,
    program = 2,
    _,

    extern fn gst_glsl_error_quark() glib.Quark;
    pub const quark = gst_glsl_error_quark;

    extern fn gst_glsl_error_get_type() usize;
    pub const getGObjectType = gst_glsl_error_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GLSL version list
pub const GLSLVersion = enum(c_int) {
    none = 0,
    @"100" = 100,
    @"110" = 110,
    @"120" = 120,
    @"130" = 130,
    @"140" = 140,
    @"150" = 150,
    @"300" = 300,
    @"310" = 310,
    @"320" = 320,
    @"330" = 330,
    @"400" = 400,
    @"410" = 410,
    @"420" = 420,
    @"430" = 430,
    @"440" = 440,
    @"450" = 450,
    _,

    extern fn gst_glsl_version_from_string(p_string: [*:0]const u8) gstgl.GLSLVersion;
    pub const fromString = gst_glsl_version_from_string;

    /// Note: this function expects either a ``version`` GLSL preprocesser directive
    /// or a valid GLSL version and/or profile.
    extern fn gst_glsl_version_profile_from_string(p_string: [*:0]const u8, p_version_ret: *gstgl.GLSLVersion, p_profile_ret: *gstgl.GLSLProfile) c_int;
    pub const profileFromString = gst_glsl_version_profile_from_string;

    extern fn gst_glsl_version_profile_to_string(p_version: gstgl.GLSLVersion, p_profile: gstgl.GLSLProfile) ?[*:0]u8;
    pub const profileToString = gst_glsl_version_profile_to_string;

    extern fn gst_glsl_version_to_string(p_version: gstgl.GLSLVersion) ?[*:0]const u8;
    pub const toString = gst_glsl_version_to_string;

    extern fn gst_glsl_version_get_type() usize;
    pub const getGObjectType = gst_glsl_version_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Output anaglyph type to generate when downmixing to mono
pub const GLStereoDownmix = enum(c_int) {
    green_magenta_dubois = 0,
    red_cyan_dubois = 1,
    amber_blue_dubois = 2,
    _,

    extern fn gst_gl_stereo_downmix_get_type() usize;
    pub const getGObjectType = gst_gl_stereo_downmix_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The OpenGL texture target that an OpenGL texture can be bound to.  The
/// `gstgl.glValueSetTextureTargetFromMask`,
/// `gstgl.glValueGetTextureTargetMask`, and
/// `gstgl.glValueSetTextureTarget` functions can be used for handling texture
/// targets with `gobject.Value`'s when e.g. dealing with `gst.Caps`.
pub const GLTextureTarget = enum(c_int) {
    none = 0,
    @"2d" = 1,
    rectangle = 2,
    external_oes = 3,
    _,

    extern fn gst_gl_texture_target_from_gl(p_target: c_uint) gstgl.GLTextureTarget;
    pub const fromGl = gst_gl_texture_target_from_gl;

    extern fn gst_gl_texture_target_from_string(p_str: [*:0]const u8) gstgl.GLTextureTarget;
    pub const fromString = gst_gl_texture_target_from_string;

    extern fn gst_gl_texture_target_to_buffer_pool_option(p_target: gstgl.GLTextureTarget) ?[*:0]const u8;
    pub const toBufferPoolOption = gst_gl_texture_target_to_buffer_pool_option;

    extern fn gst_gl_texture_target_to_gl(p_target: gstgl.GLTextureTarget) c_uint;
    pub const toGl = gst_gl_texture_target_to_gl;

    extern fn gst_gl_texture_target_to_string(p_target: gstgl.GLTextureTarget) ?[*:0]const u8;
    pub const toString = gst_gl_texture_target_to_string;

    extern fn gst_gl_texture_target_get_type() usize;
    pub const getGObjectType = gst_gl_texture_target_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLUploadReturn = enum(c_int) {
    done = 1,
    @"error" = -1,
    unsupported = -2,
    reconfigure = -3,
    unshared_gl_context = -100,
    _,

    extern fn gst_gl_upload_return_get_type() usize;
    pub const getGObjectType = gst_gl_upload_return_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLWindowError = enum(c_int) {
    failed = 0,
    old_libs = 1,
    resource_unavailable = 2,
    _,

    extern fn gst_gl_window_error_quark() glib.Quark;
    pub const quark = gst_gl_window_error_quark;

    extern fn gst_gl_window_error_get_type() usize;
    pub const getGObjectType = gst_gl_window_error_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLAPI = packed struct(c_uint) {
    opengl: bool = false,
    opengl3: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    gles1: bool = false,
    gles2: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_none: GLAPI = @bitCast(@as(c_uint, 0));
    pub const flags_opengl: GLAPI = @bitCast(@as(c_uint, 1));
    pub const flags_opengl3: GLAPI = @bitCast(@as(c_uint, 2));
    pub const flags_gles1: GLAPI = @bitCast(@as(c_uint, 32768));
    pub const flags_gles2: GLAPI = @bitCast(@as(c_uint, 65536));
    pub const flags_any: GLAPI = @bitCast(@as(c_uint, 4294967295));
    extern fn gst_gl_api_from_string(p_api_s: [*:0]const u8) gstgl.GLAPI;
    pub const fromString = gst_gl_api_from_string;

    extern fn gst_gl_api_to_string(p_api: gstgl.GLAPI) [*:0]u8;
    pub const toString = gst_gl_api_to_string;

    extern fn gst_gl_api_get_type() usize;
    pub const getGObjectType = gst_gl_api_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLBaseMemoryTransfer = packed struct(c_uint) {
    _padding0: bool = false,
    _padding1: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    download: bool = false,
    upload: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_download: GLBaseMemoryTransfer = @bitCast(@as(c_uint, 1048576));
    pub const flags_upload: GLBaseMemoryTransfer = @bitCast(@as(c_uint, 2097152));
    extern fn gst_gl_base_memory_transfer_get_type() usize;
    pub const getGObjectType = gst_gl_base_memory_transfer_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLConfigSurfaceType = packed struct(c_uint) {
    window: bool = false,
    pbuffer: bool = false,
    pixmap: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_none: GLConfigSurfaceType = @bitCast(@as(c_uint, 0));
    pub const flags_window: GLConfigSurfaceType = @bitCast(@as(c_uint, 1));
    pub const flags_pbuffer: GLConfigSurfaceType = @bitCast(@as(c_uint, 2));
    pub const flags_pixmap: GLConfigSurfaceType = @bitCast(@as(c_uint, 4));
    extern fn gst_gl_config_surface_type_to_string(p_surface_type: gstgl.GLConfigSurfaceType) ?[*:0]const u8;
    pub const toString = gst_gl_config_surface_type_to_string;

    extern fn gst_gl_config_surface_type_get_type() usize;
    pub const getGObjectType = gst_gl_config_surface_type_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLDisplayType = packed struct(c_uint) {
    x11: bool = false,
    wayland: bool = false,
    cocoa: bool = false,
    win32: bool = false,
    dispmanx: bool = false,
    egl: bool = false,
    viv_fb: bool = false,
    gbm: bool = false,
    egl_device: bool = false,
    eagl: bool = false,
    winrt: bool = false,
    android: bool = false,
    egl_surfaceless: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_none: GLDisplayType = @bitCast(@as(c_uint, 0));
    pub const flags_x11: GLDisplayType = @bitCast(@as(c_uint, 1));
    pub const flags_wayland: GLDisplayType = @bitCast(@as(c_uint, 2));
    pub const flags_cocoa: GLDisplayType = @bitCast(@as(c_uint, 4));
    pub const flags_win32: GLDisplayType = @bitCast(@as(c_uint, 8));
    pub const flags_dispmanx: GLDisplayType = @bitCast(@as(c_uint, 16));
    pub const flags_egl: GLDisplayType = @bitCast(@as(c_uint, 32));
    pub const flags_viv_fb: GLDisplayType = @bitCast(@as(c_uint, 64));
    pub const flags_gbm: GLDisplayType = @bitCast(@as(c_uint, 128));
    pub const flags_egl_device: GLDisplayType = @bitCast(@as(c_uint, 256));
    pub const flags_eagl: GLDisplayType = @bitCast(@as(c_uint, 512));
    pub const flags_winrt: GLDisplayType = @bitCast(@as(c_uint, 1024));
    pub const flags_android: GLDisplayType = @bitCast(@as(c_uint, 2048));
    pub const flags_egl_surfaceless: GLDisplayType = @bitCast(@as(c_uint, 4096));
    pub const flags_any: GLDisplayType = @bitCast(@as(c_uint, 4294967295));
    extern fn gst_gl_display_type_get_type() usize;
    pub const getGObjectType = gst_gl_display_type_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLDrmFormatFlags = packed struct(c_uint) {
    include_external: bool = false,
    linear_only: bool = false,
    include_emulated: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_include_external: GLDrmFormatFlags = @bitCast(@as(c_uint, 1));
    pub const flags_linear_only: GLDrmFormatFlags = @bitCast(@as(c_uint, 2));
    pub const flags_include_emulated: GLDrmFormatFlags = @bitCast(@as(c_uint, 4));
    extern fn gst_gl_drm_format_flags_get_type() usize;
    pub const getGObjectType = gst_gl_drm_format_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GLPlatform = packed struct(c_uint) {
    egl: bool = false,
    glx: bool = false,
    wgl: bool = false,
    cgl: bool = false,
    eagl: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_none: GLPlatform = @bitCast(@as(c_uint, 0));
    pub const flags_egl: GLPlatform = @bitCast(@as(c_uint, 1));
    pub const flags_glx: GLPlatform = @bitCast(@as(c_uint, 2));
    pub const flags_wgl: GLPlatform = @bitCast(@as(c_uint, 4));
    pub const flags_cgl: GLPlatform = @bitCast(@as(c_uint, 8));
    pub const flags_eagl: GLPlatform = @bitCast(@as(c_uint, 16));
    pub const flags_any: GLPlatform = @bitCast(@as(c_uint, 4294967295));
    extern fn gst_gl_platform_from_string(p_platform_s: [*:0]const u8) gstgl.GLPlatform;
    pub const fromString = gst_gl_platform_from_string;

    extern fn gst_gl_platform_to_string(p_platform: gstgl.GLPlatform) [*:0]u8;
    pub const toString = gst_gl_platform_to_string;

    extern fn gst_gl_platform_get_type() usize;
    pub const getGObjectType = gst_gl_platform_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GLSL profiles
pub const GLSLProfile = packed struct(c_uint) {
    es: bool = false,
    core: bool = false,
    compatibility: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_none: GLSLProfile = @bitCast(@as(c_uint, 0));
    pub const flags_es: GLSLProfile = @bitCast(@as(c_uint, 1));
    pub const flags_core: GLSLProfile = @bitCast(@as(c_uint, 2));
    pub const flags_compatibility: GLSLProfile = @bitCast(@as(c_uint, 4));
    pub const flags_any: GLSLProfile = @bitCast(@as(c_uint, 4294967295));
    extern fn gst_glsl_profile_from_string(p_string: [*:0]const u8) gstgl.GLSLProfile;
    pub const fromString = gst_glsl_profile_from_string;

    extern fn gst_glsl_profile_to_string(p_profile: gstgl.GLSLProfile) ?[*:0]const u8;
    pub const toString = gst_glsl_profile_to_string;

    extern fn gst_glsl_profile_get_type() usize;
    pub const getGObjectType = gst_glsl_profile_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

extern fn gst_buffer_add_gl_sync_meta(p_context: *gstgl.GLContext, p_buffer: *gst.Buffer) *gstgl.GLSyncMeta;
pub const bufferAddGlSyncMeta = gst_buffer_add_gl_sync_meta;

extern fn gst_buffer_add_gl_sync_meta_full(p_context: *gstgl.GLContext, p_buffer: *gst.Buffer, p_data: ?*anyopaque) *gstgl.GLSyncMeta;
pub const bufferAddGlSyncMetaFull = gst_buffer_add_gl_sync_meta_full;

extern fn gst_buffer_pool_config_get_gl_allocation_params(p_config: *gst.Structure) ?*gstgl.GLAllocationParams;
pub const bufferPoolConfigGetGlAllocationParams = gst_buffer_pool_config_get_gl_allocation_params;

/// See `gstgl.bufferPoolConfigSetGlMinFreeQueueSize`.
extern fn gst_buffer_pool_config_get_gl_min_free_queue_size(p_config: *gst.Structure) c_uint;
pub const bufferPoolConfigGetGlMinFreeQueueSize = gst_buffer_pool_config_get_gl_min_free_queue_size;

/// Sets `params` on `config`
extern fn gst_buffer_pool_config_set_gl_allocation_params(p_config: *gst.Structure, p_params: ?*const gstgl.GLAllocationParams) void;
pub const bufferPoolConfigSetGlAllocationParams = gst_buffer_pool_config_set_gl_allocation_params;

/// Instructs the `gstgl.GLBufferPool` to keep `queue_size` amount of buffers around
/// before allowing them for reuse.
///
/// This is helpful to allow GPU processing to complete before the CPU
/// operations on the same buffer could start.  Particularly useful when
/// uploading or downloading data to/from the GPU.
///
/// A value of 0 disabled this functionality.
///
/// This value must be less than the configured maximum amount of buffers for
/// this `config`.
extern fn gst_buffer_pool_config_set_gl_min_free_queue_size(p_config: *gst.Structure, p_queue_size: c_uint) void;
pub const bufferPoolConfigSetGlMinFreeQueueSize = gst_buffer_pool_config_set_gl_min_free_queue_size;

extern fn gst_context_get_gl_display(p_context: *gst.Context, p_display: ?**gstgl.GLDisplay) c_int;
pub const contextGetGlDisplay = gst_context_get_gl_display;

/// Sets `display` on `context`
extern fn gst_context_set_gl_display(p_context: *gst.Context, p_display: ?*gstgl.GLDisplay) void;
pub const contextSetGlDisplay = gst_context_set_gl_display;

extern fn gst_gl_check_extension(p_name: [*:0]const u8, p_ext: [*:0]const u8) c_int;
pub const glCheckExtension = gst_gl_check_extension;

/// Given the DRM formats in `src` `gobject.Value`, collect corresponding GST formats to
/// `dst` `gobject.Value`. This function returns `FALSE` if  the context is not an EGL
/// context.
extern fn gst_gl_dma_buf_transform_drm_formats_to_gst_formats(p_context: *gstgl.GLContext, p_src: *const gobject.Value, p_flags: gstgl.GLDrmFormatFlags, p_dst: *gobject.Value) c_int;
pub const glDmaBufTransformDrmFormatsToGstFormats = gst_gl_dma_buf_transform_drm_formats_to_gst_formats;

/// Given the video formats in `src` `gobject.Value`, collect corresponding drm formats
/// supported by `context` into `dst` `gobject.Value`. This function returns `FALSE` if
/// the context is not an EGL context.
extern fn gst_gl_dma_buf_transform_gst_formats_to_drm_formats(p_context: *gstgl.GLContext, p_src: *const gobject.Value, p_flags: gstgl.GLDrmFormatFlags, p_dst: *gobject.Value) c_int;
pub const glDmaBufTransformGstFormatsToDrmFormats = gst_gl_dma_buf_transform_gst_formats_to_drm_formats;

extern fn gst_gl_element_propagate_display_context(p_element: *gst.Element, p_display: *gstgl.GLDisplay) void;
pub const glElementPropagateDisplayContext = gst_gl_element_propagate_display_context;

/// Perform the steps necessary for retrieving a `gstgl.GLDisplay` and (optionally)
/// an application provided `gstgl.GLContext` from the surrounding elements or from
/// the application using the `gst.Context` mechanism.
///
/// If the contents of `display_ptr` or `other_context_ptr` are not `NULL`, then no
/// `gst.Context` query is necessary for `gstgl.GLDisplay` or `gstgl.GLContext` retrieval
/// or is performed.
///
/// This performs `gst.Context` queries (if necessary) for a winsys display
/// connection with `GST_GL_DISPLAY_CONTEXT_TYPE`, "gst.x11.display.handle", and
/// "GstWaylandDisplayHandleContextType" stopping after the first successful
/// retrieval.
///
/// This also performs a `gst.Context` query (if necessary) for an optional
/// application provided `gstgl.GLContext` using the name "gst.gl.app_context".
/// The returned `gstgl.GLContext` will be shared with a GStreamer created OpenGL context.
extern fn gst_gl_ensure_element_data(p_element: *gst.Element, p_display_ptr: **gstgl.GLDisplay, p_other_context_ptr: **gstgl.GLContext) c_int;
pub const glEnsureElementData = gst_gl_ensure_element_data;

/// Retrieves the stored 4x4 affine transformation matrix stored in `meta` in
/// NDC coordinates. if `meta` is NULL, an identity matrix is returned.
///
/// NDC is a left-handed coordinate system
/// - x - [-1, 1] - +ve X moves right
/// - y - [-1, 1] - +ve Y moves up
/// - z - [-1, 1] - +ve Z moves into
extern fn gst_gl_get_affine_transformation_meta_as_ndc(p_meta: ?*gstvideo.VideoAffineTransformationMeta, p_matrix: *[16]f32) void;
pub const glGetAffineTransformationMetaAsNdc = gst_gl_get_affine_transformation_meta_as_ndc;

/// Retrieve the size in bytes of a video plane of data with a certain alignment
extern fn gst_gl_get_plane_data_size(p_info: *const gstvideo.VideoInfo, p_align: *const gstvideo.VideoAlignment, p_plane: c_uint) usize;
pub const glGetPlaneDataSize = gst_gl_get_plane_data_size;

extern fn gst_gl_get_plane_start(p_info: *const gstvideo.VideoInfo, p_valign: *const gstvideo.VideoAlignment, p_plane: c_uint) usize;
pub const glGetPlaneStart = gst_gl_get_plane_start;

extern fn gst_gl_handle_context_query(p_element: *gst.Element, p_query: *gst.Query, p_display: ?*gstgl.GLDisplay, p_context: ?*gstgl.GLContext, p_other_context: ?*gstgl.GLContext) c_int;
pub const glHandleContextQuery = gst_gl_handle_context_query;

/// Helper function for implementing `gst.ElementClass.virtual_methods.set_context` in
/// OpenGL capable elements.
///
/// Retrieve's the `gstgl.GLDisplay` or `gstgl.GLContext` in `context` and places the
/// result in `display` or `other_context` respectively.
extern fn gst_gl_handle_set_context(p_element: *gst.Element, p_context: *gst.Context, p_display: **gstgl.GLDisplay, p_other_context: **gstgl.GLContext) c_int;
pub const glHandleSetContext = gst_gl_handle_set_context;

/// Inserts a marker into a GL debug stream.  Requires the 'gldebugmarker'
/// debug category to be at least `GST_LEVEL_FIXME`.
extern fn gst_gl_insert_debug_marker(p_context: *gstgl.GLContext, p_format: [*:0]const u8, ...) void;
pub const glInsertDebugMarker = gst_gl_insert_debug_marker;

/// Multiplies two 4x4 matrices, `a` and `b`, and stores the result, a
/// 2-dimensional array of `gfloat`, in `result`.
extern fn gst_gl_multiply_matrix4(p_a: *const [16]f32, p_b: *const [16]f32, p_result: *[16]f32) void;
pub const glMultiplyMatrix4 = gst_gl_multiply_matrix4;

/// Set the 4x4 affine transformation matrix stored in `meta` from the
/// NDC coordinates in `matrix`.
extern fn gst_gl_set_affine_transformation_meta_from_ndc(p_meta: *gstvideo.VideoAffineTransformationMeta, p_matrix: *const [16]f32) void;
pub const glSetAffineTransformationMetaFromNdc = gst_gl_set_affine_transformation_meta_from_ndc;

extern fn gst_gl_sized_gl_format_from_gl_format_type(p_context: *gstgl.GLContext, p_format: c_uint, p_type: c_uint) c_uint;
pub const glSizedGlFormatFromGlFormatType = gst_gl_sized_gl_format_from_gl_format_type;

extern fn gst_gl_stereo_downmix_mode_get_type() usize;
pub const glStereoDownmixModeGetType = gst_gl_stereo_downmix_mode_get_type;

/// Given `swizzle`, produce `inversion` such that:
///
/// `swizzle`[`inversion`[i]] == identity[i] where:
/// - identity = {0, 1, 2,...}
/// - unset fields are marked by -1
extern fn gst_gl_swizzle_invert(p_swizzle: *[4]c_int, p_inversion: *[4]c_int) void;
pub const glSwizzleInvert = gst_gl_swizzle_invert;

extern fn gst_gl_sync_meta_api_get_type() usize;
pub const glSyncMetaApiGetType = gst_gl_sync_meta_api_get_type;

/// See `gstgl.glValueSetTextureTargetFromMask` for what entails a mask
extern fn gst_gl_value_get_texture_target_mask(p_value: *const gobject.Value) gstgl.GLTextureTarget;
pub const glValueGetTextureTargetMask = gst_gl_value_get_texture_target_mask;

extern fn gst_gl_value_set_texture_target(p_value: *gobject.Value, p_target: gstgl.GLTextureTarget) c_int;
pub const glValueSetTextureTarget = gst_gl_value_set_texture_target;

/// A mask is a bitwise OR of (1 << target) where target is a valid
/// `gstgl.GLTextureTarget`
extern fn gst_gl_value_set_texture_target_from_mask(p_value: *gobject.Value, p_target_mask: gstgl.GLTextureTarget) c_int;
pub const glValueSetTextureTargetFromMask = gst_gl_value_set_texture_target_from_mask;

extern fn gst_gl_version_to_glsl_version(p_gl_api: gstgl.GLAPI, p_maj: c_int, p_min: c_int) gstgl.GLSLVersion;
pub const glVersionToGlslVersion = gst_gl_version_to_glsl_version;

/// Calculates the swizzle indices for `video_format` and `gl_format` in order to
/// access a texture such that accessing a texel from a texture through the swizzle
/// index produces values in the order (R, G, B, A) or (Y, U, V, A).
///
/// For multi-planer formats, the swizzle index uses the same component order (RGBA/YUVA)
/// and should be applied after combining multiple planes into a single rgba/yuva value.
/// e.g. sampling from a NV12 format would have Y from one texture and UV from
/// another texture into a (Y, U, V) value.  Add an Aplha component and then
/// perform swizzling.  Sampling from NV21 would produce (Y, V, U) which is then
/// swizzled to (Y, U, V).
extern fn gst_gl_video_format_swizzle(p_video_format: gstvideo.VideoFormat, p_swizzle: *[4]c_int) c_int;
pub const glVideoFormatSwizzle = gst_gl_video_format_swizzle;

/// Note: this function first searches the first 1 kilobytes for a ``version``
/// preprocessor directive and then executes `gstgl.glslVersionProfileFromString`.
extern fn gst_glsl_string_get_version_profile(p_s: [*:0]const u8, p_version: *gstgl.GLSLVersion, p_profile: *gstgl.GLSLProfile) c_int;
pub const glslStringGetVersionProfile = gst_glsl_string_get_version_profile;

extern fn gst_is_gl_base_memory(p_mem: *gst.Memory) c_int;
pub const isGlBaseMemory = gst_is_gl_base_memory;

extern fn gst_is_gl_buffer(p_mem: *gst.Memory) c_int;
pub const isGlBuffer = gst_is_gl_buffer;

extern fn gst_is_gl_memory(p_mem: *gst.Memory) c_int;
pub const isGlMemory = gst_is_gl_memory;

extern fn gst_is_gl_memory_pbo(p_mem: *gst.Memory) c_int;
pub const isGlMemoryPbo = gst_is_gl_memory_pbo;

extern fn gst_is_gl_renderbuffer(p_mem: *gst.Memory) c_int;
pub const isGlRenderbuffer = gst_is_gl_renderbuffer;

/// Copies the parameters from `src` into `dest`.  The subclass must compose copy
/// functions from the superclass.
pub const GLAllocationParamsCopyFunc = *const fn (p_src: *gstgl.GLAllocationParams, p_dest: *gstgl.GLAllocationParams) callconv(.c) void;

/// Free any dynamically allocated data.  The subclass must call the superclass'
/// free.
pub const GLAllocationParamsFreeFunc = *const fn (p_params: ?*anyopaque) callconv(.c) void;

pub const GLAsyncDebugLogGetMessage = *const fn (p_user_data: ?*anyopaque) callconv(.c) [*:0]u8;

/// Note: not called with a GL context current
pub const GLBaseMemoryAllocatorAllocFunction = *const fn (p_allocator: *gstgl.GLBaseMemoryAllocator, p_params: *gstgl.GLAllocationParams) callconv(.c) ?*gstgl.GLBaseMemory;

/// Also see `gst.Memory.copy`;
pub const GLBaseMemoryAllocatorCopyFunction = *const fn (p_mem: *gstgl.GLBaseMemory, p_offset: isize, p_size: isize) callconv(.c) ?*gstgl.GLBaseMemory;

/// As this virtual method is called with an OpenGL context current, use this
/// function to allocate and OpenGL resources needed for your application
pub const GLBaseMemoryAllocatorCreateFunction = *const fn (p_mem: *gstgl.GLBaseMemory, p_error: ?*?*glib.Error) callconv(.c) c_int;

/// Destroy any resources allocated throughout the lifetime of `mem`
pub const GLBaseMemoryAllocatorDestroyFunction = *const fn (p_mem: *gstgl.GLBaseMemory) callconv(.c) void;

/// Also see `gst.Memory.map`;
pub const GLBaseMemoryAllocatorMapFunction = *const fn (p_mem: *gstgl.GLBaseMemory, p_info: *gst.MapInfo, p_maxsize: usize) callconv(.c) ?*anyopaque;

/// Also see `gst.Memory.unmap`;
pub const GLBaseMemoryAllocatorUnmapFunction = *const fn (p_mem: *gstgl.GLBaseMemory, p_info: *gst.MapInfo) callconv(.c) void;

/// Represents a function to run in the GL thread with `context` and `data`
pub const GLContextThreadFunc = *const fn (p_context: *gstgl.GLContext, p_data: ?*anyopaque) callconv(.c) void;

pub const GLFilterRenderFunc = *const fn (p_filter: *gstgl.GLFilter, p_in_tex: *gstgl.GLMemory, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// callback definition for operating through a `gstgl.GLFramebuffer` object
pub const GLFramebufferFunc = *const fn (p_stuff: ?*anyopaque) callconv(.c) c_int;

pub const GLWindowCB = *const fn (p_data: ?*anyopaque) callconv(.c) void;

pub const GLWindowResizeCB = *const fn (p_data: ?*anyopaque, p_width: c_uint, p_height: c_uint) callconv(.c) void;

/// An option that can be activated on bufferpools to request OpenGL
/// synchronization metadata on buffers from the pool.
pub const BUFFER_POOL_OPTION_GL_SYNC_META = "GstBufferPoolOptionGLSyncMeta";
/// String used for `GST_GL_TEXTURE_TARGET_2D` as a `gst.BufferPool` pool option
pub const BUFFER_POOL_OPTION_GL_TEXTURE_TARGET_2D = "GstBufferPoolOptionGLTextureTarget2D";
/// String used for `GST_GL_TEXTURE_TARGET_EXTERNAL_OES` as a `gst.BufferPool` pool option
pub const BUFFER_POOL_OPTION_GL_TEXTURE_TARGET_EXTERNAL_OES = "GstBufferPoolOptionGLTextureTargetExternalOES";
/// String used for `GST_GL_TEXTURE_TARGET_RECTANGLE` as a `gst.BufferPool` pool option
pub const BUFFER_POOL_OPTION_GL_TEXTURE_TARGET_RECTANGLE = "GstBufferPoolOptionGLTextureTargetRectangle";
/// Name of the caps feature indicating the use of GL buffers
pub const CAPS_FEATURE_MEMORY_GL_BUFFER = "memory:GLBuffer";
/// Name of the caps feature for indicating the use of `gstgl.GLMemory`
pub const CAPS_FEATURE_MEMORY_GL_MEMORY = "memory:GLMemory";
/// GL Allocation flag indicating that the implementation should allocate the
/// necessary resources.
pub const GL_ALLOCATION_PARAMS_ALLOC_FLAG_ALLOC = 1;
/// GL allocation flag indicating the allocation of a GL buffer.
pub const GL_ALLOCATION_PARAMS_ALLOC_FLAG_BUFFER = 16;
/// Values >= than `GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_USER` can be used for
/// user-defined purposes.
pub const GL_ALLOCATION_PARAMS_ALLOC_FLAG_USER = 65536;
/// GL allocation flag indicating the allocation of 2D video frames
pub const GL_ALLOCATION_PARAMS_ALLOC_FLAG_VIDEO = 8;
/// GL Allocation flag for using the provided GPU handle as storage.
pub const GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_GPU_HANDLE = 4;
/// GL Allocation flag for using the provided system memory data as storage.
pub const GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_SYSMEM = 2;
/// The name for `GST_GL_API_GLES1` used in various places
pub const GL_API_GLES1_NAME = "gles1";
/// The name for `GST_GL_API_GLES2` used in various places
pub const GL_API_GLES2_NAME = "gles2";
/// The name for `GST_GL_API_OPENGL3` used in various places
pub const GL_API_OPENGL3_NAME = "opengl3";
/// The name for `GST_GL_API_OPENGL` used in various places
pub const GL_API_OPENGL_NAME = "opengl";
/// The name of the GL buffer allocator
pub const GL_BASE_MEMORY_ALLOCATOR_NAME = "GLBaseMemory";
/// The name of the GL buffer allocator
pub const GL_BUFFER_ALLOCATOR_NAME = "GLBuffer";
pub const GL_COLOR_CONVERT_EXT_FORMATS = ", RGBA64_LE, BGR10A2_LE, RGB10A2_LE, P010_10LE, P012_LE, P016_LE, Y212_LE, Y412_LE, A444_16LE, A422_16LE, A420_16LE, A444_12LE, A422_12LE, A420_12LE, A420_10LE, A422_10LE, A444_10LE, I420_12LE, I420_10LE, I422_10LE, I422_12LE, Y444_16LE, Y444_10LE";
/// The currently supported formats that can be converted
pub const GL_COLOR_CONVERT_FORMATS = "{ RGBA, RGB, RGBx, BGR, BGRx, BGRA, xRGB, xBGR, ARGB, ABGR, GBRA, GBR, RGBP, BGRP, Y444, I420, YV12, Y42B, Y41B, NV12, NV21, NV16, NV61, YUY2, UYVY, Y210, AYUV, VUYA, Y410, A444, A422, GRAY8, GRAY16_LE, GRAY16_BE, RGB16, BGR16, ARGB64, A420, AV12, NV12_16L32S, NV12_4L4, RBGA, v210";
/// The currently supported `gst.Caps` that can be converted
pub const GL_COLOR_CONVERT_VIDEO_CAPS = "video/x-raw(";
/// The canonical name of a `gst.Structure` that contains a configuration for a
/// `gstgl.GLContext`.
pub const GL_CONFIG_STRUCTURE_NAME = "gst-gl-context-config";
pub const GL_CONTEXT_TYPE_CGL = "gst.gl.context.CGL";
pub const GL_CONTEXT_TYPE_EAGL = "gst.gl.context.EAGL";
pub const GL_CONTEXT_TYPE_EGL = "gst.gl.context.EGL";
pub const GL_CONTEXT_TYPE_GLX = "gst.gl.context.GLX";
pub const GL_CONTEXT_TYPE_WGL = "gst.gl.context.WGL";
/// The name used in `gst.Context` queries for requesting a `gstgl.GLDisplay`
pub const GL_DISPLAY_CONTEXT_TYPE = "gst.gl.GLDisplay";
/// The name of the GL memory allocator
pub const GL_MEMORY_ALLOCATOR_NAME = "GLMemory";
/// The name of the GL Memory PBO allocator
pub const GL_MEMORY_PBO_ALLOCATOR_NAME = "GLMemoryPBO";
pub const GL_MEMORY_VIDEO_EXT_FORMATS = ", RGBA64_LE, BGR10A2_LE, RGB10A2_LE, P010_10LE, P012_LE, P016_LE, Y212_LE, Y412_LE, A444_16LE, A422_16LE, A420_16LE, A444_12LE, A422_12LE, A420_12LE, A420_10LE, A422_10LE, A444_10LE, I420_12LE, I420_10LE, I422_10LE, I422_12LE, Y444_10LE, Y444_16LE";
/// List of video formats that are supported by `gstgl.GLMemory`
pub const GL_MEMORY_VIDEO_FORMATS_STR = "{ RGBA, BGRA, RGBx, BGRx, ARGB, ABGR, xRGB, xBGR, GBRA, GBR, RGBP, BGRP, RGB, BGR, RGB16, BGR16, AYUV, VUYA, A444, A422, Y410, I420, YV12, NV12, NV21, NV16, NV61, YUY2, UYVY, Y210, Y41B, Y42B, Y444, GRAY8, GRAY16_LE, GRAY16_BE, ARGB64, A420, AV12, NV12_16L32S, NV12_4L4, RBGA, v210";
/// The name of the GL renderbuffer allocator
pub const GL_RENDERBUFFER_ALLOCATOR_NAME = "GLRenderbuffer";
/// String used for `GST_GL_TEXTURE_TARGET_2D` in things like caps values
pub const GL_TEXTURE_TARGET_2D_STR = "2D";
/// String used for `GST_GL_TEXTURE_TARGET_EXTERNAL_OES` in things like caps values
pub const GL_TEXTURE_TARGET_EXTERNAL_OES_STR = "external-oes";
/// String used for `GST_GL_TEXTURE_TARGET_RECTANGLE` in things like caps values
pub const GL_TEXTURE_TARGET_RECTANGLE_STR = "rectangle";
/// Flag indicating that we should map the GL object instead of to system memory.
///
/// Combining `GST_MAP_GL` with `GST_MAP_WRITE` has the same semantics as though
/// you are writing to OpenGL. Conversely, combining `GST_MAP_GL` with
/// `GST_MAP_READ` has the same semantics as though you are reading from OpenGL.
pub const MAP_GL = 131072;

test {
    @setEvalBranchQuota(100_000);
    std.testing.refAllDecls(@This());
    std.testing.refAllDecls(ext);
}
