1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Take a look at the license at the top of the repository in the LICENSE file.

use crate::RenderNode;
use crate::{GLShader, RenderNodeType};
use glib::translate::*;

glib::wrapper! {
    /// A render node using a GL shader when drawing its children nodes.
    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
    #[doc(alias = "GskGLShaderNode")]
    pub struct GLShaderNode(Shared<ffi::GskGLShaderNode>);

    match fn {
        ref => |ptr| ffi::gsk_render_node_ref(ptr as *mut ffi::GskRenderNode),
        unref => |ptr| ffi::gsk_render_node_unref(ptr as *mut ffi::GskRenderNode),
    }
}

define_render_node!(
    GLShaderNode,
    ffi::GskGLShaderNode,
    ffi::gsk_gl_shader_node_get_type,
    RenderNodeType::GlShaderNode
);

impl GLShaderNode {
    /// Creates a [`RenderNode`][crate::RenderNode] that will render the given `shader` into the
    /// area given by `bounds`.
    ///
    /// The `args` is a block of data to use for uniform input, as per types and
    /// offsets defined by the `shader`. Normally this is generated by
    /// `Gsk::`GLShader::format_args()`` or [`ShaderArgsBuilder`][crate::ShaderArgsBuilder].
    ///
    /// See [`GLShader`][crate::GLShader] for details about how the shader should be written.
    ///
    /// All the children will be rendered into textures (if they aren't already
    /// `GskTextureNodes`, which will be used directly). These textures will be
    /// sent as input to the shader.
    ///
    /// If the renderer doesn't support GL shaders, or if there is any problem
    /// when compiling the shader, then the node will draw pink. You should use
    /// [``GLShader::compile()``][crate::`GLShader::compile()`] to ensure the `shader` will work for the
    /// renderer before using it.
    /// ## `shader`
    /// the [`GLShader`][crate::GLShader]
    /// ## `bounds`
    /// the rectangle to render the shader into
    /// ## `args`
    /// Arguments for the uniforms
    /// ## `children`
    /// array of child nodes, these will
    ///  be rendered to textures and used as input.
    ///
    /// # Returns
    ///
    /// A new [`RenderNode`][crate::RenderNode]
    #[doc(alias = "gsk_gl_shader_node_new")]
    pub fn new(
        shader: &GLShader,
        bounds: &graphene::Rect,
        args: &glib::Bytes,
        children: &[RenderNode],
    ) -> Self {
        skip_assert_initialized!();
        let n_children = children.len() as u32;
        unsafe {
            from_glib_full(ffi::gsk_gl_shader_node_new(
                shader.to_glib_none().0,
                bounds.to_glib_none().0,
                args.to_glib_none().0,
                children.to_glib_none().0,
                n_children,
            ))
        }
    }

    /// Gets args for the node.
    ///
    /// # Returns
    ///
    /// A `GBytes` with the uniform arguments
    #[doc(alias = "gsk_gl_shader_node_get_args")]
    #[doc(alias = "get_args")]
    pub fn args(&self) -> Option<glib::Bytes> {
        unsafe { from_glib_none(ffi::gsk_gl_shader_node_get_args(self.to_glib_none().0)) }
    }

    /// Gets one of the children.
    /// ## `idx`
    /// the position of the child to get
    ///
    /// # Returns
    ///
    /// the `idx`'th child of `self`
    #[doc(alias = "gsk_gl_shader_node_get_child")]
    #[doc(alias = "get_child")]
    pub fn child(&self, idx: u32) -> Option<RenderNode> {
        unsafe {
            from_glib_none(ffi::gsk_gl_shader_node_get_child(
                self.to_glib_none().0,
                idx,
            ))
        }
    }

    /// Returns the number of children
    ///
    /// # Returns
    ///
    /// The number of children
    #[doc(alias = "gsk_gl_shader_node_get_n_children")]
    #[doc(alias = "get_n_children")]
    pub fn n_children(&self) -> u32 {
        unsafe { ffi::gsk_gl_shader_node_get_n_children(self.to_glib_none().0) }
    }

    /// Gets shader code for the node.
    ///
    /// # Returns
    ///
    /// the [`GLShader`][crate::GLShader] shader
    #[doc(alias = "gsk_gl_shader_node_get_shader")]
    #[doc(alias = "get_shader")]
    pub fn shader(&self) -> Option<GLShader> {
        unsafe { from_glib_none(ffi::gsk_gl_shader_node_get_shader(self.to_glib_none().0)) }
    }
}