aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2018-03-09 23:27:29 +0100
committerEmilio Cobos Álvarez <emilio@crisal.io>2018-03-09 23:27:29 +0100
commit21df4014db5ff11581fcdd328d2dd1f7226a4544 (patch)
tree41c071a3edd9320bb045ff055359d11a63a4439a
parent3fc5bf87d3fd605da7510a5a0240dac0157a9743 (diff)
downloadservo-21df4014db5ff11581fcdd328d2dd1f7226a4544.tar.gz
servo-21df4014db5ff11581fcdd328d2dd1f7226a4544.zip
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.
-rw-r--r--components/canvas/gl_context.rs3
-rw-r--r--components/constellation/constellation.rs14
-rw-r--r--components/constellation/pipeline.rs6
-rw-r--r--components/script/dom/webglrenderingcontext.rs6
-rw-r--r--components/script/dom/window.rs8
-rw-r--r--components/script/script_thread.rs6
-rw-r--r--components/script_traits/lib.rs4
-rw-r--r--components/servo/lib.rs34
8 files changed, 49 insertions, 32 deletions
diff --git a/components/canvas/gl_context.rs b/components/canvas/gl_context.rs
index e0d686f622a..7720f8f678a 100644
--- a/components/canvas/gl_context.rs
+++ b/components/canvas/gl_context.rs
@@ -24,6 +24,9 @@ pub enum GLContextFactory {
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<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| {
if cfg!(target_os = "windows") {
// Used to dispatch functions from the GLContext thread to the main thread's event loop.
diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs
index f6a47ba14b1..cdc850495b1 100644
--- a/components/constellation/constellation.rs
+++ b/components/constellation/constellation.rs
@@ -325,7 +325,7 @@ pub struct Constellation<Message, LTF, STF> {
phantom: PhantomData<(Message, LTF, STF)>,
/// 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.
webvr_chan: Option<IpcSender<WebVRMsg>>,
@@ -370,7 +370,7 @@ pub struct InitialConstellationState {
pub webrender_api_sender: webrender_api::RenderApiSender,
/// 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.
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_document: self.webrender_document,
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()
});
@@ -1431,9 +1431,11 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
}
- debug!("Exiting WebGL thread.");
- if let Err(e) = self.webgl_threads.exit() {
- warn!("Exit WebGL Thread failed ({})", e);
+ if let Some(webgl_threads) = self.webgl_threads.as_ref() {
+ debug!("Exiting WebGL thread.");
+ if let Err(e) = webgl_threads.exit() {
+ warn!("Exit WebGL Thread failed ({})", e);
+ }
}
if let Some(chan) = self.webvr_chan.as_ref() {
diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs
index 4753f0ba3eb..99603cad805 100644
--- a/components/constellation/pipeline.rs
+++ b/components/constellation/pipeline.rs
@@ -170,8 +170,8 @@ pub struct InitialPipelineState {
/// Whether this pipeline is considered private.
pub is_private: bool,
- /// A channel to the webgl thread.
- pub webgl_chan: WebGLPipeline,
+ /// A channel to the WebGL thread.
+ pub webgl_chan: Option<WebGLPipeline>,
/// A channel to the webvr thread.
pub webvr_chan: Option<IpcSender<WebVRMsg>>,
@@ -457,7 +457,7 @@ pub struct UnprivilegedPipelineContent {
script_content_process_shutdown_port: IpcReceiver<()>,
webrender_api_sender: webrender_api::RenderApiSender,
webrender_document: webrender_api::DocumentId,
- webgl_chan: WebGLPipeline,
+ webgl_chan: Option<WebGLPipeline>,
webvr_chan: Option<IpcSender<WebVRMsg>>,
}
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index fa1015582cf..0aabf2e319a 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -224,8 +224,12 @@ impl WebGLRenderingContext {
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 webgl_chan = window.webgl_chan();
webgl_chan.send(WebGLMsg::CreateContext(webgl_version, size, attrs, sender))
.unwrap();
let result = receiver.recv().unwrap();
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 2cc1515b735..f6177e90fcf 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -257,9 +257,9 @@ pub struct Window {
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"]
- webgl_chan: WebGLChan,
+ webgl_chan: Option<WebGLChan>,
/// A handle for communicating messages to the webvr thread, if available.
#[ignore_malloc_size_of = "channels are hard"]
@@ -402,7 +402,7 @@ impl Window {
self.current_viewport.clone().get()
}
- pub fn webgl_chan(&self) -> WebGLChan {
+ pub fn webgl_chan(&self) -> Option<WebGLChan> {
self.webgl_chan.clone()
}
@@ -1756,7 +1756,7 @@ impl Window {
origin: MutableOrigin,
navigation_start: u64,
navigation_start_precise: u64,
- webgl_chan: WebGLChan,
+ webgl_chan: Option<WebGLChan>,
webvr_chan: Option<IpcSender<WebVRMsg>>,
microtask_queue: Rc<MicrotaskQueue>,
webrender_document: DocumentId,
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index f386d29487e..d949e9d0b8c 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -483,8 +483,8 @@ pub struct ScriptThread {
/// The unit of related similar-origin browsing contexts' list of MutationObserver objects
mutation_observers: DomRefCell<Vec<Dom<MutationObserver>>>,
- /// A handle to the webgl thread
- webgl_chan: WebGLPipeline,
+ /// A handle to the WebGL thread
+ webgl_chan: Option<WebGLPipeline>,
/// A handle to the webvr thread, if available
webvr_chan: Option<IpcSender<WebVRMsg>>,
@@ -2130,7 +2130,7 @@ impl ScriptThread {
origin,
incomplete.navigation_start,
incomplete.navigation_start_precise,
- self.webgl_chan.channel(),
+ self.webgl_chan.as_ref().map(|chan| chan.channel()),
self.webvr_chan.clone(),
self.microtask_queue.clone(),
self.webrender_document,
diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs
index eec50faf09b..46f5ed6c90c 100644
--- a/components/script_traits/lib.rs
+++ b/components/script_traits/lib.rs
@@ -539,8 +539,8 @@ pub struct InitialScriptState {
pub pipeline_namespace_id: PipelineNamespaceId,
/// A ping will be sent on this channel once the script thread shuts down.
pub content_process_shutdown_chan: IpcSender<()>,
- /// A channel to the webgl thread used in this pipeline.
- pub webgl_chan: WebGLPipeline,
+ /// A channel to the WebGL thread used in this pipeline.
+ pub webgl_chan: Option<WebGLPipeline>,
/// A channel to the webvr thread, if available.
pub webvr_chan: Option<IpcSender<WebVRMsg>>,
/// The Webrender document ID associated with this thread.
diff --git a/components/servo/lib.rs b/components/servo/lib.rs
index 8844625af19..45b6af50c89 100644
--- a/components/servo/lib.rs
+++ b/components/servo/lib.rs
@@ -566,23 +566,31 @@ fn create_constellation(user_agent: Cow<'static, str>,
// GLContext factory used to create WebGL Contexts
let gl_factory = if opts::get().should_use_osmesa() {
- GLContextFactory::current_osmesa_handle().unwrap()
+ GLContextFactory::current_osmesa_handle()
} else {
- GLContextFactory::current_native_handle(&compositor_proxy).unwrap()
+ GLContextFactory::current_native_handle(&compositor_proxy)
};
// Initialize WebGL Thread entry point.
- let (webgl_threads, image_handler, output_handler) = WebGLThreads::new(gl_factory,
- window_gl,
- webrender_api_sender.clone(),
- webvr_compositor.map(|c| c as Box<_>));
- // Set webrender external image handler for WebGL textures
- webrender.set_external_image_handler(image_handler);
-
- // Set DOM to texture handler, if enabled.
- if let Some(output_handler) = output_handler {
- webrender.set_output_image_handler(output_handler);
- }
+ let webgl_threads = gl_factory.map(|factory| {
+ let (webgl_threads, image_handler, output_handler) =
+ WebGLThreads::new(
+ factory,
+ window_gl,
+ webrender_api_sender.clone(),
+ webvr_compositor.map(|c| c as Box<_>),
+ );
+
+ // Set webrender external image handler for WebGL textures
+ webrender.set_external_image_handler(image_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 {
compositor_proxy,