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 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
// Take a look at the license at the top of the repository in the LICENSE file.
use glib::{prelude::*, translate::*};
use crate::{GLContext, GLTextureBuilder, MemoryFormat, Texture};
#[cfg(not(feature = "gl"))]
pub type GLsync = *const libc::c_void;
#[cfg(feature = "gl")]
pub use gl::types::GLsync;
impl GLTextureBuilder {
/// Builds a new [`Texture`][crate::Texture] with the values set up in the builder.
///
/// The `destroy` function gets called when the returned texture gets released;
/// either when the texture is finalized or by an explicit call to
/// [`GLTexture::release()`][crate::GLTexture::release()]. It should release all GL resources associated
/// with the texture, such as the [`id`][struct@crate::GLTextureBuilder#id] and the
/// [`sync`][struct@crate::GLTextureBuilder#sync].
///
/// Note that it is a programming error to call this function if any mandatory
/// property has not been set.
///
/// It is possible to call this function multiple times to create multiple textures,
/// possibly with changing properties in between.
///
/// # Returns
///
/// a newly built [`Texture`][crate::Texture]
#[doc(alias = "gdk_gl_texture_builder_build")]
#[must_use = "The builder must be built to be used"]
#[allow(clippy::missing_safety_doc)]
pub unsafe fn build(self) -> Texture {
from_glib_full(ffi::gdk_gl_texture_builder_build(
self.to_glib_none().0,
None,
std::ptr::null_mut(),
))
}
#[doc(alias = "gdk_gl_texture_builder_build")]
#[must_use = "The builder must be built to be used"]
#[allow(clippy::missing_safety_doc)]
pub unsafe fn build_with_release_func<F: FnOnce() + Send + 'static>(
self,
release_func: F,
) -> Texture {
unsafe extern "C" fn destroy_closure<F: FnOnce() + Send + 'static>(
func: glib::ffi::gpointer,
) {
let released_func = Box::<F>::from_raw(func as *mut _);
released_func();
}
let released_func = Box::new(release_func);
from_glib_full(ffi::gdk_gl_texture_builder_build(
self.to_glib_none().0,
Some(destroy_closure::<F>),
Box::into_raw(released_func) as glib::ffi::gpointer,
))
}
/// Sets the context to be used for the texture. This is the context that owns
/// the texture.
///
/// The context must be set before calling [`build()`][Self::build()].
/// ## `context`
/// The context the texture beongs to or [`None`] to unset
#[doc(alias = "gdk_gl_texture_builder_set_context")]
pub fn set_context(self, context: Option<&impl IsA<GLContext>>) -> Self {
unsafe {
ffi::gdk_gl_texture_builder_set_context(
self.to_glib_none().0,
context.map(|p| p.as_ref()).to_glib_none().0,
);
}
self
}
/// Sets the format of the texture. The default is `GDK_MEMORY_R8G8B8A8_PREMULTIPLIED`.
///
/// The format is the preferred format the texture data should be downloaded to. The
/// format must be supported by the GL version of [`context`][struct@crate::GLTextureBuilder#context].
///
/// GDK's texture download code assumes that the format corresponds to the storage
/// parameters of the GL texture in an obvious way. For example, a format of
/// `GDK_MEMORY_R16G16B16A16_PREMULTIPLIED` is expected to be stored as `GL_RGBA16`
/// texture, and `GDK_MEMORY_G8A8` is expected to be stored as `GL_RG8` texture.
///
/// Setting the right format is particularly useful when using high bit depth textures
/// to preserve the bit depth, to set the correct value for unpremultiplied textures
/// and to make sure opaque textures are treated as such.
///
/// Non-RGBA textures need to have swizzling parameters set up properly to be usable
/// in GSK's shaders.
/// ## `format`
/// The texture's format
#[doc(alias = "gdk_gl_texture_builder_set_format")]
pub fn set_format(self, format: MemoryFormat) -> Self {
unsafe {
ffi::gdk_gl_texture_builder_set_format(self.to_glib_none().0, format.into_glib());
}
self
}
/// Sets whether the texture has a mipmap. This allows the renderer and other users of the
/// generated texture to use a higher quality downscaling.
///
/// Typically, the `glGenerateMipmap` function is used to generate a mimap.
/// ## `has_mipmap`
/// Whether the texture has a mipmap
#[doc(alias = "gdk_gl_texture_builder_set_has_mipmap")]
pub fn set_has_mipmap(self, has_mipmap: bool) -> Self {
unsafe {
ffi::gdk_gl_texture_builder_set_has_mipmap(
self.to_glib_none().0,
has_mipmap.into_glib(),
);
}
self
}
/// Sets the height of the texture.
///
/// The height must be set before calling [`build()`][Self::build()].
/// ## `height`
/// The texture's height or 0 to unset
#[doc(alias = "gdk_gl_texture_builder_set_height")]
pub fn set_height(self, height: i32) -> Self {
unsafe {
ffi::gdk_gl_texture_builder_set_height(self.to_glib_none().0, height);
}
self
}
/// Sets the texture id of the texture. The texture id must remain unmodified
/// until the texture was finalized. See [`build()`][Self::build()]
/// for a longer discussion.
///
/// The id must be set before calling [`build()`][Self::build()].
/// ## `id`
/// The texture id to be used for creating the texture
#[doc(alias = "gdk_gl_texture_builder_set_id")]
pub fn set_id(self, id: u32) -> Self {
unsafe {
ffi::gdk_gl_texture_builder_set_id(self.to_glib_none().0, id);
}
self
}
/// Sets the region to be updated by this texture. Together with
/// [`update-texture`][struct@crate::GLTextureBuilder#update-texture] this describes an
/// update of a previous texture.
///
/// When rendering animations of large textures, it is possible that
/// consecutive textures are only updating contents in parts of the texture.
/// It is then possible to describe this update via these two properties,
/// so that GTK can avoid rerendering parts that did not change.
///
/// An example would be a screen recording where only the mouse pointer moves.
/// ## `region`
/// the region to update
#[doc(alias = "gdk_gl_texture_builder_set_update_region")]
pub fn set_update_region(self, region: Option<&cairo::Region>) -> Self {
unsafe {
ffi::gdk_gl_texture_builder_set_update_region(
self.to_glib_none().0,
mut_override(region.to_glib_none().0),
);
}
self
}
/// Sets the texture to be updated by this texture. See
/// [`set_update_region()`][Self::set_update_region()] for an explanation.
/// ## `texture`
/// the texture to update
#[doc(alias = "gdk_gl_texture_builder_set_update_texture")]
pub fn set_update_texture(self, texture: Option<&impl IsA<Texture>>) -> Self {
unsafe {
ffi::gdk_gl_texture_builder_set_update_texture(
self.to_glib_none().0,
texture.map(|p| p.as_ref()).to_glib_none().0,
);
}
self
}
/// Sets the width of the texture.
///
/// The width must be set before calling [`build()`][Self::build()].
/// ## `width`
/// The texture's width or 0 to unset
#[doc(alias = "gdk_gl_texture_builder_set_width")]
pub fn set_width(self, width: i32) -> Self {
unsafe {
ffi::gdk_gl_texture_builder_set_width(self.to_glib_none().0, width);
}
self
}
/// Gets the `GLsync` previously set via gdk_gl_texture_builder_set_sync().
///
/// # Returns
///
/// the `GLSync`
#[doc(alias = "gdk_gl_texture_builder_get_sync")]
#[doc(alias = "get_sync")]
pub fn sync(&self) -> Option<GLsync> {
let ptr = unsafe { ffi::gdk_gl_texture_builder_get_sync(self.to_glib_none().0) };
if ptr.is_null() {
None
} else {
Some(ptr as _)
}
}
/// Sets the GLSync object to use for the texture.
///
/// GTK will wait on this object before using the created [`Texture`][crate::Texture].
///
/// The `destroy` function that is passed to [`build()`][Self::build()]
/// is responsible for freeing the sync object when it is no longer needed.
/// The texture builder does not destroy it and it is the callers
/// responsibility to make sure it doesn't leak.
/// ## `sync`
/// the GLSync object
#[doc(alias = "gdk_gl_texture_builder_set_sync")]
pub fn set_sync(self, sync: Option<GLsync>) -> Self {
let ptr = sync.unwrap_or(std::ptr::null());
unsafe {
ffi::gdk_gl_texture_builder_set_sync(self.to_glib_none().0, ptr as _);
}
self
}
}