зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
1fe5a3a13e
Коммит
63addaeaca
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче