зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #20262 - constellation: Make setting up the WebGL state fallible (from emilio:webgl-fallible); r=jdm
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. Source-Repo: https://github.com/servo/servo Source-Revision: 95f9e14e67766b36a8b72e62925a34b1818be2c8 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 0029f2ac9735f2645084e572e5f560f4348fa577
This commit is contained in:
Родитель
25d47480bb
Коммит
bef3768170
|
@ -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.
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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>>,
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
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 DOM to texture handler, if enabled.
|
||||
if let Some(output_handler) = output_handler {
|
||||
webrender.set_output_image_handler(output_handler);
|
||||
}
|
||||
// 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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче