mirror of
https://github.com/servo/servo.git
synced 2025-07-31 11:10:22 +01:00
constellation: Make setting up the WebGL state fallible.
This fixes a regression caused by the glutin update. We now are creating EGL contexts in Linux Wayland, instead of X context, so the GLContextFactory assumption of one GL back-end per platform is broken. This just works around it, for now, but in general I think not relying on available WebGL state is a good thing, and we do that already for WebVR anyway.
This commit is contained in:
parent
3fc5bf87d3
commit
21df4014db
8 changed files with 48 additions and 31 deletions
|
@ -24,6 +24,9 @@ pub enum GLContextFactory {
|
||||||
impl GLContextFactory {
|
impl GLContextFactory {
|
||||||
/// Creates a new GLContextFactory that uses the currently bound GL context to create shared contexts.
|
/// Creates a new GLContextFactory that uses the currently bound GL context to create shared contexts.
|
||||||
pub fn current_native_handle(proxy: &CompositorProxy) -> Option<GLContextFactory> {
|
pub fn current_native_handle(proxy: &CompositorProxy) -> Option<GLContextFactory> {
|
||||||
|
// 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| {
|
NativeGLContext::current_handle().map(|handle| {
|
||||||
if cfg!(target_os = "windows") {
|
if cfg!(target_os = "windows") {
|
||||||
// Used to dispatch functions from the GLContext thread to the main thread's event loop.
|
// Used to dispatch functions from the GLContext thread to the main thread's event loop.
|
||||||
|
|
|
@ -325,7 +325,7 @@ pub struct Constellation<Message, LTF, STF> {
|
||||||
phantom: PhantomData<(Message, LTF, STF)>,
|
phantom: PhantomData<(Message, LTF, STF)>,
|
||||||
|
|
||||||
/// Entry point to create and get channels to a WebGLThread.
|
/// Entry point to create and get channels to a WebGLThread.
|
||||||
webgl_threads: WebGLThreads,
|
webgl_threads: Option<WebGLThreads>,
|
||||||
|
|
||||||
/// A channel through which messages can be sent to the webvr thread.
|
/// A channel through which messages can be sent to the webvr thread.
|
||||||
webvr_chan: Option<IpcSender<WebVRMsg>>,
|
webvr_chan: Option<IpcSender<WebVRMsg>>,
|
||||||
|
@ -370,7 +370,7 @@ pub struct InitialConstellationState {
|
||||||
pub webrender_api_sender: webrender_api::RenderApiSender,
|
pub webrender_api_sender: webrender_api::RenderApiSender,
|
||||||
|
|
||||||
/// Entry point to create and get channels to a WebGLThread.
|
/// Entry point to create and get channels to a WebGLThread.
|
||||||
pub webgl_threads: WebGLThreads,
|
pub webgl_threads: Option<WebGLThreads>,
|
||||||
|
|
||||||
/// A channel to the webgl thread.
|
/// A channel to the webgl thread.
|
||||||
pub webvr_chan: Option<IpcSender<WebVRMsg>>,
|
pub webvr_chan: Option<IpcSender<WebVRMsg>>,
|
||||||
|
@ -740,7 +740,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
webrender_api_sender: self.webrender_api_sender.clone(),
|
webrender_api_sender: self.webrender_api_sender.clone(),
|
||||||
webrender_document: self.webrender_document,
|
webrender_document: self.webrender_document,
|
||||||
is_private,
|
is_private,
|
||||||
webgl_chan: self.webgl_threads.pipeline(),
|
webgl_chan: self.webgl_threads.as_ref().map(|threads| threads.pipeline()),
|
||||||
webvr_chan: self.webvr_chan.clone()
|
webvr_chan: self.webvr_chan.clone()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1431,9 +1431,11 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("Exiting WebGL thread.");
|
if let Some(webgl_threads) = self.webgl_threads.as_ref() {
|
||||||
if let Err(e) = self.webgl_threads.exit() {
|
debug!("Exiting WebGL thread.");
|
||||||
warn!("Exit WebGL Thread failed ({})", e);
|
if let Err(e) = webgl_threads.exit() {
|
||||||
|
warn!("Exit WebGL Thread failed ({})", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(chan) = self.webvr_chan.as_ref() {
|
if let Some(chan) = self.webvr_chan.as_ref() {
|
||||||
|
|
|
@ -170,8 +170,8 @@ pub struct InitialPipelineState {
|
||||||
/// Whether this pipeline is considered private.
|
/// Whether this pipeline is considered private.
|
||||||
pub is_private: bool,
|
pub is_private: bool,
|
||||||
|
|
||||||
/// A channel to the webgl thread.
|
/// A channel to the WebGL thread.
|
||||||
pub webgl_chan: WebGLPipeline,
|
pub webgl_chan: Option<WebGLPipeline>,
|
||||||
|
|
||||||
/// A channel to the webvr thread.
|
/// A channel to the webvr thread.
|
||||||
pub webvr_chan: Option<IpcSender<WebVRMsg>>,
|
pub webvr_chan: Option<IpcSender<WebVRMsg>>,
|
||||||
|
@ -457,7 +457,7 @@ pub struct UnprivilegedPipelineContent {
|
||||||
script_content_process_shutdown_port: IpcReceiver<()>,
|
script_content_process_shutdown_port: IpcReceiver<()>,
|
||||||
webrender_api_sender: webrender_api::RenderApiSender,
|
webrender_api_sender: webrender_api::RenderApiSender,
|
||||||
webrender_document: webrender_api::DocumentId,
|
webrender_document: webrender_api::DocumentId,
|
||||||
webgl_chan: WebGLPipeline,
|
webgl_chan: Option<WebGLPipeline>,
|
||||||
webvr_chan: Option<IpcSender<WebVRMsg>>,
|
webvr_chan: Option<IpcSender<WebVRMsg>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -224,8 +224,12 @@ impl WebGLRenderingContext {
|
||||||
return Err("WebGL context creation error forced by pref `webgl.testing.context_creation_error`".into());
|
return Err("WebGL context creation error forced by pref `webgl.testing.context_creation_error`".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let webgl_chan = match window.webgl_chan() {
|
||||||
|
Some(chan) => chan,
|
||||||
|
None => return Err("WebGL initialization failed early on".into()),
|
||||||
|
};
|
||||||
|
|
||||||
let (sender, receiver) = webgl_channel().unwrap();
|
let (sender, receiver) = webgl_channel().unwrap();
|
||||||
let webgl_chan = window.webgl_chan();
|
|
||||||
webgl_chan.send(WebGLMsg::CreateContext(webgl_version, size, attrs, sender))
|
webgl_chan.send(WebGLMsg::CreateContext(webgl_version, size, attrs, sender))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let result = receiver.recv().unwrap();
|
let result = receiver.recv().unwrap();
|
||||||
|
|
|
@ -257,9 +257,9 @@ pub struct Window {
|
||||||
|
|
||||||
test_runner: MutNullableDom<TestRunner>,
|
test_runner: MutNullableDom<TestRunner>,
|
||||||
|
|
||||||
/// A handle for communicating messages to the webvr thread, if available.
|
/// A handle for communicating messages to the WebGL thread, if available.
|
||||||
#[ignore_malloc_size_of = "channels are hard"]
|
#[ignore_malloc_size_of = "channels are hard"]
|
||||||
webgl_chan: WebGLChan,
|
webgl_chan: Option<WebGLChan>,
|
||||||
|
|
||||||
/// A handle for communicating messages to the webvr thread, if available.
|
/// A handle for communicating messages to the webvr thread, if available.
|
||||||
#[ignore_malloc_size_of = "channels are hard"]
|
#[ignore_malloc_size_of = "channels are hard"]
|
||||||
|
@ -402,7 +402,7 @@ impl Window {
|
||||||
self.current_viewport.clone().get()
|
self.current_viewport.clone().get()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn webgl_chan(&self) -> WebGLChan {
|
pub fn webgl_chan(&self) -> Option<WebGLChan> {
|
||||||
self.webgl_chan.clone()
|
self.webgl_chan.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1756,7 +1756,7 @@ impl Window {
|
||||||
origin: MutableOrigin,
|
origin: MutableOrigin,
|
||||||
navigation_start: u64,
|
navigation_start: u64,
|
||||||
navigation_start_precise: u64,
|
navigation_start_precise: u64,
|
||||||
webgl_chan: WebGLChan,
|
webgl_chan: Option<WebGLChan>,
|
||||||
webvr_chan: Option<IpcSender<WebVRMsg>>,
|
webvr_chan: Option<IpcSender<WebVRMsg>>,
|
||||||
microtask_queue: Rc<MicrotaskQueue>,
|
microtask_queue: Rc<MicrotaskQueue>,
|
||||||
webrender_document: DocumentId,
|
webrender_document: DocumentId,
|
||||||
|
|
|
@ -483,8 +483,8 @@ pub struct ScriptThread {
|
||||||
/// The unit of related similar-origin browsing contexts' list of MutationObserver objects
|
/// The unit of related similar-origin browsing contexts' list of MutationObserver objects
|
||||||
mutation_observers: DomRefCell<Vec<Dom<MutationObserver>>>,
|
mutation_observers: DomRefCell<Vec<Dom<MutationObserver>>>,
|
||||||
|
|
||||||
/// A handle to the webgl thread
|
/// A handle to the WebGL thread
|
||||||
webgl_chan: WebGLPipeline,
|
webgl_chan: Option<WebGLPipeline>,
|
||||||
|
|
||||||
/// A handle to the webvr thread, if available
|
/// A handle to the webvr thread, if available
|
||||||
webvr_chan: Option<IpcSender<WebVRMsg>>,
|
webvr_chan: Option<IpcSender<WebVRMsg>>,
|
||||||
|
@ -2130,7 +2130,7 @@ impl ScriptThread {
|
||||||
origin,
|
origin,
|
||||||
incomplete.navigation_start,
|
incomplete.navigation_start,
|
||||||
incomplete.navigation_start_precise,
|
incomplete.navigation_start_precise,
|
||||||
self.webgl_chan.channel(),
|
self.webgl_chan.as_ref().map(|chan| chan.channel()),
|
||||||
self.webvr_chan.clone(),
|
self.webvr_chan.clone(),
|
||||||
self.microtask_queue.clone(),
|
self.microtask_queue.clone(),
|
||||||
self.webrender_document,
|
self.webrender_document,
|
||||||
|
|
|
@ -539,8 +539,8 @@ pub struct InitialScriptState {
|
||||||
pub pipeline_namespace_id: PipelineNamespaceId,
|
pub pipeline_namespace_id: PipelineNamespaceId,
|
||||||
/// A ping will be sent on this channel once the script thread shuts down.
|
/// A ping will be sent on this channel once the script thread shuts down.
|
||||||
pub content_process_shutdown_chan: IpcSender<()>,
|
pub content_process_shutdown_chan: IpcSender<()>,
|
||||||
/// A channel to the webgl thread used in this pipeline.
|
/// A channel to the WebGL thread used in this pipeline.
|
||||||
pub webgl_chan: WebGLPipeline,
|
pub webgl_chan: Option<WebGLPipeline>,
|
||||||
/// A channel to the webvr thread, if available.
|
/// A channel to the webvr thread, if available.
|
||||||
pub webvr_chan: Option<IpcSender<WebVRMsg>>,
|
pub webvr_chan: Option<IpcSender<WebVRMsg>>,
|
||||||
/// The Webrender document ID associated with this thread.
|
/// The Webrender document ID associated with this thread.
|
||||||
|
|
|
@ -566,23 +566,31 @@ fn create_constellation(user_agent: Cow<'static, str>,
|
||||||
|
|
||||||
// GLContext factory used to create WebGL Contexts
|
// GLContext factory used to create WebGL Contexts
|
||||||
let gl_factory = if opts::get().should_use_osmesa() {
|
let gl_factory = if opts::get().should_use_osmesa() {
|
||||||
GLContextFactory::current_osmesa_handle().unwrap()
|
GLContextFactory::current_osmesa_handle()
|
||||||
} else {
|
} else {
|
||||||
GLContextFactory::current_native_handle(&compositor_proxy).unwrap()
|
GLContextFactory::current_native_handle(&compositor_proxy)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initialize WebGL Thread entry point.
|
// Initialize WebGL Thread entry point.
|
||||||
let (webgl_threads, image_handler, output_handler) = WebGLThreads::new(gl_factory,
|
let webgl_threads = gl_factory.map(|factory| {
|
||||||
window_gl,
|
let (webgl_threads, image_handler, output_handler) =
|
||||||
webrender_api_sender.clone(),
|
WebGLThreads::new(
|
||||||
webvr_compositor.map(|c| c as Box<_>));
|
factory,
|
||||||
// Set webrender external image handler for WebGL textures
|
window_gl,
|
||||||
webrender.set_external_image_handler(image_handler);
|
webrender_api_sender.clone(),
|
||||||
|
webvr_compositor.map(|c| c as Box<_>),
|
||||||
|
);
|
||||||
|
|
||||||
// Set DOM to texture handler, if enabled.
|
// Set webrender external image handler for WebGL textures
|
||||||
if let Some(output_handler) = output_handler {
|
webrender.set_external_image_handler(image_handler);
|
||||||
webrender.set_output_image_handler(output_handler);
|
|
||||||
}
|
// Set DOM to texture handler, if enabled.
|
||||||
|
if let Some(output_handler) = output_handler {
|
||||||
|
webrender.set_output_image_handler(output_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
webgl_threads
|
||||||
|
});
|
||||||
|
|
||||||
let initial_state = InitialConstellationState {
|
let initial_state = InitialConstellationState {
|
||||||
compositor_proxy,
|
compositor_proxy,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue