From 626974994a739f27373c93b19830eaa6828cc387 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 22 Jul 2015 22:53:52 -0700 Subject: [PATCH] canvas: Move to shared memory for images and canvas backing stores. The idea here is to land this before making images and canvas IPC-safe, because this will shake out bugs relating to the shared memory. There are currently test timeouts that are preventing multiprocess images and canvas from landing, and I believe those are due to the inefficiency of sending large amounts of data in the unoptimized builds we test with. By moving to shared memory, this should drastically reduce the number of copies and `serde` serialization. Under the hood, this uses Mach OOL messages on Mac and temporary memory-mapped files on Linux. --- components/canvas/Cargo.toml | 3 +++ components/canvas/canvas_paint_task.rs | 5 +++-- components/canvas/lib.rs | 1 + components/canvas/webgl_paint_task.rs | 9 ++++++--- components/canvas_traits/Cargo.toml | 3 +++ components/canvas_traits/lib.rs | 4 +++- components/layout/display_list_builder.rs | 5 +++-- components/net_traits/Cargo.toml | 3 +++ components/net_traits/image/base.rs | 7 ++++--- components/net_traits/lib.rs | 1 + components/servo/Cargo.lock | 11 ++++++++--- ports/cef/Cargo.lock | 11 ++++++++--- ports/gonk/Cargo.lock | 11 ++++++++--- 13 files changed, 54 insertions(+), 20 deletions(-) diff --git a/components/canvas/Cargo.toml b/components/canvas/Cargo.toml index 28c3be043f4..92081f00c16 100644 --- a/components/canvas/Cargo.toml +++ b/components/canvas/Cargo.toml @@ -27,6 +27,9 @@ path = "../gfx_traits" git = "https://github.com/ecoal95/rust-offscreen-rendering-context" features = ["texture_surface"] +[dependencies.ipc-channel] +git = "https://github.com/pcwalton/ipc-channel" + [dependencies] log = "0.3" cssparser = "0.3.1" diff --git a/components/canvas/canvas_paint_task.rs b/components/canvas/canvas_paint_task.rs index 450266c3883..af00d817ab6 100644 --- a/components/canvas/canvas_paint_task.rs +++ b/components/canvas/canvas_paint_task.rs @@ -13,6 +13,7 @@ use euclid::rect::Rect; use euclid::size::Size2D; use layers::platform::surface::NativeSurface; use gfx_traits::color; +use ipc_channel::ipc::IpcSharedMemory; use num::ToPrimitive; use util::opts; use util::task::spawn_named; @@ -515,9 +516,9 @@ impl<'a> CanvasPaintTask<'a> { self.drawtarget = CanvasPaintTask::create(size); } - fn send_pixel_contents(&mut self, chan: Sender>) { + fn send_pixel_contents(&mut self, chan: Sender) { self.drawtarget.snapshot().get_data_surface().with_data(|element| { - chan.send(element.to_vec()).unwrap(); + chan.send(IpcSharedMemory::from_bytes(element)).unwrap(); }) } diff --git a/components/canvas/lib.rs b/components/canvas/lib.rs index 99f5881cca1..b78f552f9bb 100644 --- a/components/canvas/lib.rs +++ b/components/canvas/lib.rs @@ -18,6 +18,7 @@ extern crate gleam; extern crate num; extern crate layers; extern crate offscreen_gl_context; +extern crate ipc_channel; #[macro_use] extern crate log; diff --git a/components/canvas/webgl_paint_task.rs b/components/canvas/webgl_paint_task.rs index 6aecf0eba33..8af5e547c3a 100644 --- a/components/canvas/webgl_paint_task.rs +++ b/components/canvas/webgl_paint_task.rs @@ -16,6 +16,7 @@ use std::sync::mpsc::{channel, Sender}; use util::vec::byte_swap; use layers::platform::surface::NativeSurface; use offscreen_gl_context::{GLContext, GLContextAttributes, ColorAttachmentType}; +use ipc_channel::ipc::IpcSharedMemory; pub struct WebGLPaintTask { size: Size2D, @@ -440,9 +441,11 @@ impl WebGLPaintTask { gl::viewport(x, y, width, height); } - fn send_pixel_contents(&mut self, chan: Sender>) { + fn send_pixel_contents(&mut self, chan: Sender) { // FIXME(#5652, dmarcos) Instead of a readback strategy we have - // to layerize the canvas + // to layerize the canvas. + // TODO(pcwalton): We'd save a copy if we had an `IpcSharedMemoryBuilder` abstraction that + // allowed you to mutate in-place before freezing the object for sending. let width = self.size.width as usize; let height = self.size.height as usize; let mut pixels = gl::read_pixels(0, 0, @@ -461,7 +464,7 @@ impl WebGLPaintTask { // rgba -> bgra byte_swap(&mut pixels); - chan.send(pixels).unwrap(); + chan.send(IpcSharedMemory::from_bytes(&pixels[..])).unwrap(); } fn send_native_surface(&self, _: Sender) { diff --git a/components/canvas_traits/Cargo.toml b/components/canvas_traits/Cargo.toml index f2594ca4701..27bb9a0fb26 100644 --- a/components/canvas_traits/Cargo.toml +++ b/components/canvas_traits/Cargo.toml @@ -19,6 +19,9 @@ git = "https://github.com/servo/rust-layers" [dependencies.offscreen_gl_context] git = "https://github.com/ecoal95/rust-offscreen-rendering-context" +[dependencies.ipc-channel] +git = "https://github.com/pcwalton/ipc-channel" + [dependencies] cssparser = "0.3.1" euclid = "0.1" diff --git a/components/canvas_traits/lib.rs b/components/canvas_traits/lib.rs index 132b4b86a8a..b8103c8f9a9 100644 --- a/components/canvas_traits/lib.rs +++ b/components/canvas_traits/lib.rs @@ -11,6 +11,7 @@ extern crate azure; extern crate euclid; extern crate cssparser; extern crate gfx_traits; +extern crate ipc_channel; extern crate layers; extern crate offscreen_gl_context; @@ -29,6 +30,7 @@ use std::sync::mpsc::{Sender}; use layers::platform::surface::NativeSurface; use offscreen_gl_context::GLContextAttributes; use core::nonzero::NonZero; +use ipc_channel::ipc::IpcSharedMemory; #[derive(Clone)] pub enum CanvasMsg { @@ -41,7 +43,7 @@ pub enum CanvasMsg { pub enum CanvasCommonMsg { Close, Recreate(Size2D), - SendPixelContents(Sender>), + SendPixelContents(Sender), SendNativeSurface(Sender), } diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index b3ad6742f4d..f13dee8fa5d 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -32,6 +32,7 @@ use gfx::display_list::{GradientStop, ImageDisplayItem, LineDisplayItem}; use gfx::display_list::{OpaqueNode, SolidColorDisplayItem}; use gfx::display_list::{StackingContext, TextDisplayItem, TextOrientation}; use gfx::paint_task::{PaintLayer, THREAD_TINT_COLORS}; +use ipc_channel::ipc::IpcSharedMemory; use msg::compositor_msg::{ScrollPolicy, LayerId}; use msg::constellation_msg::ConstellationChan; use msg::constellation_msg::Msg as ConstellationMsg; @@ -1098,14 +1099,14 @@ impl FragmentDisplayListBuilding for Fragment { .computed_inline_size.map_or(0, |w| w.to_px() as usize); let height = canvas_fragment_info.replaced_image_fragment_info .computed_block_size.map_or(0, |h| h.to_px() as usize); - let (sender, receiver) = channel::>(); + let (sender, receiver) = channel::(); let canvas_data = match canvas_fragment_info.renderer { Some(ref renderer) => { renderer.lock().unwrap().send(CanvasMsg::Common( CanvasCommonMsg::SendPixelContents(sender))).unwrap(); receiver.recv().unwrap() }, - None => vec![0xFFu8; width * height * 4], + None => IpcSharedMemory::from_byte(0xFFu8, width * height * 4), }; display_list.content.push_back(DisplayItem::ImageClass(box ImageDisplayItem{ base: BaseDisplayItem::new(stacking_relative_content_box, diff --git a/components/net_traits/Cargo.toml b/components/net_traits/Cargo.toml index bcb15a868ff..a6940c0f6c6 100644 --- a/components/net_traits/Cargo.toml +++ b/components/net_traits/Cargo.toml @@ -24,6 +24,9 @@ git = "https://github.com/servo/rust-stb-image" version = "0.6" features = [ "serde-serialization" ] +[dependencies.ipc-channel] +git = "https://github.com/pcwalton/ipc-channel" + [dependencies] log = "0.3" url = "0.2.36" diff --git a/components/net_traits/image/base.rs b/components/net_traits/image/base.rs index 1a9ee30cfb5..fa776b85c4b 100644 --- a/components/net_traits/image/base.rs +++ b/components/net_traits/image/base.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use ipc_channel::ipc::IpcSharedMemory; use png; use stb_image::image as stb_image2; use std::mem; @@ -23,7 +24,7 @@ pub struct Image { pub width: u32, pub height: u32, pub format: PixelFormat, - pub bytes: Vec, + pub bytes: IpcSharedMemory, } // TODO(pcwalton): Speed up with SIMD, or better yet, find some way to not do this. @@ -66,7 +67,7 @@ pub fn load_from_memory(buffer: &[u8]) -> Option { }; let bytes = mem::replace(bytes, Vec::new()); - + let bytes = IpcSharedMemory::from_bytes(&bytes[..]); let image = Image { width: png_image.width, height: png_image.height, @@ -96,7 +97,7 @@ pub fn load_from_memory(buffer: &[u8]) -> Option { width: image.width as u32, height: image.height as u32, format: PixelFormat::RGBA8, - bytes: image.data, + bytes: IpcSharedMemory::from_bytes(&image.data[..]), }) } stb_image2::LoadResult::ImageF32(_image) => { diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs index 0ceb00939f8..a5975bc2fa0 100644 --- a/components/net_traits/lib.rs +++ b/components/net_traits/lib.rs @@ -12,6 +12,7 @@ extern crate euclid; extern crate hyper; +extern crate ipc_channel; #[macro_use] extern crate log; extern crate png; diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 90d29e2e9e8..e3289f453ca 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -83,7 +83,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "byteorder" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -96,6 +96,7 @@ dependencies = [ "euclid 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_traits 0.0.1", "gleam 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", @@ -111,6 +112,7 @@ dependencies = [ "cssparser 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_traits 0.0.1", + "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "offscreen_gl_context 0.1.0 (git+https://github.com/ecoal95/rust-offscreen-rendering-context)", ] @@ -638,8 +640,10 @@ dependencies = [ [[package]] name = "ipc-channel" version = "0.1.0" -source = "git+https://github.com/pcwalton/ipc-channel#1043d943a4da75ba302cfbe0b55afe1c84887560" +source = "git+https://github.com/pcwalton/ipc-channel#01f43c1851774023b0bd9b7fdd12d00f087fafb2" dependencies = [ + "byteorder 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -887,6 +891,7 @@ version = "0.0.1" dependencies = [ "euclid 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "png 0.1.0 (git+https://github.com/servo/rust-png)", @@ -1504,7 +1509,7 @@ version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index eb55c30ac09..58eaf628956 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -82,7 +82,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "byteorder" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -95,6 +95,7 @@ dependencies = [ "euclid 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_traits 0.0.1", "gleam 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", @@ -110,6 +111,7 @@ dependencies = [ "cssparser 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_traits 0.0.1", + "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "offscreen_gl_context 0.1.0 (git+https://github.com/ecoal95/rust-offscreen-rendering-context)", ] @@ -630,8 +632,10 @@ dependencies = [ [[package]] name = "ipc-channel" version = "0.1.0" -source = "git+https://github.com/pcwalton/ipc-channel#1043d943a4da75ba302cfbe0b55afe1c84887560" +source = "git+https://github.com/pcwalton/ipc-channel#01f43c1851774023b0bd9b7fdd12d00f087fafb2" dependencies = [ + "byteorder 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -866,6 +870,7 @@ version = "0.0.1" dependencies = [ "euclid 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "png 0.1.0 (git+https://github.com/servo/rust-png)", @@ -1477,7 +1482,7 @@ version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock index d625915614e..8938b748c62 100644 --- a/ports/gonk/Cargo.lock +++ b/ports/gonk/Cargo.lock @@ -69,7 +69,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "byteorder" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -82,6 +82,7 @@ dependencies = [ "euclid 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_traits 0.0.1", "gleam 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", @@ -97,6 +98,7 @@ dependencies = [ "cssparser 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_traits 0.0.1", + "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "offscreen_gl_context 0.1.0 (git+https://github.com/ecoal95/rust-offscreen-rendering-context)", ] @@ -564,8 +566,10 @@ dependencies = [ [[package]] name = "ipc-channel" version = "0.1.0" -source = "git+https://github.com/pcwalton/ipc-channel#1043d943a4da75ba302cfbe0b55afe1c84887560" +source = "git+https://github.com/pcwalton/ipc-channel#01f43c1851774023b0bd9b7fdd12d00f087fafb2" dependencies = [ + "byteorder 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -792,6 +796,7 @@ version = "0.0.1" dependencies = [ "euclid 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "png 0.1.0 (git+https://github.com/servo/rust-png)", @@ -1366,7 +1371,7 @@ version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",