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
use glib::{prelude::*, translate::*};
use crate::{ffi, GLFramebuffer, GLMemoryRef};
mod sealed {
pub trait Sealed {}
impl<T: super::IsA<super::GLFramebuffer>> Sealed for T {}
}
pub trait GLFramebufferExtManual: sealed::Sealed + IsA<GLFramebuffer> + 'static {
/// 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()`][crate::gst::Memory::map()] with the map flags `GST_MAP_WRITE` | `GST_MAP_GL`.
///
/// Must be called with the same OpenGL context current that `self` was created
/// with.
/// ## `mem`
/// the [`GLMemory`][crate::GLMemory] to draw to
/// ## `func`
/// the function to run
///
/// # Returns
///
/// the result of executing `func`
#[doc(alias = "gst_gl_framebuffer_draw_to_texture")]
fn draw_to_texture<F: FnOnce()>(&self, mem: &mut GLMemoryRef, func: F) {
let mut func = std::mem::ManuallyDrop::new(func);
let user_data: *mut F = &mut *func;
unsafe extern "C" fn trampoline<F: FnOnce()>(
data: glib::ffi::gpointer,
) -> glib::ffi::gboolean {
let func = std::ptr::read(data as *mut F);
func();
glib::ffi::GTRUE
}
unsafe {
ffi::gst_gl_framebuffer_draw_to_texture(
self.as_ref().to_glib_none().0,
mem.as_mut_ptr(),
Some(trampoline::<F>),
user_data as glib::ffi::gpointer,
);
}
}
}
impl<O: IsA<GLFramebuffer>> GLFramebufferExtManual for O {}