aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Jeffrey <ajeffrey@mozilla.com>2019-12-18 19:31:12 -0600
committerAlan Jeffrey <ajeffrey@mozilla.com>2019-12-18 19:31:12 -0600
commit9f52997f41ebf7091bec66a75da66114afeee52e (patch)
tree5a9ff9b408811b7a21459fd0553ca802090c5186
parentaca438aebc9291db9f1226d2575230a5189eddea (diff)
downloadservo-9f52997f41ebf7091bec66a75da66114afeee52e.tar.gz
servo-9f52997f41ebf7091bec66a75da66114afeee52e.zip
Make wayland happier by sharing a Connection between servo and gstreamer
-rw-r--r--Cargo.lock2
-rw-r--r--ports/gstplugin/servowebsrc.rs98
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