gstreamer-gl: Require object lock in GLDisplay

The methods `gst_gl_display_get_gl_context_for_thread()`,
`gst_gl_display_create_context()`, `gst_gl_display_add_context()` and
`gst_gl_display_remove_context()` now require the display's object lock
to be held when called.

This is required by the C API.

Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/439

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1212>
This commit is contained in:
Anders Hellerup Madsen 2023-02-05 17:56:47 +01:00 committed by Sebastian Dröge
parent a021aaa3ce
commit 3ddbdbd383
4 changed files with 90 additions and 67 deletions

View file

@ -338,19 +338,23 @@ status = "generate"
[[object.function]] [[object.function]]
name = "get_gl_context_for_thread" name = "get_gl_context_for_thread"
# glib::Thread not found in `glib` # require object lock
ignore = true manual = true
[[object.function]] [[object.function]]
name = "create_context" name = "create_context"
[[object.function.parameter]] # require object lock
name = "other_context" manual = true
nullable = true
[[object.function]] [[object.function]]
name = "add_context" name = "add_context"
[object.function.return] # require object lock
bool_return_is_error = "Failed to add OpenGL context" manual = true
[[object.function]]
name = "remove_context"
# require object lock
manual = true
[[object.function]] [[object.function]]
name = "remove_window" name = "remove_window"

View file

@ -9,7 +9,7 @@ use glib::{
signal::{connect_raw, SignalHandlerId}, signal::{connect_raw, SignalHandlerId},
translate::*, translate::*,
}; };
use std::{boxed::Box as Box_, mem::transmute, ptr}; use std::{boxed::Box as Box_, mem::transmute};
glib::wrapper! { glib::wrapper! {
#[doc(alias = "GstGLDisplay")] #[doc(alias = "GstGLDisplay")]
@ -49,15 +49,6 @@ unsafe impl Send for GLDisplay {}
unsafe impl Sync for GLDisplay {} unsafe impl Sync for GLDisplay {}
pub trait GLDisplayExt: 'static { pub trait GLDisplayExt: 'static {
#[doc(alias = "gst_gl_display_add_context")]
fn add_context(&self, context: &impl IsA<GLContext>) -> Result<(), glib::error::BoolError>;
#[doc(alias = "gst_gl_display_create_context")]
fn create_context(
&self,
other_context: Option<&impl IsA<GLContext>>,
) -> Result<GLContext, glib::Error>;
#[doc(alias = "gst_gl_display_create_window")] #[doc(alias = "gst_gl_display_create_window")]
fn create_window(&self) -> Result<GLWindow, glib::BoolError>; fn create_window(&self) -> Result<GLWindow, glib::BoolError>;
@ -76,11 +67,6 @@ pub trait GLDisplayExt: 'static {
#[doc(alias = "get_handle_type")] #[doc(alias = "get_handle_type")]
fn handle_type(&self) -> GLDisplayType; fn handle_type(&self) -> GLDisplayType;
#[cfg(any(feature = "v1_18", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
#[doc(alias = "gst_gl_display_remove_context")]
fn remove_context(&self, context: &impl IsA<GLContext>);
#[doc(alias = "gst_gl_display_remove_window")] #[doc(alias = "gst_gl_display_remove_window")]
fn remove_window(&self, window: &impl IsA<GLWindow>) -> Result<(), glib::error::BoolError>; fn remove_window(&self, window: &impl IsA<GLWindow>) -> Result<(), glib::error::BoolError>;
@ -99,40 +85,6 @@ pub trait GLDisplayExt: 'static {
} }
impl<O: IsA<GLDisplay>> GLDisplayExt for O { impl<O: IsA<GLDisplay>> GLDisplayExt for O {
fn add_context(&self, context: &impl IsA<GLContext>) -> Result<(), glib::error::BoolError> {
unsafe {
glib::result_from_gboolean!(
ffi::gst_gl_display_add_context(
self.as_ref().to_glib_none().0,
context.as_ref().to_glib_none().0
),
"Failed to add OpenGL context"
)
}
}
fn create_context(
&self,
other_context: Option<&impl IsA<GLContext>>,
) -> Result<GLContext, glib::Error> {
unsafe {
let mut p_context = ptr::null_mut();
let mut error = ptr::null_mut();
let is_ok = ffi::gst_gl_display_create_context(
self.as_ref().to_glib_none().0,
other_context.map(|p| p.as_ref()).to_glib_none().0,
&mut p_context,
&mut error,
);
debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
if error.is_null() {
Ok(from_glib_full(p_context))
} else {
Err(from_glib_full(error))
}
}
}
fn create_window(&self) -> Result<GLWindow, glib::BoolError> { fn create_window(&self) -> Result<GLWindow, glib::BoolError> {
unsafe { unsafe {
Option::<_>::from_glib_full(ffi::gst_gl_display_create_window( Option::<_>::from_glib_full(ffi::gst_gl_display_create_window(
@ -172,17 +124,6 @@ impl<O: IsA<GLDisplay>> GLDisplayExt for O {
} }
} }
#[cfg(any(feature = "v1_18", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
fn remove_context(&self, context: &impl IsA<GLContext>) {
unsafe {
ffi::gst_gl_display_remove_context(
self.as_ref().to_glib_none().0,
context.as_ref().to_glib_none().0,
);
}
}
fn remove_window(&self, window: &impl IsA<GLWindow>) -> Result<(), glib::error::BoolError> { fn remove_window(&self, window: &impl IsA<GLWindow>) -> Result<(), glib::error::BoolError> {
unsafe { unsafe {
glib::result_from_gboolean!( glib::result_from_gboolean!(

View file

@ -0,0 +1,77 @@
use crate::{GLContext, GLDisplay};
use glib::prelude::*;
use glib::translate::*;
impl GLDisplay {
#[doc(alias = "gst_gl_display_get_gl_context_for_thread")]
pub fn get_gl_context_for_current_thread(
display: &gst::ObjectLockGuard<GLDisplay>,
) -> Option<GLContext> {
skip_assert_initialized!();
unsafe {
let ctx = ffi::gst_gl_display_get_gl_context_for_thread(
display.as_ref().to_glib_none().0,
std::ptr::null_mut(),
);
from_glib_full(ctx)
}
}
#[doc(alias = "gst_gl_display_create_context")]
pub fn create_context(
display: &gst::ObjectLockGuard<GLDisplay>,
other_context: Option<&impl IsA<GLContext>>,
) -> Result<GLContext, glib::Error> {
skip_assert_initialized!();
unsafe {
let mut p_context = std::ptr::null_mut();
let mut error = std::ptr::null_mut();
let is_ok = ffi::gst_gl_display_create_context(
display.as_ref().to_glib_none().0,
other_context.map(|p| p.as_ref()).to_glib_none().0,
&mut p_context,
&mut error,
);
debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
if error.is_null() {
Ok(from_glib_full(p_context))
} else {
Err(from_glib_full(error))
}
}
}
#[doc(alias = "gst_gl_display_add_context")]
pub fn add_context(
display: &gst::ObjectLockGuard<GLDisplay>,
context: &impl IsA<GLContext>,
) -> Result<(), glib::error::BoolError> {
skip_assert_initialized!();
unsafe {
glib::result_from_gboolean!(
ffi::gst_gl_display_add_context(
display.as_ref().to_glib_none().0,
context.as_ref().to_glib_none().0
),
"Failed to add OpenGL context"
)
}
}
#[cfg(any(feature = "v1_18", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
#[doc(alias = "gst_gl_display_remove_context")]
pub fn remove_context(
display: &gst::ObjectLockGuard<GLDisplay>,
context: &impl IsA<GLContext>,
) {
skip_assert_initialized!();
unsafe {
ffi::gst_gl_display_remove_context(
display.as_ref().to_glib_none().0,
context.as_ref().to_glib_none().0,
);
}
}
}

View file

@ -40,6 +40,7 @@ mod context;
pub mod functions; pub mod functions;
pub use crate::functions::*; pub use crate::functions::*;
mod gl_context; mod gl_context;
mod gl_display;
mod gl_sync_meta; mod gl_sync_meta;
mod gl_video_frame; mod gl_video_frame;
pub use crate::gl_sync_meta::*; pub use crate::gl_sync_meta::*;