diff --git a/Cargo.lock b/Cargo.lock index 9bd6cc52eb7..f045097f5ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -394,7 +394,6 @@ dependencies = [ "azure 0.36.0 (git+https://github.com/servo/rust-azure)", "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "canvas_traits 0.0.1", - "compositing 0.0.1", "cssparser 0.25.5 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.19.8 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2542,6 +2541,7 @@ dependencies = [ "msg 0.0.1", "net 0.0.1", "net_traits 0.0.1", + "offscreen_gl_context 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)", "profile 0.0.1", "profile_traits 0.0.1", "script 0.0.1", diff --git a/components/canvas/Cargo.toml b/components/canvas/Cargo.toml index 8211619ca91..e666c40cbc1 100644 --- a/components/canvas/Cargo.toml +++ b/components/canvas/Cargo.toml @@ -21,7 +21,6 @@ no_wgl = ["offscreen_gl_context/no_wgl"] azure = {git = "https://github.com/servo/rust-azure", optional = true} byteorder = "1" canvas_traits = {path = "../canvas_traits"} -compositing = {path = "../compositing"} cssparser = "0.25" euclid = "0.19" fnv = "1.0" diff --git a/components/canvas/gl_context.rs b/components/canvas/gl_context.rs index 844b60ba44d..9d2a2c8c36c 100644 --- a/components/canvas/gl_context.rs +++ b/components/canvas/gl_context.rs @@ -6,7 +6,6 @@ use super::webgl_thread::{GLState, WebGLImpl}; use canvas_traits::webgl::{ GLContextAttributes, GLLimits, WebGLCommand, WebGLCommandBacktrace, WebGLVersion, }; -use compositing::compositor_thread::{self, CompositorProxy}; use euclid::Size2D; use gleam::gl; use offscreen_gl_context::{ @@ -16,31 +15,38 @@ use offscreen_gl_context::{ use offscreen_gl_context::{GLLimits as RawGLLimits, GLVersion}; use offscreen_gl_context::{NativeGLContext, NativeGLContextHandle, NativeGLContextMethods}; use offscreen_gl_context::{OSMesaContext, OSMesaContextHandle}; -use std::sync::{Arc, Mutex}; + +pub trait CloneableDispatcher: GLContextDispatcher { + fn clone(&self) -> Box; +} /// The GLContextFactory is used to create shared GL contexts with the main thread GL context. /// Currently, shared textures are used to render WebGL textures into the WR compositor. /// In order to create a shared context, the GLContextFactory stores the handle of the main GL context. pub enum GLContextFactory { - Native(NativeGLContextHandle, Option), + Native( + NativeGLContextHandle, + Option>, + ), OSMesa(OSMesaContextHandle), } impl GLContextFactory { /// Creates a new GLContextFactory that uses the currently bound GL context to create shared contexts. - pub fn current_native_handle(proxy: &CompositorProxy) -> Option { + pub fn current_native_handle( + dispatcher: Box, + ) -> Option { + let dispatcher = if cfg!(target_os = "windows") { + // Used to dispatch functions from the GLContext thread to the main thread's + // event loop. Required to allow WGL GLContext sharing in Windows. + Some(dispatcher) + } else { + None + }; // FIXME(emilio): This assumes a single GL backend per platform which is // not true on Linux, we probably need a third `Egl` variant or abstract // it a bit more... - NativeGLContext::current_handle().map(|handle| { - if cfg!(target_os = "windows") { - // Used to dispatch functions from the GLContext thread to the main thread's event loop. - // Required to allow WGL GLContext sharing in Windows. - GLContextFactory::Native(handle, Some(MainThreadDispatcher::new(proxy.clone()))) - } else { - GLContextFactory::Native(handle, None) - } - }) + NativeGLContext::current_handle().map(|handle| GLContextFactory::Native(handle, dispatcher)) } /// Creates a new GLContextFactory that uses the currently bound OSMesa context to create shared contexts. @@ -58,7 +64,6 @@ impl GLContextFactory { let attributes = map_attrs(attributes); Ok(match *self { GLContextFactory::Native(ref handle, ref dispatcher) => { - let dispatcher = dispatcher.as_ref().map(|d| Box::new(d.clone()) as Box<_>); GLContextWrapper::Native(GLContext::new_shared_with_dispatcher( // FIXME(nox): Why are those i32 values? size.to_i32(), @@ -67,7 +72,7 @@ impl GLContextFactory { gl::GlType::default(), Self::gl_version(webgl_version), Some(handle), - dispatcher, + dispatcher.as_ref().map(|d| (**d).clone()), )?) }, GLContextFactory::OSMesa(ref handle) => { @@ -215,29 +220,6 @@ impl GLContextWrapper { } } -/// Implements GLContextDispatcher to dispatch functions from GLContext threads to the main thread's event loop. -/// It's used in Windows to allow WGL GLContext sharing. -#[derive(Clone)] -pub struct MainThreadDispatcher { - compositor_proxy: Arc>, -} - -impl MainThreadDispatcher { - fn new(proxy: CompositorProxy) -> Self { - Self { - compositor_proxy: Arc::new(Mutex::new(proxy)), - } - } -} -impl GLContextDispatcher for MainThreadDispatcher { - fn dispatch(&self, f: Box) { - self.compositor_proxy - .lock() - .unwrap() - .send(compositor_thread::Msg::Dispatch(f)); - } -} - fn map_limits(limits: RawGLLimits) -> GLLimits { GLLimits { max_vertex_attribs: limits.max_vertex_attribs, diff --git a/components/servo/Cargo.toml b/components/servo/Cargo.toml index d00f11459b4..77a297d67d1 100644 --- a/components/servo/Cargo.toml +++ b/components/servo/Cargo.toml @@ -60,6 +60,7 @@ layout_thread_2020 = {path = "../layout_thread_2020", optional = true} log = "0.4" media = {path = "../media"} msg = {path = "../msg"} +offscreen_gl_context = "0.22" net = {path = "../net"} net_traits = {path = "../net_traits"} profile = {path = "../profile"} diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 71e679b1b6f..f31cc1fcd24 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -64,7 +64,7 @@ fn webdriver(_port: u16, _constellation: Sender) {} use bluetooth::BluetoothThreadFactory; use bluetooth_traits::BluetoothRequest; -use canvas::gl_context::GLContextFactory; +use canvas::gl_context::{CloneableDispatcher, GLContextFactory}; use canvas::webgl_thread::WebGLThreads; use compositing::compositor_thread::{ CompositorProxy, CompositorReceiver, InitialCompositorState, Msg, @@ -100,6 +100,7 @@ use media::{GLPlayerThreads, WindowGLContext}; use msg::constellation_msg::{PipelineNamespace, PipelineNamespaceId}; use net::resource_thread::new_resource_threads; use net_traits::IpcSend; +use offscreen_gl_context::GLContextDispatcher; use profile::mem as profile_mem; use profile::time as profile_time; use profile_traits::mem; @@ -745,7 +746,8 @@ fn create_constellation( let gl_factory = if opts.should_use_osmesa() { GLContextFactory::current_osmesa_handle() } else { - GLContextFactory::current_native_handle(&compositor_proxy) + let dispatcher = Box::new(MainThreadDispatcher::new(compositor_proxy.clone())) as Box<_>; + GLContextFactory::current_native_handle(dispatcher) }; let (external_image_handlers, external_images) = WebrenderExternalImageHandlers::new(); @@ -937,3 +939,29 @@ fn create_sandbox() { fn create_sandbox() { panic!("Sandboxing is not supported on Windows, iOS, ARM targets and android."); } + +/// Implements GLContextDispatcher to dispatch functions from GLContext threads to the main thread's event loop. +/// It's used in Windows to allow WGL GLContext sharing. +pub struct MainThreadDispatcher { + compositor_proxy: CompositorProxy, +} + +impl MainThreadDispatcher { + fn new(proxy: CompositorProxy) -> Self { + Self { + compositor_proxy: proxy, + } + } +} +impl GLContextDispatcher for MainThreadDispatcher { + fn dispatch(&self, f: Box) { + self.compositor_proxy.send(Msg::Dispatch(f)); + } +} +impl CloneableDispatcher for MainThreadDispatcher { + fn clone(&self) -> Box { + Box::new(MainThreadDispatcher { + compositor_proxy: self.compositor_proxy.clone(), + }) as Box<_> + } +}