gtk4: Use glib::ThreadGuard instead of the fragile crate

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/272

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1024>
This commit is contained in:
Sebastian Dröge 2022-12-22 21:34:08 +02:00 committed by GStreamer Marge Bot
parent 52764e140e
commit 1026949b2b
2 changed files with 31 additions and 32 deletions

View file

@ -23,7 +23,6 @@ gst_gl_x11 = { package = "gstreamer-gl-x11", git = "https://gitlab.freedesktop.o
gst_gl_egl = { package = "gstreamer-gl-egl", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", features = ["v1_16"], optional = true } gst_gl_egl = { package = "gstreamer-gl-egl", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", features = ["v1_16"], optional = true }
once_cell = "1.0" once_cell = "1.0"
fragile = "2"
[lib] [lib]
name = "gstgtk4" name = "gstgtk4"

View file

@ -13,7 +13,7 @@ use super::SinkEvent;
use crate::sink::frame::Frame; use crate::sink::frame::Frame;
use crate::sink::paintable::Paintable; use crate::sink::paintable::Paintable;
use glib::Sender; use glib::{thread_guard::ThreadGuard, Sender};
use gtk::prelude::*; use gtk::prelude::*;
use gtk::{gdk, glib}; use gtk::{gdk, glib};
@ -25,7 +25,6 @@ use once_cell::sync::Lazy;
use std::sync::{Mutex, MutexGuard}; use std::sync::{Mutex, MutexGuard};
use crate::utils; use crate::utils;
use fragile::Fragile;
#[cfg(feature = "gst_gl")] #[cfg(feature = "gst_gl")]
use glib::translate::*; use glib::translate::*;
@ -44,9 +43,9 @@ static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
) )
}); });
#[derive(Default, Debug)] #[derive(Default)]
pub struct PaintableSink { pub struct PaintableSink {
paintable: Mutex<Option<Fragile<Paintable>>>, paintable: Mutex<Option<ThreadGuard<Paintable>>>,
info: Mutex<Option<gst_video::VideoInfo>>, info: Mutex<Option<gst_video::VideoInfo>>,
sender: Mutex<Option<Sender<SinkEvent>>>, sender: Mutex<Option<Sender<SinkEvent>>>,
pending_frame: Mutex<Option<Frame>>, pending_frame: Mutex<Option<Frame>>,
@ -109,9 +108,9 @@ impl ObjectImpl for PaintableSink {
}; };
// Getter must be called from the main thread // Getter must be called from the main thread
match paintable.try_get() { if paintable.is_owner() {
Ok(paintable) => paintable.to_value(), paintable.get_ref().to_value()
Err(_) => { } else {
gst::error!( gst::error!(
CAT, CAT,
imp: self, imp: self,
@ -120,7 +119,6 @@ impl ObjectImpl for PaintableSink {
None::<&gdk::Paintable>.to_value() None::<&gdk::Paintable>.to_value()
} }
} }
}
_ => unimplemented!(), _ => unimplemented!(),
} }
} }
@ -226,7 +224,7 @@ impl ElementImpl for PaintableSink {
utils::invoke_on_main_thread(move || { utils::invoke_on_main_thread(move || {
let paintable = self_.paintable.lock().unwrap(); let paintable = self_.paintable.lock().unwrap();
if let Some(paintable) = &*paintable { if let Some(paintable) = &*paintable {
paintable.get().handle_flush_frames(); paintable.get_ref().handle_flush_frames();
} }
}); });
} }
@ -458,16 +456,18 @@ impl PaintableSink {
} }
fn do_action(&self, action: SinkEvent) -> glib::Continue { fn do_action(&self, action: SinkEvent) -> glib::Continue {
let paintable = self.paintable.lock().unwrap().clone(); let paintable = self.paintable.lock().unwrap();
let paintable = match paintable { let paintable = match &*paintable {
Some(paintable) => paintable, Some(paintable) => paintable.clone(),
None => return glib::Continue(false), None => return glib::Continue(false),
}; };
match action { match action {
SinkEvent::FrameChanged => { SinkEvent::FrameChanged => {
gst::trace!(CAT, imp: self, "Frame changed"); gst::trace!(CAT, imp: self, "Frame changed");
paintable.get().handle_frame_changed(self.pending_frame()) paintable
.get_ref()
.handle_frame_changed(self.pending_frame())
} }
} }
@ -496,7 +496,7 @@ impl PaintableSink {
.replace(tmp_caps); .replace(tmp_caps);
} }
fn create_paintable(&self, paintable_storage: &mut MutexGuard<Option<Fragile<Paintable>>>) { fn create_paintable(&self, paintable_storage: &mut MutexGuard<Option<ThreadGuard<Paintable>>>) {
#[allow(unused_mut)] #[allow(unused_mut)]
let mut ctx = None; let mut ctx = None;
@ -516,15 +516,15 @@ impl PaintableSink {
fn initialize_paintable( fn initialize_paintable(
&self, &self,
gl_context: Option<Fragile<gdk::GLContext>>, gl_context: Option<ThreadGuard<gdk::GLContext>>,
paintable_storage: &mut MutexGuard<Option<Fragile<Paintable>>>, paintable_storage: &mut MutexGuard<Option<ThreadGuard<Paintable>>>,
) { ) {
gst::debug!(CAT, imp: self, "Initializing paintable"); gst::debug!(CAT, imp: self, "Initializing paintable");
let paintable = utils::invoke_on_main_thread(|| { let paintable = utils::invoke_on_main_thread(|| {
// grab the context out of the fragile // grab the context out of the fragile
let ctx = gl_context.map(|f| f.into_inner()); let ctx = gl_context.map(|f| f.into_inner());
Fragile::new(Paintable::new(ctx)) ThreadGuard::new(Paintable::new(ctx))
}); });
// The channel for the SinkEvents // The channel for the SinkEvents
@ -544,11 +544,11 @@ impl PaintableSink {
} }
#[cfg(feature = "gst_gl")] #[cfg(feature = "gst_gl")]
fn realize_context(&self) -> Option<Fragile<gdk::GLContext>> { fn realize_context(&self) -> Option<ThreadGuard<gdk::GLContext>> {
gst::debug!(CAT, imp: self, "Realizing GDK GL Context"); gst::debug!(CAT, imp: self, "Realizing GDK GL Context");
let weak = self.instance().downgrade(); let weak = self.instance().downgrade();
let cb = move || -> Option<Fragile<gdk::GLContext>> { let cb = move || -> Option<ThreadGuard<gdk::GLContext>> {
let obj = weak let obj = weak
.upgrade() .upgrade()
.expect("Failed to upgrade Weak ref during gl initialization."); .expect("Failed to upgrade Weak ref during gl initialization.");
@ -576,7 +576,7 @@ impl PaintableSink {
if ctx.realize().is_ok() { if ctx.realize().is_ok() {
gst::info!(CAT, obj: &obj, "Successfully realized GDK GL Context",); gst::info!(CAT, obj: &obj, "Successfully realized GDK GL Context",);
return Some(Fragile::new(ctx)); return Some(ThreadGuard::new(ctx));
} else { } else {
gst::warning!(CAT, obj: &obj, "Failed to realize GDK GL Context",); gst::warning!(CAT, obj: &obj, "Failed to realize GDK GL Context",);
} }
@ -593,8 +593,8 @@ impl PaintableSink {
#[cfg(feature = "gst_gl")] #[cfg(feature = "gst_gl")]
fn initialize_gl_wrapper( fn initialize_gl_wrapper(
&self, &self,
context: Fragile<gdk::GLContext>, context: ThreadGuard<gdk::GLContext>,
) -> Result<Fragile<gdk::GLContext>, glib::Error> { ) -> Result<ThreadGuard<gdk::GLContext>, glib::Error> {
gst::info!(CAT, imp: self, "Initializing GDK GL Context"); gst::info!(CAT, imp: self, "Initializing GDK GL Context");
let self_ = self.instance().clone(); let self_ = self.instance().clone();
utils::invoke_on_main_thread(move || self_.imp().initialize_gl(context)) utils::invoke_on_main_thread(move || self_.imp().initialize_gl(context))
@ -603,9 +603,9 @@ impl PaintableSink {
#[cfg(feature = "gst_gl")] #[cfg(feature = "gst_gl")]
fn initialize_gl( fn initialize_gl(
&self, &self,
context: Fragile<gdk::GLContext>, context: ThreadGuard<gdk::GLContext>,
) -> Result<Fragile<gdk::GLContext>, glib::Error> { ) -> Result<ThreadGuard<gdk::GLContext>, glib::Error> {
let ctx = context.get(); let ctx = context.get_ref();
let display = gtk::prelude::GLContextExt::display(ctx) let display = gtk::prelude::GLContextExt::display(ctx)
.expect("Failed to get GDK Display from GDK Context."); .expect("Failed to get GDK Display from GDK Context.");
ctx.make_current(); ctx.make_current();