aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock11
-rw-r--r--components/canvas/Cargo.toml3
-rw-r--r--components/canvas/canvas_paint_thread.rs16
-rw-r--r--components/canvas/gl_context.rs203
-rw-r--r--components/canvas/lib.rs10
-rw-r--r--components/canvas/webgl_mode/inprocess.rs95
-rw-r--r--components/canvas/webgl_mode/mod.rs6
-rw-r--r--components/canvas/webgl_paint_thread.rs379
-rw-r--r--components/canvas/webgl_thread.rs1204
-rw-r--r--components/canvas_traits/Cargo.toml3
-rw-r--r--components/canvas_traits/canvas.rs409
-rw-r--r--components/canvas_traits/lib.rs426
-rw-r--r--components/canvas_traits/webgl.rs506
-rw-r--r--components/canvas_traits/webgl_channel/ipc.rs15
-rw-r--r--components/canvas_traits/webgl_channel/mod.rs87
-rw-r--r--components/canvas_traits/webgl_channel/mpsc.rs51
-rw-r--r--components/constellation/Cargo.toml1
-rw-r--r--components/constellation/constellation.rs50
-rw-r--r--components/constellation/lib.rs1
-rw-r--r--components/constellation/pipeline.rs16
-rw-r--r--components/gfx/display_list/mod.rs13
-rw-r--r--components/layout/display_list_builder.rs65
-rw-r--r--components/layout/fragment.rs25
-rw-r--r--components/layout/webrender_helpers.rs5
-rw-r--r--components/script/dom/bindings/trace.rs29
-rw-r--r--components/script/dom/canvasgradient.rs2
-rw-r--r--components/script/dom/canvaspattern.rs2
-rw-r--r--components/script/dom/canvasrenderingcontext2d.rs16
-rw-r--r--components/script/dom/htmlcanvaselement.rs66
-rw-r--r--components/script/dom/paintrenderingcontext2d.rs10
-rw-r--r--components/script/dom/paintworkletglobalscope.rs3
-rw-r--r--components/script/dom/vrdisplay.rs36
-rw-r--r--components/script/dom/webgl_extensions/ext/oesvertexarrayobject.rs15
-rw-r--r--components/script/dom/webgl_extensions/ext/webglvertexarrayobjectoes.rs2
-rw-r--r--components/script/dom/webgl_extensions/extensions.rs2
-rw-r--r--components/script/dom/webgl_validations/tex_image_2d.rs2
-rw-r--r--components/script/dom/webglbuffer.rs29
-rw-r--r--components/script/dom/webglframebuffer.rs41
-rw-r--r--components/script/dom/webglprogram.rs56
-rw-r--r--components/script/dom/webglrenderbuffer.rs24
-rw-r--r--components/script/dom/webglrenderingcontext.rs448
-rw-r--r--components/script/dom/webglshader.rs25
-rw-r--r--components/script/dom/webgltexture.rs30
-rw-r--r--components/script/dom/webgluniformlocation.rs2
-rw-r--r--components/script/dom/window.rs19
-rw-r--r--components/script/script_thread.rs12
-rw-r--r--components/script_layout_interface/lib.rs9
-rw-r--r--components/script_traits/Cargo.toml1
-rw-r--r--components/script_traits/lib.rs8
-rw-r--r--components/script_traits/script_msg.rs8
-rw-r--r--components/servo/lib.rs45
-rw-r--r--components/webvr/Cargo.toml3
-rw-r--r--components/webvr/lib.rs3
-rw-r--r--components/webvr/webvr_thread.rs32
54 files changed, 1426 insertions, 3154 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 4455b98c203..759122f23e5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -325,7 +325,6 @@ version = "0.0.1"
dependencies = [
"azure 0.20.1 (git+https://github.com/servo/rust-azure)",
"canvas_traits 0.0.1",
- "compositing 0.0.1",
"cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -333,7 +332,7 @@ dependencies = [
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"offscreen_gl_context 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender 0.48.0 (git+https://github.com/servo/webrender)",
+ "servo_config 0.0.1",
"webrender_api 0.48.0 (git+https://github.com/servo/webrender)",
]
@@ -346,10 +345,7 @@ dependencies = [
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "offscreen_gl_context 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "servo_config 0.0.1",
"webrender_api 0.48.0 (git+https://github.com/servo/webrender)",
]
@@ -530,6 +526,7 @@ dependencies = [
"msg 0.0.1",
"net 0.0.1",
"net_traits 0.0.1",
+ "offscreen_gl_context 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
"profile_traits 0.0.1",
"script_traits 0.0.1",
"serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2599,6 +2596,7 @@ dependencies = [
"metrics 0.0.1",
"msg 0.0.1",
"net_traits 0.0.1",
+ "offscreen_gl_context 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
"profile_traits 0.0.1",
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3531,13 +3529,12 @@ dependencies = [
name = "webvr"
version = "0.0.1"
dependencies = [
- "canvas_traits 0.0.1",
- "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"script_traits 0.0.1",
"servo_config 0.0.1",
+ "webrender_api 0.48.0 (git+https://github.com/servo/webrender)",
"webvr_traits 0.0.1",
]
diff --git a/components/canvas/Cargo.toml b/components/canvas/Cargo.toml
index e8bf234a052..ad149daccb6 100644
--- a/components/canvas/Cargo.toml
+++ b/components/canvas/Cargo.toml
@@ -12,7 +12,6 @@ path = "lib.rs"
[dependencies]
azure = {git = "https://github.com/servo/rust-azure"}
canvas_traits = {path = "../canvas_traits"}
-compositing = {path = "../compositing"}
cssparser = "0.19"
euclid = "0.15"
gleam = "0.4"
@@ -20,5 +19,5 @@ ipc-channel = "0.8"
log = "0.3.5"
num-traits = "0.1.32"
offscreen_gl_context = { version = "0.11", features = ["serde"] }
-webrender = {git = "https://github.com/servo/webrender"}
+servo_config = {path = "../config"}
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
diff --git a/components/canvas/canvas_paint_thread.rs b/components/canvas/canvas_paint_thread.rs
index 8fe05d1f6a9..b7e21777001 100644
--- a/components/canvas/canvas_paint_thread.rs
+++ b/components/canvas/canvas_paint_thread.rs
@@ -8,7 +8,7 @@ use azure::azure_hl::{BackendType, DrawOptions, DrawTarget, Pattern, StrokeOptio
use azure::azure_hl::{Color, ColorPattern, DrawSurfaceOptions, Filter, PathBuilder};
use azure::azure_hl::{ExtendMode, GradientStop, LinearGradientPattern, RadialGradientPattern};
use azure::azure_hl::SurfacePattern;
-use canvas_traits::canvas::*;
+use canvas_traits::*;
use cssparser::RGBA;
use euclid::{Transform2D, Point2D, Vector2D, Rect, Size2D};
use ipc_channel::ipc::{self, IpcSender};
@@ -193,8 +193,12 @@ impl<'a> CanvasPaintThread<'a> {
Canvas2dMsg::SetShadowColor(ref color) => painter.set_shadow_color(color.to_azure_style()),
}
},
- CanvasMsg::Close => break,
- CanvasMsg::Recreate(size) => painter.recreate(size),
+ CanvasMsg::Common(message) => {
+ match message {
+ CanvasCommonMsg::Close => break,
+ CanvasCommonMsg::Recreate(size) => painter.recreate(size),
+ }
+ },
CanvasMsg::FromScript(message) => {
match message {
FromScriptMsg::SendPixels(chan) => {
@@ -209,6 +213,8 @@ impl<'a> CanvasPaintThread<'a> {
}
}
}
+ CanvasMsg::WebGL(_) => panic!("Wrong WebGL message sent to Canvas2D thread"),
+ CanvasMsg::WebVR(_) => panic!("Wrong WebVR message sent to Canvas2D thread"),
}
}
}).expect("Thread spawning failed");
@@ -565,7 +571,7 @@ impl<'a> CanvasPaintThread<'a> {
})
}
- fn send_data(&mut self, chan: IpcSender<CanvasImageData>) {
+ fn send_data(&mut self, chan: IpcSender<CanvasData>) {
self.drawtarget.snapshot().get_data_surface().with_data(|element| {
let size = self.drawtarget.get_size();
@@ -608,7 +614,7 @@ impl<'a> CanvasPaintThread<'a> {
let data = CanvasImageData {
image_key: self.image_key.unwrap(),
};
- chan.send(data).unwrap();
+ chan.send(CanvasData::Image(data)).unwrap();
})
}
diff --git a/components/canvas/gl_context.rs b/components/canvas/gl_context.rs
deleted file mode 100644
index 69a26c0e03c..00000000000
--- a/components/canvas/gl_context.rs
+++ /dev/null
@@ -1,203 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-use canvas_traits::webgl::WebGLCommand;
-use compositing::compositor_thread::{CompositorProxy, self};
-use euclid::Size2D;
-use gleam::gl;
-use offscreen_gl_context::{ColorAttachmentType, GLContext, GLContextAttributes, GLContextDispatcher, GLLimits};
-use offscreen_gl_context::{NativeGLContext, NativeGLContextHandle, NativeGLContextMethods};
-use offscreen_gl_context::{OSMesaContext, OSMesaContextHandle};
-use std::sync::{Arc, Mutex};
-use super::webgl_thread::WebGLImpl;
-
-/// 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<MainThreadDispatcher>),
- 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<GLContextFactory> {
- 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_compositor_proxy())))
- } else {
- GLContextFactory::Native(handle, None)
- }
- })
- }
-
- /// Creates a new GLContextFactory that uses the currently bound OSMesa context to create shared contexts.
- pub fn current_osmesa_handle() -> Option<GLContextFactory> {
- OSMesaContext::current_handle().map(GLContextFactory::OSMesa)
- }
-
- /// Creates a new shared GLContext with the main GLContext
- pub fn new_shared_context(&self,
- size: Size2D<i32>,
- attributes: GLContextAttributes) -> Result<GLContextWrapper, &'static str> {
- match *self {
- GLContextFactory::Native(ref handle, ref dispatcher) => {
- let dispatcher = dispatcher.as_ref().map(|d| Box::new(d.clone()) as Box<_>);
- let ctx = GLContext::<NativeGLContext>::new_shared_with_dispatcher(size,
- attributes,
- ColorAttachmentType::Texture,
- gl::GlType::default(),
- Some(handle),
- dispatcher);
- ctx.map(GLContextWrapper::Native)
- }
- GLContextFactory::OSMesa(ref handle) => {
- let ctx = GLContext::<OSMesaContext>::new_shared_with_dispatcher(size.to_untyped(),
- attributes,
- ColorAttachmentType::Texture,
- gl::GlType::default(),
- Some(handle),
- None);
- ctx.map(GLContextWrapper::OSMesa)
- }
- }
- }
-
- /// Creates a new non-shared GLContext
- pub fn new_context(&self,
- size: Size2D<i32>,
- attributes: GLContextAttributes) -> Result<GLContextWrapper, &'static str> {
- match *self {
- GLContextFactory::Native(..) => {
- let ctx = GLContext::<NativeGLContext>::new_shared_with_dispatcher(size,
- attributes,
- ColorAttachmentType::Texture,
- gl::GlType::default(),
- None,
- None);
- ctx.map(GLContextWrapper::Native)
- }
- GLContextFactory::OSMesa(_) => {
- let ctx = GLContext::<OSMesaContext>::new_shared_with_dispatcher(size.to_untyped(),
- attributes,
- ColorAttachmentType::Texture,
- gl::GlType::default(),
- None,
- None);
- ctx.map(GLContextWrapper::OSMesa)
- }
- }
- }
-}
-
-
-/// GLContextWrapper used to abstract NativeGLContext and OSMesaContext types
-pub enum GLContextWrapper {
- Native(GLContext<NativeGLContext>),
- OSMesa(GLContext<OSMesaContext>),
-}
-
-impl GLContextWrapper {
- pub fn make_current(&self) {
- match *self {
- GLContextWrapper::Native(ref ctx) => {
- ctx.make_current().unwrap();
- }
- GLContextWrapper::OSMesa(ref ctx) => {
- ctx.make_current().unwrap();
- }
- }
- }
-
- pub fn unbind(&self) {
- match *self {
- GLContextWrapper::Native(ref ctx) => {
- ctx.unbind().unwrap();
- }
- GLContextWrapper::OSMesa(ref ctx) => {
- ctx.unbind().unwrap();
- }
- }
- }
-
- pub fn apply_command(&self, cmd: WebGLCommand) {
- match *self {
- GLContextWrapper::Native(ref ctx) => {
- WebGLImpl::apply(ctx, cmd);
- }
- GLContextWrapper::OSMesa(ref ctx) => {
- WebGLImpl::apply(ctx, cmd);
- }
- }
- }
-
- pub fn gl(&self) -> &gl::Gl {
- match *self {
- GLContextWrapper::Native(ref ctx) => {
- ctx.gl()
- }
- GLContextWrapper::OSMesa(ref ctx) => {
- ctx.gl()
- }
- }
- }
-
- pub fn get_info(&self) -> (Size2D<i32>, u32, GLLimits) {
- match *self {
- GLContextWrapper::Native(ref ctx) => {
- let (real_size, texture_id) = {
- let draw_buffer = ctx.borrow_draw_buffer().unwrap();
- (draw_buffer.size(), draw_buffer.get_bound_texture_id().unwrap())
- };
-
- let limits = ctx.borrow_limits().clone();
-
- (real_size, texture_id, limits)
- }
- GLContextWrapper::OSMesa(ref ctx) => {
- let (real_size, texture_id) = {
- let draw_buffer = ctx.borrow_draw_buffer().unwrap();
- (draw_buffer.size(), draw_buffer.get_bound_texture_id().unwrap())
- };
-
- let limits = ctx.borrow_limits().clone();
-
- (real_size, texture_id, limits)
- }
- }
- }
-
- pub fn resize(&mut self, size: Size2D<i32>) -> Result<(), &'static str> {
- match *self {
- GLContextWrapper::Native(ref mut ctx) => {
- ctx.resize(size)
- }
- GLContextWrapper::OSMesa(ref mut ctx) => {
- ctx.resize(size)
- }
- }
- }
-}
-
-/// 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<Mutex<CompositorProxy>>
-}
-
-impl MainThreadDispatcher {
- fn new(proxy: CompositorProxy) -> Self {
- Self {
- compositor_proxy: Arc::new(Mutex::new(proxy)),
- }
- }
-}
-impl GLContextDispatcher for MainThreadDispatcher {
- fn dispatch(&self, f: Box<Fn() + Send>) {
- self.compositor_proxy.lock().unwrap().send(compositor_thread::Msg::Dispatch(f));
- }
-}
diff --git a/components/canvas/lib.rs b/components/canvas/lib.rs
index b9f0823a07d..a3d90909637 100644
--- a/components/canvas/lib.rs
+++ b/components/canvas/lib.rs
@@ -6,18 +6,16 @@
extern crate azure;
extern crate canvas_traits;
-extern crate compositing;
extern crate cssparser;
extern crate euclid;
extern crate gleam;
extern crate ipc_channel;
-#[macro_use] extern crate log;
+#[macro_use]
+extern crate log;
extern crate num_traits;
extern crate offscreen_gl_context;
-extern crate webrender;
+extern crate servo_config;
extern crate webrender_api;
pub mod canvas_paint_thread;
-pub mod gl_context;
-mod webgl_mode;
-pub mod webgl_thread;
+pub mod webgl_paint_thread;
diff --git a/components/canvas/webgl_mode/inprocess.rs b/components/canvas/webgl_mode/inprocess.rs
deleted file mode 100644
index 257f1395545..00000000000
--- a/components/canvas/webgl_mode/inprocess.rs
+++ /dev/null
@@ -1,95 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-use ::gl_context::GLContextFactory;
-use ::webgl_thread::{WebGLExternalImageApi, WebGLExternalImageHandler, WebGLThreadObserver, WebGLThread};
-use canvas_traits::webgl::{WebGLChan, WebGLContextId, WebGLMsg, WebGLPipeline, WebGLReceiver};
-use canvas_traits::webgl::{WebGLSender, WebVRCommand, WebVRRenderHandler};
-use canvas_traits::webgl::webgl_channel;
-use euclid::Size2D;
-use std::marker::PhantomData;
-use webrender;
-use webrender_api;
-
-/// WebGL Threading API entry point that lives in the constellation.
-pub struct WebGLThreads(WebGLSender<WebGLMsg>);
-
-impl WebGLThreads {
- /// Creates a new WebGLThreads object
- pub fn new(gl_factory: GLContextFactory,
- webrender_api_sender: webrender_api::RenderApiSender,
- webvr_compositor: Option<Box<WebVRRenderHandler>>)
- -> (WebGLThreads, Box<webrender::ExternalImageHandler>) {
- // This implementation creates a single `WebGLThread` for all the pipelines.
- let channel = WebGLThread::start(gl_factory,
- webrender_api_sender,
- webvr_compositor.map(|c| WebVRRenderWrapper(c)),
- PhantomData);
- let external = WebGLExternalImageHandler::new(WebGLExternalImages::new(channel.clone()));
- (WebGLThreads(channel), Box::new(external))
- }
-
- /// Gets the WebGLThread handle for each script pipeline.
- pub fn pipeline(&self) -> WebGLPipeline {
- // This mode creates a single thread, so the existing WebGLChan is just cloned.
- WebGLPipeline(WebGLChan(self.0.clone()))
- }
-
- /// Sends a exit message to close the WebGLThreads and release all WebGLContexts.
- pub fn exit(&self) -> Result<(), &'static str> {
- self.0.send(WebGLMsg::Exit).map_err(|_| "Failed to send Exit message")
- }
-}
-
-/// Bridge between the webrender::ExternalImage callbacks and the WebGLThreads.
-struct WebGLExternalImages {
- 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>)>),
-}
-
-impl WebGLExternalImages {
- fn new(channel: WebGLSender<WebGLMsg>) -> Self {
- Self {
- webgl_channel: channel,
- lock_channel: webgl_channel().unwrap(),
- }
- }
-}
-
-impl WebGLExternalImageApi for WebGLExternalImages {
- fn lock(&mut self, ctx_id: WebGLContextId) -> (u32, Size2D<i32>) {
- self.webgl_channel.send(WebGLMsg::Lock(ctx_id, self.lock_channel.0.clone())).unwrap();
- self.lock_channel.1.recv().unwrap()
- }
-
- fn unlock(&mut self, ctx_id: WebGLContextId) {
- self.webgl_channel.send(WebGLMsg::Unlock(ctx_id)).unwrap();
- }
-}
-
-/// Custom observer used in a `WebGLThread`.
-impl WebGLThreadObserver for PhantomData<()> {
- fn on_context_create(&mut self, ctx_id: WebGLContextId, texture_id: u32, size: Size2D<i32>) {
- debug!("WebGLContext created (ctx_id: {:?} texture_id: {:?} size: {:?}", ctx_id, texture_id, size);
- }
-
- fn on_context_resize(&mut self, ctx_id: WebGLContextId, texture_id: u32, size: Size2D<i32>) {
- debug!("WebGLContext resized (ctx_id: {:?} texture_id: {:?} size: {:?}", ctx_id, texture_id, size);
- }
-
- fn on_context_delete(&mut self, ctx_id: WebGLContextId) {
- debug!("WebGLContext deleted (ctx_id: {:?})", ctx_id);
- }
-}
-
-
-/// Wrapper to send WebVR commands used in `WebGLThread`.
-struct WebVRRenderWrapper(Box<WebVRRenderHandler>);
-
-impl WebVRRenderHandler for WebVRRenderWrapper {
- fn handle(&mut self, command: WebVRCommand, texture: Option<(u32, Size2D<i32>)>) {
- self.0.handle(command, texture);
- }
-}
diff --git a/components/canvas/webgl_mode/mod.rs b/components/canvas/webgl_mode/mod.rs
deleted file mode 100644
index 660818fb096..00000000000
--- a/components/canvas/webgl_mode/mod.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-mod inprocess;
-pub use self::inprocess::WebGLThreads;
diff --git a/components/canvas/webgl_paint_thread.rs b/components/canvas/webgl_paint_thread.rs
new file mode 100644
index 00000000000..2b6819effba
--- /dev/null
+++ b/components/canvas/webgl_paint_thread.rs
@@ -0,0 +1,379 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use canvas_traits::{CanvasCommonMsg, CanvasData, CanvasMsg, CanvasImageData};
+use canvas_traits::{FromLayoutMsg, FromScriptMsg, byte_swap};
+use euclid::Size2D;
+use gleam::gl;
+use ipc_channel::ipc::{self, IpcSender};
+use offscreen_gl_context::{ColorAttachmentType, GLContext, GLLimits};
+use offscreen_gl_context::{GLContextAttributes, NativeGLContext, OSMesaContext};
+use servo_config::opts;
+use std::borrow::ToOwned;
+use std::mem;
+use std::sync::Arc;
+use std::sync::mpsc::channel;
+use std::thread;
+use webrender_api;
+
+enum GLContextWrapper {
+ Native(GLContext<NativeGLContext>),
+ OSMesa(GLContext<OSMesaContext>),
+}
+
+impl GLContextWrapper {
+ fn new(size: Size2D<i32>,
+ attributes: GLContextAttributes,
+ gl_type: gl::GlType) -> Result<GLContextWrapper, &'static str> {
+ if opts::get().should_use_osmesa() {
+ let ctx = GLContext::<OSMesaContext>::new(size,
+ attributes,
+ ColorAttachmentType::Texture,
+ gl_type,
+ None);
+ ctx.map(GLContextWrapper::OSMesa)
+ } else {
+ let ctx = GLContext::<NativeGLContext>::new(size,
+ attributes,
+ ColorAttachmentType::Texture,
+ gl_type,
+ None);
+ ctx.map(GLContextWrapper::Native)
+ }
+ }
+
+ pub fn get_limits(&self) -> GLLimits {
+ match *self {
+ GLContextWrapper::Native(ref ctx) => {
+ ctx.borrow_limits().clone()
+ }
+ GLContextWrapper::OSMesa(ref ctx) => {
+ ctx.borrow_limits().clone()
+ }
+ }
+ }
+
+ fn resize(&mut self, size: Size2D<i32>) -> Result<Size2D<i32>, &'static str> {
+ match *self {
+ GLContextWrapper::Native(ref mut ctx) => {
+ ctx.resize(size)?;
+ Ok(ctx.borrow_draw_buffer().unwrap().size())
+ }
+ GLContextWrapper::OSMesa(ref mut ctx) => {
+ ctx.resize(size)?;
+ Ok(ctx.borrow_draw_buffer().unwrap().size())
+ }
+ }
+ }
+
+ fn gl(&self) -> &gl::Gl {
+ match *self {
+ GLContextWrapper::Native(ref ctx) => {
+ ctx.gl()
+ }
+ GLContextWrapper::OSMesa(ref ctx) => {
+ ctx.gl()
+ }
+ }
+ }
+
+ pub fn make_current(&self) {
+ match *self {
+ GLContextWrapper::Native(ref ctx) => {
+ ctx.make_current().unwrap();
+ }
+ GLContextWrapper::OSMesa(ref ctx) => {
+ ctx.make_current().unwrap();
+ }
+ }
+ }
+
+ pub fn apply_command(&self, cmd: webrender_api::WebGLCommand) {
+ match *self {
+ GLContextWrapper::Native(ref ctx) => {
+ cmd.apply(ctx);
+ }
+ GLContextWrapper::OSMesa(ref ctx) => {
+ cmd.apply(ctx);
+ }
+ }
+ }
+}
+
+enum WebGLPaintTaskData {
+ WebRender(webrender_api::RenderApi, webrender_api::WebGLContextId),
+ Readback {
+ context: GLContextWrapper,
+ webrender_api: webrender_api::RenderApi,
+ image_key: Option<webrender_api::ImageKey>,
+ /// An old webrender image key that can be deleted when the next epoch ends.
+ old_image_key: Option<webrender_api::ImageKey>,
+ /// An old webrender image key that can be deleted when the current epoch ends.
+ very_old_image_key: Option<webrender_api::ImageKey>,
+ },
+}
+
+pub struct WebGLPaintThread {
+ size: Size2D<i32>,
+ data: WebGLPaintTaskData,
+}
+
+fn create_readback_painter(size: Size2D<i32>,
+ attrs: GLContextAttributes,
+ webrender_api: webrender_api::RenderApi,
+ gl_type: gl::GlType)
+ -> Result<(WebGLPaintThread, GLLimits), String> {
+ let context = GLContextWrapper::new(size, attrs, gl_type)?;
+ let limits = context.get_limits();
+ let painter = WebGLPaintThread {
+ size: size,
+ data: WebGLPaintTaskData::Readback {
+ context: context,
+ webrender_api: webrender_api,
+ image_key: None,
+ old_image_key: None,
+ very_old_image_key: None,
+ },
+ };
+
+ Ok((painter, limits))
+}
+
+impl WebGLPaintThread {
+ fn new(size: Size2D<i32>,
+ attrs: GLContextAttributes,
+ webrender_api_sender: webrender_api::RenderApiSender,
+ gl_type: gl::GlType)
+ -> Result<(WebGLPaintThread, GLLimits), String> {
+ let wr_api = webrender_api_sender.create_api();
+ let device_size = webrender_api::DeviceIntSize::from_untyped(&size);
+ match wr_api.request_webgl_context(&device_size, attrs) {
+ Ok((id, limits)) => {
+ let painter = WebGLPaintThread {
+ data: WebGLPaintTaskData::WebRender(wr_api, id),
+ size: size
+ };
+ Ok((painter, limits))
+ },
+ Err(msg) => {
+ warn!("Initial context creation failed, falling back to readback: {}", msg);
+ create_readback_painter(size, attrs, wr_api, gl_type)
+ }
+ }
+ }
+
+ fn handle_webgl_message(&self, message: webrender_api::WebGLCommand) {
+ debug!("WebGL message: {:?}", message);
+ match self.data {
+ WebGLPaintTaskData::WebRender(ref api, id) => {
+ api.send_webgl_command(id, message);
+ }
+ WebGLPaintTaskData::Readback { ref context, .. } => {
+ context.apply_command(message);
+ }
+ }
+ }
+
+ fn handle_webvr_message(&self, message: webrender_api::VRCompositorCommand) {
+ match self.data {
+ WebGLPaintTaskData::WebRender(ref api, id) => {
+ api.send_vr_compositor_command(id, message);
+ }
+ WebGLPaintTaskData::Readback { .. } => {
+ error!("Webrender is required for WebVR implementation");
+ }
+ }
+ }
+
+
+ /// Creates a new `WebGLPaintThread` and returns an `IpcSender` to
+ /// communicate with it.
+ pub fn start(size: Size2D<i32>,
+ attrs: GLContextAttributes,
+ webrender_api_sender: webrender_api::RenderApiSender)
+ -> Result<(IpcSender<CanvasMsg>, GLLimits), String> {
+ let (sender, receiver) = ipc::channel::<CanvasMsg>().unwrap();
+ let (result_chan, result_port) = channel();
+ thread::Builder::new().name("WebGLThread".to_owned()).spawn(move || {
+ let gl_type = gl::GlType::default();
+ let mut painter = match WebGLPaintThread::new(size, attrs, webrender_api_sender, gl_type) {
+ Ok((thread, limits)) => {
+ result_chan.send(Ok(limits)).unwrap();
+ thread
+ },
+ Err(e) => {
+ result_chan.send(Err(e)).unwrap();
+ return
+ }
+ };
+ painter.init();
+ loop {
+ match receiver.recv().unwrap() {
+ CanvasMsg::WebGL(message) => painter.handle_webgl_message(message),
+ CanvasMsg::Common(message) => {
+ match message {
+ CanvasCommonMsg::Close => break,
+ // TODO(emilio): handle error nicely
+ CanvasCommonMsg::Recreate(size) => painter.recreate(size).unwrap(),
+ }
+ },
+ CanvasMsg::FromScript(message) => {
+ match message {
+ FromScriptMsg::SendPixels(chan) =>{
+ // Read the comment on
+ // HTMLCanvasElement::fetch_all_data.
+ chan.send(None).unwrap();
+ }
+ }
+ }
+ CanvasMsg::FromLayout(message) => {
+ match message {
+ FromLayoutMsg::SendData(chan) =>
+ painter.send_data(chan),
+ }
+ }
+ CanvasMsg::Canvas2d(_) => panic!("Wrong message sent to WebGLThread"),
+ CanvasMsg::WebVR(message) => painter.handle_webvr_message(message)
+ }
+ }
+ }).expect("Thread spawning failed");
+
+ result_port.recv().unwrap().map(|limits| (sender, limits))
+ }
+
+ fn send_data(&mut self, chan: IpcSender<CanvasData>) {
+ match self.data {
+ WebGLPaintTaskData::Readback {
+ ref context,
+ ref webrender_api,
+ ref mut image_key,
+ ref mut old_image_key,
+ ref mut very_old_image_key,
+ } => {
+ let width = self.size.width as usize;
+ let height = self.size.height as usize;
+
+ let mut pixels = context.gl().read_pixels(0, 0,
+ self.size.width as gl::GLsizei,
+ self.size.height as gl::GLsizei,
+ gl::RGBA, gl::UNSIGNED_BYTE);
+ // flip image vertically (texture is upside down)
+ let orig_pixels = pixels.clone();
+ let stride = width * 4;
+ for y in 0..height {
+ let dst_start = y * stride;
+ let src_start = (height - y - 1) * stride;
+ let src_slice = &orig_pixels[src_start .. src_start + stride];
+ (&mut pixels[dst_start .. dst_start + stride]).clone_from_slice(&src_slice[..stride]);
+ }
+
+ // rgba -> bgra
+ byte_swap(&mut pixels);
+
+ let descriptor = webrender_api::ImageDescriptor {
+ width: width as u32,
+ height: height as u32,
+ stride: None,
+ format: webrender_api::ImageFormat::BGRA8,
+ offset: 0,
+ is_opaque: false,
+ };
+ let data = webrender_api::ImageData::Raw(Arc::new(pixels));
+
+ let mut updates = webrender_api::ResourceUpdates::new();
+
+ match *image_key {
+ Some(image_key) => {
+ updates.update_image(image_key,
+ descriptor,
+ data,
+ None);
+ }
+ None => {
+ *image_key = Some(webrender_api.generate_image_key());
+ updates.add_image(image_key.unwrap(),
+ descriptor,
+ data,
+ None);
+ }
+ }
+
+ if let Some(image_key) = mem::replace(very_old_image_key, old_image_key.take()) {
+ updates.delete_image(image_key);
+ }
+
+ webrender_api.update_resources(updates);
+
+ let image_data = CanvasImageData {
+ image_key: image_key.unwrap(),
+ };
+
+ chan.send(CanvasData::Image(image_data)).unwrap();
+ }
+ WebGLPaintTaskData::WebRender(_, id) => {
+ chan.send(CanvasData::WebGL(id)).unwrap();
+ }
+ }
+ }
+
+ #[allow(unsafe_code)]
+ fn recreate(&mut self, size: Size2D<i32>) -> Result<(), &'static str> {
+ match self.data {
+ WebGLPaintTaskData::Readback { ref mut context, ref mut image_key, ref mut old_image_key, .. } => {
+ if size.width > self.size.width ||
+ size.height > self.size.height {
+ self.size = context.resize(size)?;
+ } else {
+ self.size = size;
+ context.gl().scissor(0, 0, size.width, size.height);
+ }
+ // Webrender doesn't let images change size, so we clear the webrender image key.
+ if let Some(image_key) = image_key.take() {
+ // If this executes, then we are in a new epoch since we last recreated the canvas,
+ // so `old_image_key` must be `None`.
+ debug_assert!(old_image_key.is_none());
+ *old_image_key = Some(image_key);
+ }
+ }
+ WebGLPaintTaskData::WebRender(ref api, id) => {
+ let device_size = webrender_api::DeviceIntSize::from_untyped(&size);
+ api.resize_webgl_context(id, &device_size);
+ }
+ }
+
+ Ok(())
+ }
+
+ fn init(&mut self) {
+ if let WebGLPaintTaskData::Readback { ref context, .. } = self.data {
+ context.make_current();
+ }
+ }
+}
+
+impl Drop for WebGLPaintThread {
+ fn drop(&mut self) {
+ if let WebGLPaintTaskData::Readback {
+ ref mut webrender_api,
+ image_key,
+ old_image_key,
+ very_old_image_key,
+ ..
+ } = self.data {
+ let mut updates = webrender_api::ResourceUpdates::new();
+
+ if let Some(image_key) = image_key {
+ updates.delete_image(image_key);
+ }
+ if let Some(image_key) = old_image_key {
+ updates.delete_image(image_key);
+ }
+ if let Some(image_key) = very_old_image_key {
+ updates.delete_image(image_key);
+ }
+
+ webrender_api.update_resources(updates);
+ }
+ }
+}
diff --git a/components/canvas/webgl_thread.rs b/components/canvas/webgl_thread.rs
deleted file mode 100644
index 907233a3b89..00000000000
--- a/components/canvas/webgl_thread.rs
+++ /dev/null
@@ -1,1204 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-use canvas_traits::canvas::byte_swap;
-use canvas_traits::webgl::*;
-use euclid::Size2D;
-use gleam::gl;
-use offscreen_gl_context::{GLContext, GLContextAttributes, GLLimits, NativeGLContextMethods};
-use std::collections::HashMap;
-use std::mem;
-use std::thread;
-use super::gl_context::{GLContextFactory, GLContextWrapper};
-use webrender;
-use webrender_api;
-
-/// WebGL Threading API entry point that lives in the constellation.
-/// It allows to get a WebGLThread handle for each script pipeline.
-pub use ::webgl_mode::WebGLThreads;
-
-/// A WebGLThread manages the life cycle and message multiplexing of
-/// a set of WebGLContexts living in the same thread.
-pub struct WebGLThread<VR: WebVRRenderHandler + 'static, OB: WebGLThreadObserver> {
- /// Factory used to create a new GLContext shared with the WR/Main thread.
- gl_factory: GLContextFactory,
- /// Channel used to generate/update or delete `webrender_api::ImageKey`s.
- webrender_api: webrender_api::RenderApi,
- /// Map of live WebGLContexts.
- contexts: HashMap<WebGLContextId, GLContextWrapper>,
- /// Cached information for WebGLContexts.
- cached_context_info: HashMap<WebGLContextId, WebGLContextInfo>,
- /// Current bound context.
- bound_context_id: Option<WebGLContextId>,
- /// Id generator for new WebGLContexts.
- next_webgl_id: usize,
- /// Handler user to send WebVR commands.
- webvr_compositor: Option<VR>,
- /// Generic observer that listens WebGLContext creation, resize or removal events.
- observer: OB,
-}
-
-impl<VR: WebVRRenderHandler + 'static, OB: WebGLThreadObserver> WebGLThread<VR, OB> {
- pub fn new(gl_factory: GLContextFactory,
- webrender_api_sender: webrender_api::RenderApiSender,
- webvr_compositor: Option<VR>,
- observer: OB) -> Self {
- WebGLThread {
- gl_factory,
- webrender_api: webrender_api_sender.create_api(),
- contexts: HashMap::new(),
- cached_context_info: HashMap::new(),
- bound_context_id: None,
- next_webgl_id: 0,
- webvr_compositor,
- observer: observer,
- }
- }
-
- /// Creates a new `WebGLThread` and returns a Sender to
- /// communicate with it.
- pub fn start(gl_factory: GLContextFactory,
- webrender_api_sender: webrender_api::RenderApiSender,
- webvr_compositor: Option<VR>,
- observer: OB)
- -> WebGLSender<WebGLMsg> {
- let (sender, receiver) = webgl_channel::<WebGLMsg>().unwrap();
- let result = sender.clone();
- thread::Builder::new().name("WebGLThread".to_owned()).spawn(move || {
- let mut renderer = WebGLThread::new(gl_factory,
- webrender_api_sender,
- webvr_compositor,
- observer);
- let webgl_chan = WebGLChan(sender);
- loop {
- let msg = receiver.recv().unwrap();
- let exit = renderer.handle_msg(msg, &webgl_chan);
- if exit {
- return;
- }
- }
- }).expect("Thread spawning failed");
-
- result
- }
-
- /// Handles a generic WebGLMsg message
- #[inline]
- fn handle_msg(&mut self, msg: WebGLMsg, webgl_chan: &WebGLChan) -> bool {
- match msg {
- WebGLMsg::CreateContext(size, attributes, result_sender) => {
- let result = self.create_webgl_context(size, attributes);
- result_sender.send(result.map(|(id, limits, share_mode)|
- WebGLCreateContextResult {
- sender: WebGLMsgSender::new(id, webgl_chan.clone()),
- limits: limits,
- share_mode: share_mode,
- }
- )).unwrap();
- },
- WebGLMsg::ResizeContext(ctx_id, size, sender) => {
- self.resize_webgl_context(ctx_id, size, sender);
- },
- WebGLMsg::RemoveContext(ctx_id) => {
- self.remove_webgl_context(ctx_id);
- },
- WebGLMsg::WebGLCommand(ctx_id, command) => {
- self.handle_webgl_command(ctx_id, command);
- },
- WebGLMsg::WebVRCommand(ctx_id, command) => {
- self.handle_webvr_command(ctx_id, command);
- },
- WebGLMsg::Lock(ctx_id, sender) => {
- self.handle_lock(ctx_id, sender);
- },
- WebGLMsg::Unlock(ctx_id) => {
- self.handle_unlock(ctx_id);
- },
- WebGLMsg::UpdateWebRenderImage(ctx_id, sender) => {
- self.handle_update_wr_image(ctx_id, sender);
- },
- WebGLMsg::Exit => {
- return true;
- }
- }
-
- false
- }
-
- /// Handles a WebGLCommand for a specific WebGLContext
- fn handle_webgl_command(&mut self, context_id: WebGLContextId, command: WebGLCommand) {
- if let Some(ctx) = Self::make_current_if_needed(context_id, &self.contexts, &mut self.bound_context_id) {
- ctx.apply_command(command);
- }
- }
-
- /// Handles a WebVRCommand for a specific WebGLContext
- fn handle_webvr_command(&mut self, context_id: WebGLContextId, command: WebVRCommand) {
- Self::make_current_if_needed(context_id, &self.contexts, &mut self.bound_context_id);
- let texture = match command {
- WebVRCommand::SubmitFrame(..) => {
- self.cached_context_info.get(&context_id)
- },
- _ => None
- };
- self.webvr_compositor.as_mut().unwrap().handle(command, texture.map(|t| (t.texture_id, t.size)));
- }
-
- /// Handles a lock external callback received from webrender::ExternalImageHandler
- fn handle_lock(&mut self, context_id: WebGLContextId, sender: WebGLSender<(u32, Size2D<i32>)>) {
- let ctx = Self::make_current_if_needed(context_id, &self.contexts, &mut self.bound_context_id)
- .expect("WebGLContext not found in a WebGLMsg::Lock message");
- let info = self.cached_context_info.get_mut(&context_id).unwrap();
- // Use a OpenGL Fence to perform the lock.
- info.gl_sync = Some(ctx.gl().fence_sync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0));
-
- sender.send((info.texture_id, info.size)).unwrap();
- }
-
- /// Handles an unlock external callback received from webrender::ExternalImageHandler
- fn handle_unlock(&mut self, context_id: WebGLContextId) {
- let ctx = Self::make_current_if_needed(context_id, &self.contexts, &mut self.bound_context_id)
- .expect("WebGLContext not found in a WebGLMsg::Unlock message");
- let info = self.cached_context_info.get_mut(&context_id).unwrap();
- if let Some(gl_sync) = info.gl_sync.take() {
- // glFlush must be called before glWaitSync.
- ctx.gl().flush();
- // Wait until the GLSync object is signaled.
- ctx.gl().wait_sync(gl_sync, 0, gl::TIMEOUT_IGNORED);
- // Release the GLSync object.
- ctx.gl().delete_sync(gl_sync);
- }
- }
-
- /// Creates a new WebGLContext
- fn create_webgl_context(&mut self,
- size: Size2D<i32>,
- attributes: GLContextAttributes)
- -> Result<(WebGLContextId, GLLimits, WebGLContextShareMode), String> {
- // First try to create a shared context for the best performance.
- // Fallback to readback mode if the shared context creation fails.
- let result = self.gl_factory.new_shared_context(size, attributes)
- .map(|r| (r, WebGLContextShareMode::SharedTexture))
- .or_else(|_| {
- let ctx = self.gl_factory.new_context(size, attributes);
- ctx.map(|r| (r, WebGLContextShareMode::Readback))
- });
-
- // Creating a new GLContext may make the current bound context_id dirty.
- // Clear it to ensure that make_current() is called in subsequent commands.
- self.bound_context_id = None;
-
- match result {
- Ok((ctx, share_mode)) => {
- let id = WebGLContextId(self.next_webgl_id);
- let (size, texture_id, limits) = ctx.get_info();
- self.next_webgl_id += 1;
- self.contexts.insert(id, ctx);
- self.cached_context_info.insert(id, WebGLContextInfo {
- texture_id,
- size,
- alpha: attributes.alpha,
- image_key: None,
- share_mode,
- gl_sync: None,
- old_image_key: None,
- very_old_image_key: None,
- });
-
- self.observer.on_context_create(id, texture_id, size);
-
- Ok((id, limits, share_mode))
- },
- Err(msg) => {
- Err(msg.to_owned())
- }
- }
- }
-
- /// Resizes a WebGLContext
- fn resize_webgl_context(&mut self,
- context_id: WebGLContextId,
- size: Size2D<i32>,
- sender: WebGLSender<Result<(), String>>) {
- let ctx = Self::make_current_if_needed_mut(context_id, &mut self.contexts, &mut self.bound_context_id);
- match ctx.resize(size) {
- Ok(_) => {
- let (real_size, texture_id, _) = ctx.get_info();
- self.observer.on_context_resize(context_id, texture_id, real_size);
-
- let info = self.cached_context_info.get_mut(&context_id).unwrap();
- // Update webgl texture size. Texture id may change too.
- info.texture_id = texture_id;
- info.size = real_size;
- // WR doesn't support resizing and requires to create a new `ImageKey`.
- // Mark the current image_key to be deleted later in the next epoch.
- if let Some(image_key) = info.image_key.take() {
- // If this executes, then we are in a new epoch since we last recreated the canvas,
- // so `old_image_key` must be `None`.
- debug_assert!(info.old_image_key.is_none());
- info.old_image_key = Some(image_key);
- }
-
- sender.send(Ok(())).unwrap();
- },
- Err(msg) => {
- sender.send(Err(msg.into())).unwrap();
- }
- }
- }
-
- /// Removes a WebGLContext and releases attached resources.
- fn remove_webgl_context(&mut self, context_id: WebGLContextId) {
- // Release webrender image keys.
- if let Some(info) = self.cached_context_info.remove(&context_id) {
- let mut updates = webrender_api::ResourceUpdates::new();
-
- if let Some(image_key) = info.image_key {
- updates.delete_image(image_key);
- }
- if let Some(image_key) = info.old_image_key {
- updates.delete_image(image_key);
- }
- if let Some(image_key) = info.very_old_image_key {
- updates.delete_image(image_key);
- }
-
- self.webrender_api.update_resources(updates)
- }
-
- // Release GL context.
- if self.contexts.remove(&context_id).is_some() {
- self.observer.on_context_delete(context_id);
- }
-
- // Removing a GLContext may make the current bound context_id dirty.
- self.bound_context_id = None;
- }
-
- /// Handles the creation/update of webrender_api::ImageKeys fpr a specific WebGLContext.
- /// This method is invoked from a UpdateWebRenderImage message sent by the layout thread.
- /// If SharedTexture is used the UpdateWebRenderImage message is sent only after a WebGLContext creation or resize.
- /// If Readback is used UpdateWebRenderImage message is sent always on each layout iteration in order to
- /// submit the updated raw pixels.
- fn handle_update_wr_image(&mut self, context_id: WebGLContextId, sender: WebGLSender<webrender_api::ImageKey>) {
- let info = self.cached_context_info.get_mut(&context_id).unwrap();
- let webrender_api = &self.webrender_api;
-
- let image_key = match info.share_mode {
- WebGLContextShareMode::SharedTexture => {
- let size = info.size;
- let alpha = info.alpha;
- // Reuse existing ImageKey or generate a new one.
- // When using a shared texture ImageKeys are only generated after a WebGLContext creation or resize.
- *info.image_key.get_or_insert_with(|| {
- Self::create_wr_external_image(webrender_api, size, alpha, context_id)
- })
- },
- WebGLContextShareMode::Readback => {
- let pixels = Self::raw_pixels(&self.contexts[&context_id], info.size);
- match info.image_key.clone() {
- Some(image_key) => {
- // ImageKey was already created, but WR Images must
- // be updated every frame in readback mode to send the new raw pixels.
- Self::update_wr_readback_image(webrender_api,
- info.size,
- info.alpha,
- image_key,
- pixels);
-
- image_key
- },
- None => {
- // Generate a new ImageKey for Readback mode.
- let image_key = Self::create_wr_readback_image(webrender_api,
- info.size,
- info.alpha,
- pixels);
- info.image_key = Some(image_key);
- image_key
- }
- }
- }
- };
-
- // Delete old image
- if let Some(image_key) = mem::replace(&mut info.very_old_image_key, info.old_image_key.take()) {
- let mut updates = webrender_api::ResourceUpdates::new();
- updates.delete_image(image_key);
- self.webrender_api.update_resources(updates);
- }
-
- // Send the ImageKey to the Layout thread.
- sender.send(image_key).unwrap();
- }
-
- /// Gets a reference to a GLContextWrapper for a given WebGLContextId and makes it current if required.
- fn make_current_if_needed<'a>(context_id: WebGLContextId,
- contexts: &'a HashMap<WebGLContextId, GLContextWrapper>,
- bound_id: &mut Option<WebGLContextId>) -> Option<&'a GLContextWrapper> {
- contexts.get(&context_id).and_then(|ctx| {
- if Some(context_id) != *bound_id {
- ctx.make_current();
- *bound_id = Some(context_id);
- }
-
- Some(ctx)
- })
- }
-
- /// Gets a mutable reference to a GLContextWrapper for a WebGLContextId and makes it current if required.
- fn make_current_if_needed_mut<'a>(context_id: WebGLContextId,
- contexts: &'a mut HashMap<WebGLContextId, GLContextWrapper>,
- bound_id: &mut Option<WebGLContextId>) -> &'a mut GLContextWrapper {
- let ctx = contexts.get_mut(&context_id).expect("WebGLContext not found!");
- if Some(context_id) != *bound_id {
- ctx.make_current();
- *bound_id = Some(context_id);
- }
- ctx
- }
-
- /// Creates a `webrender_api::ImageKey` that uses shared textures.
- fn create_wr_external_image(webrender_api: &webrender_api::RenderApi,
- size: Size2D<i32>,
- alpha: bool,
- context_id: WebGLContextId) -> webrender_api::ImageKey {
- let descriptor = Self::image_descriptor(size, alpha);
-
- let data = webrender_api::ExternalImageData {
- id: webrender_api::ExternalImageId(context_id.0 as u64),
- channel_index: 0,
- image_type: webrender_api::ExternalImageType::Texture2DHandle,
- };
- let data = webrender_api::ImageData::External(data);
-
- let image_key = webrender_api.generate_image_key();
- let mut updates = webrender_api::ResourceUpdates::new();
- updates.add_image(image_key,
- descriptor,
- data,
- None);
- webrender_api.update_resources(updates);
-
- image_key
- }
-
- /// Creates a `webrender_api::ImageKey` that uses raw pixels.
- fn create_wr_readback_image(webrender_api: &webrender_api::RenderApi,
- size: Size2D<i32>,
- alpha: bool,
- data: Vec<u8>) -> webrender_api::ImageKey {
- let descriptor = Self::image_descriptor(size, alpha);
- let data = webrender_api::ImageData::new(data);
-
- let image_key = webrender_api.generate_image_key();
- let mut updates = webrender_api::ResourceUpdates::new();
- updates.add_image(image_key,
- descriptor,
- data,
- None);
- webrender_api.update_resources(updates);
-
- image_key
- }
-
- /// Updates a `webrender_api::ImageKey` that uses raw pixels.
- fn update_wr_readback_image(webrender_api: &webrender_api::RenderApi,
- size: Size2D<i32>,
- alpha: bool,
- image_key: webrender_api::ImageKey,
- data: Vec<u8>) {
- let descriptor = Self::image_descriptor(size, alpha);
- let data = webrender_api::ImageData::new(data);
-
- let mut updates = webrender_api::ResourceUpdates::new();
- updates.update_image(image_key,
- descriptor,
- data,
- None);
- webrender_api.update_resources(updates);
- }
-
- /// Helper function to create a `webrender_api::ImageDescriptor`.
- fn image_descriptor(size: Size2D<i32>, alpha: bool) -> webrender_api::ImageDescriptor {
- webrender_api::ImageDescriptor {
- width: size.width as u32,
- height: size.height as u32,
- stride: None,
- format: if alpha { webrender_api::ImageFormat::BGRA8 } else { webrender_api::ImageFormat::RGB8 },
- offset: 0,
- is_opaque: !alpha,
- }
- }
-
- /// Helper function to fetch the raw pixels used in readback mode.
- fn raw_pixels(context: &GLContextWrapper, size: Size2D<i32>) -> Vec<u8> {
- let width = size.width as usize;
- let height = size.height as usize;
-
- let mut pixels = context.gl().read_pixels(0, 0,
- size.width as gl::GLsizei,
- size.height as gl::GLsizei,
- gl::RGBA, gl::UNSIGNED_BYTE);
- // flip image vertically (texture is upside down)
- let orig_pixels = pixels.clone();
- let stride = width * 4;
- for y in 0..height {
- let dst_start = y * stride;
- let src_start = (height - y - 1) * stride;
- let src_slice = &orig_pixels[src_start .. src_start + stride];
- (&mut pixels[dst_start .. dst_start + stride]).clone_from_slice(&src_slice[..stride]);
- }
- byte_swap(&mut pixels);
- pixels
- }
-}
-
-impl<VR: WebVRRenderHandler + 'static, OB: WebGLThreadObserver> Drop for WebGLThread<VR, OB> {
- fn drop(&mut self) {
- // Call remove_context functions in order to correctly delete WebRender image keys.
- let context_ids: Vec<WebGLContextId> = self.contexts.keys().map(|id| *id).collect();
- for id in context_ids {
- self.remove_webgl_context(id);
- }
- }
-}
-
-/// Helper struct to store cached WebGLContext information.
-struct WebGLContextInfo {
- /// Render to texture identifier used by the WebGLContext.
- texture_id: u32,
- /// Size of the WebGLContext.
- size: Size2D<i32>,
- /// True if the WebGLContext uses an alpha channel.
- alpha: bool,
- /// Currently used WebRender image key.
- image_key: Option<webrender_api::ImageKey>,
- /// The sharing mode used to send the image to WebRender.
- share_mode: WebGLContextShareMode,
- /// GLSync Object used for a correct synchronization with Webrender external image callbacks.
- gl_sync: Option<gl::GLsync>,
- /// An old WebRender image key that can be deleted when the next epoch ends.
- old_image_key: Option<webrender_api::ImageKey>,
- /// An old WebRender image key that can be deleted when the current epoch ends.
- very_old_image_key: Option<webrender_api::ImageKey>,
-}
-
-/// Trait used to observe events in a WebGL Thread.
-/// Used in webrender::ExternalImageHandler when multiple WebGL threads are used.
-pub trait WebGLThreadObserver: Send + 'static {
- fn on_context_create(&mut self, ctx_id: WebGLContextId, texture_id: u32, size: Size2D<i32>);
- fn on_context_resize(&mut self, ctx_id: WebGLContextId, texture_id: u32, size: Size2D<i32>);
- fn on_context_delete(&mut self, ctx_id: WebGLContextId);
-}
-
-/// This trait is used as a bridge between the `WebGLThreads` implementation and
-/// the WR ExternalImageHandler API implemented in the `WebGLExternalImageHandler` struct.
-/// `WebGLExternalImageHandler<T>` takes care of type conversions between WR and WebGL info (e.g keys, uvs).
-/// It uses this trait to notify lock/unlock messages and get the required info that WR needs.
-/// `WebGLThreads` receives lock/unlock message notifications and takes care of sending
-/// the unlock/lock messages to the appropiate `WebGLThread`.
-pub trait WebGLExternalImageApi {
- fn lock(&mut self, ctx_id: WebGLContextId) -> (u32, Size2D<i32>);
- fn unlock(&mut self, ctx_id: WebGLContextId);
-}
-
-/// WebRender External Image Handler implementation
-pub struct WebGLExternalImageHandler<T: WebGLExternalImageApi> {
- handler: T,
-}
-
-impl<T: WebGLExternalImageApi> WebGLExternalImageHandler<T> {
- pub fn new(handler: T) -> Self {
- Self {
- handler: handler
- }
- }
-}
-
-impl<T: WebGLExternalImageApi> webrender::ExternalImageHandler for WebGLExternalImageHandler<T> {
- /// Lock the external image. Then, WR could start to read the image content.
- /// The WR client should not change the image content until the unlock() call.
- fn lock(&mut self,
- key: webrender_api::ExternalImageId,
- _channel_index: u8) -> webrender::ExternalImage {
- let ctx_id = WebGLContextId(key.0 as _);
- let (texture_id, size) = self.handler.lock(ctx_id);
-
- webrender::ExternalImage {
- u0: 0.0,
- u1: size.width as f32,
- v1: 0.0,
- v0: size.height as f32,
- source: webrender::ExternalImageSource::NativeTexture(texture_id),
- }
-
- }
- /// Unlock the external image. The WR should not read the image content
- /// after this call.
- fn unlock(&mut self,
- key: webrender_api::ExternalImageId,
- _channel_index: u8) {
- let ctx_id = WebGLContextId(key.0 as _);
- self.handler.unlock(ctx_id);
- }
-}
-
-/// WebGL Commands Implementation
-pub struct WebGLImpl;
-
-impl WebGLImpl {
- pub fn apply<Native: NativeGLContextMethods>(ctx: &GLContext<Native>, command: WebGLCommand) {
- match command {
- WebGLCommand::GetContextAttributes(sender) =>
- sender.send(*ctx.borrow_attributes()).unwrap(),
- WebGLCommand::ActiveTexture(target) =>
- ctx.gl().active_texture(target),
- WebGLCommand::AttachShader(program_id, shader_id) =>
- ctx.gl().attach_shader(program_id.get(), shader_id.get()),
- WebGLCommand::DetachShader(program_id, shader_id) =>
- ctx.gl().detach_shader(program_id.get(), shader_id.get()),
- WebGLCommand::BindAttribLocation(program_id, index, name) =>
- ctx.gl().bind_attrib_location(program_id.get(), index, &name),
- WebGLCommand::BlendColor(r, g, b, a) =>
- ctx.gl().blend_color(r, g, b, a),
- WebGLCommand::BlendEquation(mode) =>
- ctx.gl().blend_equation(mode),
- WebGLCommand::BlendEquationSeparate(mode_rgb, mode_alpha) =>
- ctx.gl().blend_equation_separate(mode_rgb, mode_alpha),
- WebGLCommand::BlendFunc(src, dest) =>
- ctx.gl().blend_func(src, dest),
- WebGLCommand::BlendFuncSeparate(src_rgb, dest_rgb, src_alpha, dest_alpha) =>
- ctx.gl().blend_func_separate(src_rgb, dest_rgb, src_alpha, dest_alpha),
- WebGLCommand::BufferData(buffer_type, data, usage) =>
- gl::buffer_data(ctx.gl(), buffer_type, &data, usage),
- WebGLCommand::BufferSubData(buffer_type, offset, data) =>
- gl::buffer_sub_data(ctx.gl(), buffer_type, offset, &data),
- WebGLCommand::Clear(mask) =>
- ctx.gl().clear(mask),
- WebGLCommand::ClearColor(r, g, b, a) =>
- ctx.gl().clear_color(r, g, b, a),
- WebGLCommand::ClearDepth(depth) =>
- ctx.gl().clear_depth(depth),
- WebGLCommand::ClearStencil(stencil) =>
- ctx.gl().clear_stencil(stencil),
- WebGLCommand::ColorMask(r, g, b, a) =>
- ctx.gl().color_mask(r, g, b, a),
- WebGLCommand::CopyTexImage2D(target, level, internal_format, x, y, width, height, border) =>
- ctx.gl().copy_tex_image_2d(target, level, internal_format, x, y, width, height, border),
- WebGLCommand::CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height) =>
- ctx.gl().copy_tex_sub_image_2d(target, level, xoffset, yoffset, x, y, width, height),
- WebGLCommand::CullFace(mode) =>
- ctx.gl().cull_face(mode),
- WebGLCommand::DepthFunc(func) =>
- ctx.gl().depth_func(func),
- WebGLCommand::DepthMask(flag) =>
- ctx.gl().depth_mask(flag),
- WebGLCommand::DepthRange(near, far) =>
- ctx.gl().depth_range(near, far),
- WebGLCommand::Disable(cap) =>
- ctx.gl().disable(cap),
- WebGLCommand::Enable(cap) =>
- ctx.gl().enable(cap),
- WebGLCommand::FramebufferRenderbuffer(target, attachment, renderbuffertarget, rb) =>
- ctx.gl().framebuffer_renderbuffer(target, attachment, renderbuffertarget,
- rb.map_or(0, WebGLRenderbufferId::get)),
- WebGLCommand::FramebufferTexture2D(target, attachment, textarget, texture, level) =>
- ctx.gl().framebuffer_texture_2d(target, attachment, textarget,
- texture.map_or(0, WebGLTextureId::get), level),
- WebGLCommand::FrontFace(mode) =>
- ctx.gl().front_face(mode),
- WebGLCommand::DisableVertexAttribArray(attrib_id) =>
- ctx.gl().disable_vertex_attrib_array(attrib_id),
- WebGLCommand::DrawArrays(mode, first, count) =>
- ctx.gl().draw_arrays(mode, first, count),
- WebGLCommand::DrawElements(mode, count, type_, offset) =>
- ctx.gl().draw_elements(mode, count, type_, offset as u32),
- WebGLCommand::EnableVertexAttribArray(attrib_id) =>
- ctx.gl().enable_vertex_attrib_array(attrib_id),
- WebGLCommand::Hint(name, val) =>
- ctx.gl().hint(name, val),
- WebGLCommand::IsEnabled(cap, chan) =>
- chan.send(ctx.gl().is_enabled(cap) != 0).unwrap(),
- WebGLCommand::LineWidth(width) =>
- ctx.gl().line_width(width),
- WebGLCommand::PixelStorei(name, val) =>
- ctx.gl().pixel_store_i(name, val),
- WebGLCommand::PolygonOffset(factor, units) =>
- ctx.gl().polygon_offset(factor, units),
- WebGLCommand::ReadPixels(x, y, width, height, format, pixel_type, chan) =>
- Self::read_pixels(ctx.gl(), x, y, width, height, format, pixel_type, chan),
- WebGLCommand::RenderbufferStorage(target, format, width, height) =>
- ctx.gl().renderbuffer_storage(target, format, width, height),
- WebGLCommand::SampleCoverage(value, invert) =>
- ctx.gl().sample_coverage(value, invert),
- WebGLCommand::Scissor(x, y, width, height) =>
- ctx.gl().scissor(x, y, width, height),
- WebGLCommand::StencilFunc(func, ref_, mask) =>
- ctx.gl().stencil_func(func, ref_, mask),
- WebGLCommand::StencilFuncSeparate(face, func, ref_, mask) =>
- ctx.gl().stencil_func_separate(face, func, ref_, mask),
- WebGLCommand::StencilMask(mask) =>
- ctx.gl().stencil_mask(mask),
- WebGLCommand::StencilMaskSeparate(face, mask) =>
- ctx.gl().stencil_mask_separate(face, mask),
- WebGLCommand::StencilOp(fail, zfail, zpass) =>
- ctx.gl().stencil_op(fail, zfail, zpass),
- WebGLCommand::StencilOpSeparate(face, fail, zfail, zpass) =>
- ctx.gl().stencil_op_separate(face, fail, zfail, zpass),
- WebGLCommand::GetActiveAttrib(program_id, index, chan) =>
- Self::active_attrib(ctx.gl(), program_id, index, chan),
- WebGLCommand::GetActiveUniform(program_id, index, chan) =>
- Self::active_uniform(ctx.gl(), program_id, index, chan),
- WebGLCommand::GetAttribLocation(program_id, name, chan) =>
- Self::attrib_location(ctx.gl(), program_id, name, chan),
- WebGLCommand::GetVertexAttrib(index, pname, chan) =>
- Self::vertex_attrib(ctx.gl(), index, pname, chan),
- WebGLCommand::GetVertexAttribOffset(index, pname, chan) =>
- Self::vertex_attrib_offset(ctx.gl(), index, pname, chan),
- WebGLCommand::GetBufferParameter(target, param_id, chan) =>
- Self::buffer_parameter(ctx.gl(), target, param_id, chan),
- WebGLCommand::GetParameter(param_id, chan) =>
- Self::parameter(ctx.gl(), param_id, chan),
- WebGLCommand::GetProgramParameter(program_id, param_id, chan) =>
- Self::program_parameter(ctx.gl(), program_id, param_id, chan),
- WebGLCommand::GetShaderParameter(shader_id, param_id, chan) =>
- Self::shader_parameter(ctx.gl(), shader_id, param_id, chan),
- WebGLCommand::GetShaderPrecisionFormat(shader_type, precision_type, chan) =>
- Self::shader_precision_format(ctx.gl(), shader_type, precision_type, chan),
- WebGLCommand::GetExtensions(chan) =>
- Self::get_extensions(ctx.gl(), chan),
- WebGLCommand::GetUniformLocation(program_id, name, chan) =>
- Self::uniform_location(ctx.gl(), program_id, name, chan),
- WebGLCommand::GetShaderInfoLog(shader_id, chan) =>
- Self::shader_info_log(ctx.gl(), shader_id, chan),
- WebGLCommand::GetProgramInfoLog(program_id, chan) =>
- Self::program_info_log(ctx.gl(), program_id, chan),
- WebGLCommand::CompileShader(shader_id, source) =>
- Self::compile_shader(ctx.gl(), shader_id, source),
- WebGLCommand::CreateBuffer(chan) =>
- Self::create_buffer(ctx.gl(), chan),
- WebGLCommand::CreateFramebuffer(chan) =>
- Self::create_framebuffer(ctx.gl(), chan),
- WebGLCommand::CreateRenderbuffer(chan) =>
- Self::create_renderbuffer(ctx.gl(), chan),
- WebGLCommand::CreateTexture(chan) =>
- Self::create_texture(ctx.gl(), chan),
- WebGLCommand::CreateProgram(chan) =>
- Self::create_program(ctx.gl(), chan),
- WebGLCommand::CreateShader(shader_type, chan) =>
- Self::create_shader(ctx.gl(), shader_type, chan),
- WebGLCommand::DeleteBuffer(id) =>
- ctx.gl().delete_buffers(&[id.get()]),
- WebGLCommand::DeleteFramebuffer(id) =>
- ctx.gl().delete_framebuffers(&[id.get()]),
- WebGLCommand::DeleteRenderbuffer(id) =>
- ctx.gl().delete_renderbuffers(&[id.get()]),
- WebGLCommand::DeleteTexture(id) =>
- ctx.gl().delete_textures(&[id.get()]),
- WebGLCommand::DeleteProgram(id) =>
- ctx.gl().delete_program(id.get()),
- WebGLCommand::DeleteShader(id) =>
- ctx.gl().delete_shader(id.get()),
- WebGLCommand::BindBuffer(target, id) =>
- ctx.gl().bind_buffer(target, id.map_or(0, WebGLBufferId::get)),
- WebGLCommand::BindFramebuffer(target, request) =>
- Self::bind_framebuffer(ctx.gl(), target, request, ctx),
- WebGLCommand::BindRenderbuffer(target, id) =>
- ctx.gl().bind_renderbuffer(target, id.map_or(0, WebGLRenderbufferId::get)),
- WebGLCommand::BindTexture(target, id) =>
- ctx.gl().bind_texture(target, id.map_or(0, WebGLTextureId::get)),
- WebGLCommand::LinkProgram(program_id) =>
- ctx.gl().link_program(program_id.get()),
- WebGLCommand::Uniform1f(uniform_id, v) =>
- ctx.gl().uniform_1f(uniform_id, v),
- WebGLCommand::Uniform1fv(uniform_id, v) =>
- ctx.gl().uniform_1fv(uniform_id, &v),
- WebGLCommand::Uniform1i(uniform_id, v) =>
- ctx.gl().uniform_1i(uniform_id, v),
- WebGLCommand::Uniform1iv(uniform_id, v) =>
- ctx.gl().uniform_1iv(uniform_id, &v),
- WebGLCommand::Uniform2f(uniform_id, x, y) =>
- ctx.gl().uniform_2f(uniform_id, x, y),
- WebGLCommand::Uniform2fv(uniform_id, v) =>
- ctx.gl().uniform_2fv(uniform_id, &v),
- WebGLCommand::Uniform2i(uniform_id, x, y) =>
- ctx.gl().uniform_2i(uniform_id, x, y),
- WebGLCommand::Uniform2iv(uniform_id, v) =>
- ctx.gl().uniform_2iv(uniform_id, &v),
- WebGLCommand::Uniform3f(uniform_id, x, y, z) =>
- ctx.gl().uniform_3f(uniform_id, x, y, z),
- WebGLCommand::Uniform3fv(uniform_id, v) =>
- ctx.gl().uniform_3fv(uniform_id, &v),
- WebGLCommand::Uniform3i(uniform_id, x, y, z) =>
- ctx.gl().uniform_3i(uniform_id, x, y, z),
- WebGLCommand::Uniform3iv(uniform_id, v) =>
- ctx.gl().uniform_3iv(uniform_id, &v),
- WebGLCommand::Uniform4f(uniform_id, x, y, z, w) =>
- ctx.gl().uniform_4f(uniform_id, x, y, z, w),
- WebGLCommand::Uniform4fv(uniform_id, v) =>
- ctx.gl().uniform_4fv(uniform_id, &v),
- WebGLCommand::Uniform4i(uniform_id, x, y, z, w) =>
- ctx.gl().uniform_4i(uniform_id, x, y, z, w),
- WebGLCommand::Uniform4iv(uniform_id, v) =>
- ctx.gl().uniform_4iv(uniform_id, &v),
- WebGLCommand::UniformMatrix2fv(uniform_id, transpose, v) =>
- ctx.gl().uniform_matrix_2fv(uniform_id, transpose, &v),
- WebGLCommand::UniformMatrix3fv(uniform_id, transpose, v) =>
- ctx.gl().uniform_matrix_3fv(uniform_id, transpose, &v),
- WebGLCommand::UniformMatrix4fv(uniform_id, transpose, v) =>
- ctx.gl().uniform_matrix_4fv(uniform_id, transpose, &v),
- WebGLCommand::UseProgram(program_id) =>
- ctx.gl().use_program(program_id.get()),
- WebGLCommand::ValidateProgram(program_id) =>
- ctx.gl().validate_program(program_id.get()),
- WebGLCommand::VertexAttrib(attrib_id, x, y, z, w) =>
- ctx.gl().vertex_attrib_4f(attrib_id, x, y, z, w),
- WebGLCommand::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset) =>
- ctx.gl().vertex_attrib_pointer_f32(attrib_id, size, normalized, stride, offset),
- WebGLCommand::VertexAttribPointer(attrib_id, size, data_type, normalized, stride, offset) =>
- ctx.gl().vertex_attrib_pointer(attrib_id, size, data_type, normalized, stride, offset),
- WebGLCommand::Viewport(x, y, width, height) =>
- ctx.gl().viewport(x, y, width, height),
- WebGLCommand::TexImage2D(target, level, internal, width, height, format, data_type, data) =>
- ctx.gl().tex_image_2d(target, level, internal, width, height,
- /*border*/0, format, data_type, Some(&data)),
- WebGLCommand::TexParameteri(target, name, value) =>
- ctx.gl().tex_parameter_i(target, name, value),
- WebGLCommand::TexParameterf(target, name, value) =>
- ctx.gl().tex_parameter_f(target, name, value),
- WebGLCommand::TexSubImage2D(target, level, xoffset, yoffset, x, y, width, height, data) =>
- ctx.gl().tex_sub_image_2d(target, level, xoffset, yoffset, x, y, width, height, &data),
- WebGLCommand::DrawingBufferWidth(sender) =>
- sender.send(ctx.borrow_draw_buffer().unwrap().size().width).unwrap(),
- WebGLCommand::DrawingBufferHeight(sender) =>
- sender.send(ctx.borrow_draw_buffer().unwrap().size().height).unwrap(),
- WebGLCommand::Finish(sender) =>
- Self::finish(ctx.gl(), sender),
- WebGLCommand::Flush =>
- ctx.gl().flush(),
- WebGLCommand::GenerateMipmap(target) =>
- ctx.gl().generate_mipmap(target),
- WebGLCommand::CreateVertexArray(chan) =>
- Self::create_vertex_array(ctx.gl(), chan),
- WebGLCommand::DeleteVertexArray(id) =>
- ctx.gl().delete_vertex_arrays(&[id.get()]),
- WebGLCommand::BindVertexArray(id) =>
- ctx.gl().bind_vertex_array(id.map_or(0, WebGLVertexArrayId::get)),
- }
-
- // TODO: update test expectations in order to enable debug assertions
- //if cfg!(debug_assertions) {
- let error = ctx.gl().get_error();
- assert!(error == gl::NO_ERROR, "Unexpected WebGL error: 0x{:x} ({})", error, error);
- //}
- }
-
- fn read_pixels(gl: &gl::Gl, x: i32, y: i32, width: i32, height: i32, format: u32, pixel_type: u32,
- chan: WebGLSender<Vec<u8>>) {
- let result = gl.read_pixels(x, y, width, height, format, pixel_type);
- chan.send(result).unwrap()
- }
-
- fn active_attrib(gl: &gl::Gl,
- program_id: WebGLProgramId,
- index: u32,
- chan: WebGLSender<WebGLResult<(i32, u32, String)>>) {
- let result = if index >= gl.get_program_iv(program_id.get(), gl::ACTIVE_ATTRIBUTES) as u32 {
- Err(WebGLError::InvalidValue)
- } else {
- Ok(gl.get_active_attrib(program_id.get(), index))
- };
- chan.send(result).unwrap();
- }
-
- fn active_uniform(gl: &gl::Gl,
- program_id: WebGLProgramId,
- index: u32,
- chan: WebGLSender<WebGLResult<(i32, u32, String)>>) {
- let result = if index >= gl.get_program_iv(program_id.get(), gl::ACTIVE_UNIFORMS) as u32 {
- Err(WebGLError::InvalidValue)
- } else {
- Ok(gl.get_active_uniform(program_id.get(), index))
- };
- chan.send(result).unwrap();
- }
-
- fn attrib_location(gl: &gl::Gl,
- program_id: WebGLProgramId,
- name: String,
- chan: WebGLSender<Option<i32>> ) {
- let attrib_location = gl.get_attrib_location(program_id.get(), &name);
-
- let attrib_location = if attrib_location == -1 {
- None
- } else {
- Some(attrib_location)
- };
-
- chan.send(attrib_location).unwrap();
- }
-
- fn parameter(gl: &gl::Gl,
- param_id: u32,
- chan: WebGLSender<WebGLResult<WebGLParameter>>) {
- let result = match param_id {
- gl::ACTIVE_TEXTURE |
- gl::ALPHA_BITS |
- gl::BLEND_DST_ALPHA |
- gl::BLEND_DST_RGB |
- gl::BLEND_EQUATION_ALPHA |
- gl::BLEND_EQUATION_RGB |
- gl::BLEND_SRC_ALPHA |
- gl::BLEND_SRC_RGB |
- gl::BLUE_BITS |
- gl::CULL_FACE_MODE |
- gl::DEPTH_BITS |
- gl::DEPTH_FUNC |
- gl::FRONT_FACE |
- //gl::GENERATE_MIPMAP_HINT |
- gl::GREEN_BITS |
- //gl::IMPLEMENTATION_COLOR_READ_FORMAT |
- //gl::IMPLEMENTATION_COLOR_READ_TYPE |
- gl::MAX_COMBINED_TEXTURE_IMAGE_UNITS |
- gl::MAX_CUBE_MAP_TEXTURE_SIZE |
- //gl::MAX_FRAGMENT_UNIFORM_VECTORS |
- gl::MAX_RENDERBUFFER_SIZE |
- gl::MAX_TEXTURE_IMAGE_UNITS |
- gl::MAX_TEXTURE_SIZE |
- //gl::MAX_VARYING_VECTORS |
- gl::MAX_VERTEX_ATTRIBS |
- gl::MAX_VERTEX_TEXTURE_IMAGE_UNITS |
- //gl::MAX_VERTEX_UNIFORM_VECTORS |
- gl::PACK_ALIGNMENT |
- gl::RED_BITS |
- gl::SAMPLE_BUFFERS |
- gl::SAMPLES |
- gl::STENCIL_BACK_FAIL |
- gl::STENCIL_BACK_FUNC |
- gl::STENCIL_BACK_PASS_DEPTH_FAIL |
- gl::STENCIL_BACK_PASS_DEPTH_PASS |
- gl::STENCIL_BACK_REF |
- gl::STENCIL_BACK_VALUE_MASK |
- gl::STENCIL_BACK_WRITEMASK |
- gl::STENCIL_BITS |
- gl::STENCIL_CLEAR_VALUE |
- gl::STENCIL_FAIL |
- gl::STENCIL_FUNC |
- gl::STENCIL_PASS_DEPTH_FAIL |
- gl::STENCIL_PASS_DEPTH_PASS |
- gl::STENCIL_REF |
- gl::STENCIL_VALUE_MASK |
- gl::STENCIL_WRITEMASK |
- gl::SUBPIXEL_BITS |
- gl::UNPACK_ALIGNMENT =>
- //gl::UNPACK_COLORSPACE_CONVERSION_WEBGL =>
- Ok(WebGLParameter::Int(gl.get_integer_v(param_id))),
-
- gl::BLEND |
- gl::CULL_FACE |
- gl::DEPTH_TEST |
- gl::DEPTH_WRITEMASK |
- gl::DITHER |
- gl::POLYGON_OFFSET_FILL |
- gl::SAMPLE_COVERAGE_INVERT |
- gl::STENCIL_TEST =>
- //gl::UNPACK_FLIP_Y_WEBGL |
- //gl::UNPACK_PREMULTIPLY_ALPHA_WEBGL =>
- Ok(WebGLParameter::Bool(gl.get_boolean_v(param_id) != 0)),
-
- gl::DEPTH_CLEAR_VALUE |
- gl::LINE_WIDTH |
- gl::POLYGON_OFFSET_FACTOR |
- gl::POLYGON_OFFSET_UNITS |
- gl::SAMPLE_COVERAGE_VALUE =>
- Ok(WebGLParameter::Float(gl.get_float_v(param_id))),
-
- gl::VERSION => Ok(WebGLParameter::String("WebGL 1.0".to_owned())),
- gl::RENDERER |
- gl::VENDOR => Ok(WebGLParameter::String("Mozilla/Servo".to_owned())),
- gl::SHADING_LANGUAGE_VERSION => Ok(WebGLParameter::String("WebGL GLSL ES 1.0".to_owned())),
-
- // TODO(zbarsky, emilio): Implement support for the following valid parameters
- // Float32Array
- gl::ALIASED_LINE_WIDTH_RANGE |
- //gl::ALIASED_POINT_SIZE_RANGE |
- //gl::BLEND_COLOR |
- gl::COLOR_CLEAR_VALUE |
- gl::DEPTH_RANGE |
-
- // WebGLBuffer
- gl::ARRAY_BUFFER_BINDING |
- gl::ELEMENT_ARRAY_BUFFER_BINDING |
-
- // WebGLFrameBuffer
- gl::FRAMEBUFFER_BINDING |
-
- // WebGLRenderBuffer
- gl::RENDERBUFFER_BINDING |
-
- // WebGLProgram
- gl::CURRENT_PROGRAM |
-
- // WebGLTexture
- gl::TEXTURE_BINDING_2D |
- gl::TEXTURE_BINDING_CUBE_MAP |
-
- // sequence<GlBoolean>
- gl::COLOR_WRITEMASK |
-
- // Uint32Array
- gl::COMPRESSED_TEXTURE_FORMATS |
-
- // Int32Array
- gl::MAX_VIEWPORT_DIMS |
- gl::SCISSOR_BOX |
- gl::VIEWPORT => Err(WebGLError::InvalidEnum),
-
- // Invalid parameters
- _ => Err(WebGLError::InvalidEnum)
- };
-
- chan.send(result).unwrap();
- }
-
- fn finish(gl: &gl::Gl, chan: WebGLSender<()>) {
- gl.finish();
- chan.send(()).unwrap();
- }
-
- fn vertex_attrib(gl: &gl::Gl,
- index: u32,
- pname: u32,
- chan: WebGLSender<WebGLResult<WebGLParameter>>) {
- let result = if index >= gl.get_integer_v(gl::MAX_VERTEX_ATTRIBS) as u32 {
- Err(WebGLError::InvalidValue)
- } else {
- match pname {
- gl::VERTEX_ATTRIB_ARRAY_ENABLED |
- gl::VERTEX_ATTRIB_ARRAY_NORMALIZED =>
- Ok(WebGLParameter::Bool(gl.get_vertex_attrib_iv(index, pname) != 0)),
- gl::VERTEX_ATTRIB_ARRAY_SIZE |
- gl::VERTEX_ATTRIB_ARRAY_STRIDE |
- gl::VERTEX_ATTRIB_ARRAY_TYPE =>
- Ok(WebGLParameter::Int(gl.get_vertex_attrib_iv(index, pname))),
- gl::CURRENT_VERTEX_ATTRIB =>
- Ok(WebGLParameter::FloatArray(gl.get_vertex_attrib_fv(index, pname))),
- // gl::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING should return WebGLBuffer
- _ => Err(WebGLError::InvalidEnum),
- }
- };
-
- chan.send(result).unwrap();
- }
-
- fn vertex_attrib_offset(gl: &gl::Gl,
- index: u32,
- pname: u32,
- chan: WebGLSender<WebGLResult<isize>>) {
- let result = match pname {
- gl::VERTEX_ATTRIB_ARRAY_POINTER => Ok(gl.get_vertex_attrib_pointer_v(index, pname)),
- _ => Err(WebGLError::InvalidEnum),
- };
-
- chan.send(result).unwrap();
- }
-
- fn buffer_parameter(gl: &gl::Gl,
- target: u32,
- param_id: u32,
- chan: WebGLSender<WebGLResult<WebGLParameter>>) {
- let result = match param_id {
- gl::BUFFER_SIZE |
- gl::BUFFER_USAGE =>
- Ok(WebGLParameter::Int(gl.get_buffer_parameter_iv(target, param_id))),
- _ => Err(WebGLError::InvalidEnum),
- };
-
- chan.send(result).unwrap();
- }
-
- fn program_parameter(gl: &gl::Gl,
- program_id: WebGLProgramId,
- param_id: u32,
- chan: WebGLSender<WebGLResult<WebGLParameter>>) {
- let result = match param_id {
- gl::DELETE_STATUS |
- gl::LINK_STATUS |
- gl::VALIDATE_STATUS =>
- Ok(WebGLParameter::Bool(gl.get_program_iv(program_id.get(), param_id) != 0)),
- gl::ATTACHED_SHADERS |
- gl::ACTIVE_ATTRIBUTES |
- gl::ACTIVE_UNIFORMS =>
- Ok(WebGLParameter::Int(gl.get_program_iv(program_id.get(), param_id))),
- _ => Err(WebGLError::InvalidEnum),
- };
-
- chan.send(result).unwrap();
- }
-
- fn shader_parameter(gl: &gl::Gl,
- shader_id: WebGLShaderId,
- param_id: u32,
- chan: WebGLSender<WebGLResult<WebGLParameter>>) {
- let result = match param_id {
- gl::SHADER_TYPE =>
- Ok(WebGLParameter::Int(gl.get_shader_iv(shader_id.get(), param_id))),
- gl::DELETE_STATUS |
- gl::COMPILE_STATUS =>
- Ok(WebGLParameter::Bool(gl.get_shader_iv(shader_id.get(), param_id) != 0)),
- _ => Err(WebGLError::InvalidEnum),
- };
-
- chan.send(result).unwrap();
- }
-
- fn shader_precision_format(gl: &gl::Gl,
- shader_type: u32,
- precision_type: u32,
- chan: WebGLSender<WebGLResult<(i32, i32, i32)>>) {
- let result = match precision_type {
- gl::LOW_FLOAT |
- gl::MEDIUM_FLOAT |
- gl::HIGH_FLOAT |
- gl::LOW_INT |
- gl::MEDIUM_INT |
- gl::HIGH_INT => {
- Ok(gl.get_shader_precision_format(shader_type, precision_type))
- },
- _=> {
- Err(WebGLError::InvalidEnum)
- }
- };
-
- chan.send(result).unwrap();
- }
-
- fn get_extensions(gl: &gl::Gl, chan: WebGLSender<String>) {
- chan.send(gl.get_string(gl::EXTENSIONS)).unwrap();
- }
-
- fn uniform_location(gl: &gl::Gl,
- program_id: WebGLProgramId,
- name: String,
- chan: WebGLSender<Option<i32>>) {
- let location = gl.get_uniform_location(program_id.get(), &name);
- let location = if location == -1 {
- None
- } else {
- Some(location)
- };
-
- chan.send(location).unwrap();
- }
-
-
- fn shader_info_log(gl: &gl::Gl, shader_id: WebGLShaderId, chan: WebGLSender<String>) {
- let log = gl.get_shader_info_log(shader_id.get());
- chan.send(log).unwrap();
- }
-
- fn program_info_log(gl: &gl::Gl, program_id: WebGLProgramId, chan: WebGLSender<String>) {
- let log = gl.get_program_info_log(program_id.get());
- chan.send(log).unwrap();
- }
-
- #[allow(unsafe_code)]
- fn create_buffer(gl: &gl::Gl, chan: WebGLSender<Option<WebGLBufferId>>) {
- let buffer = gl.gen_buffers(1)[0];
- let buffer = if buffer == 0 {
- None
- } else {
- Some(unsafe { WebGLBufferId::new(buffer) })
- };
- chan.send(buffer).unwrap();
- }
-
- #[allow(unsafe_code)]
- fn create_framebuffer(gl: &gl::Gl, chan: WebGLSender<Option<WebGLFramebufferId>>) {
- let framebuffer = gl.gen_framebuffers(1)[0];
- let framebuffer = if framebuffer == 0 {
- None
- } else {
- Some(unsafe { WebGLFramebufferId::new(framebuffer) })
- };
- chan.send(framebuffer).unwrap();
- }
-
- #[allow(unsafe_code)]
- fn create_renderbuffer(gl: &gl::Gl, chan: WebGLSender<Option<WebGLRenderbufferId>>) {
- let renderbuffer = gl.gen_renderbuffers(1)[0];
- let renderbuffer = if renderbuffer == 0 {
- None
- } else {
- Some(unsafe { WebGLRenderbufferId::new(renderbuffer) })
- };
- chan.send(renderbuffer).unwrap();
- }
-
- #[allow(unsafe_code)]
- fn create_texture(gl: &gl::Gl, chan: WebGLSender<Option<WebGLTextureId>>) {
- let texture = gl.gen_textures(1)[0];
- let texture = if texture == 0 {
- None
- } else {
- Some(unsafe { WebGLTextureId::new(texture) })
- };
- chan.send(texture).unwrap();
- }
-
- #[allow(unsafe_code)]
- fn create_program(gl: &gl::Gl, chan: WebGLSender<Option<WebGLProgramId>>) {
- let program = gl.create_program();
- let program = if program == 0 {
- None
- } else {
- Some(unsafe { WebGLProgramId::new(program) })
- };
- chan.send(program).unwrap();
- }
-
- #[allow(unsafe_code)]
- fn create_shader(gl: &gl::Gl, shader_type: u32, chan: WebGLSender<Option<WebGLShaderId>>) {
- let shader = gl.create_shader(shader_type);
- let shader = if shader == 0 {
- None
- } else {
- Some(unsafe { WebGLShaderId::new(shader) })
- };
- chan.send(shader).unwrap();
- }
-
- #[allow(unsafe_code)]
- fn create_vertex_array(gl: &gl::Gl, chan: WebGLSender<Option<WebGLVertexArrayId>>) {
- let vao = gl.gen_vertex_arrays(1)[0];
- let vao = if vao == 0 {
- None
- } else {
- Some(unsafe { WebGLVertexArrayId::new(vao) })
- };
- chan.send(vao).unwrap();
- }
-
- #[inline]
- fn bind_framebuffer<Native: NativeGLContextMethods>(gl: &gl::Gl,
- target: u32,
- request: WebGLFramebufferBindingRequest,
- ctx: &GLContext<Native>) {
- let id = match request {
- WebGLFramebufferBindingRequest::Explicit(id) => id.get(),
- WebGLFramebufferBindingRequest::Default =>
- ctx.borrow_draw_buffer().unwrap().get_framebuffer(),
- };
-
- gl.bind_framebuffer(target, id);
- }
-
-
- #[inline]
- fn compile_shader(gl: &gl::Gl, shader_id: WebGLShaderId, source: String) {
- gl.shader_source(shader_id.get(), &[source.as_bytes()]);
- gl.compile_shader(shader_id.get());
- }
-}
diff --git a/components/canvas_traits/Cargo.toml b/components/canvas_traits/Cargo.toml
index 43cc74e60b1..afc23f4a2e0 100644
--- a/components/canvas_traits/Cargo.toml
+++ b/components/canvas_traits/Cargo.toml
@@ -15,8 +15,5 @@ euclid = "0.15"
heapsize = "0.4"
heapsize_derive = "0.1"
ipc-channel = "0.8"
-lazy_static = "0.2"
-offscreen_gl_context = { version = "0.11", features = ["serde"] }
serde = "1.0"
-servo_config = {path = "../config"}
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
diff --git a/components/canvas_traits/canvas.rs b/components/canvas_traits/canvas.rs
deleted file mode 100644
index 92444d03799..00000000000
--- a/components/canvas_traits/canvas.rs
+++ /dev/null
@@ -1,409 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-use cssparser::RGBA;
-use euclid::{Transform2D, Point2D, Vector2D, Rect, Size2D};
-use ipc_channel::ipc::IpcSender;
-use std::default::Default;
-use std::str::FromStr;
-use webrender_api;
-
-#[derive(Clone, Deserialize, Serialize)]
-pub enum FillRule {
- Nonzero,
- Evenodd,
-}
-
-#[derive(Clone, Deserialize, Serialize)]
-pub enum CanvasMsg {
- Canvas2d(Canvas2dMsg),
- FromLayout(FromLayoutMsg),
- FromScript(FromScriptMsg),
- Recreate(Size2D<i32>),
- Close,
-}
-
-#[derive(Clone, Deserialize, Serialize)]
-pub struct CanvasImageData {
- pub image_key: webrender_api::ImageKey,
-}
-
-#[derive(Clone, Deserialize, Serialize)]
-pub enum Canvas2dMsg {
- Arc(Point2D<f32>, f32, f32, f32, bool),
- ArcTo(Point2D<f32>, Point2D<f32>, f32),
- DrawImage(Vec<u8>, Size2D<f64>, Rect<f64>, Rect<f64>, bool),
- DrawImageSelf(Size2D<f64>, Rect<f64>, Rect<f64>, bool),
- DrawImageInOther(
- IpcSender<CanvasMsg>, Size2D<f64>, Rect<f64>, Rect<f64>, bool, IpcSender<()>),
- BeginPath,
- BezierCurveTo(Point2D<f32>, Point2D<f32>, Point2D<f32>),
- ClearRect(Rect<f32>),
- Clip,
- ClosePath,
- Fill,
- FillRect(Rect<f32>),
- GetImageData(Rect<i32>, Size2D<f64>, IpcSender<Vec<u8>>),
- IsPointInPath(f64, f64, FillRule, IpcSender<bool>),
- LineTo(Point2D<f32>),
- MoveTo(Point2D<f32>),
- PutImageData(Vec<u8>, Vector2D<f64>, Size2D<f64>, Rect<f64>),
- QuadraticCurveTo(Point2D<f32>, Point2D<f32>),
- Rect(Rect<f32>),
- RestoreContext,
- SaveContext,
- StrokeRect(Rect<f32>),
- Stroke,
- SetFillStyle(FillOrStrokeStyle),
- SetStrokeStyle(FillOrStrokeStyle),
- SetLineWidth(f32),
- SetLineCap(LineCapStyle),
- SetLineJoin(LineJoinStyle),
- SetMiterLimit(f32),
- SetGlobalAlpha(f32),
- SetGlobalComposition(CompositionOrBlending),
- SetTransform(Transform2D<f32>),
- SetShadowOffsetX(f64),
- SetShadowOffsetY(f64),
- SetShadowBlur(f64),
- SetShadowColor(RGBA),
-}
-
-#[derive(Clone, Deserialize, Serialize)]
-pub enum FromLayoutMsg {
- SendData(IpcSender<CanvasImageData>),
-}
-
-#[derive(Clone, Deserialize, Serialize)]
-pub enum FromScriptMsg {
- SendPixels(IpcSender<Option<Vec<u8>>>),
-}
-
-#[derive(Clone, Deserialize, Serialize, HeapSizeOf)]
-pub struct CanvasGradientStop {
- pub offset: f64,
- pub color: RGBA,
-}
-
-#[derive(Clone, Deserialize, Serialize, HeapSizeOf)]
-pub struct LinearGradientStyle {
- pub x0: f64,
- pub y0: f64,
- pub x1: f64,
- pub y1: f64,
- pub stops: Vec<CanvasGradientStop>
-}
-
-impl LinearGradientStyle {
- pub fn new(x0: f64, y0: f64, x1: f64, y1: f64, stops: Vec<CanvasGradientStop>)
- -> LinearGradientStyle {
- LinearGradientStyle {
- x0: x0,
- y0: y0,
- x1: x1,
- y1: y1,
- stops: stops,
- }
- }
-}
-
-#[derive(Clone, Deserialize, Serialize, HeapSizeOf)]
-pub struct RadialGradientStyle {
- pub x0: f64,
- pub y0: f64,
- pub r0: f64,
- pub x1: f64,
- pub y1: f64,
- pub r1: f64,
- pub stops: Vec<CanvasGradientStop>
-}
-
-impl RadialGradientStyle {
- pub fn new(x0: f64, y0: f64, r0: f64, x1: f64, y1: f64, r1: f64, stops: Vec<CanvasGradientStop>)
- -> RadialGradientStyle {
- RadialGradientStyle {
- x0: x0,
- y0: y0,
- r0: r0,
- x1: x1,
- y1: y1,
- r1: r1,
- stops: stops,
- }
- }
-}
-
-#[derive(Clone, Deserialize, Serialize)]
-pub struct SurfaceStyle {
- pub surface_data: Vec<u8>,
- pub surface_size: Size2D<i32>,
- pub repeat_x: bool,
- pub repeat_y: bool,
-}
-
-impl SurfaceStyle {
- pub fn new(surface_data: Vec<u8>, surface_size: Size2D<i32>, repeat_x: bool, repeat_y: bool)
- -> SurfaceStyle {
- SurfaceStyle {
- surface_data: surface_data,
- surface_size: surface_size,
- repeat_x: repeat_x,
- repeat_y: repeat_y,
- }
- }
-}
-
-
-#[derive(Clone, Deserialize, Serialize)]
-pub enum FillOrStrokeStyle {
- Color(RGBA),
- LinearGradient(LinearGradientStyle),
- RadialGradient(RadialGradientStyle),
- Surface(SurfaceStyle),
-}
-
-#[derive(Copy, Clone, PartialEq, Deserialize, Serialize, HeapSizeOf)]
-pub enum LineCapStyle {
- Butt = 0,
- Round = 1,
- Square = 2,
-}
-
-impl FromStr for LineCapStyle {
- type Err = ();
-
- fn from_str(string: &str) -> Result<LineCapStyle, ()> {
- match string {
- "butt" => Ok(LineCapStyle::Butt),
- "round" => Ok(LineCapStyle::Round),
- "square" => Ok(LineCapStyle::Square),
- _ => Err(()),
- }
- }
-}
-
-#[derive(Copy, Clone, PartialEq, Deserialize, Serialize, HeapSizeOf)]
-pub enum LineJoinStyle {
- Round = 0,
- Bevel = 1,
- Miter = 2,
-}
-
-impl FromStr for LineJoinStyle {
- type Err = ();
-
- fn from_str(string: &str) -> Result<LineJoinStyle, ()> {
- match string {
- "round" => Ok(LineJoinStyle::Round),
- "bevel" => Ok(LineJoinStyle::Bevel),
- "miter" => Ok(LineJoinStyle::Miter),
- _ => Err(()),
- }
- }
-}
-
-#[derive(Copy, Clone, PartialEq, Deserialize, Serialize)]
-pub enum RepetitionStyle {
- Repeat,
- RepeatX,
- RepeatY,
- NoRepeat,
-}
-
-impl FromStr for RepetitionStyle {
- type Err = ();
-
- fn from_str(string: &str) -> Result<RepetitionStyle, ()> {
- match string {
- "repeat" => Ok(RepetitionStyle::Repeat),
- "repeat-x" => Ok(RepetitionStyle::RepeatX),
- "repeat-y" => Ok(RepetitionStyle::RepeatY),
- "no-repeat" => Ok(RepetitionStyle::NoRepeat),
- _ => Err(()),
- }
- }
-}
-
-#[derive(Copy, Clone, PartialEq, Deserialize, Serialize, HeapSizeOf)]
-pub enum CompositionStyle {
- SrcIn,
- SrcOut,
- SrcOver,
- SrcAtop,
- DestIn,
- DestOut,
- DestOver,
- DestAtop,
- Copy,
- Lighter,
- Xor,
-}
-
-impl FromStr for CompositionStyle {
- type Err = ();
-
- fn from_str(string: &str) -> Result<CompositionStyle, ()> {
- match string {
- "source-in" => Ok(CompositionStyle::SrcIn),
- "source-out" => Ok(CompositionStyle::SrcOut),
- "source-over" => Ok(CompositionStyle::SrcOver),
- "source-atop" => Ok(CompositionStyle::SrcAtop),
- "destination-in" => Ok(CompositionStyle::DestIn),
- "destination-out" => Ok(CompositionStyle::DestOut),
- "destination-over" => Ok(CompositionStyle::DestOver),
- "destination-atop" => Ok(CompositionStyle::DestAtop),
- "copy" => Ok(CompositionStyle::Copy),
- "lighter" => Ok(CompositionStyle::Lighter),
- "xor" => Ok(CompositionStyle::Xor),
- _ => Err(())
- }
- }
-}
-
-impl CompositionStyle {
- pub fn to_str(&self) -> &str {
- match *self {
- CompositionStyle::SrcIn => "source-in",
- CompositionStyle::SrcOut => "source-out",
- CompositionStyle::SrcOver => "source-over",
- CompositionStyle::SrcAtop => "source-atop",
- CompositionStyle::DestIn => "destination-in",
- CompositionStyle::DestOut => "destination-out",
- CompositionStyle::DestOver => "destination-over",
- CompositionStyle::DestAtop => "destination-atop",
- CompositionStyle::Copy => "copy",
- CompositionStyle::Lighter => "lighter",
- CompositionStyle::Xor => "xor",
- }
- }
-}
-
-#[derive(Copy, Clone, PartialEq, Deserialize, Serialize, HeapSizeOf)]
-pub enum BlendingStyle {
- Multiply,
- Screen,
- Overlay,
- Darken,
- Lighten,
- ColorDodge,
- ColorBurn,
- HardLight,
- SoftLight,
- Difference,
- Exclusion,
- Hue,
- Saturation,
- Color,
- Luminosity,
-}
-
-impl FromStr for BlendingStyle {
- type Err = ();
-
- fn from_str(string: &str) -> Result<BlendingStyle, ()> {
- match string {
- "multiply" => Ok(BlendingStyle::Multiply),
- "screen" => Ok(BlendingStyle::Screen),
- "overlay" => Ok(BlendingStyle::Overlay),
- "darken" => Ok(BlendingStyle::Darken),
- "lighten" => Ok(BlendingStyle::Lighten),
- "color-dodge" => Ok(BlendingStyle::ColorDodge),
- "color-burn" => Ok(BlendingStyle::ColorBurn),
- "hard-light" => Ok(BlendingStyle::HardLight),
- "soft-light" => Ok(BlendingStyle::SoftLight),
- "difference" => Ok(BlendingStyle::Difference),
- "exclusion" => Ok(BlendingStyle::Exclusion),
- "hue" => Ok(BlendingStyle::Hue),
- "saturation" => Ok(BlendingStyle::Saturation),
- "color" => Ok(BlendingStyle::Color),
- "luminosity" => Ok(BlendingStyle::Luminosity),
- _ => Err(())
- }
- }
-}
-
-impl BlendingStyle {
- pub fn to_str(&self) -> &str {
- match *self {
- BlendingStyle::Multiply => "multiply",
- BlendingStyle::Screen => "screen",
- BlendingStyle::Overlay => "overlay",
- BlendingStyle::Darken => "darken",
- BlendingStyle::Lighten => "lighten",
- BlendingStyle::ColorDodge => "color-dodge",
- BlendingStyle::ColorBurn => "color-burn",
- BlendingStyle::HardLight => "hard-light",
- BlendingStyle::SoftLight => "soft-light",
- BlendingStyle::Difference => "difference",
- BlendingStyle::Exclusion => "exclusion",
- BlendingStyle::Hue => "hue",
- BlendingStyle::Saturation => "saturation",
- BlendingStyle::Color => "color",
- BlendingStyle::Luminosity => "luminosity",
- }
- }
-}
-
-#[derive(Copy, Clone, PartialEq, Deserialize, Serialize, HeapSizeOf)]
-pub enum CompositionOrBlending {
- Composition(CompositionStyle),
- Blending(BlendingStyle),
-}
-
-impl Default for CompositionOrBlending {
- fn default() -> CompositionOrBlending {
- CompositionOrBlending::Composition(CompositionStyle::SrcOver)
- }
-}
-
-impl FromStr for CompositionOrBlending {
- type Err = ();
-
- fn from_str(string: &str) -> Result<CompositionOrBlending, ()> {
- if let Ok(op) = CompositionStyle::from_str(string) {
- return Ok(CompositionOrBlending::Composition(op));
- }
-
- if let Ok(op) = BlendingStyle::from_str(string) {
- return Ok(CompositionOrBlending::Blending(op));
- }
-
- Err(())
- }
-}
-
-// TODO(pcwalton): Speed up with SIMD, or better yet, find some way to not do this.
-pub fn byte_swap(data: &mut [u8]) {
- let length = data.len();
- // FIXME(rust #27741): Range::step_by is not stable yet as of this writing.
- let mut i = 0;
- while i < length {
- let r = data[i + 2];
- data[i + 2] = data[i + 0];
- data[i + 0] = r;
- i += 4;
- }
-}
-
-pub fn multiply_u8_pixel(a: u8, b: u8) -> u8 {
- return (a as u32 * b as u32 / 255) as u8;
-}
-
-pub fn byte_swap_and_premultiply(data: &mut [u8]) {
- let length = data.len();
-
- let mut i = 0;
- while i < length {
- let r = data[i + 2];
- let g = data[i + 1];
- let b = data[i + 0];
- let a = data[i + 3];
-
- data[i + 0] = multiply_u8_pixel(r, a);
- data[i + 1] = multiply_u8_pixel(g, a);
- data[i + 2] = multiply_u8_pixel(b, a);
-
- i += 4;
- }
-}
diff --git a/components/canvas_traits/lib.rs b/components/canvas_traits/lib.rs
index 7830d669e3e..1f6d9eda087 100644
--- a/components/canvas_traits/lib.rs
+++ b/components/canvas_traits/lib.rs
@@ -4,22 +4,432 @@
#![crate_name = "canvas_traits"]
#![crate_type = "rlib"]
-#![feature(nonzero)]
#![deny(unsafe_code)]
-extern crate core;
extern crate cssparser;
extern crate euclid;
extern crate heapsize;
#[macro_use] extern crate heapsize_derive;
extern crate ipc_channel;
-#[macro_use] extern crate lazy_static;
-extern crate offscreen_gl_context;
#[macro_use] extern crate serde;
-extern crate servo_config;
extern crate webrender_api;
-pub mod canvas;
-pub mod webgl;
-mod webgl_channel;
+use cssparser::RGBA;
+use euclid::{Transform2D, Point2D, Vector2D, Rect, Size2D};
+use ipc_channel::ipc::IpcSender;
+use std::default::Default;
+use std::str::FromStr;
+use webrender_api::{WebGLCommand, WebGLContextId, VRCompositorCommand};
+
+#[derive(Clone, Deserialize, Serialize)]
+pub enum FillRule {
+ Nonzero,
+ Evenodd,
+}
+
+#[derive(Clone, Deserialize, Serialize)]
+pub enum CanvasMsg {
+ Canvas2d(Canvas2dMsg),
+ Common(CanvasCommonMsg),
+ FromLayout(FromLayoutMsg),
+ FromScript(FromScriptMsg),
+ WebGL(WebGLCommand),
+ WebVR(VRCompositorCommand)
+}
+
+#[derive(Clone, Deserialize, Serialize)]
+pub enum CanvasCommonMsg {
+ Close,
+ Recreate(Size2D<i32>),
+}
+
+#[derive(Clone, Deserialize, Serialize)]
+pub enum CanvasData {
+ Image(CanvasImageData),
+ WebGL(WebGLContextId),
+}
+
+#[derive(Clone, Deserialize, Serialize)]
+pub struct CanvasImageData {
+ pub image_key: webrender_api::ImageKey,
+}
+
+#[derive(Clone, Deserialize, Serialize)]
+pub enum FromLayoutMsg {
+ SendData(IpcSender<CanvasData>),
+}
+
+#[derive(Clone, Deserialize, Serialize)]
+pub enum FromScriptMsg {
+ SendPixels(IpcSender<Option<Vec<u8>>>),
+}
+
+#[derive(Clone, Deserialize, Serialize)]
+pub enum Canvas2dMsg {
+ Arc(Point2D<f32>, f32, f32, f32, bool),
+ ArcTo(Point2D<f32>, Point2D<f32>, f32),
+ DrawImage(Vec<u8>, Size2D<f64>, Rect<f64>, Rect<f64>, bool),
+ DrawImageSelf(Size2D<f64>, Rect<f64>, Rect<f64>, bool),
+ DrawImageInOther(
+ IpcSender<CanvasMsg>, Size2D<f64>, Rect<f64>, Rect<f64>, bool, IpcSender<()>),
+ BeginPath,
+ BezierCurveTo(Point2D<f32>, Point2D<f32>, Point2D<f32>),
+ ClearRect(Rect<f32>),
+ Clip,
+ ClosePath,
+ Fill,
+ FillRect(Rect<f32>),
+ GetImageData(Rect<i32>, Size2D<f64>, IpcSender<Vec<u8>>),
+ IsPointInPath(f64, f64, FillRule, IpcSender<bool>),
+ LineTo(Point2D<f32>),
+ MoveTo(Point2D<f32>),
+ PutImageData(Vec<u8>, Vector2D<f64>, Size2D<f64>, Rect<f64>),
+ QuadraticCurveTo(Point2D<f32>, Point2D<f32>),
+ Rect(Rect<f32>),
+ RestoreContext,
+ SaveContext,
+ StrokeRect(Rect<f32>),
+ Stroke,
+ SetFillStyle(FillOrStrokeStyle),
+ SetStrokeStyle(FillOrStrokeStyle),
+ SetLineWidth(f32),
+ SetLineCap(LineCapStyle),
+ SetLineJoin(LineJoinStyle),
+ SetMiterLimit(f32),
+ SetGlobalAlpha(f32),
+ SetGlobalComposition(CompositionOrBlending),
+ SetTransform(Transform2D<f32>),
+ SetShadowOffsetX(f64),
+ SetShadowOffsetY(f64),
+ SetShadowBlur(f64),
+ SetShadowColor(RGBA),
+}
+
+#[derive(Clone, Deserialize, Serialize, HeapSizeOf)]
+pub struct CanvasGradientStop {
+ pub offset: f64,
+ pub color: RGBA,
+}
+
+#[derive(Clone, Deserialize, Serialize, HeapSizeOf)]
+pub struct LinearGradientStyle {
+ pub x0: f64,
+ pub y0: f64,
+ pub x1: f64,
+ pub y1: f64,
+ pub stops: Vec<CanvasGradientStop>
+}
+
+impl LinearGradientStyle {
+ pub fn new(x0: f64, y0: f64, x1: f64, y1: f64, stops: Vec<CanvasGradientStop>)
+ -> LinearGradientStyle {
+ LinearGradientStyle {
+ x0: x0,
+ y0: y0,
+ x1: x1,
+ y1: y1,
+ stops: stops,
+ }
+ }
+}
+
+#[derive(Clone, Deserialize, Serialize, HeapSizeOf)]
+pub struct RadialGradientStyle {
+ pub x0: f64,
+ pub y0: f64,
+ pub r0: f64,
+ pub x1: f64,
+ pub y1: f64,
+ pub r1: f64,
+ pub stops: Vec<CanvasGradientStop>
+}
+
+impl RadialGradientStyle {
+ pub fn new(x0: f64, y0: f64, r0: f64, x1: f64, y1: f64, r1: f64, stops: Vec<CanvasGradientStop>)
+ -> RadialGradientStyle {
+ RadialGradientStyle {
+ x0: x0,
+ y0: y0,
+ r0: r0,
+ x1: x1,
+ y1: y1,
+ r1: r1,
+ stops: stops,
+ }
+ }
+}
+
+#[derive(Clone, Deserialize, Serialize)]
+pub struct SurfaceStyle {
+ pub surface_data: Vec<u8>,
+ pub surface_size: Size2D<i32>,
+ pub repeat_x: bool,
+ pub repeat_y: bool,
+}
+
+impl SurfaceStyle {
+ pub fn new(surface_data: Vec<u8>, surface_size: Size2D<i32>, repeat_x: bool, repeat_y: bool)
+ -> SurfaceStyle {
+ SurfaceStyle {
+ surface_data: surface_data,
+ surface_size: surface_size,
+ repeat_x: repeat_x,
+ repeat_y: repeat_y,
+ }
+ }
+}
+
+
+#[derive(Clone, Deserialize, Serialize)]
+pub enum FillOrStrokeStyle {
+ Color(RGBA),
+ LinearGradient(LinearGradientStyle),
+ RadialGradient(RadialGradientStyle),
+ Surface(SurfaceStyle),
+}
+
+#[derive(Copy, Clone, PartialEq, Deserialize, Serialize, HeapSizeOf)]
+pub enum LineCapStyle {
+ Butt = 0,
+ Round = 1,
+ Square = 2,
+}
+
+impl FromStr for LineCapStyle {
+ type Err = ();
+
+ fn from_str(string: &str) -> Result<LineCapStyle, ()> {
+ match string {
+ "butt" => Ok(LineCapStyle::Butt),
+ "round" => Ok(LineCapStyle::Round),
+ "square" => Ok(LineCapStyle::Square),
+ _ => Err(()),
+ }
+ }
+}
+
+#[derive(Copy, Clone, PartialEq, Deserialize, Serialize, HeapSizeOf)]
+pub enum LineJoinStyle {
+ Round = 0,
+ Bevel = 1,
+ Miter = 2,
+}
+
+impl FromStr for LineJoinStyle {
+ type Err = ();
+
+ fn from_str(string: &str) -> Result<LineJoinStyle, ()> {
+ match string {
+ "round" => Ok(LineJoinStyle::Round),
+ "bevel" => Ok(LineJoinStyle::Bevel),
+ "miter" => Ok(LineJoinStyle::Miter),
+ _ => Err(()),
+ }
+ }
+}
+
+#[derive(Copy, Clone, PartialEq, Deserialize, Serialize)]
+pub enum RepetitionStyle {
+ Repeat,
+ RepeatX,
+ RepeatY,
+ NoRepeat,
+}
+
+impl FromStr for RepetitionStyle {
+ type Err = ();
+
+ fn from_str(string: &str) -> Result<RepetitionStyle, ()> {
+ match string {
+ "repeat" => Ok(RepetitionStyle::Repeat),
+ "repeat-x" => Ok(RepetitionStyle::RepeatX),
+ "repeat-y" => Ok(RepetitionStyle::RepeatY),
+ "no-repeat" => Ok(RepetitionStyle::NoRepeat),
+ _ => Err(()),
+ }
+ }
+}
+
+#[derive(Copy, Clone, PartialEq, Deserialize, Serialize, HeapSizeOf)]
+pub enum CompositionStyle {
+ SrcIn,
+ SrcOut,
+ SrcOver,
+ SrcAtop,
+ DestIn,
+ DestOut,
+ DestOver,
+ DestAtop,
+ Copy,
+ Lighter,
+ Xor,
+}
+
+impl FromStr for CompositionStyle {
+ type Err = ();
+
+ fn from_str(string: &str) -> Result<CompositionStyle, ()> {
+ match string {
+ "source-in" => Ok(CompositionStyle::SrcIn),
+ "source-out" => Ok(CompositionStyle::SrcOut),
+ "source-over" => Ok(CompositionStyle::SrcOver),
+ "source-atop" => Ok(CompositionStyle::SrcAtop),
+ "destination-in" => Ok(CompositionStyle::DestIn),
+ "destination-out" => Ok(CompositionStyle::DestOut),
+ "destination-over" => Ok(CompositionStyle::DestOver),
+ "destination-atop" => Ok(CompositionStyle::DestAtop),
+ "copy" => Ok(CompositionStyle::Copy),
+ "lighter" => Ok(CompositionStyle::Lighter),
+ "xor" => Ok(CompositionStyle::Xor),
+ _ => Err(())
+ }
+ }
+}
+
+impl CompositionStyle {
+ pub fn to_str(&self) -> &str {
+ match *self {
+ CompositionStyle::SrcIn => "source-in",
+ CompositionStyle::SrcOut => "source-out",
+ CompositionStyle::SrcOver => "source-over",
+ CompositionStyle::SrcAtop => "source-atop",
+ CompositionStyle::DestIn => "destination-in",
+ CompositionStyle::DestOut => "destination-out",
+ CompositionStyle::DestOver => "destination-over",
+ CompositionStyle::DestAtop => "destination-atop",
+ CompositionStyle::Copy => "copy",
+ CompositionStyle::Lighter => "lighter",
+ CompositionStyle::Xor => "xor",
+ }
+ }
+}
+
+#[derive(Copy, Clone, PartialEq, Deserialize, Serialize, HeapSizeOf)]
+pub enum BlendingStyle {
+ Multiply,
+ Screen,
+ Overlay,
+ Darken,
+ Lighten,
+ ColorDodge,
+ ColorBurn,
+ HardLight,
+ SoftLight,
+ Difference,
+ Exclusion,
+ Hue,
+ Saturation,
+ Color,
+ Luminosity,
+}
+
+impl FromStr for BlendingStyle {
+ type Err = ();
+
+ fn from_str(string: &str) -> Result<BlendingStyle, ()> {
+ match string {
+ "multiply" => Ok(BlendingStyle::Multiply),
+ "screen" => Ok(BlendingStyle::Screen),
+ "overlay" => Ok(BlendingStyle::Overlay),
+ "darken" => Ok(BlendingStyle::Darken),
+ "lighten" => Ok(BlendingStyle::Lighten),
+ "color-dodge" => Ok(BlendingStyle::ColorDodge),
+ "color-burn" => Ok(BlendingStyle::ColorBurn),
+ "hard-light" => Ok(BlendingStyle::HardLight),
+ "soft-light" => Ok(BlendingStyle::SoftLight),
+ "difference" => Ok(BlendingStyle::Difference),
+ "exclusion" => Ok(BlendingStyle::Exclusion),
+ "hue" => Ok(BlendingStyle::Hue),
+ "saturation" => Ok(BlendingStyle::Saturation),
+ "color" => Ok(BlendingStyle::Color),
+ "luminosity" => Ok(BlendingStyle::Luminosity),
+ _ => Err(())
+ }
+ }
+}
+
+impl BlendingStyle {
+ pub fn to_str(&self) -> &str {
+ match *self {
+ BlendingStyle::Multiply => "multiply",
+ BlendingStyle::Screen => "screen",
+ BlendingStyle::Overlay => "overlay",
+ BlendingStyle::Darken => "darken",
+ BlendingStyle::Lighten => "lighten",
+ BlendingStyle::ColorDodge => "color-dodge",
+ BlendingStyle::ColorBurn => "color-burn",
+ BlendingStyle::HardLight => "hard-light",
+ BlendingStyle::SoftLight => "soft-light",
+ BlendingStyle::Difference => "difference",
+ BlendingStyle::Exclusion => "exclusion",
+ BlendingStyle::Hue => "hue",
+ BlendingStyle::Saturation => "saturation",
+ BlendingStyle::Color => "color",
+ BlendingStyle::Luminosity => "luminosity",
+ }
+ }
+}
+
+#[derive(Copy, Clone, PartialEq, Deserialize, Serialize, HeapSizeOf)]
+pub enum CompositionOrBlending {
+ Composition(CompositionStyle),
+ Blending(BlendingStyle),
+}
+
+impl Default for CompositionOrBlending {
+ fn default() -> CompositionOrBlending {
+ CompositionOrBlending::Composition(CompositionStyle::SrcOver)
+ }
+}
+
+impl FromStr for CompositionOrBlending {
+ type Err = ();
+
+ fn from_str(string: &str) -> Result<CompositionOrBlending, ()> {
+ if let Ok(op) = CompositionStyle::from_str(string) {
+ return Ok(CompositionOrBlending::Composition(op));
+ }
+
+ if let Ok(op) = BlendingStyle::from_str(string) {
+ return Ok(CompositionOrBlending::Blending(op));
+ }
+
+ Err(())
+ }
+}
+
+// TODO(pcwalton): Speed up with SIMD, or better yet, find some way to not do this.
+pub fn byte_swap(data: &mut [u8]) {
+ let length = data.len();
+ // FIXME(rust #27741): Range::step_by is not stable yet as of this writing.
+ let mut i = 0;
+ while i < length {
+ let r = data[i + 2];
+ data[i + 2] = data[i + 0];
+ data[i + 0] = r;
+ i += 4;
+ }
+}
+
+pub fn multiply_u8_pixel(a: u8, b: u8) -> u8 {
+ return (a as u32 * b as u32 / 255) as u8;
+}
+
+pub fn byte_swap_and_premultiply(data: &mut [u8]) {
+ let length = data.len();
+
+ let mut i = 0;
+ while i < length {
+ let r = data[i + 2];
+ let g = data[i + 1];
+ let b = data[i + 0];
+ let a = data[i + 3];
+
+ data[i + 0] = multiply_u8_pixel(r, a);
+ data[i + 1] = multiply_u8_pixel(g, a);
+ data[i + 2] = multiply_u8_pixel(b, a);
+
+ i += 4;
+ }
+}
diff --git a/components/canvas_traits/webgl.rs b/components/canvas_traits/webgl.rs
deleted file mode 100644
index 1bd6eb0649b..00000000000
--- a/components/canvas_traits/webgl.rs
+++ /dev/null
@@ -1,506 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-use core::nonzero::NonZero;
-use euclid::Size2D;
-use offscreen_gl_context::{GLContextAttributes, GLLimits};
-use std::fmt;
-use webrender_api;
-
-/// Sender type used in WebGLCommands.
-pub use ::webgl_channel::WebGLSender;
-/// Receiver type used in WebGLCommands.
-pub use ::webgl_channel::WebGLReceiver;
-/// Result type for send()/recv() calls in in WebGLCommands.
-pub use ::webgl_channel::WebGLSendResult;
-/// Helper function that creates a WebGL channel (WebGLSender, WebGLReceiver) to be used in WebGLCommands.
-pub use ::webgl_channel::webgl_channel;
-/// Entry point type used in a Script Pipeline to get the WebGLChan to be used in that thread.
-pub use ::webgl_channel::WebGLPipeline;
-/// Entry point channel type used for sending WebGLMsg messages to the WebGL renderer.
-pub use ::webgl_channel::WebGLChan;
-
-/// WebGL Message API
-#[derive(Clone, Deserialize, Serialize)]
-pub enum WebGLMsg {
- /// Creates a new WebGLContext.
- CreateContext(Size2D<i32>, GLContextAttributes, WebGLSender<Result<(WebGLCreateContextResult), String>>),
- /// Resizes a WebGLContext.
- ResizeContext(WebGLContextId, Size2D<i32>, WebGLSender<Result<(), String>>),
- /// Drops a WebGLContext.
- RemoveContext(WebGLContextId),
- /// Runs a WebGLCommand in a specific WebGLContext.
- WebGLCommand(WebGLContextId, WebGLCommand),
- /// Runs a WebVRCommand in a specific WebGLContext.
- WebVRCommand(WebGLContextId, WebVRCommand),
- /// Locks a specific WebGLContext. Lock messages are used for a correct synchronization
- /// with WebRender external image API.
- /// WR locks a external texture when it wants to use the shared texture contents.
- /// The WR client should not change the shared texture content until the Unlock call.
- /// Currently OpenGL Sync Objects are used to implement the synchronization mechanism.
- Lock(WebGLContextId, WebGLSender<(u32, Size2D<i32>)>),
- /// Unlocks a specific WebGLContext. Unlock messages are used for a correct synchronization
- /// with WebRender external image API.
- /// The WR unlocks a context when it finished reading the shared texture contents.
- /// Unlock messages are always sent after a Lock message.
- Unlock(WebGLContextId),
- /// Creates or updates the image keys required for WebRender.
- UpdateWebRenderImage(WebGLContextId, WebGLSender<webrender_api::ImageKey>),
- /// Frees all resources and closes the thread.
- Exit,
-}
-
-/// Contains the WebGLCommand sender and information about a WebGLContext
-#[derive(Clone, Deserialize, Serialize)]
-pub struct WebGLCreateContextResult {
- /// Sender instance to send commands to the specific WebGLContext
- pub sender: WebGLMsgSender,
- /// Information about the internal GL Context.
- pub limits: GLLimits,
- /// How the WebGLContext is shared with WebRender.
- pub share_mode: WebGLContextShareMode,
-}
-
-#[derive(Clone, Copy, Deserialize, HeapSizeOf, Serialize)]
-pub enum WebGLContextShareMode {
- /// Fast: a shared texture_id is used in WebRender.
- SharedTexture,
- /// Slow: glReadPixels is used to send pixels to WebRender each frame.
- Readback,
-}
-
-/// Helper struct to send WebGLCommands to a specific WebGLContext.
-#[derive(Clone, Deserialize, HeapSizeOf, Serialize)]
-pub struct WebGLMsgSender {
- ctx_id: WebGLContextId,
- #[ignore_heap_size_of = "channels are hard"]
- sender: WebGLChan,
-}
-
-impl WebGLMsgSender {
- pub fn new(id: WebGLContextId, sender: WebGLChan) -> Self {
- WebGLMsgSender {
- ctx_id: id,
- sender: sender,
- }
- }
-
- /// Send a WebGLCommand message
- #[inline]
- pub fn send(&self, command: WebGLCommand) -> WebGLSendResult {
- self.sender.send(WebGLMsg::WebGLCommand(self.ctx_id, command))
- }
-
- /// Send a WebVRCommand message
- #[inline]
- pub fn send_vr(&self, command: WebVRCommand) -> WebGLSendResult {
- self.sender.send(WebGLMsg::WebVRCommand(self.ctx_id, command))
- }
-
- /// Send a resize message
- #[inline]
- pub fn send_resize(&self,
- size: Size2D<i32>,
- sender: WebGLSender<Result<(), String>>)
- -> WebGLSendResult {
- self.sender.send(WebGLMsg::ResizeContext(self.ctx_id, size, sender))
- }
-
- #[inline]
- pub fn send_remove(&self) -> WebGLSendResult {
- self.sender.send(WebGLMsg::RemoveContext(self.ctx_id))
- }
-
- #[inline]
- pub fn send_update_wr_image(&self, sender: WebGLSender<webrender_api::ImageKey>) -> WebGLSendResult {
- self.sender.send(WebGLMsg::UpdateWebRenderImage(self.ctx_id, sender))
- }
-}
-
-/// WebGL Commands for a specific WebGLContext
-#[derive(Clone, Deserialize, Serialize)]
-pub enum WebGLCommand {
- GetContextAttributes(WebGLSender<GLContextAttributes>),
- ActiveTexture(u32),
- BlendColor(f32, f32, f32, f32),
- BlendEquation(u32),
- BlendEquationSeparate(u32, u32),
- BlendFunc(u32, u32),
- BlendFuncSeparate(u32, u32, u32, u32),
- AttachShader(WebGLProgramId, WebGLShaderId),
- DetachShader(WebGLProgramId, WebGLShaderId),
- BindAttribLocation(WebGLProgramId, u32, String),
- BufferData(u32, Vec<u8>, u32),
- BufferSubData(u32, isize, Vec<u8>),
- Clear(u32),
- ClearColor(f32, f32, f32, f32),
- ClearDepth(f64),
- ClearStencil(i32),
- ColorMask(bool, bool, bool, bool),
- CullFace(u32),
- FrontFace(u32),
- DepthFunc(u32),
- DepthMask(bool),
- DepthRange(f64, f64),
- Enable(u32),
- Disable(u32),
- CompileShader(WebGLShaderId, String),
- CopyTexImage2D(u32, i32, u32, i32, i32, i32, i32, i32),
- CopyTexSubImage2D(u32, i32, i32, i32, i32, i32, i32, i32),
- CreateBuffer(WebGLSender<Option<WebGLBufferId>>),
- CreateFramebuffer(WebGLSender<Option<WebGLFramebufferId>>),
- CreateRenderbuffer(WebGLSender<Option<WebGLRenderbufferId>>),
- CreateTexture(WebGLSender<Option<WebGLTextureId>>),
- CreateProgram(WebGLSender<Option<WebGLProgramId>>),
- CreateShader(u32, WebGLSender<Option<WebGLShaderId>>),
- DeleteBuffer(WebGLBufferId),
- DeleteFramebuffer(WebGLFramebufferId),
- DeleteRenderbuffer(WebGLRenderbufferId),
- DeleteTexture(WebGLTextureId),
- DeleteProgram(WebGLProgramId),
- DeleteShader(WebGLShaderId),
- BindBuffer(u32, Option<WebGLBufferId>),
- BindFramebuffer(u32, WebGLFramebufferBindingRequest),
- BindRenderbuffer(u32, Option<WebGLRenderbufferId>),
- BindTexture(u32, Option<WebGLTextureId>),
- DisableVertexAttribArray(u32),
- DrawArrays(u32, i32, i32),
- DrawElements(u32, i32, u32, i64),
- EnableVertexAttribArray(u32),
- FramebufferRenderbuffer(u32, u32, u32, Option<WebGLRenderbufferId>),
- FramebufferTexture2D(u32, u32, u32, Option<WebGLTextureId>, i32),
- GetBufferParameter(u32, u32, WebGLSender<WebGLResult<WebGLParameter>>),
- GetExtensions(WebGLSender<String>),
- GetParameter(u32, WebGLSender<WebGLResult<WebGLParameter>>),
- GetProgramParameter(WebGLProgramId, u32, WebGLSender<WebGLResult<WebGLParameter>>),
- GetShaderParameter(WebGLShaderId, u32, WebGLSender<WebGLResult<WebGLParameter>>),
- GetShaderPrecisionFormat(u32, u32, WebGLSender<WebGLResult<(i32, i32, i32)>>),
- GetActiveAttrib(WebGLProgramId, u32, WebGLSender<WebGLResult<(i32, u32, String)>>),
- GetActiveUniform(WebGLProgramId, u32, WebGLSender<WebGLResult<(i32, u32, String)>>),
- GetAttribLocation(WebGLProgramId, String, WebGLSender<Option<i32>>),
- GetUniformLocation(WebGLProgramId, String, WebGLSender<Option<i32>>),
- GetVertexAttrib(u32, u32, WebGLSender<WebGLResult<WebGLParameter>>),
- GetVertexAttribOffset(u32, u32, WebGLSender<WebGLResult<isize>>),
- GetShaderInfoLog(WebGLShaderId, WebGLSender<String>),
- GetProgramInfoLog(WebGLProgramId, WebGLSender<String>),
- PolygonOffset(f32, f32),
- RenderbufferStorage(u32, u32, i32, i32),
- ReadPixels(i32, i32, i32, i32, u32, u32, WebGLSender<Vec<u8>>),
- SampleCoverage(f32, bool),
- Scissor(i32, i32, i32, i32),
- StencilFunc(u32, i32, u32),
- StencilFuncSeparate(u32, u32, i32, u32),
- StencilMask(u32),
- StencilMaskSeparate(u32, u32),
- StencilOp(u32, u32, u32),
- StencilOpSeparate(u32, u32, u32, u32),
- Hint(u32, u32),
- IsEnabled(u32, WebGLSender<bool>),
- LineWidth(f32),
- PixelStorei(u32, i32),
- LinkProgram(WebGLProgramId),
- Uniform1f(i32, f32),
- Uniform1fv(i32, Vec<f32>),
- Uniform1i(i32, i32),
- Uniform1iv(i32, Vec<i32>),
- Uniform2f(i32, f32, f32),
- Uniform2fv(i32, Vec<f32>),
- Uniform2i(i32, i32, i32),
- Uniform2iv(i32, Vec<i32>),
- Uniform3f(i32, f32, f32, f32),
- Uniform3fv(i32, Vec<f32>),
- Uniform3i(i32, i32, i32, i32),
- Uniform3iv(i32, Vec<i32>),
- Uniform4f(i32, f32, f32, f32, f32),
- Uniform4fv(i32, Vec<f32>),
- Uniform4i(i32, i32, i32, i32, i32),
- Uniform4iv(i32, Vec<i32>),
- UniformMatrix2fv(i32, bool, Vec<f32>),
- UniformMatrix3fv(i32, bool, Vec<f32>),
- UniformMatrix4fv(i32, bool, Vec<f32>),
- UseProgram(WebGLProgramId),
- ValidateProgram(WebGLProgramId),
- VertexAttrib(u32, f32, f32, f32, f32),
- VertexAttribPointer(u32, i32, u32, bool, i32, u32),
- VertexAttribPointer2f(u32, i32, bool, i32, u32),
- Viewport(i32, i32, i32, i32),
- TexImage2D(u32, i32, i32, i32, i32, u32, u32, Vec<u8>),
- TexParameteri(u32, u32, i32),
- TexParameterf(u32, u32, f32),
- TexSubImage2D(u32, i32, i32, i32, i32, i32, u32, u32, Vec<u8>),
- DrawingBufferWidth(WebGLSender<i32>),
- DrawingBufferHeight(WebGLSender<i32>),
- Finish(WebGLSender<()>),
- Flush,
- GenerateMipmap(u32),
- CreateVertexArray(WebGLSender<Option<WebGLVertexArrayId>>),
- DeleteVertexArray(WebGLVertexArrayId),
- BindVertexArray(Option<WebGLVertexArrayId>),
-}
-
-macro_rules! define_resource_id_struct {
- ($name:ident) => {
- #[derive(Clone, Copy, Eq, Hash, PartialEq)]
- pub struct $name(NonZero<u32>);
-
- impl $name {
- #[allow(unsafe_code)]
- #[inline]
- pub unsafe fn new(id: u32) -> Self {
- $name(NonZero::new_unchecked(id))
- }
-
- #[inline]
- pub fn get(self) -> u32 {
- self.0.get()
- }
- }
-
- };
-}
-
-macro_rules! define_resource_id {
- ($name:ident) => {
- define_resource_id_struct!($name);
-
- #[allow(unsafe_code)]
- impl<'de> ::serde::Deserialize<'de> for $name {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where D: ::serde::Deserializer<'de>
- {
- let id = try!(u32::deserialize(deserializer));
- if id == 0 {
- Err(::serde::de::Error::custom("expected a non-zero value"))
- } else {
- Ok(unsafe { $name::new(id) })
- }
- }
- }
-
- impl ::serde::Serialize for $name {
- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- where S: ::serde::Serializer
- {
- self.get().serialize(serializer)
- }
- }
-
- impl ::std::fmt::Debug for $name {
- fn fmt(&self, fmt: &mut ::std::fmt::Formatter)
- -> Result<(), ::std::fmt::Error> {
- fmt.debug_tuple(stringify!($name))
- .field(&self.get())
- .finish()
- }
- }
-
- impl ::std::fmt::Display for $name {
- fn fmt(&self, fmt: &mut ::std::fmt::Formatter)
- -> Result<(), ::std::fmt::Error> {
- write!(fmt, "{}", self.get())
- }
- }
-
- impl ::heapsize::HeapSizeOf for $name {
- fn heap_size_of_children(&self) -> usize { 0 }
- }
- }
-}
-
-define_resource_id!(WebGLBufferId);
-define_resource_id!(WebGLFramebufferId);
-define_resource_id!(WebGLRenderbufferId);
-define_resource_id!(WebGLTextureId);
-define_resource_id!(WebGLProgramId);
-define_resource_id!(WebGLShaderId);
-define_resource_id!(WebGLVertexArrayId);
-
-#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
-pub struct WebGLContextId(pub usize);
-
-impl ::heapsize::HeapSizeOf for WebGLContextId {
- fn heap_size_of_children(&self) -> usize { 0 }
-}
-
-#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
-pub enum WebGLError {
- InvalidEnum,
- InvalidFramebufferOperation,
- InvalidOperation,
- InvalidValue,
- OutOfMemory,
- ContextLost,
-}
-
-#[derive(Clone, Debug, Deserialize, Serialize)]
-pub enum WebGLFramebufferBindingRequest {
- Explicit(WebGLFramebufferId),
- Default,
-}
-
-#[derive(Clone, Debug, Deserialize, Serialize)]
-pub enum WebGLParameter {
- Int(i32),
- Bool(bool),
- String(String),
- Float(f32),
- FloatArray(Vec<f32>),
- Invalid,
-}
-
-pub type WebGLResult<T> = Result<T, WebGLError>;
-
-#[derive(Clone, Debug, Deserialize, Serialize)]
-pub enum WebGLShaderParameter {
- Int(i32),
- Bool(bool),
- Invalid,
-}
-
-pub type WebVRDeviceId = u32;
-
-// WebVR commands that must be called in the WebGL render thread.
-#[derive(Clone, Deserialize, Serialize)]
-pub enum WebVRCommand {
- /// Start presenting to a VR device.
- Create(WebVRDeviceId),
- /// Synchronize the pose information to be used in the frame.
- SyncPoses(WebVRDeviceId, f64, f64, WebGLSender<Result<Vec<u8>, ()>>),
- /// Submit the frame to a VR device using the specified texture coordinates.
- SubmitFrame(WebVRDeviceId, [f32; 4], [f32; 4]),
- /// Stop presenting to a VR device
- Release(WebVRDeviceId)
-}
-
-// Trait object that handles WebVR commands.
-// Receives the texture id and size associated to the WebGLContext.
-pub trait WebVRRenderHandler: Send {
- fn handle(&mut self, command: WebVRCommand, texture: Option<(u32, Size2D<i32>)>);
-}
-
-impl fmt::Debug for WebGLCommand {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use self::WebGLCommand::*;
- let name = match *self {
- GetContextAttributes(..) => "GetContextAttributes",
- ActiveTexture(..) => "ActiveTexture",
- BlendColor(..) => "BlendColor",
- BlendEquation(..) => "BlendEquation",
- BlendEquationSeparate(..) => "BlendEquationSeparate",
- BlendFunc(..) => "BlendFunc",
- BlendFuncSeparate(..) => "BlendFuncSeparate",
- AttachShader(..) => "AttachShader",
- DetachShader(..) => "DetachShader",
- BindAttribLocation(..) => "BindAttribLocation",
- BufferData(..) => "BufferData",
- BufferSubData(..) => "BufferSubData",
- Clear(..) => "Clear",
- ClearColor(..) => "ClearColor",
- ClearDepth(..) => "ClearDepth",
- ClearStencil(..) => "ClearStencil",
- ColorMask(..) => "ColorMask",
- CopyTexImage2D(..) => "CopyTexImage2D",
- CopyTexSubImage2D(..) => "CopyTexSubImage2D",
- CullFace(..) => "CullFace",
- FrontFace(..) => "FrontFace",
- DepthFunc(..) => "DepthFunc",
- DepthMask(..) => "DepthMask",
- DepthRange(..) => "DepthRange",
- Enable(..) => "Enable",
- Disable(..) => "Disable",
- CompileShader(..) => "CompileShader",
- CreateBuffer(..) => "CreateBuffer",
- CreateFramebuffer(..) => "CreateFramebuffer",
- CreateRenderbuffer(..) => "CreateRenderbuffer",
- CreateTexture(..) => "CreateTexture",
- CreateProgram(..) => "CreateProgram",
- CreateShader(..) => "CreateShader",
- DeleteBuffer(..) => "DeleteBuffer",
- DeleteFramebuffer(..) => "DeleteFramebuffer",
- DeleteRenderbuffer(..) => "DeleteRenderBuffer",
- DeleteTexture(..) => "DeleteTexture",
- DeleteProgram(..) => "DeleteProgram",
- DeleteShader(..) => "DeleteShader",
- BindBuffer(..) => "BindBuffer",
- BindFramebuffer(..) => "BindFramebuffer",
- BindRenderbuffer(..) => "BindRenderbuffer",
- BindTexture(..) => "BindTexture",
- DisableVertexAttribArray(..) => "DisableVertexAttribArray",
- DrawArrays(..) => "DrawArrays",
- DrawElements(..) => "DrawElements",
- EnableVertexAttribArray(..) => "EnableVertexAttribArray",
- FramebufferRenderbuffer(..) => "FramebufferRenderbuffer",
- FramebufferTexture2D(..) => "FramebufferTexture2D",
- GetBufferParameter(..) => "GetBufferParameter",
- GetExtensions(..) => "GetExtensions",
- GetParameter(..) => "GetParameter",
- GetProgramParameter(..) => "GetProgramParameter",
- GetShaderParameter(..) => "GetShaderParameter",
- GetShaderPrecisionFormat(..) => "GetShaderPrecisionFormat",
- GetActiveAttrib(..) => "GetActiveAttrib",
- GetActiveUniform(..) => "GetActiveUniform",
- GetAttribLocation(..) => "GetAttribLocation",
- GetUniformLocation(..) => "GetUniformLocation",
- GetShaderInfoLog(..) => "GetShaderInfoLog",
- GetProgramInfoLog(..) => "GetProgramInfoLog",
- GetVertexAttrib(..) => "GetVertexAttrib",
- GetVertexAttribOffset(..) => "GetVertexAttribOffset",
- PolygonOffset(..) => "PolygonOffset",
- ReadPixels(..) => "ReadPixels",
- RenderbufferStorage(..) => "RenderbufferStorage",
- SampleCoverage(..) => "SampleCoverage",
- Scissor(..) => "Scissor",
- StencilFunc(..) => "StencilFunc",
- StencilFuncSeparate(..) => "StencilFuncSeparate",
- StencilMask(..) => "StencilMask",
- StencilMaskSeparate(..) => "StencilMaskSeparate",
- StencilOp(..) => "StencilOp",
- StencilOpSeparate(..) => "StencilOpSeparate",
- Hint(..) => "Hint",
- IsEnabled(..) => "IsEnabled",
- LineWidth(..) => "LineWidth",
- PixelStorei(..) => "PixelStorei",
- LinkProgram(..) => "LinkProgram",
- Uniform1f(..) => "Uniform1f",
- Uniform1fv(..) => "Uniform1fv",
- Uniform1i(..) => "Uniform1i",
- Uniform1iv(..) => "Uniform1iv",
- Uniform2f(..) => "Uniform2f",
- Uniform2fv(..) => "Uniform2fv",
- Uniform2i(..) => "Uniform2i",
- Uniform2iv(..) => "Uniform2iv",
- Uniform3f(..) => "Uniform3f",
- Uniform3fv(..) => "Uniform3fv",
- Uniform3i(..) => "Uniform3i",
- Uniform3iv(..) => "Uniform3iv",
- Uniform4f(..) => "Uniform4f",
- Uniform4fv(..) => "Uniform4fv",
- Uniform4i(..) => "Uniform4i",
- Uniform4iv(..) => "Uniform4iv",
- UniformMatrix2fv(..) => "UniformMatrix2fv",
- UniformMatrix3fv(..) => "UniformMatrix3fv",
- UniformMatrix4fv(..) => "UniformMatrix4fv",
- UseProgram(..) => "UseProgram",
- ValidateProgram(..) => "ValidateProgram",
- VertexAttrib(..) => "VertexAttrib",
- VertexAttribPointer2f(..) => "VertexAttribPointer2f",
- VertexAttribPointer(..) => "VertexAttribPointer",
- Viewport(..) => "Viewport",
- TexImage2D(..) => "TexImage2D",
- TexParameteri(..) => "TexParameteri",
- TexParameterf(..) => "TexParameterf",
- TexSubImage2D(..) => "TexSubImage2D",
- DrawingBufferWidth(..) => "DrawingBufferWidth",
- DrawingBufferHeight(..) => "DrawingBufferHeight",
- Finish(..) => "Finish",
- Flush => "Flush",
- GenerateMipmap(..) => "GenerateMipmap",
- CreateVertexArray(..) => "CreateVertexArray",
- DeleteVertexArray(..) => "DeleteVertexArray",
- BindVertexArray(..) => "BindVertexArray"
- };
-
- write!(f, "CanvasWebGLMsg::{}(..)", name)
- }
-}
diff --git a/components/canvas_traits/webgl_channel/ipc.rs b/components/canvas_traits/webgl_channel/ipc.rs
deleted file mode 100644
index ac3020bbc7a..00000000000
--- a/components/canvas_traits/webgl_channel/ipc.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-use ipc_channel;
-use serde::{Deserialize, Serialize};
-use std::io;
-
-pub type WebGLSender<T> = ipc_channel::ipc::IpcSender<T>;
-pub type WebGLReceiver<T> = ipc_channel::ipc::IpcReceiver<T>;
-
-pub fn webgl_channel<T: Serialize + for<'de> Deserialize<'de>>()
- -> Result<(WebGLSender<T>, WebGLReceiver<T>), io::Error> {
- ipc_channel::ipc::channel()
-}
diff --git a/components/canvas_traits/webgl_channel/mod.rs b/components/canvas_traits/webgl_channel/mod.rs
deleted file mode 100644
index 1ac4ce15cb1..00000000000
--- a/components/canvas_traits/webgl_channel/mod.rs
+++ /dev/null
@@ -1,87 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//! Enum wrappers to be able to select different channel implementations at runtime.
-
-mod ipc;
-mod mpsc;
-
-use ::webgl::WebGLMsg;
-use serde::{Deserialize, Serialize};
-use servo_config::opts;
-
-lazy_static! {
- static ref IS_MULTIPROCESS: bool = {
- opts::multiprocess()
- };
-}
-
-#[derive(Clone, Deserialize, Serialize)]
-pub enum WebGLSender<T: Serialize> {
- Ipc(ipc::WebGLSender<T>),
- Mpsc(mpsc::WebGLSender<T>),
-}
-
-impl<T: Serialize> WebGLSender<T> {
- #[inline]
- pub fn send(&self, msg: T) -> WebGLSendResult {
- match *self {
- WebGLSender::Ipc(ref sender) => {
- sender.send(msg).map_err(|_| ())
- },
- WebGLSender::Mpsc(ref sender) => {
- sender.send(msg).map_err(|_| ())
- }
- }
- }
-}
-
-pub type WebGLSendResult = Result<(), ()>;
-
-pub enum WebGLReceiver<T> where T: for<'de> Deserialize<'de> + Serialize {
- Ipc(ipc::WebGLReceiver<T>),
- Mpsc(mpsc::WebGLReceiver<T>),
-}
-
-impl<T> WebGLReceiver<T> where T: for<'de> Deserialize<'de> + Serialize {
- pub fn recv(&self) -> Result<T, ()> {
- match *self {
- WebGLReceiver::Ipc(ref receiver) => {
- receiver.recv().map_err(|_| ())
- },
- WebGLReceiver::Mpsc(ref receiver) => {
- receiver.recv().map_err(|_| ())
- }
- }
- }
-}
-
-pub fn webgl_channel<T>() -> Result<(WebGLSender<T>, WebGLReceiver<T>), ()>
- where T: for<'de> Deserialize<'de> + Serialize {
- if *IS_MULTIPROCESS {
- ipc::webgl_channel().map(|(tx, rx)| (WebGLSender::Ipc(tx), WebGLReceiver::Ipc(rx)))
- .map_err(|_| ())
- } else {
- mpsc::webgl_channel().map(|(tx, rx)| (WebGLSender::Mpsc(tx), WebGLReceiver::Mpsc(rx)))
- }
-}
-
-#[derive(Clone, Deserialize, Serialize)]
-pub struct WebGLChan(pub WebGLSender<WebGLMsg>);
-
-impl WebGLChan {
- #[inline]
- pub fn send(&self, msg: WebGLMsg) -> WebGLSendResult {
- self.0.send(msg)
- }
-}
-
-#[derive(Clone, Deserialize, Serialize)]
-pub struct WebGLPipeline(pub WebGLChan);
-
-impl WebGLPipeline {
- pub fn channel(&self) -> WebGLChan {
- self.0.clone()
- }
-}
diff --git a/components/canvas_traits/webgl_channel/mpsc.rs b/components/canvas_traits/webgl_channel/mpsc.rs
deleted file mode 100644
index b0fe29241f3..00000000000
--- a/components/canvas_traits/webgl_channel/mpsc.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-use serde::{Deserialize, Serialize};
-use serde::{Deserializer, Serializer};
-use std::sync::mpsc;
-
-#[macro_use]
-macro_rules! unreachable_serializable {
- ($name:ident) => {
- impl<T> Serialize for $name<T> {
- fn serialize<S: Serializer>(&self, _: S) -> Result<S::Ok, S::Error> {
- unreachable!();
- }
- }
-
- impl<'a, T> Deserialize<'a> for $name<T> {
- fn deserialize<D>(_: D) -> Result<$name<T>, D::Error>
- where D: Deserializer<'a> {
- unreachable!();
- }
- }
- };
-}
-
-#[derive(Clone)]
-pub struct WebGLSender<T>(mpsc::Sender<T>);
-pub struct WebGLReceiver<T>(mpsc::Receiver<T>);
-
-impl<T> WebGLSender<T> {
- #[inline]
- pub fn send(&self, data: T) -> Result<(), mpsc::SendError<T>> {
- self.0.send(data)
- }
-}
-
-impl<T> WebGLReceiver<T> {
- #[inline]
- pub fn recv(&self) -> Result<T, mpsc::RecvError> {
- self.0.recv()
- }
-}
-
-pub fn webgl_channel<T>() -> Result<(WebGLSender<T>, WebGLReceiver<T>), ()> {
- let (sender, receiver) = mpsc::channel();
- Ok((WebGLSender(sender), WebGLReceiver(receiver)))
-}
-
-unreachable_serializable!(WebGLReceiver);
-unreachable_serializable!(WebGLSender);
diff --git a/components/constellation/Cargo.toml b/components/constellation/Cargo.toml
index f2ab08dc190..ff6bd2700f0 100644
--- a/components/constellation/Cargo.toml
+++ b/components/constellation/Cargo.toml
@@ -30,6 +30,7 @@ metrics = {path = "../metrics"}
msg = {path = "../msg"}
net = {path = "../net"}
net_traits = {path = "../net_traits"}
+offscreen_gl_context = { version = "0.11", features = ["serde"] }
profile_traits = {path = "../profile_traits"}
script_traits = {path = "../script_traits"}
serde = "1.0"
diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs
index 3e9b0cc80be..1685a32d8d2 100644
--- a/components/constellation/constellation.rs
+++ b/components/constellation/constellation.rs
@@ -70,8 +70,8 @@ use bluetooth_traits::BluetoothRequest;
use browsingcontext::{BrowsingContext, SessionHistoryChange, SessionHistoryEntry};
use browsingcontext::{FullyActiveBrowsingContextsIterator, AllBrowsingContextsIterator};
use canvas::canvas_paint_thread::CanvasPaintThread;
-use canvas::webgl_thread::WebGLThreads;
-use canvas_traits::canvas::CanvasMsg;
+use canvas::webgl_paint_thread::WebGLPaintThread;
+use canvas_traits::CanvasMsg;
use clipboard::{ClipboardContext, ClipboardProvider};
use compositing::SendableFrameTree;
use compositing::compositor_thread::CompositorProxy;
@@ -96,6 +96,7 @@ use net_traits::pub_domains::reg_host;
use net_traits::request::RequestInit;
use net_traits::storage_thread::{StorageThreadMsg, StorageType};
use network_listener::NetworkListener;
+use offscreen_gl_context::{GLContextAttributes, GLLimits};
use pipeline::{InitialPipelineState, Pipeline};
use profile_traits::mem;
use profile_traits::time;
@@ -297,11 +298,8 @@ pub struct Constellation<Message, LTF, STF> {
/// Phantom data that keeps the Rust type system happy.
phantom: PhantomData<(Message, LTF, STF)>,
- /// Entry point to create and get channels to a WebGLThread.
- webgl_threads: WebGLThreads,
-
/// A channel through which messages can be sent to the webvr thread.
- webvr_chan: Option<IpcSender<WebVRMsg>>,
+ webvr_thread: Option<IpcSender<WebVRMsg>>,
}
/// State needed to construct a constellation.
@@ -339,12 +337,6 @@ pub struct InitialConstellationState {
/// Webrender API.
pub webrender_api_sender: webrender_api::RenderApiSender,
- /// Entry point to create and get channels to a WebGLThread.
- pub webgl_threads: WebGLThreads,
-
- /// A channel to the webgl thread.
- pub webvr_chan: Option<IpcSender<WebVRMsg>>,
-
/// Whether the constellation supports the clipboard.
/// TODO: this field is not used, remove it?
pub supports_clipboard: bool,
@@ -589,8 +581,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
info!("Using seed {} for random pipeline closure.", seed);
(rng, prob)
}),
- webgl_threads: state.webgl_threads,
- webvr_chan: state.webvr_chan,
+ webvr_thread: None
};
constellation.run();
@@ -709,8 +700,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(),
- webvr_chan: self.webvr_chan.clone()
+ webvr_thread: self.webvr_thread.clone()
});
let pipeline = match result {
@@ -1004,6 +994,10 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
FromCompositorMsg::LogEntry(top_level_browsing_context_id, thread_name, entry) => {
self.handle_log_entry(top_level_browsing_context_id, thread_name, entry);
}
+ FromCompositorMsg::SetWebVRThread(webvr_thread) => {
+ assert!(self.webvr_thread.is_none());
+ self.webvr_thread = Some(webvr_thread)
+ }
FromCompositorMsg::WebVREvents(pipeline_ids, events) => {
debug!("constellation got {:?} WebVR events", events.len());
self.handle_webvr_events(pipeline_ids, events);
@@ -1160,6 +1154,10 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
debug!("constellation got create-canvas-paint-thread message");
self.handle_create_canvas_paint_thread_msg(&size, sender)
}
+ FromScriptMsg::CreateWebGLPaintThread(size, attributes, sender) => {
+ debug!("constellation got create-WebGL-paint-thread message");
+ self.handle_create_webgl_paint_thread_msg(&size, attributes, sender)
+ }
FromScriptMsg::NodeStatus(message) => {
debug!("constellation got NodeStatus message");
self.compositor_proxy.send(ToCompositorMsg::Status(source_top_ctx_id, message));
@@ -1369,12 +1367,7 @@ 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(chan) = self.webvr_chan.as_ref() {
+ if let Some(chan) = self.webvr_thread.as_ref() {
debug!("Exiting WebVR thread.");
if let Err(e) = chan.send(WebVRMsg::Exit) {
warn!("Exit WebVR thread failed ({})", e);
@@ -2142,6 +2135,19 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
}
+ fn handle_create_webgl_paint_thread_msg(
+ &mut self,
+ size: &Size2D<i32>,
+ attributes: GLContextAttributes,
+ response_sender: IpcSender<Result<(IpcSender<CanvasMsg>, GLLimits), String>>) {
+ let webrender_api = self.webrender_api_sender.clone();
+ let response = WebGLPaintThread::start(*size, attributes, webrender_api);
+
+ if let Err(e) = response_sender.send(response) {
+ warn!("Create WebGL paint thread response failed ({})", e);
+ }
+ }
+
fn handle_webdriver_msg(&mut self, msg: WebDriverCommandMsg) {
// Find the script channel for the given parent pipeline,
// and pass the event to that script thread.
diff --git a/components/constellation/lib.rs b/components/constellation/lib.rs
index 1c444ff6603..d2ac0f00dea 100644
--- a/components/constellation/lib.rs
+++ b/components/constellation/lib.rs
@@ -30,6 +30,7 @@ extern crate metrics;
extern crate msg;
extern crate net;
extern crate net_traits;
+extern crate offscreen_gl_context;
extern crate profile_traits;
extern crate script_traits;
#[macro_use] extern crate serde;
diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs
index 74ce33ff564..92a5fb041ef 100644
--- a/components/constellation/pipeline.rs
+++ b/components/constellation/pipeline.rs
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use bluetooth_traits::BluetoothRequest;
-use canvas_traits::webgl::WebGLPipeline;
use compositing::CompositionPipeline;
use compositing::CompositorProxy;
use compositing::compositor_thread::Msg as CompositorMsg;
@@ -172,12 +171,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 webvr thread.
- pub webvr_chan: Option<IpcSender<WebVRMsg>>,
+ pub webvr_thread: Option<IpcSender<WebVRMsg>>,
}
impl Pipeline {
@@ -275,8 +270,7 @@ impl Pipeline {
script_content_process_shutdown_port: script_content_process_shutdown_port,
webrender_api_sender: state.webrender_api_sender,
webrender_document: state.webrender_document,
- webgl_chan: state.webgl_chan,
- webvr_chan: state.webvr_chan,
+ webvr_thread: state.webvr_thread,
};
// Spawn the child process.
@@ -476,8 +470,7 @@ pub struct UnprivilegedPipelineContent {
script_content_process_shutdown_port: IpcReceiver<()>,
webrender_api_sender: webrender_api::RenderApiSender,
webrender_document: webrender_api::DocumentId,
- webgl_chan: WebGLPipeline,
- webvr_chan: Option<IpcSender<WebVRMsg>>,
+ webvr_thread: Option<IpcSender<WebVRMsg>>,
}
impl UnprivilegedPipelineContent {
@@ -506,8 +499,7 @@ impl UnprivilegedPipelineContent {
window_size: self.window_size,
pipeline_namespace_id: self.pipeline_namespace_id,
content_process_shutdown_chan: self.script_content_process_shutdown_chan,
- webgl_chan: self.webgl_chan,
- webvr_chan: self.webvr_chan,
+ webvr_thread: self.webvr_thread,
}, self.load_data.clone());
LTF::create(self.id,
diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs
index 98ece855d25..2d1b7c593dc 100644
--- a/components/gfx/display_list/mod.rs
+++ b/components/gfx/display_list/mod.rs
@@ -34,7 +34,7 @@ use style_traits::cursor::Cursor;
use text::TextRun;
use text::glyph::ByteIndex;
use webrender_api::{self, ClipAndScrollInfo, ClipId, ColorF, GradientStop, LocalClip};
-use webrender_api::{MixBlendMode, ScrollPolicy, ScrollSensitivity, TransformStyle};
+use webrender_api::{MixBlendMode, ScrollPolicy, ScrollSensitivity, TransformStyle, WebGLContextId};
pub use style::dom::OpaqueNode;
@@ -598,6 +598,7 @@ pub enum DisplayItem {
SolidColor(Box<SolidColorDisplayItem>),
Text(Box<TextDisplayItem>),
Image(Box<ImageDisplayItem>),
+ WebGL(Box<WebGLDisplayItem>),
Border(Box<BorderDisplayItem>),
Gradient(Box<GradientDisplayItem>),
RadialGradient(Box<RadialGradientDisplayItem>),
@@ -927,6 +928,14 @@ pub struct ImageDisplayItem {
/// 5.3.
pub image_rendering: image_rendering::T,
}
+
+#[derive(Clone, HeapSizeOf, Deserialize, Serialize)]
+pub struct WebGLDisplayItem {
+ pub base: BaseDisplayItem,
+ pub context_id: WebGLContextId,
+}
+
+
/// Paints an iframe.
#[derive(Clone, HeapSizeOf, Deserialize, Serialize)]
pub struct IframeDisplayItem {
@@ -1240,6 +1249,7 @@ impl DisplayItem {
DisplayItem::SolidColor(ref solid_color) => &solid_color.base,
DisplayItem::Text(ref text) => &text.base,
DisplayItem::Image(ref image_item) => &image_item.base,
+ DisplayItem::WebGL(ref webgl_item) => &webgl_item.base,
DisplayItem::Border(ref border) => &border.base,
DisplayItem::Gradient(ref gradient) => &gradient.base,
DisplayItem::RadialGradient(ref gradient) => &gradient.base,
@@ -1365,6 +1375,7 @@ impl fmt::Debug for DisplayItem {
text.range.begin().0 as usize..(text.range.begin().0 + text.range.length().0) as usize])
}
DisplayItem::Image(_) => "Image".to_owned(),
+ DisplayItem::WebGL(_) => "WebGL".to_owned(),
DisplayItem::Border(_) => "Border".to_owned(),
DisplayItem::Gradient(_) => "Gradient".to_owned(),
DisplayItem::RadialGradient(_) => "RadialGradient".to_owned(),
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs
index 75e288e4826..3fc63df7c49 100644
--- a/components/layout/display_list_builder.rs
+++ b/components/layout/display_list_builder.rs
@@ -12,13 +12,13 @@
use app_units::{AU_PER_PX, Au};
use block::{BlockFlow, BlockStackingContextType};
-use canvas_traits::canvas::{CanvasMsg, FromLayoutMsg};
+use canvas_traits::{CanvasData, CanvasMsg, FromLayoutMsg};
use context::LayoutContext;
use euclid::{Transform3D, Point2D, Vector2D, Rect, SideOffsets2D, Size2D, TypedSize2D};
use flex::FlexFlow;
use flow::{BaseFlow, Flow, IS_ABSOLUTELY_POSITIONED};
use flow_ref::FlowRef;
-use fragment::{CanvasFragmentSource, CoordinateSystem, Fragment, ImageFragmentInfo, ScannedTextFragmentInfo};
+use fragment::{CoordinateSystem, Fragment, ImageFragmentInfo, ScannedTextFragmentInfo};
use fragment::{SpecificFragmentInfo, TruncatedFragmentInfo};
use gfx::display_list;
use gfx::display_list::{BLUR_INFLATION_FACTOR, BaseDisplayItem, BorderDetails, BorderDisplayItem};
@@ -28,7 +28,7 @@ use gfx::display_list::{GradientDisplayItem, IframeDisplayItem, ImageBorder, Ima
use gfx::display_list::{LineDisplayItem, NormalBorder, OpaqueNode, PushTextShadowDisplayItem};
use gfx::display_list::{PopTextShadowDisplayItem, RadialGradientDisplayItem, ScrollRoot};
use gfx::display_list::{ScrollRootType, SolidColorDisplayItem, StackingContext, StackingContextType};
-use gfx::display_list::{TextDisplayItem, TextOrientation, WebRenderImageInfo};
+use gfx::display_list::{TextDisplayItem, TextOrientation, WebGLDisplayItem, WebRenderImageInfo};
use gfx_traits::{combine_id_with_fragment_type, FragmentType, StackingContextId};
use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, LAST_FRAGMENT_OF_ELEMENT};
use ipc_channel::ipc;
@@ -1978,22 +1978,15 @@ impl FragmentDisplayListBuilding for Fragment {
let computed_width = canvas_fragment_info.dom_width.to_px();
let computed_height = canvas_fragment_info.dom_height.to_px();
- let (image_key, format) = match canvas_fragment_info.source {
- CanvasFragmentSource::WebGL(image_key) => {
- (image_key, PixelFormat::BGRA8)
+ let canvas_data = match canvas_fragment_info.ipc_renderer {
+ Some(ref ipc_renderer) => {
+ let ipc_renderer = ipc_renderer.lock().unwrap();
+ let (sender, receiver) = ipc::channel().unwrap();
+ ipc_renderer.send(CanvasMsg::FromLayout(
+ FromLayoutMsg::SendData(sender))).unwrap();
+ receiver.recv().unwrap()
},
- CanvasFragmentSource::Image(ref ipc_renderer) => {
- match *ipc_renderer {
- Some(ref ipc_renderer) => {
- let ipc_renderer = ipc_renderer.lock().unwrap();
- let (sender, receiver) = ipc::channel().unwrap();
- ipc_renderer.send(CanvasMsg::FromLayout(
- FromLayoutMsg::SendData(sender))).unwrap();
- (receiver.recv().unwrap().image_key, PixelFormat::BGRA8)
- },
- None => return,
- }
- }
+ None => return,
};
let base = state.create_base_display_item(
@@ -2002,19 +1995,29 @@ impl FragmentDisplayListBuilding for Fragment {
self.node,
self.style.get_cursor(Cursor::Default),
DisplayListSection::Content);
- let display_item = DisplayItem::Image(box ImageDisplayItem {
- base: base,
- webrender_image: WebRenderImageInfo {
- width: computed_width as u32,
- height: computed_height as u32,
- format: format,
- key: Some(image_key),
- },
- image_data: None,
- stretch_size: stacking_relative_content_box.size,
- tile_spacing: Size2D::zero(),
- image_rendering: image_rendering::T::auto,
- });
+ let display_item = match canvas_data {
+ CanvasData::Image(canvas_data) => {
+ DisplayItem::Image(box ImageDisplayItem {
+ base: base,
+ webrender_image: WebRenderImageInfo {
+ width: computed_width as u32,
+ height: computed_height as u32,
+ format: PixelFormat::BGRA8,
+ key: Some(canvas_data.image_key),
+ },
+ image_data: None,
+ stretch_size: stacking_relative_content_box.size,
+ tile_spacing: Size2D::zero(),
+ image_rendering: image_rendering::T::auto,
+ })
+ }
+ CanvasData::WebGL(context_id) => {
+ DisplayItem::WebGL(box WebGLDisplayItem {
+ base: base,
+ context_id: context_id,
+ })
+ }
+ };
state.add_display_item(display_item);
}
diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs
index f4928262e99..2510b185d1c 100644
--- a/components/layout/fragment.rs
+++ b/components/layout/fragment.rs
@@ -8,7 +8,7 @@
use ServoArc;
use app_units::Au;
-use canvas_traits::canvas::CanvasMsg;
+use canvas_traits::CanvasMsg;
use context::{LayoutContext, with_thread_local_font_context};
use euclid::{Transform3D, Point2D, Vector2D, Radians, Rect, Size2D};
use floats::ClearType;
@@ -30,7 +30,7 @@ use msg::constellation_msg::{BrowsingContextId, PipelineId};
use net_traits::image::base::{Image, ImageMetadata};
use net_traits::image_cache::{ImageOrMetadataAvailable, UsePlaceholder};
use range::*;
-use script_layout_interface::{HTMLCanvasData, HTMLCanvasDataSource};
+use script_layout_interface::HTMLCanvasData;
use script_layout_interface::SVGSVGData;
use script_layout_interface::wrapper_traits::{PseudoElementType, ThreadSafeLayoutElement, ThreadSafeLayoutNode};
use serde::ser::{Serialize, SerializeStruct, Serializer};
@@ -53,7 +53,6 @@ use style::values::{self, Either, Auto};
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
use text;
use text::TextRunScanner;
-use webrender_api;
use wrapper::ThreadSafeLayoutNodeHelpers;
// From gfxFontConstants.h in Firefox.
@@ -323,31 +322,17 @@ impl InlineAbsoluteFragmentInfo {
}
#[derive(Clone)]
-pub enum CanvasFragmentSource {
- WebGL(webrender_api::ImageKey),
- Image(Option<Arc<Mutex<IpcSender<CanvasMsg>>>>)
-}
-
-#[derive(Clone)]
pub struct CanvasFragmentInfo {
- pub source: CanvasFragmentSource,
+ pub ipc_renderer: Option<Arc<Mutex<IpcSender<CanvasMsg>>>>,
pub dom_width: Au,
pub dom_height: Au,
}
impl CanvasFragmentInfo {
pub fn new(data: HTMLCanvasData) -> CanvasFragmentInfo {
- let source = match data.source {
- HTMLCanvasDataSource::WebGL(texture_id) => {
- CanvasFragmentSource::WebGL(texture_id)
- },
- HTMLCanvasDataSource::Image(ipc_sender) => {
- CanvasFragmentSource::Image(ipc_sender.map(|renderer| Arc::new(Mutex::new(renderer))))
- }
- };
-
CanvasFragmentInfo {
- source: source,
+ ipc_renderer: data.ipc_renderer
+ .map(|renderer| Arc::new(Mutex::new(renderer))),
dom_width: Au::from_px(data.width as i32),
dom_height: Au::from_px(data.height as i32),
}
diff --git a/components/layout/webrender_helpers.rs b/components/layout/webrender_helpers.rs
index 6e5a774e283..6b8b334d52d 100644
--- a/components/layout/webrender_helpers.rs
+++ b/components/layout/webrender_helpers.rs
@@ -305,6 +305,11 @@ impl WebRenderDisplayItemConverter for DisplayItem {
}
}
}
+ DisplayItem::WebGL(ref item) => {
+ builder.push_webgl_canvas(item.base.bounds.to_rectf(),
+ Some(item.base.local_clip),
+ item.context_id);
+ }
DisplayItem::Border(ref item) => {
let rect = item.base.bounds.to_rectf();
let widths = item.border_widths.to_border_widths();
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index 4168fb4effa..81017cd344e 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -30,11 +30,8 @@
//! `JSTraceable` to a datatype.
use app_units::Au;
-use canvas_traits::canvas::{CanvasGradientStop, LinearGradientStyle, RadialGradientStyle};
-use canvas_traits::canvas::{CompositionOrBlending, LineCapStyle, LineJoinStyle, RepetitionStyle};
-use canvas_traits::webgl::{WebGLBufferId, WebGLFramebufferId, WebGLProgramId, WebGLRenderbufferId};
-use canvas_traits::webgl::{WebGLChan, WebGLContextShareMode, WebGLError, WebGLPipeline, WebGLMsgSender};
-use canvas_traits::webgl::{WebGLReceiver, WebGLSender, WebGLShaderId, WebGLTextureId, WebGLVertexArrayId};
+use canvas_traits::{CanvasGradientStop, LinearGradientStyle, RadialGradientStyle};
+use canvas_traits::{CompositionOrBlending, LineCapStyle, LineJoinStyle, RepetitionStyle};
use cssparser::RGBA;
use devtools_traits::{CSSError, TimelineMarkerType, WorkerId};
use dom::abstractworker::SharedRt;
@@ -108,7 +105,8 @@ use style::stylesheets::keyframes_rule::Keyframe;
use style::values::specified::Length;
use time::Duration;
use uuid::Uuid;
-use webrender_api::ImageKey;
+use webrender_api::{WebGLBufferId, WebGLError, WebGLFramebufferId, WebGLProgramId};
+use webrender_api::{WebGLRenderbufferId, WebGLShaderId, WebGLTextureId, WebGLVertexArrayId};
use webvr_traits::WebVRGamepadHand;
/// A trait to allow tracing (only) DOM objects.
@@ -393,13 +391,8 @@ unsafe_no_jsmanaged_fields!(OpaqueStyleAndLayoutData);
unsafe_no_jsmanaged_fields!(PathBuf);
unsafe_no_jsmanaged_fields!(CSSErrorReporter);
unsafe_no_jsmanaged_fields!(DrawAPaintImageResult);
-unsafe_no_jsmanaged_fields!(ImageKey);
unsafe_no_jsmanaged_fields!(WebGLBufferId);
-unsafe_no_jsmanaged_fields!(WebGLChan);
-unsafe_no_jsmanaged_fields!(WebGLContextShareMode);
unsafe_no_jsmanaged_fields!(WebGLFramebufferId);
-unsafe_no_jsmanaged_fields!(WebGLMsgSender);
-unsafe_no_jsmanaged_fields!(WebGLPipeline);
unsafe_no_jsmanaged_fields!(WebGLProgramId);
unsafe_no_jsmanaged_fields!(WebGLRenderbufferId);
unsafe_no_jsmanaged_fields!(WebGLShaderId);
@@ -473,20 +466,6 @@ unsafe impl<T: Send> JSTraceable for Sender<T> {
}
}
-unsafe impl<T: Send> JSTraceable for WebGLReceiver<T> where T: for<'de> Deserialize<'de> + Serialize {
- #[inline]
- unsafe fn trace(&self, _: *mut JSTracer) {
- // Do nothing
- }
-}
-
-unsafe impl<T: Send> JSTraceable for WebGLSender<T> where T: for<'de> Deserialize<'de> + Serialize {
- #[inline]
- unsafe fn trace(&self, _: *mut JSTracer) {
- // Do nothing
- }
-}
-
unsafe impl JSTraceable for Transform2D<f32> {
#[inline]
unsafe fn trace(&self, _trc: *mut JSTracer) {
diff --git a/components/script/dom/canvasgradient.rs b/components/script/dom/canvasgradient.rs
index 3a0707ab5eb..64df591f760 100644
--- a/components/script/dom/canvasgradient.rs
+++ b/components/script/dom/canvasgradient.rs
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use canvas_traits::canvas::{CanvasGradientStop, FillOrStrokeStyle, LinearGradientStyle, RadialGradientStyle};
+use canvas_traits::{CanvasGradientStop, FillOrStrokeStyle, LinearGradientStyle, RadialGradientStyle};
use cssparser::{Parser, ParserInput, RGBA};
use cssparser::Color as CSSColor;
use dom::bindings::cell::DOMRefCell;
diff --git a/components/script/dom/canvaspattern.rs b/components/script/dom/canvaspattern.rs
index 46bcbedcef0..5d9dd5cb767 100644
--- a/components/script/dom/canvaspattern.rs
+++ b/components/script/dom/canvaspattern.rs
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use canvas_traits::canvas::{FillOrStrokeStyle, RepetitionStyle, SurfaceStyle};
+use canvas_traits::{FillOrStrokeStyle, RepetitionStyle, SurfaceStyle};
use dom::bindings::codegen::Bindings::CanvasPatternBinding;
use dom::bindings::js::Root;
use dom::bindings::reflector::{Reflector, reflect_dom_object};
diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs
index d4fcfae4ab8..55d2ef3ceb4 100644
--- a/components/script/dom/canvasrenderingcontext2d.rs
+++ b/components/script/dom/canvasrenderingcontext2d.rs
@@ -2,10 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use canvas_traits::canvas::{Canvas2dMsg, CanvasMsg};
-use canvas_traits::canvas::{CompositionOrBlending, FillOrStrokeStyle, FillRule};
-use canvas_traits::canvas::{LineCapStyle, LineJoinStyle, LinearGradientStyle};
-use canvas_traits::canvas::{RadialGradientStyle, RepetitionStyle, byte_swap_and_premultiply};
+use canvas_traits::{Canvas2dMsg, CanvasCommonMsg, CanvasMsg};
+use canvas_traits::{CompositionOrBlending, FillOrStrokeStyle, FillRule};
+use canvas_traits::{LineCapStyle, LineJoinStyle, LinearGradientStyle};
+use canvas_traits::{RadialGradientStyle, RepetitionStyle, byte_swap_and_premultiply};
use cssparser::{Parser, ParserInput, RGBA};
use cssparser::Color as CSSColor;
use dom::bindings::cell::DOMRefCell;
@@ -163,7 +163,7 @@ impl CanvasRenderingContext2D {
pub fn set_bitmap_dimensions(&self, size: Size2D<i32>) {
self.reset_to_initial_state();
self.ipc_renderer
- .send(CanvasMsg::Recreate(size))
+ .send(CanvasMsg::Common(CanvasCommonMsg::Recreate(size)))
.unwrap();
}
@@ -173,6 +173,10 @@ impl CanvasRenderingContext2D {
*self.state.borrow_mut() = CanvasContextState::new();
}
+ pub fn ipc_renderer(&self) -> IpcSender<CanvasMsg> {
+ self.ipc_renderer.clone()
+ }
+
fn mark_as_dirty(&self) {
if let Some(ref canvas) = self.canvas {
canvas.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
@@ -1388,7 +1392,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
impl Drop for CanvasRenderingContext2D {
fn drop(&mut self) {
- if let Err(err) = self.ipc_renderer.send(CanvasMsg::Close) {
+ if let Err(err) = self.ipc_renderer.send(CanvasMsg::Common(CanvasCommonMsg::Close)) {
warn!("Could not close canvas: {}", err)
}
}
diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs
index 3d89c08b230..a95ff766171 100644
--- a/components/script/dom/htmlcanvaselement.rs
+++ b/components/script/dom/htmlcanvaselement.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use base64;
-use canvas_traits::canvas::{CanvasMsg, FromScriptMsg};
+use canvas_traits::{CanvasMsg, FromScriptMsg};
use dom::attr::Attr;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasRenderingContext2DMethods;
@@ -30,11 +30,11 @@ use euclid::Size2D;
use html5ever::{LocalName, Prefix};
use image::ColorType;
use image::png::PNGEncoder;
-use ipc_channel::ipc;
+use ipc_channel::ipc::{self, IpcSender};
use js::error::throw_type_error;
use js::jsapi::{HandleValue, JSContext};
use offscreen_gl_context::GLContextAttributes;
-use script_layout_interface::{HTMLCanvasData, HTMLCanvasDataSource};
+use script_layout_interface::HTMLCanvasData;
use std::iter::repeat;
use style::attr::{AttrValue, LengthOrPercentageOrAuto};
@@ -106,22 +106,21 @@ impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
fn data(&self) -> HTMLCanvasData {
unsafe {
let canvas = &*self.unsafe_get();
- let source = match canvas.context.borrow_for_layout().as_ref() {
- Some(&CanvasContext::Context2d(ref context)) => {
- HTMLCanvasDataSource::Image(Some(context.to_layout().get_ipc_renderer()))
- },
- Some(&CanvasContext::WebGL(ref context)) => {
- context.to_layout().canvas_data_source()
- },
- None => {
- HTMLCanvasDataSource::Image(None)
+ let ipc_renderer = canvas.context.borrow_for_layout().as_ref().map(|context| {
+ match *context {
+ CanvasContext::Context2d(ref context) => {
+ context.to_layout().get_ipc_renderer()
+ },
+ CanvasContext::WebGL(ref context) => {
+ context.to_layout().get_ipc_renderer()
+ },
}
- };
+ });
let width_attr = canvas.upcast::<Element>().get_attr_for_layout(&ns!(), &local_name!("width"));
let height_attr = canvas.upcast::<Element>().get_attr_for_layout(&ns!(), &local_name!("height"));
HTMLCanvasData {
- source: source,
+ ipc_renderer: ipc_renderer,
width: width_attr.map_or(DEFAULT_WIDTH, |val| val.as_uint()),
height: height_attr.map_or(DEFAULT_HEIGHT, |val| val.as_uint()),
}
@@ -151,6 +150,15 @@ impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
impl HTMLCanvasElement {
+ pub fn ipc_renderer(&self) -> Option<IpcSender<CanvasMsg>> {
+ self.context.borrow().as_ref().map(|context| {
+ match *context {
+ CanvasContext::Context2d(ref context) => context.ipc_renderer(),
+ CanvasContext::WebGL(ref context) => context.ipc_renderer(),
+ }
+ })
+ }
+
pub fn get_or_init_2d_context(&self) -> Option<Root<CanvasRenderingContext2D>> {
if self.context.borrow().is_none() {
let window = window_from_node(self);
@@ -213,26 +221,22 @@ impl HTMLCanvasElement {
return None
}
- let data = match self.context.borrow().as_ref() {
- Some(&CanvasContext::Context2d(ref context)) => {
- let (sender, receiver) = ipc::channel().unwrap();
- let msg = CanvasMsg::FromScript(FromScriptMsg::SendPixels(sender));
- context.get_ipc_renderer().send(msg).unwrap();
+ let data = if let Some(renderer) = self.ipc_renderer() {
+ let (sender, receiver) = ipc::channel().unwrap();
+ let msg = CanvasMsg::FromScript(FromScriptMsg::SendPixels(sender));
+ renderer.send(msg).unwrap();
- match receiver.recv().unwrap() {
- Some(pixels) => pixels,
- None => {
- return None;
- }
+ match receiver.recv().unwrap() {
+ Some(pixels) => pixels,
+ None => {
+ // TODO(emilio, #14109): Not sure if WebGL canvas is
+ // required for 2d spec, but I think it's not, if so, make
+ // this return a readback from the GL context.
+ return None;
}
- },
- Some(&CanvasContext::WebGL(_)) => {
- // TODO: add a method in WebGLRenderingContext to get the pixels.
- return None;
- },
- None => {
- repeat(0xffu8).take((size.height as usize) * (size.width as usize) * 4).collect()
}
+ } else {
+ repeat(0xffu8).take((size.height as usize) * (size.width as usize) * 4).collect()
};
Some((data, size))
diff --git a/components/script/dom/paintrenderingcontext2d.rs b/components/script/dom/paintrenderingcontext2d.rs
index c6b62b50e15..c3aa9e4c98b 100644
--- a/components/script/dom/paintrenderingcontext2d.rs
+++ b/components/script/dom/paintrenderingcontext2d.rs
@@ -2,9 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use canvas_traits::canvas::CanvasImageData;
-use canvas_traits::canvas::CanvasMsg;
-use canvas_traits::canvas::FromLayoutMsg;
+use canvas_traits::CanvasData;
+use canvas_traits::CanvasMsg;
+use canvas_traits::FromLayoutMsg;
use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasFillRule;
use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasLineCap;
use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasLineJoin;
@@ -58,9 +58,9 @@ impl PaintRenderingContext2D {
PaintRenderingContext2DBinding::Wrap)
}
- pub fn send_data(&self, sender: IpcSender<CanvasImageData>) {
+ pub fn send_data(&self, sender: IpcSender<CanvasData>) {
let msg = CanvasMsg::FromLayout(FromLayoutMsg::SendData(sender));
- let _ = self.context.get_ipc_renderer().send(msg);
+ let _ = self.context.ipc_renderer().send(msg);
}
pub fn take_missing_image_urls(&self) -> Vec<ServoUrl> {
diff --git a/components/script/dom/paintworkletglobalscope.rs b/components/script/dom/paintworkletglobalscope.rs
index 607c432c78a..b0a43cbf25d 100644
--- a/components/script/dom/paintworkletglobalscope.rs
+++ b/components/script/dom/paintworkletglobalscope.rs
@@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+use canvas_traits::CanvasData;
use dom::bindings::callback::CallbackContainer;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::PaintWorkletGlobalScopeBinding;
@@ -297,7 +298,7 @@ impl PaintWorkletGlobalScope {
let (sender, receiver) = ipc::channel().expect("IPC channel creation.");
rendering_context.send_data(sender);
let image_key = match receiver.recv() {
- Ok(data) => Some(data.image_key),
+ Ok(CanvasData::Image(data)) => Some(data.image_key),
_ => None,
};
diff --git a/components/script/dom/vrdisplay.rs b/components/script/dom/vrdisplay.rs
index a36bd27ad29..54f06fb928f 100644
--- a/components/script/dom/vrdisplay.rs
+++ b/components/script/dom/vrdisplay.rs
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use canvas_traits::webgl::{webgl_channel, WebGLReceiver, WebVRCommand};
+use canvas_traits::CanvasMsg;
use core::ops::Deref;
use dom::bindings::callback::ExceptionHandling;
use dom::bindings::cell::DOMRefCell;
@@ -32,7 +32,8 @@ use dom::vrpose::VRPose;
use dom::vrstageparameters::VRStageParameters;
use dom::webglrenderingcontext::WebGLRenderingContext;
use dom_struct::dom_struct;
-use ipc_channel::ipc::{self, IpcSender};
+use ipc_channel::ipc;
+use ipc_channel::ipc::{IpcSender, IpcReceiver};
use js::jsapi::JSContext;
use script_runtime::CommonScriptMsg;
use script_runtime::ScriptThreadEventCategory::WebVREvent;
@@ -42,6 +43,7 @@ use std::mem;
use std::rc::Rc;
use std::sync::mpsc;
use std::thread;
+use webrender_api::VRCompositorCommand;
use webvr_traits::{WebVRDisplayData, WebVRDisplayEvent, WebVRFrameData, WebVRLayer, WebVRMsg};
#[dom_struct]
@@ -69,7 +71,7 @@ pub struct VRDisplay {
// Compositor VRFrameData synchonization
frame_data_status: Cell<VRFrameDataStatus>,
#[ignore_heap_size_of = "channels are hard"]
- frame_data_receiver: DOMRefCell<Option<WebGLReceiver<Result<Vec<u8>, ()>>>>,
+ frame_data_receiver: DOMRefCell<Option<IpcReceiver<Result<Vec<u8>, ()>>>>,
running_display_raf: Cell<bool>,
paused: Cell<bool>,
stopped_on_pause: Cell<bool>,
@@ -384,10 +386,11 @@ impl VRDisplayMethods for VRDisplay {
return;
}
- let display_id = self.display.borrow().display_id;
+ let api_sender = self.layer_ctx.get().unwrap().ipc_renderer();
+ let display_id = self.display.borrow().display_id as u64;
let layer = self.layer.borrow();
- let msg = WebVRCommand::SubmitFrame(display_id, layer.left_bounds, layer.right_bounds);
- self.layer_ctx.get().unwrap().send_vr_command(msg);
+ let msg = VRCompositorCommand::SubmitFrame(display_id, layer.left_bounds, layer.right_bounds);
+ api_sender.send(CanvasMsg::WebVR(msg)).unwrap();
}
// https://w3c.github.io/webvr/spec/1.1/#dom-vrdisplay-getlayers
@@ -486,11 +489,11 @@ impl VRDisplay {
fn init_present(&self) {
self.presenting.set(true);
- let (sync_sender, sync_receiver) = webgl_channel().unwrap();
+ let (sync_sender, sync_receiver) = ipc::channel().unwrap();
*self.frame_data_receiver.borrow_mut() = Some(sync_receiver);
- let display_id = self.display.borrow().display_id;
- let api_sender = self.layer_ctx.get().unwrap().webgl_sender();
+ let display_id = self.display.borrow().display_id as u64;
+ let api_sender = self.layer_ctx.get().unwrap().ipc_renderer();
let js_sender = self.global().script_chan();
let address = Trusted::new(&*self);
let near_init = self.depth_near.get();
@@ -508,7 +511,7 @@ impl VRDisplay {
let mut far = far_init;
// Initialize compositor
- api_sender.send_vr(WebVRCommand::Create(display_id)).unwrap();
+ api_sender.send(CanvasMsg::WebVR(VRCompositorCommand::Create(display_id))).unwrap();
loop {
// Run RAF callbacks on JavaScript thread
let msg = box NotifyDisplayRAF {
@@ -518,8 +521,8 @@ impl VRDisplay {
js_sender.send(CommonScriptMsg::RunnableMsg(WebVREvent, msg)).unwrap();
// Run Sync Poses in parallell on Render thread
- let msg = WebVRCommand::SyncPoses(display_id, near, far, sync_sender.clone());
- api_sender.send_vr(msg).unwrap();
+ let msg = VRCompositorCommand::SyncPoses(display_id, near, far, sync_sender.clone());
+ api_sender.send(CanvasMsg::WebVR(msg)).unwrap();
// Wait until both SyncPoses & RAF ends
if let Ok(depth) = raf_receiver.recv().unwrap() {
@@ -538,9 +541,10 @@ impl VRDisplay {
self.presenting.set(false);
*self.frame_data_receiver.borrow_mut() = None;
- let api_sender = self.layer_ctx.get().unwrap().webgl_sender();
- let display_id = self.display.borrow().display_id;
- api_sender.send_vr(WebVRCommand::Release(display_id)).unwrap();
+ let api_sender = self.layer_ctx.get().unwrap().ipc_renderer();
+ let display_id = self.display.borrow().display_id as u64;
+ let msg = VRCompositorCommand::Release(display_id);
+ api_sender.send(CanvasMsg::WebVR(msg)).unwrap();
}
// Only called when the JSContext is destroyed while presenting.
@@ -623,7 +627,7 @@ impl Runnable for NotifyDisplayRAF {
}
-// WebVR Spec: If the number of values in the leftBounds/rightBounds arrays
+// WebVR Spect: If the number of values in the leftBounds/rightBounds arrays
// is not 0 or 4 for any of the passed layers the promise is rejected
fn parse_bounds(src: &Option<Vec<Finite<f32>>>, dst: &mut [f32; 4]) -> Result<(), &'static str> {
match *src {
diff --git a/components/script/dom/webgl_extensions/ext/oesvertexarrayobject.rs b/components/script/dom/webgl_extensions/ext/oesvertexarrayobject.rs
index 48385a3d50f..097742f5441 100644
--- a/components/script/dom/webgl_extensions/ext/oesvertexarrayobject.rs
+++ b/components/script/dom/webgl_extensions/ext/oesvertexarrayobject.rs
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use canvas_traits::webgl::{webgl_channel, WebGLCommand, WebGLError};
+use canvas_traits::CanvasMsg;
use dom::bindings::codegen::Bindings::OESVertexArrayObjectBinding::{self, OESVertexArrayObjectMethods};
use dom::bindings::codegen::Bindings::OESVertexArrayObjectBinding::OESVertexArrayObjectConstants;
use dom::bindings::js::{JS, MutNullableJS, Root};
@@ -15,6 +15,7 @@ use js::jsapi::JSContext;
use js::jsval::{JSVal, NullValue};
use std::iter;
use super::{WebGLExtension, WebGLExtensions};
+use webrender_api::{self, WebGLCommand, WebGLError};
#[dom_struct]
pub struct OESVertexArrayObject {
@@ -47,8 +48,8 @@ impl OESVertexArrayObject {
impl OESVertexArrayObjectMethods for OESVertexArrayObject {
// https://www.khronos.org/registry/webgl/extensions/OES_vertex_array_object/
fn CreateVertexArrayOES(&self) -> Option<Root<WebGLVertexArrayObjectOES>> {
- let (sender, receiver) = webgl_channel().unwrap();
- self.ctx.send_command(WebGLCommand::CreateVertexArray(sender));
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ self.ctx.send_renderer_message(CanvasMsg::WebGL(WebGLCommand::CreateVertexArray(sender)));
let result = receiver.recv().unwrap();
result.map(|vao_id| WebGLVertexArrayObjectOES::new(&self.global(), vao_id))
@@ -65,7 +66,7 @@ impl OESVertexArrayObjectMethods for OESVertexArrayObject {
if let Some(bound_vao) = self.bound_vao.get() {
if bound_vao.id() == vao.id() {
self.bound_vao.set(None);
- self.ctx.send_command(WebGLCommand::BindVertexArray(None));
+ self.ctx.send_renderer_message(CanvasMsg::WebGL(WebGLCommand::BindVertexArray(None)));
}
}
@@ -79,7 +80,7 @@ impl OESVertexArrayObjectMethods for OESVertexArrayObject {
}
// Delete the vao
- self.ctx.send_command(WebGLCommand::DeleteVertexArray(vao.id()));
+ self.ctx.send_renderer_message(CanvasMsg::WebGL(WebGLCommand::DeleteVertexArray(vao.id())));
vao.set_deleted();
}
}
@@ -113,7 +114,7 @@ impl OESVertexArrayObjectMethods for OESVertexArrayObject {
return;
}
- self.ctx.send_command(WebGLCommand::BindVertexArray(Some(vao.id())));
+ self.ctx.send_renderer_message(CanvasMsg::WebGL(WebGLCommand::BindVertexArray(Some(vao.id()))));
vao.set_ever_bound();
self.bound_vao.set(Some(&vao));
@@ -123,7 +124,7 @@ impl OESVertexArrayObjectMethods for OESVertexArrayObject {
let element_array = vao.bound_buffer_element_array();
self.ctx.set_bound_buffer_element_array(element_array.as_ref().map(|buffer| &**buffer));
} else {
- self.ctx.send_command(WebGLCommand::BindVertexArray(None));
+ self.ctx.send_renderer_message(CanvasMsg::WebGL(WebGLCommand::BindVertexArray(None)));
self.bound_vao.set(None);
self.ctx.set_bound_attrib_buffers(iter::empty());
}
diff --git a/components/script/dom/webgl_extensions/ext/webglvertexarrayobjectoes.rs b/components/script/dom/webgl_extensions/ext/webglvertexarrayobjectoes.rs
index 2fe109cafa6..e44b7c9bc42 100644
--- a/components/script/dom/webgl_extensions/ext/webglvertexarrayobjectoes.rs
+++ b/components/script/dom/webgl_extensions/ext/webglvertexarrayobjectoes.rs
@@ -2,7 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use canvas_traits::webgl::WebGLVertexArrayId;
use core::cell::Ref;
use core::iter::FromIterator;
use dom::bindings::cell::DOMRefCell;
@@ -16,6 +15,7 @@ use dom::webglobject::WebGLObject;
use dom_struct::dom_struct;
use std::cell::Cell;
use std::collections::HashMap;
+use webrender_api::WebGLVertexArrayId;
#[dom_struct]
pub struct WebGLVertexArrayObjectOES {
diff --git a/components/script/dom/webgl_extensions/extensions.rs b/components/script/dom/webgl_extensions/extensions.rs
index 2a780b129ff..28c32dede64 100644
--- a/components/script/dom/webgl_extensions/extensions.rs
+++ b/components/script/dom/webgl_extensions/extensions.rs
@@ -2,7 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use canvas_traits::webgl::WebGLError;
use core::iter::FromIterator;
use core::nonzero::NonZero;
use dom::bindings::cell::DOMRefCell;
@@ -20,6 +19,7 @@ use std::cell::Ref;
use std::collections::{HashMap, HashSet};
use super::{ext, WebGLExtension};
use super::wrapper::{WebGLExtensionWrapper, TypedWebGLExtensionWrapper};
+use webrender_api::WebGLError;
// Data types that are implemented for texImage2D and texSubImage2D in WebGLRenderingContext
// but must trigger a InvalidValue error until the related WebGL Extensions are enabled.
diff --git a/components/script/dom/webgl_validations/tex_image_2d.rs b/components/script/dom/webgl_validations/tex_image_2d.rs
index cd5320453c7..41b2795bc14 100644
--- a/components/script/dom/webgl_validations/tex_image_2d.rs
+++ b/components/script/dom/webgl_validations/tex_image_2d.rs
@@ -2,13 +2,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use canvas_traits::webgl::WebGLError::*;
use dom::bindings::js::Root;
use dom::webglrenderingcontext::WebGLRenderingContext;
use dom::webgltexture::WebGLTexture;
use std::{self, fmt};
use super::WebGLValidator;
use super::types::{TexImageTarget, TexDataType, TexFormat};
+use webrender_api::WebGLError::*;
/// The errors that the texImage* family of functions can generate.
#[derive(Debug)]
diff --git a/components/script/dom/webglbuffer.rs b/components/script/dom/webglbuffer.rs
index 96db4466d56..448956a9b90 100644
--- a/components/script/dom/webglbuffer.rs
+++ b/components/script/dom/webglbuffer.rs
@@ -3,8 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
-use canvas_traits::webgl::{WebGLBufferId, WebGLCommand, WebGLError, WebGLMsgSender, WebGLResult, WebGLVertexArrayId};
-use canvas_traits::webgl::webgl_channel;
+use canvas_traits::CanvasMsg;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::WebGLBufferBinding;
use dom::bindings::js::Root;
@@ -12,9 +11,11 @@ use dom::bindings::reflector::reflect_dom_object;
use dom::webglobject::WebGLObject;
use dom::window::Window;
use dom_struct::dom_struct;
+use ipc_channel::ipc::IpcSender;
use std::cell::Cell;
use std::collections::HashSet;
-
+use webrender_api;
+use webrender_api::{WebGLBufferId, WebGLCommand, WebGLError, WebGLResult, WebGLVertexArrayId};
#[dom_struct]
pub struct WebGLBuffer {
@@ -28,11 +29,11 @@ pub struct WebGLBuffer {
vao_references: DOMRefCell<Option<HashSet<WebGLVertexArrayId>>>,
pending_delete: Cell<bool>,
#[ignore_heap_size_of = "Defined in ipc-channel"]
- renderer: WebGLMsgSender,
+ renderer: IpcSender<CanvasMsg>,
}
impl WebGLBuffer {
- fn new_inherited(renderer: WebGLMsgSender,
+ fn new_inherited(renderer: IpcSender<CanvasMsg>,
id: WebGLBufferId)
-> WebGLBuffer {
WebGLBuffer {
@@ -47,17 +48,17 @@ impl WebGLBuffer {
}
}
- pub fn maybe_new(window: &Window, renderer: WebGLMsgSender)
+ pub fn maybe_new(window: &Window, renderer: IpcSender<CanvasMsg>)
-> Option<Root<WebGLBuffer>> {
- let (sender, receiver) = webgl_channel().unwrap();
- renderer.send(WebGLCommand::CreateBuffer(sender)).unwrap();
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ renderer.send(CanvasMsg::WebGL(WebGLCommand::CreateBuffer(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|buffer_id| WebGLBuffer::new(window, renderer, buffer_id))
}
pub fn new(window: &Window,
- renderer: WebGLMsgSender,
+ renderer: IpcSender<CanvasMsg>,
id: WebGLBufferId)
-> Root<WebGLBuffer> {
reflect_dom_object(box WebGLBuffer::new_inherited(renderer, id),
@@ -80,7 +81,7 @@ impl WebGLBuffer {
} else {
self.target.set(Some(target));
}
- let msg = WebGLCommand::BindBuffer(target, Some(self.id));
+ let msg = CanvasMsg::WebGL(WebGLCommand::BindBuffer(target, Some(self.id)));
self.renderer.send(msg).unwrap();
Ok(())
@@ -93,7 +94,9 @@ impl WebGLBuffer {
}
}
self.capacity.set(data.len());
- self.renderer.send(WebGLCommand::BufferData(target, data.to_vec(), usage)).unwrap();
+ self.renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::BufferData(target, data.to_vec(), usage)))
+ .unwrap();
Ok(())
}
@@ -105,7 +108,7 @@ impl WebGLBuffer {
pub fn delete(&self) {
if !self.is_deleted.get() {
self.is_deleted.set(true);
- let _ = self.renderer.send(WebGLCommand::DeleteBuffer(self.id));
+ let _ = self.renderer.send(CanvasMsg::WebGL(WebGLCommand::DeleteBuffer(self.id)));
}
}
@@ -141,7 +144,7 @@ impl WebGLBuffer {
if let Some(ref mut vao_refs) = *self.vao_references.borrow_mut() {
if vao_refs.take(&id).is_some() && self.pending_delete.get() {
// WebGL spec: The deleted buffers should no longer be valid when the VAOs are deleted
- let _ = self.renderer.send(WebGLCommand::DeleteBuffer(self.id));
+ let _ = self.renderer.send(CanvasMsg::WebGL(WebGLCommand::DeleteBuffer(self.id)));
self.is_deleted.set(true);
}
}
diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs
index 7a6b1090064..bb486c80c38 100644
--- a/components/script/dom/webglframebuffer.rs
+++ b/components/script/dom/webglframebuffer.rs
@@ -3,9 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
-use canvas_traits::webgl::{WebGLCommand, WebGLFramebufferBindingRequest, WebGLFramebufferId};
-use canvas_traits::webgl::{WebGLMsgSender, WebGLResult, WebGLError};
-use canvas_traits::webgl::webgl_channel;
+use canvas_traits::CanvasMsg;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::WebGLFramebufferBinding;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
@@ -16,7 +14,10 @@ use dom::webglrenderbuffer::WebGLRenderbuffer;
use dom::webgltexture::WebGLTexture;
use dom::window::Window;
use dom_struct::dom_struct;
+use ipc_channel::ipc::IpcSender;
use std::cell::Cell;
+use webrender_api;
+use webrender_api::{WebGLCommand, WebGLFramebufferBindingRequest, WebGLFramebufferId, WebGLResult, WebGLError};
#[must_root]
#[derive(JSTraceable, Clone, HeapSizeOf)]
@@ -35,7 +36,7 @@ pub struct WebGLFramebuffer {
size: Cell<Option<(i32, i32)>>,
status: Cell<u32>,
#[ignore_heap_size_of = "Defined in ipc-channel"]
- renderer: WebGLMsgSender,
+ renderer: IpcSender<CanvasMsg>,
// The attachment points for textures and renderbuffers on this
// FBO.
@@ -46,7 +47,7 @@ pub struct WebGLFramebuffer {
}
impl WebGLFramebuffer {
- fn new_inherited(renderer: WebGLMsgSender,
+ fn new_inherited(renderer: IpcSender<CanvasMsg>,
id: WebGLFramebufferId)
-> WebGLFramebuffer {
WebGLFramebuffer {
@@ -64,17 +65,17 @@ impl WebGLFramebuffer {
}
}
- pub fn maybe_new(window: &Window, renderer: WebGLMsgSender)
+ pub fn maybe_new(window: &Window, renderer: IpcSender<CanvasMsg>)
-> Option<Root<WebGLFramebuffer>> {
- let (sender, receiver) = webgl_channel().unwrap();
- renderer.send(WebGLCommand::CreateFramebuffer(sender)).unwrap();
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ renderer.send(CanvasMsg::WebGL(WebGLCommand::CreateFramebuffer(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|fb_id| WebGLFramebuffer::new(window, renderer, fb_id))
}
pub fn new(window: &Window,
- renderer: WebGLMsgSender,
+ renderer: IpcSender<CanvasMsg>,
id: WebGLFramebufferId)
-> Root<WebGLFramebuffer> {
reflect_dom_object(box WebGLFramebuffer::new_inherited(renderer, id),
@@ -97,13 +98,13 @@ impl WebGLFramebuffer {
self.target.set(Some(target));
let cmd = WebGLCommand::BindFramebuffer(target, WebGLFramebufferBindingRequest::Explicit(self.id));
- self.renderer.send(cmd).unwrap();
+ self.renderer.send(CanvasMsg::WebGL(cmd)).unwrap();
}
pub fn delete(&self) {
if !self.is_deleted.get() {
self.is_deleted.set(true);
- let _ = self.renderer.send(WebGLCommand::DeleteFramebuffer(self.id));
+ let _ = self.renderer.send(CanvasMsg::WebGL(WebGLCommand::DeleteFramebuffer(self.id)));
}
}
@@ -204,10 +205,10 @@ impl WebGLFramebuffer {
}
};
- self.renderer.send(WebGLCommand::FramebufferRenderbuffer(constants::FRAMEBUFFER,
- attachment,
- constants::RENDERBUFFER,
- rb_id)).unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::FramebufferRenderbuffer(constants::FRAMEBUFFER,
+ attachment,
+ constants::RENDERBUFFER,
+ rb_id))).unwrap();
self.update_status();
Ok(())
@@ -280,11 +281,11 @@ impl WebGLFramebuffer {
}
};
- self.renderer.send(WebGLCommand::FramebufferTexture2D(constants::FRAMEBUFFER,
- attachment,
- textarget,
- tex_id,
- level)).unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::FramebufferTexture2D(constants::FRAMEBUFFER,
+ attachment,
+ textarget,
+ tex_id,
+ level))).unwrap();
self.update_status();
Ok(())
diff --git a/components/script/dom/webglprogram.rs b/components/script/dom/webglprogram.rs
index 6c298bb83fb..c76a2f3da18 100644
--- a/components/script/dom/webglprogram.rs
+++ b/components/script/dom/webglprogram.rs
@@ -3,8 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
-use canvas_traits::webgl::{WebGLCommand, WebGLError, WebGLMsgSender, WebGLParameter, WebGLProgramId, WebGLResult};
-use canvas_traits::webgl::webgl_channel;
+use canvas_traits::CanvasMsg;
use dom::bindings::codegen::Bindings::WebGLProgramBinding;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use dom::bindings::js::{MutNullableJS, Root};
@@ -16,7 +15,10 @@ use dom::webglrenderingcontext::MAX_UNIFORM_AND_ATTRIBUTE_LEN;
use dom::webglshader::WebGLShader;
use dom::window::Window;
use dom_struct::dom_struct;
+use ipc_channel::ipc::IpcSender;
use std::cell::Cell;
+use webrender_api;
+use webrender_api::{WebGLCommand, WebGLError, WebGLParameter, WebGLProgramId, WebGLResult};
#[dom_struct]
pub struct WebGLProgram {
@@ -28,11 +30,11 @@ pub struct WebGLProgram {
fragment_shader: MutNullableJS<WebGLShader>,
vertex_shader: MutNullableJS<WebGLShader>,
#[ignore_heap_size_of = "Defined in ipc-channel"]
- renderer: WebGLMsgSender,
+ renderer: IpcSender<CanvasMsg>,
}
impl WebGLProgram {
- fn new_inherited(renderer: WebGLMsgSender,
+ fn new_inherited(renderer: IpcSender<CanvasMsg>,
id: WebGLProgramId)
-> WebGLProgram {
WebGLProgram {
@@ -47,17 +49,17 @@ impl WebGLProgram {
}
}
- pub fn maybe_new(window: &Window, renderer: WebGLMsgSender)
+ pub fn maybe_new(window: &Window, renderer: IpcSender<CanvasMsg>)
-> Option<Root<WebGLProgram>> {
- let (sender, receiver) = webgl_channel().unwrap();
- renderer.send(WebGLCommand::CreateProgram(sender)).unwrap();
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ renderer.send(CanvasMsg::WebGL(WebGLCommand::CreateProgram(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|program_id| WebGLProgram::new(window, renderer, program_id))
}
pub fn new(window: &Window,
- renderer: WebGLMsgSender,
+ renderer: IpcSender<CanvasMsg>,
id: WebGLProgramId)
-> Root<WebGLProgram> {
reflect_dom_object(box WebGLProgram::new_inherited(renderer, id),
@@ -76,7 +78,7 @@ impl WebGLProgram {
pub fn delete(&self) {
if !self.is_deleted.get() {
self.is_deleted.set(true);
- let _ = self.renderer.send(WebGLCommand::DeleteProgram(self.id));
+ let _ = self.renderer.send(CanvasMsg::WebGL(WebGLCommand::DeleteProgram(self.id)));
if let Some(shader) = self.fragment_shader.get() {
shader.decrement_attached_counter();
@@ -115,7 +117,7 @@ impl WebGLProgram {
}
self.linked.set(true);
- self.renderer.send(WebGLCommand::LinkProgram(self.id)).unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::LinkProgram(self.id))).unwrap();
Ok(())
}
@@ -128,7 +130,7 @@ impl WebGLProgram {
return Err(WebGLError::InvalidOperation);
}
- self.renderer.send(WebGLCommand::UseProgram(self.id)).unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::UseProgram(self.id))).unwrap();
Ok(())
}
@@ -137,7 +139,7 @@ impl WebGLProgram {
if self.is_deleted() {
return Err(WebGLError::InvalidOperation);
}
- self.renderer.send(WebGLCommand::ValidateProgram(self.id)).unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::ValidateProgram(self.id))).unwrap();
Ok(())
}
@@ -164,7 +166,7 @@ impl WebGLProgram {
shader_slot.set(Some(shader));
shader.increment_attached_counter();
- self.renderer.send(WebGLCommand::AttachShader(self.id, shader.id())).unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::AttachShader(self.id, shader.id()))).unwrap();
Ok(())
}
@@ -194,7 +196,7 @@ impl WebGLProgram {
shader_slot.set(None);
shader.decrement_attached_counter();
- self.renderer.send(WebGLCommand::DetachShader(self.id, shader.id())).unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::DetachShader(self.id, shader.id()))).unwrap();
Ok(())
}
@@ -214,7 +216,7 @@ impl WebGLProgram {
}
self.renderer
- .send(WebGLCommand::BindAttribLocation(self.id, index, String::from(name)))
+ .send(CanvasMsg::WebGL(WebGLCommand::BindAttribLocation(self.id, index, String::from(name))))
.unwrap();
Ok(())
}
@@ -223,9 +225,9 @@ impl WebGLProgram {
if self.is_deleted() {
return Err(WebGLError::InvalidValue);
}
- let (sender, receiver) = webgl_channel().unwrap();
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
self.renderer
- .send(WebGLCommand::GetActiveUniform(self.id, index, sender))
+ .send(CanvasMsg::WebGL(WebGLCommand::GetActiveUniform(self.id, index, sender)))
.unwrap();
receiver.recv().unwrap().map(|(size, ty, name)|
@@ -237,9 +239,9 @@ impl WebGLProgram {
if self.is_deleted() {
return Err(WebGLError::InvalidValue);
}
- let (sender, receiver) = webgl_channel().unwrap();
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
self.renderer
- .send(WebGLCommand::GetActiveAttrib(self.id, index, sender))
+ .send(CanvasMsg::WebGL(WebGLCommand::GetActiveAttrib(self.id, index, sender)))
.unwrap();
receiver.recv().unwrap().map(|(size, ty, name)|
@@ -264,9 +266,9 @@ impl WebGLProgram {
return Ok(None);
}
- let (sender, receiver) = webgl_channel().unwrap();
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
self.renderer
- .send(WebGLCommand::GetAttribLocation(self.id, String::from(name), sender))
+ .send(CanvasMsg::WebGL(WebGLCommand::GetAttribLocation(self.id, String::from(name), sender)))
.unwrap();
Ok(receiver.recv().unwrap())
}
@@ -285,9 +287,9 @@ impl WebGLProgram {
return Ok(None);
}
- let (sender, receiver) = webgl_channel().unwrap();
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
self.renderer
- .send(WebGLCommand::GetUniformLocation(self.id, String::from(name), sender))
+ .send(CanvasMsg::WebGL(WebGLCommand::GetUniformLocation(self.id, String::from(name), sender)))
.unwrap();
Ok(receiver.recv().unwrap())
}
@@ -306,15 +308,15 @@ impl WebGLProgram {
return Ok("One or more shaders failed to compile".to_string());
}
}
- let (sender, receiver) = webgl_channel().unwrap();
- self.renderer.send(WebGLCommand::GetProgramInfoLog(self.id, sender)).unwrap();
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::GetProgramInfoLog(self.id, sender))).unwrap();
Ok(receiver.recv().unwrap())
}
/// glGetProgramParameter
pub fn parameter(&self, param_id: u32) -> WebGLResult<WebGLParameter> {
- let (sender, receiver) = webgl_channel().unwrap();
- self.renderer.send(WebGLCommand::GetProgramParameter(self.id, param_id, sender)).unwrap();
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::GetProgramParameter(self.id, param_id, sender))).unwrap();
receiver.recv().unwrap()
}
}
diff --git a/components/script/dom/webglrenderbuffer.rs b/components/script/dom/webglrenderbuffer.rs
index 9a855651cc9..03589365c43 100644
--- a/components/script/dom/webglrenderbuffer.rs
+++ b/components/script/dom/webglrenderbuffer.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
-use canvas_traits::webgl::{webgl_channel, WebGLCommand, WebGLError, WebGLMsgSender, WebGLRenderbufferId, WebGLResult};
+use canvas_traits::CanvasMsg;
use dom::bindings::codegen::Bindings::WebGLRenderbufferBinding;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use dom::bindings::js::Root;
@@ -11,7 +11,10 @@ use dom::bindings::reflector::reflect_dom_object;
use dom::webglobject::WebGLObject;
use dom::window::Window;
use dom_struct::dom_struct;
+use ipc_channel::ipc::IpcSender;
use std::cell::Cell;
+use webrender_api;
+use webrender_api::{WebGLCommand, WebGLRenderbufferId, WebGLResult, WebGLError};
#[dom_struct]
pub struct WebGLRenderbuffer {
@@ -22,11 +25,11 @@ pub struct WebGLRenderbuffer {
size: Cell<Option<(i32, i32)>>,
internal_format: Cell<Option<u32>>,
#[ignore_heap_size_of = "Defined in ipc-channel"]
- renderer: WebGLMsgSender,
+ renderer: IpcSender<CanvasMsg>,
}
impl WebGLRenderbuffer {
- fn new_inherited(renderer: WebGLMsgSender,
+ fn new_inherited(renderer: IpcSender<CanvasMsg>,
id: WebGLRenderbufferId)
-> WebGLRenderbuffer {
WebGLRenderbuffer {
@@ -40,17 +43,17 @@ impl WebGLRenderbuffer {
}
}
- pub fn maybe_new(window: &Window, renderer: WebGLMsgSender)
+ pub fn maybe_new(window: &Window, renderer: IpcSender<CanvasMsg>)
-> Option<Root<WebGLRenderbuffer>> {
- let (sender, receiver) = webgl_channel().unwrap();
- renderer.send(WebGLCommand::CreateRenderbuffer(sender)).unwrap();
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ renderer.send(CanvasMsg::WebGL(WebGLCommand::CreateRenderbuffer(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|renderbuffer_id| WebGLRenderbuffer::new(window, renderer, renderbuffer_id))
}
pub fn new(window: &Window,
- renderer: WebGLMsgSender,
+ renderer: IpcSender<CanvasMsg>,
id: WebGLRenderbufferId)
-> Root<WebGLRenderbuffer> {
reflect_dom_object(box WebGLRenderbuffer::new_inherited(renderer, id),
@@ -71,14 +74,14 @@ impl WebGLRenderbuffer {
pub fn bind(&self, target: u32) {
self.ever_bound.set(true);
- let msg = WebGLCommand::BindRenderbuffer(target, Some(self.id));
+ let msg = CanvasMsg::WebGL(WebGLCommand::BindRenderbuffer(target, Some(self.id)));
self.renderer.send(msg).unwrap();
}
pub fn delete(&self) {
if !self.is_deleted.get() {
self.is_deleted.set(true);
- let _ = self.renderer.send(WebGLCommand::DeleteRenderbuffer(self.id));
+ let _ = self.renderer.send(CanvasMsg::WebGL(WebGLCommand::DeleteRenderbuffer(self.id)));
}
}
@@ -107,7 +110,8 @@ impl WebGLRenderbuffer {
// FIXME: Invalidate completeness after the call
- let msg = WebGLCommand::RenderbufferStorage(constants::RENDERBUFFER, internal_format, width, height);
+ let msg = CanvasMsg::WebGL(WebGLCommand::RenderbufferStorage(constants::RENDERBUFFER,
+ internal_format, width, height));
self.renderer.send(msg).unwrap();
self.size.set(Some((width, height)));
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index c45362b4fe2..20fe133e02c 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -3,11 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use byteorder::{NativeEndian, ReadBytesExt, WriteBytesExt};
-use canvas_traits::canvas::{byte_swap, multiply_u8_pixel};
-use canvas_traits::webgl::{WebGLContextShareMode, WebGLCommand, WebGLError};
-use canvas_traits::webgl::{WebGLFramebufferBindingRequest, WebGLMsg, WebGLMsgSender, WebGLParameter, WebVRCommand};
-use canvas_traits::webgl::WebGLError::*;
-use canvas_traits::webgl::webgl_channel;
+use canvas_traits::{CanvasCommonMsg, CanvasMsg, byte_swap, multiply_u8_pixel};
use core::cell::Ref;
use core::iter::FromIterator;
use core::nonzero::NonZero;
@@ -23,6 +19,7 @@ use dom::bindings::js::{JS, LayoutJS, MutNullableJS, Root};
use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::event::{Event, EventBubbles, EventCancelable};
+use dom::globalscope::GlobalScope;
use dom::htmlcanvaselement::HTMLCanvasElement;
use dom::htmlcanvaselement::utils as canvas_utils;
use dom::node::{Node, NodeDamage, window_from_node};
@@ -45,6 +42,7 @@ use dom::window::Window;
use dom_struct::dom_struct;
use euclid::Size2D;
use half::f16;
+use ipc_channel::ipc::{self, IpcSender};
use js::conversions::ConversionBehavior;
use js::jsapi::{JSContext, JSObject, Type, Rooted};
use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UndefinedValue};
@@ -52,11 +50,13 @@ use js::typedarray::{TypedArray, TypedArrayElement, Float32, Int32};
use net_traits::image::base::PixelFormat;
use net_traits::image_cache::ImageResponse;
use offscreen_gl_context::{GLContextAttributes, GLLimits};
-use script_layout_interface::HTMLCanvasDataSource;
+use script_traits::ScriptMsg;
use servo_config::prefs::PREFS;
use std::cell::Cell;
use std::collections::HashMap;
use webrender_api;
+use webrender_api::{WebGLCommand, WebGLError, WebGLFramebufferBindingRequest, WebGLParameter};
+use webrender_api::WebGLError::*;
type ImagePixelResult = Result<(Vec<u8>, Size2D<i32>, bool), ()>;
pub const MAX_UNIFORM_AND_ATTRIBUTE_LEN: usize = 256;
@@ -92,7 +92,9 @@ macro_rules! handle_object_deletion {
}
if let Some(command) = $unbind_command {
- $self_.send_command(command);
+ $self_.ipc_renderer
+ .send(CanvasMsg::WebGL(command))
+ .unwrap();
}
}
};
@@ -133,15 +135,12 @@ bitflags! {
#[dom_struct]
pub struct WebGLRenderingContext {
reflector_: Reflector,
- #[ignore_heap_size_of = "Channels are hard"]
- webgl_sender: WebGLMsgSender,
- #[ignore_heap_size_of = "Defined in webrender"]
- webrender_image: Cell<Option<webrender_api::ImageKey>>,
- share_mode: WebGLContextShareMode,
+ #[ignore_heap_size_of = "Defined in ipc-channel"]
+ ipc_renderer: IpcSender<CanvasMsg>,
#[ignore_heap_size_of = "Defined in offscreen_gl_context"]
limits: GLLimits,
canvas: JS<HTMLCanvasElement>,
- #[ignore_heap_size_of = "Defined in canvas_traits"]
+ #[ignore_heap_size_of = "Defined in webrender_api"]
last_error: Cell<Option<WebGLError>>,
texture_unpacking_settings: Cell<TextureUnpacking>,
texture_unpacking_alignment: Cell<u32>,
@@ -159,7 +158,7 @@ pub struct WebGLRenderingContext {
current_scissor: Cell<(i32, i32, i32, i32)>,
#[ignore_heap_size_of = "Because it's small"]
current_clear_color: Cell<(f32, f32, f32, f32)>,
- extension_manager: WebGLExtensions,
+ extension_manager: WebGLExtensions
}
impl WebGLRenderingContext {
@@ -172,19 +171,17 @@ impl WebGLRenderingContext {
return Err("WebGL context creation error forced by pref `webgl.testing.context_creation_error`".into());
}
- let (sender, receiver) = webgl_channel().unwrap();
- let webgl_chan = window.webgl_chan();
- webgl_chan.send(WebGLMsg::CreateContext(size, attrs, sender))
- .unwrap();
+ let (sender, receiver) = ipc::channel().unwrap();
+ let script_to_constellation_chan = window.upcast::<GlobalScope>().script_to_constellation_chan();
+ script_to_constellation_chan.send(ScriptMsg::CreateWebGLPaintThread(size, attrs, sender))
+ .unwrap();
let result = receiver.recv().unwrap();
- result.map(|ctx_data| {
+ result.map(|(ipc_renderer, context_limits)| {
WebGLRenderingContext {
reflector_: Reflector::new(),
- webgl_sender: ctx_data.sender,
- webrender_image: Cell::new(None),
- share_mode: ctx_data.share_mode,
- limits: ctx_data.limits,
+ ipc_renderer: ipc_renderer,
+ limits: context_limits,
canvas: JS::from_ref(canvas),
last_error: Cell::new(None),
texture_unpacking_settings: Cell::new(CONVERT_COLORSPACE),
@@ -256,43 +253,31 @@ impl WebGLRenderingContext {
}
pub fn recreate(&self, size: Size2D<i32>) {
- let (sender, receiver) = webgl_channel().unwrap();
- self.webgl_sender.send_resize(size, sender).unwrap();
-
- if let Err(msg) = receiver.recv().unwrap() {
- error!("Error resizing WebGLContext: {}", msg);
- return;
- };
-
- // Reset webrender_image because resize creates a new image_key.
- // The new image key is set in the next handle_layout() method.
- self.webrender_image.set(None);
+ self.ipc_renderer.send(CanvasMsg::Common(CanvasCommonMsg::Recreate(size))).unwrap();
// ClearColor needs to be restored because after a resize the GLContext is recreated
// and the framebuffer is cleared using the default black transparent color.
let color = self.current_clear_color.get();
- self.send_command(WebGLCommand::ClearColor(color.0, color.1, color.2, color.3));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::ClearColor(color.0, color.1, color.2, color.3)))
+ .unwrap();
// WebGL Spec: Scissor rect must not change if the canvas is resized.
// See: webgl/conformance-1.0.3/conformance/rendering/gl-scissor-canvas-dimensions.html
// NativeContext handling library changes the scissor after a resize, so we need to reset the
// default scissor when the canvas was created or the last scissor that the user set.
let rect = self.current_scissor.get();
- self.send_command(WebGLCommand::Scissor(rect.0, rect.1, rect.2, rect.3));
- }
-
- pub fn webgl_sender(&self) -> WebGLMsgSender {
- self.webgl_sender.clone()
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Scissor(rect.0, rect.1, rect.2, rect.3)))
+ .unwrap()
}
- #[inline]
- pub fn send_command(&self, command: WebGLCommand) {
- self.webgl_sender.send(command).unwrap();
+ pub fn ipc_renderer(&self) -> IpcSender<CanvasMsg> {
+ self.ipc_renderer.clone()
}
- #[inline]
- pub fn send_vr_command(&self, command: WebVRCommand) {
- self.webgl_sender.send_vr(command).unwrap();
+ pub fn send_renderer_message(&self, msg: CanvasMsg) {
+ self.ipc_renderer.send(msg).unwrap();
}
pub fn get_extension_manager<'a>(&'a self) -> &'a WebGLExtensions {
@@ -385,7 +370,9 @@ impl WebGLRenderingContext {
self.current_vertex_attrib_0.set((x, y, z, w))
}
- self.send_command(WebGLCommand::VertexAttrib(indx, x, y, z, w));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::VertexAttrib(indx, x, y, z, w)))
+ .unwrap();
}
fn get_current_framebuffer_size(&self) -> Option<(i32, i32)> {
@@ -718,8 +705,8 @@ impl WebGLRenderingContext {
// WebGLContext (probably via GetPixels()).
ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement::HTMLCanvasElement(canvas) => {
if let Some((mut data, size)) = canvas.fetch_all_data() {
- // Pixels got from Canvas have already alpha premultiplied
byte_swap(&mut data);
+ // Pixels got from Canvas have already alpha premultiplied
(data, size, true)
} else {
return Err(());
@@ -958,7 +945,9 @@ impl WebGLRenderingContext {
// GL_UNPACK_ALIGNMENT, while for textures from images or
// canvas (produced by rgba8_image_to_tex_image_data()), it
// will be 1.
- self.send_command(WebGLCommand::PixelStorei(constants::UNPACK_ALIGNMENT, unpacking_alignment as i32));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::PixelStorei(constants::UNPACK_ALIGNMENT, unpacking_alignment as i32)))
+ .unwrap();
let format = internal_format.as_gl_constant();
let data_type = data_type.as_gl_constant();
@@ -972,7 +961,9 @@ impl WebGLRenderingContext {
data_type,
pixels);
- self.send_command(msg);
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(msg))
+ .unwrap();
if let Some(fb) = self.bound_framebuffer.get() {
fb.invalidate_texture(&*texture);
@@ -1014,7 +1005,9 @@ impl WebGLRenderingContext {
// GL_UNPACK_ALIGNMENT, while for textures from images or
// canvas (produced by rgba8_image_to_tex_image_data()), it
// will be 1.
- self.send_command(WebGLCommand::PixelStorei(constants::UNPACK_ALIGNMENT, unpacking_alignment as i32));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::PixelStorei(constants::UNPACK_ALIGNMENT, unpacking_alignment as i32)))
+ .unwrap();
// TODO(emilio): convert colorspace if requested
let msg = WebGLCommand::TexSubImage2D(target.as_gl_constant(),
@@ -1023,7 +1016,9 @@ impl WebGLRenderingContext {
format.as_gl_constant(),
data_type.as_gl_constant(), pixels);
- self.send_command(msg);
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(msg))
+ .unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14
@@ -1040,38 +1035,17 @@ impl WebGLRenderingContext {
}
fn get_gl_extensions(&self) -> String {
- let (sender, receiver) = webgl_channel().unwrap();
- self.send_command(WebGLCommand::GetExtensions(sender));
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::GetExtensions(sender)))
+ .unwrap();
receiver.recv().unwrap()
}
-
- fn layout_handle(&self) -> webrender_api::ImageKey {
- match self.share_mode {
- WebGLContextShareMode::SharedTexture => {
- // WR using ExternalTexture requires a single update message.
- self.webrender_image.get().unwrap_or_else(|| {
- let (sender, receiver) = webgl_channel().unwrap();
- self.webgl_sender.send_update_wr_image(sender).unwrap();
- let image_key = receiver.recv().unwrap();
- self.webrender_image.set(Some(image_key));
-
- image_key
- })
- },
- WebGLContextShareMode::Readback => {
- // WR using Readback requires to update WR image every frame
- // in order to send the new raw pixels.
- let (sender, receiver) = webgl_channel().unwrap();
- self.webgl_sender.send_update_wr_image(sender).unwrap();
- receiver.recv().unwrap()
- }
- }
- }
}
impl Drop for WebGLRenderingContext {
fn drop(&mut self) {
- self.webgl_sender.send_remove().unwrap();
+ self.ipc_renderer.send(CanvasMsg::Common(CanvasCommonMsg::Close)).unwrap();
}
}
@@ -1127,36 +1101,45 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11
fn Flush(&self) {
- self.send_command(WebGLCommand::Flush);
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Flush))
+ .unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11
fn Finish(&self) {
- let (sender, receiver) = webgl_channel().unwrap();
- self.send_command(WebGLCommand::Finish(sender));
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Finish(sender)))
+ .unwrap();
receiver.recv().unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.1
fn DrawingBufferWidth(&self) -> i32 {
- let (sender, receiver) = webgl_channel().unwrap();
- self.send_command(WebGLCommand::DrawingBufferWidth(sender));
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::DrawingBufferWidth(sender)))
+ .unwrap();
receiver.recv().unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.1
fn DrawingBufferHeight(&self) -> i32 {
- let (sender, receiver) = webgl_channel().unwrap();
- self.send_command(WebGLCommand::DrawingBufferHeight(sender));
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::DrawingBufferHeight(sender)))
+ .unwrap();
receiver.recv().unwrap()
}
#[allow(unsafe_code)]
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
unsafe fn GetBufferParameter(&self, _cx: *mut JSContext, target: u32, parameter: u32) -> JSVal {
- let (sender, receiver) = webgl_channel().unwrap();
- self.send_command(WebGLCommand::GetBufferParameter(target, parameter, sender));
-
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::GetBufferParameter(target, parameter, sender)))
+ .unwrap();
match handle_potential_webgl_error!(self, receiver.recv().unwrap(), WebGLParameter::Invalid) {
WebGLParameter::Int(val) => Int32Value(val),
WebGLParameter::Bool(_) => panic!("Buffer parameter should not be bool"),
@@ -1222,9 +1205,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
}
}
- let (sender, receiver) = webgl_channel().unwrap();
- self.send_command(WebGLCommand::GetParameter(parameter, sender));
-
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::GetParameter(parameter, sender)))
+ .unwrap();
match handle_potential_webgl_error!(self, receiver.recv().unwrap(), WebGLParameter::Invalid) {
WebGLParameter::Int(val) => Int32Value(val),
WebGLParameter::Bool(val) => BooleanValue(val),
@@ -1259,13 +1243,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.2
fn GetContextAttributes(&self) -> Option<WebGLContextAttributes> {
- let (sender, receiver) = webgl_channel().unwrap();
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
// If the send does not succeed, assume context lost
- if self.webgl_sender.send(WebGLCommand::GetContextAttributes(sender)).is_err() {
+ if let Err(_) = self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::GetContextAttributes(sender))) {
return None;
}
-
let attrs = receiver.recv().unwrap();
Some(WebGLContextAttributes {
@@ -1301,12 +1285,12 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn ActiveTexture(&self, texture: u32) {
- self.send_command(WebGLCommand::ActiveTexture(texture));
+ self.ipc_renderer.send(CanvasMsg::WebGL(WebGLCommand::ActiveTexture(texture))).unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn BlendColor(&self, r: f32, g: f32, b: f32, a: f32) {
- self.send_command(WebGLCommand::BlendColor(r, g, b, a));
+ self.ipc_renderer.send(CanvasMsg::WebGL(WebGLCommand::BlendColor(r, g, b, a))).unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
@@ -1315,7 +1299,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return self.webgl_error(InvalidEnum);
}
- self.send_command(WebGLCommand::BlendEquation(mode));
+ self.ipc_renderer.send(CanvasMsg::WebGL(WebGLCommand::BlendEquation(mode))).unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
@@ -1324,7 +1308,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return self.webgl_error(InvalidEnum);
}
- self.send_command(WebGLCommand::BlendEquationSeparate(mode_rgb, mode_alpha));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::BlendEquationSeparate(mode_rgb, mode_alpha)))
+ .unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
@@ -1341,7 +1327,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return self.webgl_error(InvalidOperation);
}
- self.send_command(WebGLCommand::BlendFunc(src_factor, dest_factor));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::BlendFunc(src_factor, dest_factor)))
+ .unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
@@ -1358,7 +1346,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return self.webgl_error(InvalidOperation);
}
- self.send_command(WebGLCommand::BlendFuncSeparate(src_rgb, dest_rgb, src_alpha, dest_alpha));
+ self.ipc_renderer.send(
+ CanvasMsg::WebGL(WebGLCommand::BlendFuncSeparate(src_rgb, dest_rgb, src_alpha, dest_alpha))).unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
@@ -1404,7 +1393,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
} else {
slot.set(None);
// Unbind the current buffer
- self.send_command(WebGLCommand::BindBuffer(target, None));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::BindBuffer(target, None)))
+ .unwrap()
}
}
@@ -1429,7 +1420,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
} else {
// Bind the default framebuffer
let cmd = WebGLCommand::BindFramebuffer(target, WebGLFramebufferBindingRequest::Default);
- self.send_command(cmd);
+ self.ipc_renderer.send(CanvasMsg::WebGL(cmd)).unwrap();
self.bound_framebuffer.set(framebuffer);
}
}
@@ -1451,7 +1442,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
_ => {
self.bound_renderbuffer.set(None);
// Unbind the currently bound renderbuffer
- self.send_command(WebGLCommand::BindRenderbuffer(target, None));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::BindRenderbuffer(target, None)))
+ .unwrap()
}
}
}
@@ -1472,7 +1465,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
} else {
slot.set(None);
// Unbind the currently bound texture
- self.send_command(WebGLCommand::BindTexture(target, None));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::BindTexture(target, None)))
+ .unwrap()
}
}
@@ -1590,7 +1585,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if (offset as usize) + data_vec.len() > bound_buffer.capacity() {
return Ok(self.webgl_error(InvalidValue));
}
- self.send_command(WebGLCommand::BufferSubData(target, offset as isize, data_vec));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::BufferSubData(target, offset as isize, data_vec)))
+ .unwrap();
Ok(())
}
@@ -1673,7 +1670,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
width as i32, height as i32,
border as i32);
- self.send_command(msg);
+ self.ipc_renderer.send(CanvasMsg::WebGL(msg)).unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
@@ -1717,7 +1714,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
x, y,
width as i32, height as i32);
- self.send_command(msg);
+ self.ipc_renderer.send(CanvasMsg::WebGL(msg)).unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11
@@ -1726,36 +1723,46 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return;
}
- self.send_command(WebGLCommand::Clear(mask));
+ self.ipc_renderer.send(CanvasMsg::WebGL(WebGLCommand::Clear(mask))).unwrap();
self.mark_as_dirty();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn ClearColor(&self, red: f32, green: f32, blue: f32, alpha: f32) {
self.current_clear_color.set((red, green, blue, alpha));
- self.send_command(WebGLCommand::ClearColor(red, green, blue, alpha));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::ClearColor(red, green, blue, alpha)))
+ .unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn ClearDepth(&self, depth: f32) {
- self.send_command(WebGLCommand::ClearDepth(depth as f64))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::ClearDepth(depth as f64)))
+ .unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn ClearStencil(&self, stencil: i32) {
- self.send_command(WebGLCommand::ClearStencil(stencil))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::ClearStencil(stencil)))
+ .unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn ColorMask(&self, r: bool, g: bool, b: bool, a: bool) {
- self.send_command(WebGLCommand::ColorMask(r, g, b, a))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::ColorMask(r, g, b, a)))
+ .unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn CullFace(&self, mode: u32) {
match mode {
constants::FRONT | constants::BACK | constants::FRONT_AND_BACK =>
- self.send_command(WebGLCommand::CullFace(mode)),
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::CullFace(mode)))
+ .unwrap(),
_ => self.webgl_error(InvalidEnum),
}
}
@@ -1764,7 +1771,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
fn FrontFace(&self, mode: u32) {
match mode {
constants::CW | constants::CCW =>
- self.send_command(WebGLCommand::FrontFace(mode)),
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::FrontFace(mode)))
+ .unwrap(),
_ => self.webgl_error(InvalidEnum),
}
}
@@ -1775,14 +1784,18 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
constants::EQUAL | constants::LEQUAL |
constants::GREATER | constants::NOTEQUAL |
constants::GEQUAL | constants::ALWAYS =>
- self.send_command(WebGLCommand::DepthFunc(func)),
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::DepthFunc(func)))
+ .unwrap(),
_ => self.webgl_error(InvalidEnum),
}
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn DepthMask(&self, flag: bool) {
- self.send_command(WebGLCommand::DepthMask(flag))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::DepthMask(flag)))
+ .unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
@@ -1796,20 +1809,26 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return self.webgl_error(InvalidOperation);
}
- self.send_command(WebGLCommand::DepthRange(near as f64, far as f64))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::DepthRange(near as f64, far as f64)))
+ .unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn Enable(&self, cap: u32) {
if self.validate_feature_enum(cap) {
- self.send_command(WebGLCommand::Enable(cap));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Enable(cap)))
+ .unwrap();
}
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn Disable(&self, cap: u32) {
if self.validate_feature_enum(cap) {
- self.send_command(WebGLCommand::Disable(cap));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Disable(cap)))
+ .unwrap()
}
}
@@ -1824,27 +1843,27 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// generated objects, either here or in the webgl thread
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
fn CreateBuffer(&self) -> Option<Root<WebGLBuffer>> {
- WebGLBuffer::maybe_new(self.global().as_window(), self.webgl_sender.clone())
+ WebGLBuffer::maybe_new(self.global().as_window(), self.ipc_renderer.clone())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6
fn CreateFramebuffer(&self) -> Option<Root<WebGLFramebuffer>> {
- WebGLFramebuffer::maybe_new(self.global().as_window(), self.webgl_sender.clone())
+ WebGLFramebuffer::maybe_new(self.global().as_window(), self.ipc_renderer.clone())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7
fn CreateRenderbuffer(&self) -> Option<Root<WebGLRenderbuffer>> {
- WebGLRenderbuffer::maybe_new(self.global().as_window(), self.webgl_sender.clone())
+ WebGLRenderbuffer::maybe_new(self.global().as_window(), self.ipc_renderer.clone())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
fn CreateTexture(&self) -> Option<Root<WebGLTexture>> {
- WebGLTexture::maybe_new(self.global().as_window(), self.webgl_sender.clone())
+ WebGLTexture::maybe_new(self.global().as_window(), self.ipc_renderer.clone())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
fn CreateProgram(&self) -> Option<Root<WebGLProgram>> {
- WebGLProgram::maybe_new(self.global().as_window(), self.webgl_sender.clone())
+ WebGLProgram::maybe_new(self.global().as_window(), self.ipc_renderer.clone())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
@@ -1856,7 +1875,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return None;
}
}
- WebGLShader::maybe_new(self.global().as_window(), self.webgl_sender.clone(), shader_type)
+ WebGLShader::maybe_new(self.global().as_window(), self.ipc_renderer.clone(), shader_type)
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
@@ -1980,7 +1999,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return;
}
- self.send_command(WebGLCommand::DrawArrays(mode, first, count));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::DrawArrays(mode, first, count)))
+ .unwrap();
self.mark_as_dirty();
},
_ => self.webgl_error(InvalidEnum),
@@ -2044,7 +2065,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
constants::LINE_LOOP | constants::LINES |
constants::TRIANGLE_STRIP | constants::TRIANGLE_FAN |
constants::TRIANGLES => {
- self.send_command(WebGLCommand::DrawElements(mode, count, type_, offset));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::DrawElements(mode, count, type_, offset)))
+ .unwrap();
self.mark_as_dirty();
},
_ => self.webgl_error(InvalidEnum),
@@ -2057,7 +2080,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return self.webgl_error(InvalidValue);
}
- self.send_command(WebGLCommand::EnableVertexAttribArray(attrib_id));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::EnableVertexAttribArray(attrib_id)))
+ .unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@@ -2066,7 +2091,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return self.webgl_error(InvalidValue);
}
- self.send_command(WebGLCommand::DisableVertexAttribArray(attrib_id));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::DisableVertexAttribArray(attrib_id)))
+ .unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@@ -2196,11 +2223,11 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
shader_type: u32,
precision_type: u32)
-> Option<Root<WebGLShaderPrecisionFormat>> {
- let (sender, receiver) = webgl_channel().unwrap();
- self.send_command(WebGLCommand::GetShaderPrecisionFormat(shader_type,
- precision_type,
- sender));
-
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ self.ipc_renderer.send(CanvasMsg::WebGL(WebGLCommand::GetShaderPrecisionFormat(shader_type,
+ precision_type,
+ sender)))
+ .unwrap();
match receiver.recv().unwrap() {
Ok((range_min, range_max, precision)) => {
Some(WebGLShaderPrecisionFormat::new(self.global().as_window(), range_min, range_max, precision))
@@ -2241,8 +2268,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return jsval.get();
}
- let (sender, receiver) = webgl_channel().unwrap();
- self.send_command(WebGLCommand::GetVertexAttrib(index, pname, sender));
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ self.ipc_renderer.send(CanvasMsg::WebGL(WebGLCommand::GetVertexAttrib(index, pname, sender))).unwrap();
match handle_potential_webgl_error!(self, receiver.recv().unwrap(), WebGLParameter::Invalid) {
WebGLParameter::Int(val) => Int32Value(val),
@@ -2260,8 +2287,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn GetVertexAttribOffset(&self, index: u32, pname: u32) -> i64 {
- let (sender, receiver) = webgl_channel().unwrap();
- self.send_command(WebGLCommand::GetVertexAttribOffset(index, pname, sender));
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ self.ipc_renderer.send(CanvasMsg::WebGL(WebGLCommand::GetVertexAttribOffset(index, pname, sender))).unwrap();
handle_potential_webgl_error!(self, receiver.recv().unwrap(), 0) as i64
}
@@ -2280,7 +2307,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
_ => return self.webgl_error(InvalidEnum),
}
- self.send_command(WebGLCommand::Hint(target, mode));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Hint(target, mode)))
+ .unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
@@ -2292,8 +2321,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn IsEnabled(&self, cap: u32) -> bool {
if self.validate_feature_enum(cap) {
- let (sender, receiver) = webgl_channel().unwrap();
- self.send_command(WebGLCommand::IsEnabled(cap, sender));
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::IsEnabled(cap, sender)))
+ .unwrap();
return receiver.recv().unwrap();
}
@@ -2331,7 +2362,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return self.webgl_error(InvalidValue);
}
- self.send_command(WebGLCommand::LineWidth(width))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::LineWidth(width)))
+ .unwrap()
}
// NOTE: Usage of this function could affect rendering while we keep using
@@ -2387,7 +2420,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn PolygonOffset(&self, factor: f32, units: f32) {
- self.send_command(WebGLCommand::PolygonOffset(factor, units))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::PolygonOffset(factor, units)))
+ .unwrap()
}
#[allow(unsafe_code)]
@@ -2487,8 +2522,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
_ => return Ok(self.webgl_error(InvalidOperation)),
};
- let (sender, receiver) = webgl_channel().unwrap();
- self.send_command(WebGLCommand::ReadPixels(x, y, width, height, format, pixel_type, sender));
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::ReadPixels(x, y, width, height, format, pixel_type, sender)))
+ .unwrap();
let result = receiver.recv().unwrap();
@@ -2504,7 +2541,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn SampleCoverage(&self, value: f32, invert: bool) {
- self.send_command(WebGLCommand::SampleCoverage(value, invert));
+ self.ipc_renderer.send(CanvasMsg::WebGL(WebGLCommand::SampleCoverage(value, invert))).unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.4
@@ -2514,7 +2551,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
}
self.current_scissor.set((x, y, width, height));
- self.send_command(WebGLCommand::Scissor(x, y, width, height));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Scissor(x, y, width, height)))
+ .unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
@@ -2522,7 +2561,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
match func {
constants::NEVER | constants::LESS | constants::EQUAL | constants::LEQUAL |
constants::GREATER | constants::NOTEQUAL | constants::GEQUAL | constants::ALWAYS =>
- self.send_command(WebGLCommand::StencilFunc(func, ref_, mask)),
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::StencilFunc(func, ref_, mask)))
+ .unwrap(),
_ => self.webgl_error(InvalidEnum),
}
}
@@ -2537,21 +2578,27 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
match func {
constants::NEVER | constants::LESS | constants::EQUAL | constants::LEQUAL |
constants::GREATER | constants::NOTEQUAL | constants::GEQUAL | constants::ALWAYS =>
- self.send_command(WebGLCommand::StencilFuncSeparate(face, func, ref_, mask)),
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::StencilFuncSeparate(face, func, ref_, mask)))
+ .unwrap(),
_ => self.webgl_error(InvalidEnum),
}
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn StencilMask(&self, mask: u32) {
- self.send_command(WebGLCommand::StencilMask(mask))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::StencilMask(mask)))
+ .unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn StencilMaskSeparate(&self, face: u32, mask: u32) {
match face {
constants::FRONT | constants::BACK | constants::FRONT_AND_BACK =>
- self.send_command(WebGLCommand::StencilMaskSeparate(face, mask)),
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::StencilMaskSeparate(face, mask)))
+ .unwrap(),
_ => return self.webgl_error(InvalidEnum),
}
}
@@ -2560,7 +2607,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
fn StencilOp(&self, fail: u32, zfail: u32, zpass: u32) {
if self.validate_stencil_actions(fail) && self.validate_stencil_actions(zfail) &&
self.validate_stencil_actions(zpass) {
- self.send_command(WebGLCommand::StencilOp(fail, zfail, zpass));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::StencilOp(fail, zfail, zpass)))
+ .unwrap()
} else {
self.webgl_error(InvalidEnum)
}
@@ -2575,7 +2624,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if self.validate_stencil_actions(fail) && self.validate_stencil_actions(zfail) &&
self.validate_stencil_actions(zpass) {
- self.send_command(WebGLCommand::StencilOpSeparate(face, fail, zfail, zpass))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::StencilOpSeparate(face, fail, zfail, zpass)))
+ .unwrap()
} else {
self.webgl_error(InvalidEnum)
}
@@ -2607,7 +2658,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
uniform: Option<&WebGLUniformLocation>,
val: f32) {
if self.validate_uniform_parameters(uniform, UniformSetterType::Float, &[val]) {
- self.send_command(WebGLCommand::Uniform1f(uniform.unwrap().id(), val))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform1f(uniform.unwrap().id(), val)))
+ .unwrap()
}
}
@@ -2616,7 +2669,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
uniform: Option<&WebGLUniformLocation>,
val: i32) {
if self.validate_uniform_parameters(uniform, UniformSetterType::Int, &[val]) {
- self.send_command(WebGLCommand::Uniform1i(uniform.unwrap().id(), val))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform1i(uniform.unwrap().id(), val)))
+ .unwrap()
}
}
@@ -2630,7 +2685,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
let data_vec = typed_array_or_sequence_to_vec::<Int32>(cx, data, ConversionBehavior::Default)?;
if self.validate_uniform_parameters(uniform, UniformSetterType::Int, &data_vec) {
- self.send_command(WebGLCommand::Uniform1iv(uniform.unwrap().id(), data_vec))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform1iv(uniform.unwrap().id(), data_vec)))
+ .unwrap()
}
Ok(())
@@ -2646,7 +2703,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
let data_vec = typed_array_or_sequence_to_vec::<Float32>(cx, data, ())?;
if self.validate_uniform_parameters(uniform, UniformSetterType::Float, &data_vec) {
- self.send_command(WebGLCommand::Uniform1fv(uniform.unwrap().id(), data_vec));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform1fv(uniform.unwrap().id(), data_vec)))
+ .unwrap()
}
Ok(())
@@ -2657,7 +2716,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
uniform: Option<&WebGLUniformLocation>,
x: f32, y: f32) {
if self.validate_uniform_parameters(uniform, UniformSetterType::FloatVec2, &[x, y]) {
- self.send_command(WebGLCommand::Uniform2f(uniform.unwrap().id(), x, y));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform2f(uniform.unwrap().id(), x, y)))
+ .unwrap()
}
}
@@ -2673,7 +2734,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if self.validate_uniform_parameters(uniform,
UniformSetterType::FloatVec2,
&data_vec) {
- self.send_command(WebGLCommand::Uniform2fv(uniform.unwrap().id(), data_vec));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform2fv(uniform.unwrap().id(), data_vec)))
+ .unwrap()
}
Ok(())
@@ -2686,7 +2749,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if self.validate_uniform_parameters(uniform,
UniformSetterType::IntVec2,
&[x, y]) {
- self.send_command(WebGLCommand::Uniform2i(uniform.unwrap().id(), x, y));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform2i(uniform.unwrap().id(), x, y)))
+ .unwrap()
}
}
@@ -2702,7 +2767,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if self.validate_uniform_parameters(uniform,
UniformSetterType::IntVec2,
&data_vec) {
- self.send_command(WebGLCommand::Uniform2iv(uniform.unwrap().id(), data_vec));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform2iv(uniform.unwrap().id(), data_vec)))
+ .unwrap()
}
Ok(())
@@ -2715,7 +2782,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if self.validate_uniform_parameters(uniform,
UniformSetterType::FloatVec3,
&[x, y, z]) {
- self.send_command(WebGLCommand::Uniform3f(uniform.unwrap().id(), x, y, z));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform3f(uniform.unwrap().id(), x, y, z)))
+ .unwrap()
}
}
@@ -2731,7 +2800,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if self.validate_uniform_parameters(uniform,
UniformSetterType::FloatVec3,
&data_vec) {
- self.send_command(WebGLCommand::Uniform3fv(uniform.unwrap().id(), data_vec))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform3fv(uniform.unwrap().id(), data_vec)))
+ .unwrap()
}
Ok(())
@@ -2744,7 +2815,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if self.validate_uniform_parameters(uniform,
UniformSetterType::IntVec3,
&[x, y, z]) {
- self.send_command(WebGLCommand::Uniform3i(uniform.unwrap().id(), x, y, z))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform3i(uniform.unwrap().id(), x, y, z)))
+ .unwrap()
}
}
@@ -2760,7 +2833,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if self.validate_uniform_parameters(uniform,
UniformSetterType::IntVec3,
&data_vec) {
- self.send_command(WebGLCommand::Uniform3iv(uniform.unwrap().id(), data_vec))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform3iv(uniform.unwrap().id(), data_vec)))
+ .unwrap()
}
Ok(())
@@ -2773,7 +2848,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if self.validate_uniform_parameters(uniform,
UniformSetterType::IntVec4,
&[x, y, z, w]) {
- self.send_command(WebGLCommand::Uniform4i(uniform.unwrap().id(), x, y, z, w))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform4i(uniform.unwrap().id(), x, y, z, w)))
+ .unwrap()
}
}
@@ -2790,7 +2867,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if self.validate_uniform_parameters(uniform,
UniformSetterType::IntVec4,
&data_vec) {
- self.send_command(WebGLCommand::Uniform4iv(uniform.unwrap().id(), data_vec))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform4iv(uniform.unwrap().id(), data_vec)))
+ .unwrap()
}
Ok(())
@@ -2803,7 +2882,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if self.validate_uniform_parameters(uniform,
UniformSetterType::FloatVec4,
&[x, y, z, w]) {
- self.send_command(WebGLCommand::Uniform4f(uniform.unwrap().id(), x, y, z, w))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform4f(uniform.unwrap().id(), x, y, z, w)))
+ .unwrap()
}
}
@@ -2819,7 +2900,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if self.validate_uniform_parameters(uniform,
UniformSetterType::FloatVec4,
&data_vec) {
- self.send_command(WebGLCommand::Uniform4fv(uniform.unwrap().id(), data_vec))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform4fv(uniform.unwrap().id(), data_vec)))
+ .unwrap()
}
Ok(())
@@ -2837,7 +2920,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if self.validate_uniform_parameters(uniform,
UniformSetterType::FloatMat2,
&data_vec) {
- self.send_command(WebGLCommand::UniformMatrix2fv(uniform.unwrap().id(), transpose, data_vec));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::UniformMatrix2fv(uniform.unwrap().id(), transpose, data_vec)))
+ .unwrap()
}
Ok(())
@@ -2855,7 +2940,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if self.validate_uniform_parameters(uniform,
UniformSetterType::FloatMat3,
&data_vec) {
- self.send_command(WebGLCommand::UniformMatrix3fv(uniform.unwrap().id(), transpose, data_vec));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::UniformMatrix3fv(uniform.unwrap().id(), transpose, data_vec)))
+ .unwrap()
}
Ok(())
@@ -2873,7 +2960,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if self.validate_uniform_parameters(uniform,
UniformSetterType::FloatMat4,
&data_vec) {
- self.send_command(WebGLCommand::UniformMatrix4fv(uniform.unwrap().id(), transpose, data_vec));
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::UniformMatrix4fv(uniform.unwrap().id(), transpose, data_vec)))
+ .unwrap()
}
Ok(())
@@ -3009,8 +3098,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
self.bound_attrib_buffers.borrow_mut().insert(attrib_id, JS::from_ref(&*buffer_array));
- let msg = WebGLCommand::VertexAttribPointer(attrib_id, size, data_type, normalized, stride, offset as u32);
- self.send_command(msg);
+ let msg = CanvasMsg::WebGL(
+ WebGLCommand::VertexAttribPointer(attrib_id, size, data_type, normalized, stride, offset as u32));
+ self.ipc_renderer.send(msg).unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.4
@@ -3019,7 +3109,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return self.webgl_error(InvalidValue)
}
- self.send_command(WebGLCommand::Viewport(x, y, width, height))
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::Viewport(x, y, width, height)))
+ .unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
@@ -3364,13 +3456,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
pub trait LayoutCanvasWebGLRenderingContextHelpers {
#[allow(unsafe_code)]
- unsafe fn canvas_data_source(&self) -> HTMLCanvasDataSource;
+ unsafe fn get_ipc_renderer(&self) -> IpcSender<CanvasMsg>;
}
impl LayoutCanvasWebGLRenderingContextHelpers for LayoutJS<WebGLRenderingContext> {
#[allow(unsafe_code)]
- unsafe fn canvas_data_source(&self) -> HTMLCanvasDataSource {
- HTMLCanvasDataSource::WebGL((*self.unsafe_get()).layout_handle())
+ unsafe fn get_ipc_renderer(&self) -> IpcSender<CanvasMsg> {
+ (*self.unsafe_get()).ipc_renderer.clone()
}
}
diff --git a/components/script/dom/webglshader.rs b/components/script/dom/webglshader.rs
index cf6fc55072d..edd9cf7bdb3 100644
--- a/components/script/dom/webglshader.rs
+++ b/components/script/dom/webglshader.rs
@@ -4,7 +4,7 @@
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
use angle::hl::{BuiltInResources, Output, ShaderValidator};
-use canvas_traits::webgl::{webgl_channel, WebGLCommand, WebGLMsgSender, WebGLParameter, WebGLResult, WebGLShaderId};
+use canvas_traits::CanvasMsg;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::WebGLShaderBinding;
use dom::bindings::js::Root;
@@ -13,8 +13,11 @@ use dom::bindings::str::DOMString;
use dom::webglobject::WebGLObject;
use dom::window::Window;
use dom_struct::dom_struct;
+use ipc_channel::ipc::IpcSender;
use std::cell::Cell;
use std::sync::{ONCE_INIT, Once};
+use webrender_api;
+use webrender_api::{WebGLCommand, WebGLParameter, WebGLResult, WebGLShaderId};
#[derive(Clone, Copy, PartialEq, Debug, JSTraceable, HeapSizeOf)]
pub enum ShaderCompilationStatus {
@@ -34,7 +37,7 @@ pub struct WebGLShader {
attached_counter: Cell<u32>,
compilation_status: Cell<ShaderCompilationStatus>,
#[ignore_heap_size_of = "Defined in ipc-channel"]
- renderer: WebGLMsgSender,
+ renderer: IpcSender<CanvasMsg>,
}
#[cfg(not(target_os = "android"))]
@@ -46,7 +49,7 @@ const SHADER_OUTPUT_FORMAT: Output = Output::Essl;
static GLSLANG_INITIALIZATION: Once = ONCE_INIT;
impl WebGLShader {
- fn new_inherited(renderer: WebGLMsgSender,
+ fn new_inherited(renderer: IpcSender<CanvasMsg>,
id: WebGLShaderId,
shader_type: u32)
-> WebGLShader {
@@ -65,18 +68,18 @@ impl WebGLShader {
}
pub fn maybe_new(window: &Window,
- renderer: WebGLMsgSender,
+ renderer: IpcSender<CanvasMsg>,
shader_type: u32)
-> Option<Root<WebGLShader>> {
- let (sender, receiver) = webgl_channel().unwrap();
- renderer.send(WebGLCommand::CreateShader(shader_type, sender)).unwrap();
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ renderer.send(CanvasMsg::WebGL(WebGLCommand::CreateShader(shader_type, sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|shader_id| WebGLShader::new(window, renderer, shader_id, shader_type))
}
pub fn new(window: &Window,
- renderer: WebGLMsgSender,
+ renderer: IpcSender<CanvasMsg>,
id: WebGLShaderId,
shader_type: u32)
-> Root<WebGLShader> {
@@ -115,7 +118,7 @@ impl WebGLShader {
// will succeed.
// It could be interesting to retrieve the info log from the paint thread though
let msg = WebGLCommand::CompileShader(self.id, translated_source);
- self.renderer.send(msg).unwrap();
+ self.renderer.send(CanvasMsg::WebGL(msg)).unwrap();
self.compilation_status.set(ShaderCompilationStatus::Succeeded);
},
Err(error) => {
@@ -139,7 +142,7 @@ impl WebGLShader {
pub fn delete(&self) {
if !self.is_deleted.get() {
self.is_deleted.set(true);
- let _ = self.renderer.send(WebGLCommand::DeleteShader(self.id));
+ let _ = self.renderer.send(CanvasMsg::WebGL(WebGLCommand::DeleteShader(self.id)));
}
}
@@ -167,8 +170,8 @@ impl WebGLShader {
/// glGetParameter
pub fn parameter(&self, param_id: u32) -> WebGLResult<WebGLParameter> {
- let (sender, receiver) = webgl_channel().unwrap();
- self.renderer.send(WebGLCommand::GetShaderParameter(self.id, param_id, sender)).unwrap();
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::GetShaderParameter(self.id, param_id, sender))).unwrap();
receiver.recv().unwrap()
}
diff --git a/components/script/dom/webgltexture.rs b/components/script/dom/webgltexture.rs
index 048af5d10e0..88d5faaf5c8 100644
--- a/components/script/dom/webgltexture.rs
+++ b/components/script/dom/webgltexture.rs
@@ -3,8 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
-
-use canvas_traits::webgl::{webgl_channel, WebGLCommand, WebGLError, WebGLMsgSender, WebGLResult, WebGLTextureId};
+use canvas_traits::CanvasMsg;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use dom::bindings::codegen::Bindings::WebGLTextureBinding;
@@ -14,8 +13,11 @@ use dom::webgl_validations::types::{TexImageTarget, TexFormat, TexDataType};
use dom::webglobject::WebGLObject;
use dom::window::Window;
use dom_struct::dom_struct;
+use ipc_channel::ipc::IpcSender;
use std::cell::Cell;
use std::cmp;
+use webrender_api;
+use webrender_api::{WebGLCommand, WebGLError, WebGLResult, WebGLTextureId};
pub enum TexParameterValue {
Float(f32),
@@ -44,11 +46,11 @@ pub struct WebGLTexture {
min_filter: Cell<Option<u32>>,
mag_filter: Cell<Option<u32>>,
#[ignore_heap_size_of = "Defined in ipc-channel"]
- renderer: WebGLMsgSender,
+ renderer: IpcSender<CanvasMsg>,
}
impl WebGLTexture {
- fn new_inherited(renderer: WebGLMsgSender,
+ fn new_inherited(renderer: IpcSender<CanvasMsg>,
id: WebGLTextureId)
-> WebGLTexture {
WebGLTexture {
@@ -65,17 +67,17 @@ impl WebGLTexture {
}
}
- pub fn maybe_new(window: &Window, renderer: WebGLMsgSender)
+ pub fn maybe_new(window: &Window, renderer: IpcSender<CanvasMsg>)
-> Option<Root<WebGLTexture>> {
- let (sender, receiver) = webgl_channel().unwrap();
- renderer.send(WebGLCommand::CreateTexture(sender)).unwrap();
+ let (sender, receiver) = webrender_api::channel::msg_channel().unwrap();
+ renderer.send(CanvasMsg::WebGL(WebGLCommand::CreateTexture(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|texture_id| WebGLTexture::new(window, renderer, texture_id))
}
pub fn new(window: &Window,
- renderer: WebGLMsgSender,
+ renderer: IpcSender<CanvasMsg>,
id: WebGLTextureId)
-> Root<WebGLTexture> {
reflect_dom_object(box WebGLTexture::new_inherited(renderer, id),
@@ -111,7 +113,7 @@ impl WebGLTexture {
self.target.set(Some(target));
}
- let msg = WebGLCommand::BindTexture(target, Some(self.id));
+ let msg = CanvasMsg::WebGL(WebGLCommand::BindTexture(target, Some(self.id)));
self.renderer.send(msg).unwrap();
Ok(())
@@ -166,7 +168,7 @@ impl WebGLTexture {
return Err(WebGLError::InvalidOperation);
}
- self.renderer.send(WebGLCommand::GenerateMipmap(target)).unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::GenerateMipmap(target))).unwrap();
if self.base_mipmap_level + base_image_info.get_max_mimap_levels() == 0 {
return Err(WebGLError::InvalidOperation);
@@ -179,7 +181,7 @@ impl WebGLTexture {
pub fn delete(&self) {
if !self.is_deleted.get() {
self.is_deleted.set(true);
- let _ = self.renderer.send(WebGLCommand::DeleteTexture(self.id));
+ let _ = self.renderer.send(CanvasMsg::WebGL(WebGLCommand::DeleteTexture(self.id)));
}
}
@@ -214,7 +216,7 @@ impl WebGLTexture {
constants::LINEAR_MIPMAP_LINEAR => {
self.min_filter.set(Some(int_value as u32));
self.renderer
- .send(WebGLCommand::TexParameteri(target, name, int_value))
+ .send(CanvasMsg::WebGL(WebGLCommand::TexParameteri(target, name, int_value)))
.unwrap();
Ok(())
},
@@ -228,7 +230,7 @@ impl WebGLTexture {
constants::LINEAR => {
self.mag_filter.set(Some(int_value as u32));
self.renderer
- .send(WebGLCommand::TexParameteri(target, name, int_value))
+ .send(CanvasMsg::WebGL(WebGLCommand::TexParameteri(target, name, int_value)))
.unwrap();
Ok(())
},
@@ -243,7 +245,7 @@ impl WebGLTexture {
constants::MIRRORED_REPEAT |
constants::REPEAT => {
self.renderer
- .send(WebGLCommand::TexParameteri(target, name, int_value))
+ .send(CanvasMsg::WebGL(WebGLCommand::TexParameteri(target, name, int_value)))
.unwrap();
Ok(())
},
diff --git a/components/script/dom/webgluniformlocation.rs b/components/script/dom/webgluniformlocation.rs
index 47292adeb18..228808303c4 100644
--- a/components/script/dom/webgluniformlocation.rs
+++ b/components/script/dom/webgluniformlocation.rs
@@ -3,12 +3,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
-use canvas_traits::webgl::WebGLProgramId;
use dom::bindings::codegen::Bindings::WebGLUniformLocationBinding;
use dom::bindings::js::Root;
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::window::Window;
use dom_struct::dom_struct;
+use webrender_api::WebGLProgramId;
#[dom_struct]
pub struct WebGLUniformLocation {
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 2da650ee1ee..90693a2ccbf 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -5,7 +5,6 @@
use app_units::Au;
use base64;
use bluetooth_traits::BluetoothRequest;
-use canvas_traits::webgl::WebGLChan;
use cssparser::{Parser, ParserInput};
use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker, TimelineMarkerType};
use dom::bindings::cell::DOMRefCell;
@@ -265,11 +264,7 @@ pub struct Window {
/// A handle for communicating messages to the webvr thread, if available.
#[ignore_heap_size_of = "channels are hard"]
- webgl_chan: WebGLChan,
-
- /// A handle for communicating messages to the webvr thread, if available.
- #[ignore_heap_size_of = "channels are hard"]
- webvr_chan: Option<IpcSender<WebVRMsg>>,
+ webvr_thread: Option<IpcSender<WebVRMsg>>,
/// A map for storing the previous permission state read results.
permission_state_invocation_results: DOMRefCell<HashMap<String, PermissionState>>,
@@ -385,12 +380,8 @@ impl Window {
self.current_viewport.clone().get()
}
- pub fn webgl_chan(&self) -> WebGLChan {
- self.webgl_chan.clone()
- }
-
pub fn webvr_thread(&self) -> Option<IpcSender<WebVRMsg>> {
- self.webvr_chan.clone()
+ self.webvr_thread.clone()
}
fn new_paint_worklet(&self) -> Root<Worklet> {
@@ -1809,8 +1800,7 @@ impl Window {
origin: MutableOrigin,
navigation_start: u64,
navigation_start_precise: f64,
- webgl_chan: WebGLChan,
- webvr_chan: Option<IpcSender<WebVRMsg>>)
+ webvr_thread: Option<IpcSender<WebVRMsg>>)
-> Root<Window> {
let layout_rpc: Box<LayoutRPC + Send> = {
let (rpc_send, rpc_recv) = channel();
@@ -1876,8 +1866,7 @@ impl Window {
scroll_offsets: DOMRefCell::new(HashMap::new()),
media_query_lists: WeakMediaQueryListVec::new(),
test_runner: Default::default(),
- webgl_chan: webgl_chan,
- webvr_chan: webvr_chan,
+ webvr_thread: webvr_thread,
permission_state_invocation_results: DOMRefCell::new(HashMap::new()),
pending_layout_images: DOMRefCell::new(HashMap::new()),
unminified_js_dir: DOMRefCell::new(None),
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index 4a05002637a..ea8038897ac 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -18,7 +18,6 @@
//! loop.
use bluetooth_traits::BluetoothRequest;
-use canvas_traits::webgl::WebGLPipeline;
use devtools;
use devtools_traits::{DevtoolScriptControlMsg, DevtoolsPageInfo};
use devtools_traits::{ScriptToDevtoolsControlMsg, WorkerId};
@@ -509,11 +508,8 @@ pub struct ScriptThread {
/// The unit of related similar-origin browsing contexts' list of MutationObserver objects
mutation_observers: DOMRefCell<Vec<JS<MutationObserver>>>,
- /// A handle to the webgl thread
- webgl_chan: WebGLPipeline,
-
/// A handle to the webvr thread, if available
- webvr_chan: Option<IpcSender<WebVRMsg>>,
+ webvr_thread: Option<IpcSender<WebVRMsg>>,
/// The worklet thread pool
worklet_thread_pool: DOMRefCell<Option<Rc<WorkletThreadPool>>>,
@@ -885,8 +881,7 @@ impl ScriptThread {
layout_to_constellation_chan: state.layout_to_constellation_chan,
- webgl_chan: state.webgl_chan,
- webvr_chan: state.webvr_chan,
+ webvr_thread: state.webvr_thread,
worklet_thread_pool: Default::default(),
@@ -2033,8 +2028,7 @@ impl ScriptThread {
origin,
incomplete.navigation_start,
incomplete.navigation_start_precise,
- self.webgl_chan.channel(),
- self.webvr_chan.clone());
+ self.webvr_thread.clone());
// Initialize the browsing context for the window.
let window_proxy = self.local_window_proxy(&window,
diff --git a/components/script_layout_interface/lib.rs b/components/script_layout_interface/lib.rs
index 7c0f97ef917..e3e956096bb 100644
--- a/components/script_layout_interface/lib.rs
+++ b/components/script_layout_interface/lib.rs
@@ -43,7 +43,7 @@ pub mod rpc;
pub mod wrapper_traits;
use atomic_refcell::AtomicRefCell;
-use canvas_traits::canvas::CanvasMsg;
+use canvas_traits::CanvasMsg;
use core::nonzero::NonZero;
use ipc_channel::ipc::IpcSender;
use libc::c_void;
@@ -124,13 +124,8 @@ pub enum LayoutElementType {
SVGSVGElement,
}
-pub enum HTMLCanvasDataSource {
- WebGL(webrender_api::ImageKey),
- Image(Option<IpcSender<CanvasMsg>>)
-}
-
pub struct HTMLCanvasData {
- pub source: HTMLCanvasDataSource,
+ pub ipc_renderer: Option<IpcSender<CanvasMsg>>,
pub width: u32,
pub height: u32,
}
diff --git a/components/script_traits/Cargo.toml b/components/script_traits/Cargo.toml
index 2c083b2773c..70fcdbb3f33 100644
--- a/components/script_traits/Cargo.toml
+++ b/components/script_traits/Cargo.toml
@@ -25,6 +25,7 @@ libc = "0.2"
metrics = {path = "../metrics"}
msg = {path = "../msg"}
net_traits = {path = "../net_traits"}
+offscreen_gl_context = { version = "0.11", features = ["serde"] }
profile_traits = {path = "../profile_traits"}
rustc-serialize = "0.3.4"
serde = "1.0"
diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs
index 4a197e759ff..85122d35c3c 100644
--- a/components/script_traits/lib.rs
+++ b/components/script_traits/lib.rs
@@ -24,6 +24,7 @@ extern crate ipc_channel;
extern crate libc;
extern crate msg;
extern crate net_traits;
+extern crate offscreen_gl_context;
extern crate profile_traits;
extern crate rustc_serialize;
#[macro_use] extern crate serde;
@@ -38,7 +39,6 @@ mod script_msg;
pub mod webdriver_msg;
use bluetooth_traits::BluetoothRequest;
-use canvas_traits::webgl::WebGLPipeline;
use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, WorkerId};
use euclid::{Size2D, Length, Point2D, Vector2D, Rect, ScaleFactor, TypedSize2D};
use gfx_traits::Epoch;
@@ -524,10 +524,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 webvr thread, if available.
- pub webvr_chan: Option<IpcSender<WebVRMsg>>
+ pub webvr_thread: Option<IpcSender<WebVRMsg>>
}
/// This trait allows creating a `ScriptThread` without depending on the `script`
@@ -761,6 +759,8 @@ pub enum ConstellationMsg {
Reload(TopLevelBrowsingContextId),
/// A log entry, with the top-level browsing context id and thread name
LogEntry(Option<TopLevelBrowsingContextId>, Option<String>, LogEntry),
+ /// Set the WebVR thread channel.
+ SetWebVRThread(IpcSender<WebVRMsg>),
/// Dispatch WebVR events to the subscribed script threads.
WebVREvents(Vec<PipelineId>, Vec<WebVREvent>),
/// Create a new top level browsing context.
diff --git a/components/script_traits/script_msg.rs b/components/script_traits/script_msg.rs
index 156f85a2be7..4fd8fca5c7f 100644
--- a/components/script_traits/script_msg.rs
+++ b/components/script_traits/script_msg.rs
@@ -12,7 +12,7 @@ use LoadData;
use MozBrowserEvent;
use WorkerGlobalScopeInit;
use WorkerScriptLoadOrigin;
-use canvas_traits::canvas::CanvasMsg;
+use canvas_traits::CanvasMsg;
use devtools_traits::{ScriptToDevtoolsControlMsg, WorkerId};
use euclid::{Point2D, Size2D, TypedSize2D};
use ipc_channel::ipc::IpcSender;
@@ -21,6 +21,7 @@ use msg::constellation_msg::{Key, KeyModifiers, KeyState};
use net_traits::CoreResourceMsg;
use net_traits::request::RequestInit;
use net_traits::storage_thread::StorageType;
+use offscreen_gl_context::{GLContextAttributes, GLLimits};
use servo_url::ImmutableOrigin;
use servo_url::ServoUrl;
use style_traits::CSSPixel;
@@ -77,6 +78,11 @@ pub enum ScriptMsg {
/// Requests that a new 2D canvas thread be created. (This is done in the constellation because
/// 2D canvases may use the GPU and we don't want to give untrusted content access to the GPU.)
CreateCanvasPaintThread(Size2D<i32>, IpcSender<IpcSender<CanvasMsg>>),
+ /// Requests that a new WebGL thread be created. (This is done in the constellation because
+ /// WebGL uses the GPU and we don't want to give untrusted content access to the GPU.)
+ CreateWebGLPaintThread(Size2D<i32>,
+ GLContextAttributes,
+ IpcSender<Result<(IpcSender<CanvasMsg>, GLLimits), String>>),
/// Notifies the constellation that this frame has received focus.
Focus,
/// Forward an event that was sent to the parent window.
diff --git a/components/servo/lib.rs b/components/servo/lib.rs
index 93e6d4cf454..07212a2b2d1 100644
--- a/components/servo/lib.rs
+++ b/components/servo/lib.rs
@@ -68,8 +68,6 @@ fn webdriver(_port: u16, _constellation: Sender<ConstellationMsg>) { }
use bluetooth::BluetoothThreadFactory;
use bluetooth_traits::BluetoothRequest;
-use canvas::gl_context::GLContextFactory;
-use canvas::webgl_thread::WebGLThreads;
use compositing::IOCompositor;
use compositing::compositor_thread::{self, CompositorProxy, CompositorReceiver, InitialCompositorState};
use compositing::windowing::WindowEvent;
@@ -151,7 +149,7 @@ impl<Window> Servo<Window> where Window: WindowMethods + 'static {
let mut resource_path = resources_dir_path().unwrap();
resource_path.push("shaders");
- let (mut webrender, webrender_api_sender) = {
+ let (webrender, webrender_api_sender) = {
// TODO(gw): Duplicates device_pixels_per_screen_px from compositor. Tidy up!
let scale_factor = window.hidpi_factor().get();
let device_pixel_ratio = match opts.device_pixels_per_px {
@@ -213,7 +211,7 @@ impl<Window> Servo<Window> where Window: WindowMethods + 'static {
debugger_chan,
devtools_chan,
supports_clipboard,
- &mut webrender,
+ &webrender,
webrender_document,
webrender_api_sender);
@@ -290,7 +288,7 @@ fn create_constellation(user_agent: Cow<'static, str>,
debugger_chan: Option<debugger::Sender>,
devtools_chan: Option<Sender<devtools_traits::DevtoolsControlMsg>>,
supports_clipboard: bool,
- webrender: &mut webrender::Renderer,
+ webrender: &webrender::Renderer,
webrender_document: webrender_api::DocumentId,
webrender_api_sender: webrender_api::RenderApiSender)
-> (Sender<ConstellationMsg>, SWManagerSenders) {
@@ -306,30 +304,6 @@ fn create_constellation(user_agent: Cow<'static, str>,
let resource_sender = public_resource_threads.sender();
- let (webvr_chan, webvr_constellation_sender, webvr_compositor) = if PREFS.is_webvr_enabled() {
- // WebVR initialization
- let (mut handler, sender) = WebVRCompositorHandler::new();
- let (webvr_thread, constellation_sender) = WebVRThread::spawn(sender);
- handler.set_webvr_thread_sender(webvr_thread.clone());
- (Some(webvr_thread), Some(constellation_sender), Some(handler))
- } else {
- (None, None, None)
- };
-
- // GLContext factory used to create WebGL Contexts
- let gl_factory = if opts::get().should_use_osmesa() {
- GLContextFactory::current_osmesa_handle().unwrap()
- } else {
- GLContextFactory::current_native_handle(&compositor_proxy).unwrap()
- };
-
- // Initialize WebGL Thread entry point.
- let (webgl_threads, image_handler) = WebGLThreads::new(gl_factory,
- 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 initial_state = InitialConstellationState {
compositor_proxy,
debugger_chan,
@@ -343,17 +317,20 @@ fn create_constellation(user_agent: Cow<'static, str>,
supports_clipboard,
webrender_document,
webrender_api_sender,
- webgl_threads,
- webvr_chan,
};
let (constellation_chan, from_swmanager_sender) =
Constellation::<script_layout_interface::message::Msg,
layout_thread::LayoutThread,
script::script_thread::ScriptThread>::start(initial_state);
- if let Some(webvr_constellation_sender) = webvr_constellation_sender {
- // Set constellation channel used by WebVR thread to broadcast events
- webvr_constellation_sender.send(constellation_chan.clone()).unwrap();
+ if PREFS.is_webvr_enabled() {
+ // WebVR initialization
+ let (mut handler, sender) = WebVRCompositorHandler::new();
+ let webvr_thread = WebVRThread::spawn(constellation_chan.clone(), sender);
+ handler.set_webvr_thread_sender(webvr_thread.clone());
+
+ webrender.set_vr_compositor_handler(handler);
+ constellation_chan.send(ConstellationMsg::SetWebVRThread(webvr_thread)).unwrap();
}
// channels to communicate with Service Worker Manager
diff --git a/components/webvr/Cargo.toml b/components/webvr/Cargo.toml
index f6a7427a709..f7edd95d6d8 100644
--- a/components/webvr/Cargo.toml
+++ b/components/webvr/Cargo.toml
@@ -10,11 +10,10 @@ name = "webvr"
path = "lib.rs"
[dependencies]
-canvas_traits = {path = "../canvas_traits"}
-euclid = "0.15"
ipc-channel = "0.8"
log = "0.3"
msg = {path = "../msg"}
script_traits = {path = "../script_traits"}
servo_config = {path = "../config"}
webvr_traits = {path = "../webvr_traits" }
+webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
diff --git a/components/webvr/lib.rs b/components/webvr/lib.rs
index 0ad9722b21e..62f3e992fdc 100644
--- a/components/webvr/lib.rs
+++ b/components/webvr/lib.rs
@@ -4,14 +4,13 @@
#![deny(unsafe_code)]
-extern crate canvas_traits;
-extern crate euclid;
extern crate ipc_channel;
#[macro_use]
extern crate log;
extern crate msg;
extern crate script_traits;
extern crate servo_config;
+extern crate webrender_api;
extern crate webvr_traits;
mod webvr_thread;
diff --git a/components/webvr/webvr_thread.rs b/components/webvr/webvr_thread.rs
index 77f42a6b39e..ec550153870 100644
--- a/components/webvr/webvr_thread.rs
+++ b/components/webvr/webvr_thread.rs
@@ -2,8 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use canvas_traits::webgl;
-use euclid::Size2D;
use ipc_channel::ipc;
use ipc_channel::ipc::{IpcReceiver, IpcSender};
use msg::constellation_msg::PipelineId;
@@ -13,6 +11,8 @@ use std::{thread, time};
use std::collections::{HashMap, HashSet};
use std::sync::mpsc;
use std::sync::mpsc::{Receiver, Sender};
+use webrender_api;
+use webrender_api::DeviceIntSize;
use webvr_traits::{WebVRMsg, WebVRResult};
use webvr_traits::webvr::*;
@@ -34,7 +34,7 @@ use webvr_traits::webvr::*;
/// ids using the WebVR APIs. These ids are used to implement privacy guidelines defined in the WebVR Spec.
/// * When a JavaScript thread gains access to present to a headset, WebVRThread is not used as a intermediary in
/// the VRDisplay.requestAnimationFrame loop in order to minimize latency. A direct communication with WebRender
-/// is used instead. See WebVRCompositorHandler and the WebVRCommands for more details.
+/// is used instead. See WebVRCompositorHandler and the VRCompositorCommanda for more details.
pub struct WebVRThread {
receiver: IpcReceiver<WebVRMsg>,
sender: IpcSender<WebVRMsg>,
@@ -66,17 +66,15 @@ impl WebVRThread {
}
}
- pub fn spawn(vr_compositor_chan: WebVRCompositorSender)
- -> (IpcSender<WebVRMsg>, Sender<Sender<ConstellationMsg>>) {
+ pub fn spawn(constellation_chan: Sender<ConstellationMsg>,
+ vr_compositor_chan: WebVRCompositorSender)
+ -> IpcSender<WebVRMsg> {
let (sender, receiver) = ipc::channel().unwrap();
- let (constellation_sender, constellation_receiver) = mpsc::channel();
let sender_clone = sender.clone();
thread::Builder::new().name("WebVRThread".into()).spawn(move || {
- let constellation_chan = constellation_receiver.recv().unwrap();
WebVRThread::new(receiver, sender_clone, constellation_chan, vr_compositor_chan).start();
}).expect("Thread spawning failed");
-
- (sender, constellation_sender)
+ sender
}
fn start(&mut self) {
@@ -307,7 +305,7 @@ impl WebVRThread {
pub struct WebVRCompositor(*mut VRDisplay);
pub struct WebVRCompositorHandler {
- compositors: HashMap<webgl::WebVRDeviceId, WebVRCompositor>,
+ compositors: HashMap<webrender_api::VRCompositorId, WebVRCompositor>,
webvr_thread_receiver: Receiver<Option<WebVRCompositor>>,
webvr_thread_sender: Option<IpcSender<WebVRMsg>>
}
@@ -330,14 +328,14 @@ impl WebVRCompositorHandler {
}
}
-impl webgl::WebVRRenderHandler for WebVRCompositorHandler {
+impl webrender_api::VRCompositorHandler for WebVRCompositorHandler {
#[allow(unsafe_code)]
- fn handle(&mut self, cmd: webgl::WebVRCommand, texture: Option<(u32, Size2D<i32>)>) {
+ fn handle(&mut self, cmd: webrender_api::VRCompositorCommand, texture: Option<(u32, DeviceIntSize)>) {
match cmd {
- webgl::WebVRCommand::Create(compositor_id) => {
+ webrender_api::VRCompositorCommand::Create(compositor_id) => {
self.create_compositor(compositor_id);
}
- webgl::WebVRCommand::SyncPoses(compositor_id, near, far, sender) => {
+ webrender_api::VRCompositorCommand::SyncPoses(compositor_id, near, far, sender) => {
if let Some(compositor) = self.compositors.get(&compositor_id) {
let pose = unsafe {
(*compositor.0).sync_poses();
@@ -348,7 +346,7 @@ impl webgl::WebVRRenderHandler for WebVRCompositorHandler {
let _ = sender.send(Err(()));
}
}
- webgl::WebVRCommand::SubmitFrame(compositor_id, left_bounds, right_bounds) => {
+ webrender_api::VRCompositorCommand::SubmitFrame(compositor_id, left_bounds, right_bounds) => {
if let Some(compositor) = self.compositors.get(&compositor_id) {
if let Some((texture_id, size)) = texture {
let layer = VRLayer {
@@ -363,7 +361,7 @@ impl webgl::WebVRRenderHandler for WebVRCompositorHandler {
}
}
}
- webgl::WebVRCommand::Release(compositor_id) => {
+ webrender_api::VRCompositorCommand::Release(compositor_id) => {
self.compositors.remove(&compositor_id);
}
}
@@ -372,7 +370,7 @@ impl webgl::WebVRRenderHandler for WebVRCompositorHandler {
impl WebVRCompositorHandler {
#[allow(unsafe_code)]
- fn create_compositor(&mut self, display_id: webgl::WebVRDeviceId) {
+ fn create_compositor(&mut self, display_id: webrender_api::VRCompositorId) {
let sender = match self.webvr_thread_sender {
Some(ref s) => s,
None => return,