diff options
author | Alan Jeffrey <ajeffrey@mozilla.com> | 2019-12-18 19:31:12 -0600 |
---|---|---|
committer | Alan Jeffrey <ajeffrey@mozilla.com> | 2019-12-18 19:31:12 -0600 |
commit | 9f52997f41ebf7091bec66a75da66114afeee52e (patch) | |
tree | 5a9ff9b408811b7a21459fd0553ca802090c5186 | |
parent | aca438aebc9291db9f1226d2575230a5189eddea (diff) | |
download | servo-9f52997f41ebf7091bec66a75da66114afeee52e.tar.gz servo-9f52997f41ebf7091bec66a75da66114afeee52e.zip |
Make wayland happier by sharing a Connection between servo and gstreamer
-rw-r--r-- | Cargo.lock | 2 | ||||
-rw-r--r-- | ports/gstplugin/servowebsrc.rs | 98 |
2 files changed, 74 insertions, 26 deletions
diff --git a/Cargo.lock b/Cargo.lock index 74ca6dee135..7c63170a11a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5502,7 +5502,7 @@ dependencies = [ [[package]] name = "surfman" version = "0.2.0" -source = "git+https://github.com/pcwalton/surfman?branch=multi#f9337ace825a2a42aec4cad042441e2ddb4e6e11" +source = "git+https://github.com/pcwalton/surfman?branch=multi#808e5c5906dbcc6707536c8bac8bcc9389b4e1eb" dependencies = [ "bitflags", "cgl 0.3.2", diff --git a/ports/gstplugin/servowebsrc.rs b/ports/gstplugin/servowebsrc.rs index 5629ba42284..6fd0a4467a8 100644 --- a/ports/gstplugin/servowebsrc.rs +++ b/ports/gstplugin/servowebsrc.rs @@ -126,6 +126,7 @@ pub struct ServoWebSrc { info: Mutex<Option<VideoInfo>>, buffer_pool: Mutex<Option<BufferPool>>, gl_context: Mutex<Option<GLContext>>, + connection: Mutex<Option<Connection>>, // When did the plugin get created? start: Instant, // How long should each frame last? @@ -156,9 +157,17 @@ thread_local! { static GFX_CACHE: RefCell<HashMap<GLContext, ServoWebSrcGfx>> = RefCell::new(HashMap::new()); } +struct ConnectionWhichImplementsDebug(Connection); + +impl std::fmt::Debug for ConnectionWhichImplementsDebug { + fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + "Connection".fmt(fmt) + } +} + #[derive(Debug)] enum ServoWebSrcMsg { - Start(GLVersion, ServoUrl), + Start(ConnectionWhichImplementsDebug, GLVersion, ServoUrl), GetSwapChain(Sender<SwapChain<Device>>), Resize(Size2D<i32, DevicePixel>), Heartbeat, @@ -186,8 +195,8 @@ struct ServoThreadGfx { impl ServoThread { fn new(receiver: Receiver<ServoWebSrcMsg>) -> Self { - let (version, url) = match receiver.recv() { - Ok(ServoWebSrcMsg::Start(version, url)) => (version, url), + let (connection, version, url) = match receiver.recv() { + Ok(ServoWebSrcMsg::Start(connection, version, url)) => (connection.0, version, url), e => panic!("Failed to start ({:?})", e), }; info!( @@ -195,7 +204,7 @@ impl ServoThread { version.major, version.minor, url ); let embedder = Box::new(ServoWebSrcEmbedder); - let window = Rc::new(ServoWebSrcWindow::new(version)); + let window = Rc::new(ServoWebSrcWindow::new(connection, version)); let swap_chain = window.swap_chain.clone(); let gfx = window.gfx.clone(); let mut servo = Servo::new(embedder, window); @@ -289,13 +298,12 @@ struct ServoWebSrcWindow { } impl ServoWebSrcWindow { - fn new(version: GLVersion) -> Self { + fn new(connection: Connection, version: GLVersion) -> Self { let flags = ContextAttributeFlags::DEPTH | ContextAttributeFlags::STENCIL | ContextAttributeFlags::ALPHA; let attributes = ContextAttributes { version, flags }; - let connection = Connection::new().expect("Failed to create connection"); let adapter = connection .create_adapter() .expect("Failed to create adapter"); @@ -330,7 +338,7 @@ impl ServoWebSrcWindow { .make_context_current(&mut context) .expect("Failed to make context current"); debug_assert_eq!(gl.get_error(), gl::NO_ERROR); - let access = SurfaceAccess::GPUCPU; + let access = SurfaceAccess::GPUOnly; let size = Size2D::new(512, 512); let surface_type = SurfaceType::Generic { size }; let surface = device @@ -489,6 +497,7 @@ impl ObjectSubclass for ServoWebSrc { let url = Mutex::new(None); let buffer_pool = Mutex::new(None); let gl_context = Mutex::new(None); + let connection = Mutex::new(None); let start = Instant::now(); let frame_duration_micros = AtomicU64::new(DEFAULT_FRAME_DURATION.as_micros() as u64); let next_frame_micros = AtomicU64::new(0); @@ -498,6 +507,7 @@ impl ObjectSubclass for ServoWebSrc { url, buffer_pool, gl_context, + connection, start, frame_duration_micros, next_frame_micros, @@ -650,21 +660,33 @@ impl BaseSrcImpl for ServoWebSrc { } let gl_context = unsafe { GLContext::from_glib_borrow(gst_gl_context) }; let gl_version = gl_context.get_gl_version(); - let version = if cfg!(all(unix, not(target_os = "macos"))) { - // TODO this is just a workaround. Fix it! - GLVersion { major: 3, minor: 0 } - } else { - GLVersion { - major: gl_version.0 as u8, - minor: gl_version.1 as u8, - } + let version = GLVersion { + major: gl_version.0 as u8, + minor: gl_version.1 as u8, }; - // Save the GL context for later use + // Get the surfman connection on the GL thread + let mut task = BootstrapSurfmanOnGLThread { + servo_web_src: self, + result: None, + }; + + let data = &mut task as *mut BootstrapSurfmanOnGLThread as *mut c_void; + unsafe { + gst_gl_context_thread_add(gst_gl_context, Some(bootstrap_surfman_on_gl_thread), data) + }; + let connection = task.result.expect("Failed to get connection"); + + // Save the GL context and connection for later use *self.gl_context.lock().expect("Poisoned lock") = Some(gl_context); + *self.connection.lock().expect("Poisoned lock") = Some(connection.clone()); // Inform servo we're starting - let _ = self.sender.send(ServoWebSrcMsg::Start(version, url)); + let _ = self.sender.send(ServoWebSrcMsg::Start( + ConnectionWhichImplementsDebug(connection), + version, + url, + )); Ok(()) } @@ -723,14 +745,14 @@ impl BaseSrcImpl for ServoWebSrc { // Fill the buffer on the GL thread let result = Err(FlowError::Error); - let mut task = RunOnGLThread { + let mut task = FillOnGLThread { servo_web_src: self, src, gl_memory, result, }; - let data = &mut task as *mut RunOnGLThread as *mut c_void; + let data = &mut task as *mut FillOnGLThread as *mut c_void; unsafe { gst_gl_context_thread_add(gl_memory.mem.context, Some(fill_on_gl_thread), data) }; task.result?; @@ -749,7 +771,32 @@ impl BaseSrcImpl for ServoWebSrc { } } -struct RunOnGLThread<'a> { +struct BootstrapSurfmanOnGLThread<'a> { + servo_web_src: &'a ServoWebSrc, + result: Option<Connection>, +} + +unsafe extern "C" fn bootstrap_surfman_on_gl_thread(context: *mut GstGLContext, data: *mut c_void) { + let task = &mut *(data as *mut BootstrapSurfmanOnGLThread); + let gl_context = GLContext::from_glib_borrow(context); + task.result = task.servo_web_src.bootstrap_surfman(gl_context); +} + +impl ServoWebSrc { + // Runs on the GL thread + fn bootstrap_surfman(&self, gl_context: GLContext) -> Option<Connection> { + gl_context + .activate(true) + .expect("Failed to activate GL context"); + let native_connection = + NativeConnection::current().expect("Failed to bootstrap native connection"); + let connection = unsafe { Connection::from_native_connection(native_connection) } + .expect("Failed to bootstrap surfman connection"); + Some(connection) + } +} + +struct FillOnGLThread<'a> { servo_web_src: &'a ServoWebSrc, src: &'a BaseSrc, gl_memory: &'a GstGLMemory, @@ -757,7 +804,7 @@ struct RunOnGLThread<'a> { } unsafe extern "C" fn fill_on_gl_thread(context: *mut GstGLContext, data: *mut c_void) { - let task = &mut *(data as *mut RunOnGLThread); + let task = &mut *(data as *mut FillOnGLThread); let gl_context = GLContext::from_glib_borrow(context); task.result = task .servo_web_src @@ -789,10 +836,8 @@ impl ServoWebSrc { let mut gfx_cache = gfx_cache.borrow_mut(); let gfx = gfx_cache.entry(gl_context.clone()).or_insert_with(|| { debug!("Bootstrapping surfman"); - let native_connection = - NativeConnection::current().expect("Failed to bootstrap native connection"); - let connection = unsafe { Connection::from_native_connection(native_connection) } - .expect("Failed to bootstrap surfman connection"); + let connection_guard = self.connection.lock().unwrap(); + let connection = connection_guard.as_ref().expect("Failed to get surfman"); let adapter = connection .create_adapter() .expect("Failed to bootstrap surfman adapter"); @@ -829,6 +874,9 @@ impl ServoWebSrc { } }); + gfx.device + .make_context_current(&gfx.context) + .expect("Failed to make surfman context current"); debug_assert_eq!(gfx.gl.get_error(), gl::NO_ERROR); // Save the current GL state |