diff options
Diffstat (limited to 'components/canvas/webgl_mode/inprocess.rs')
-rw-r--r-- | components/canvas/webgl_mode/inprocess.rs | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/components/canvas/webgl_mode/inprocess.rs b/components/canvas/webgl_mode/inprocess.rs index 257f1395545..71ab8d8a934 100644 --- a/components/canvas/webgl_mode/inprocess.rs +++ b/components/canvas/webgl_mode/inprocess.rs @@ -8,7 +8,9 @@ use canvas_traits::webgl::{WebGLChan, WebGLContextId, WebGLMsg, WebGLPipeline, W use canvas_traits::webgl::{WebGLSender, WebVRCommand, WebVRRenderHandler}; use canvas_traits::webgl::webgl_channel; use euclid::Size2D; +use gleam::gl; use std::marker::PhantomData; +use std::rc::Rc; use webrender; use webrender_api; @@ -18,6 +20,7 @@ pub struct WebGLThreads(WebGLSender<WebGLMsg>); impl WebGLThreads { /// Creates a new WebGLThreads object pub fn new(gl_factory: GLContextFactory, + webrender_gl: Rc<gl::Gl>, webrender_api_sender: webrender_api::RenderApiSender, webvr_compositor: Option<Box<WebVRRenderHandler>>) -> (WebGLThreads, Box<webrender::ExternalImageHandler>) { @@ -26,7 +29,7 @@ impl WebGLThreads { webrender_api_sender, webvr_compositor.map(|c| WebVRRenderWrapper(c)), PhantomData); - let external = WebGLExternalImageHandler::new(WebGLExternalImages::new(channel.clone())); + let external = WebGLExternalImageHandler::new(WebGLExternalImages::new(webrender_gl, channel.clone())); (WebGLThreads(channel), Box::new(external)) } @@ -44,14 +47,16 @@ impl WebGLThreads { /// Bridge between the webrender::ExternalImage callbacks and the WebGLThreads. struct WebGLExternalImages { + webrender_gl: Rc<gl::Gl>, webgl_channel: WebGLSender<WebGLMsg>, // Used to avoid creating a new channel on each received WebRender request. - lock_channel: (WebGLSender<(u32, Size2D<i32>)>, WebGLReceiver<(u32, Size2D<i32>)>), + lock_channel: (WebGLSender<(u32, Size2D<i32>, usize)>, WebGLReceiver<(u32, Size2D<i32>, usize)>), } impl WebGLExternalImages { - fn new(channel: WebGLSender<WebGLMsg>) -> Self { + fn new(webrender_gl: Rc<gl::Gl>, channel: WebGLSender<WebGLMsg>) -> Self { Self { + webrender_gl, webgl_channel: channel, lock_channel: webgl_channel().unwrap(), } @@ -60,8 +65,15 @@ impl WebGLExternalImages { impl WebGLExternalImageApi for WebGLExternalImages { fn lock(&mut self, ctx_id: WebGLContextId) -> (u32, Size2D<i32>) { + // WebGL Thread has it's own GL command queue that we need to synchronize with the WR GL command queue. + // The WebGLMsg::Lock message inserts a fence in the WebGL command queue. self.webgl_channel.send(WebGLMsg::Lock(ctx_id, self.lock_channel.0.clone())).unwrap(); - self.lock_channel.1.recv().unwrap() + let (image_id, size, gl_sync) = self.lock_channel.1.recv().unwrap(); + // The next glWaitSync call is run on the WR thread and it's used to synchronize the two + // flows of OpenGL commands in order to avoid WR using a semi-ready WebGL texture. + // glWaitSync doesn't block WR thread, it affects only internal OpenGL subsystem. + self.webrender_gl.wait_sync(gl_sync as gl::GLsync, 0, gl::TIMEOUT_IGNORED); + (image_id, size) } fn unlock(&mut self, ctx_id: WebGLContextId) { |