servo: Merge #18114 - Revert "Auto merge of #17891 - MortimerGoro:webgl_move, r=glennw,emilio" (from emilio:revert-webgl-refactor); r=nox

This reverts commit 90f55ea4580e2a15f7d70d0491444f18b972d450, reversing
changes made to 2e60b27a2186a8cba4b952960155dfcf3f47d7db.

Doing that per Josh's request, since it's causing very frequent intermittent OOMs on the android builders.

Source-Repo: https://github.com/servo/servo
Source-Revision: 4d10d39e8fe841c5fe2ac58da2daaa13c10c140e

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 0474db248269e8cf2b094bfa04e32701137c46c8
This commit is contained in:
Emilio Cobos Álvarez 2017-08-16 09:45:13 -05:00
Родитель 1fe5a3a13e
Коммит 63addaeaca
54 изменённых файлов: 1426 добавлений и 3154 удалений

11
servo/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",
]

Просмотреть файл

@ -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"]}

Просмотреть файл

@ -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();
})
}

Просмотреть файл

@ -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));
}
}

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);
}
}

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);
}
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -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"]}

Просмотреть файл

@ -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;
}
}

Просмотреть файл

@ -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;
}
}

Просмотреть файл

@ -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)
}
}

Просмотреть файл

@ -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()
}

Просмотреть файл

@ -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()
}
}

Просмотреть файл

@ -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);

Просмотреть файл

@ -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"

Просмотреть файл

@ -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.

Просмотреть файл

@ -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;

Просмотреть файл

@ -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,

Просмотреть файл

@ -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(),

Просмотреть файл

@ -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)
},
CanvasFragmentSource::Image(ref ipc_renderer) => {
match *ipc_renderer {
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().image_key, PixelFormat::BGRA8)
receiver.recv().unwrap()
},
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 {
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: format,
key: Some(image_key),
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);
}

Просмотреть файл

@ -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.
@ -322,32 +321,18 @@ 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),
}

Просмотреть файл

@ -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();

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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;

Просмотреть файл

@ -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};

Просмотреть файл

@ -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)
}
}

Просмотреть файл

@ -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()))
let ipc_renderer = canvas.context.borrow_for_layout().as_ref().map(|context| {
match *context {
CanvasContext::Context2d(ref context) => {
context.to_layout().get_ipc_renderer()
},
Some(&CanvasContext::WebGL(ref context)) => {
context.to_layout().canvas_data_source()
CanvasContext::WebGL(ref context) => {
context.to_layout().get_ipc_renderer()
},
None => {
HTMLCanvasDataSource::Image(None)
}
};
});
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 data = if let Some(renderer) = self.ipc_renderer() {
let (sender, receiver) = ipc::channel().unwrap();
let msg = CanvasMsg::FromScript(FromScriptMsg::SendPixels(sender));
context.get_ipc_renderer().send(msg).unwrap();
renderer.send(msg).unwrap();
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 => {
} else {
repeat(0xffu8).take((size.height as usize) * (size.width as usize) * 4).collect()
}
};
Some((data, size))

Просмотреть файл

@ -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> {

Просмотреть файл

@ -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,
};

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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());
}

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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.

Просмотреть файл

@ -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)]

Просмотреть файл

@ -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);
}
}

Просмотреть файл

@ -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,
self.renderer.send(CanvasMsg::WebGL(WebGLCommand::FramebufferRenderbuffer(constants::FRAMEBUFFER,
attachment,
constants::RENDERBUFFER,
rb_id)).unwrap();
rb_id))).unwrap();
self.update_status();
Ok(())
@ -280,11 +281,11 @@ impl WebGLFramebuffer {
}
};
self.renderer.send(WebGLCommand::FramebufferTexture2D(constants::FRAMEBUFFER,
self.renderer.send(CanvasMsg::WebGL(WebGLCommand::FramebufferTexture2D(constants::FRAMEBUFFER,
attachment,
textarget,
tex_id,
level)).unwrap();
level))).unwrap();
self.update_status();
Ok(())

Просмотреть файл

@ -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()
}
}

Просмотреть файл

@ -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)));

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -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()
}

Просмотреть файл

@ -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(())
},

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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),

Просмотреть файл

@ -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,

Просмотреть файл

@ -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,
}

Просмотреть файл

@ -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"

Просмотреть файл

@ -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.

Просмотреть файл

@ -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.

Просмотреть файл

@ -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

Просмотреть файл

@ -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"]}

Просмотреть файл

@ -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;

Просмотреть файл

@ -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,