Skip to content

Commit

Permalink
Auto merge of #6705 - pcwalton:image-cache-shmem, r=jdm
Browse files Browse the repository at this point in the history
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.

r? @jdm

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/6705)
<!-- Reviewable:end -->
  • Loading branch information
bors-servo committed Jul 24, 2015
2 parents b386d7a + 0461ae9 commit ace452d
Show file tree
Hide file tree
Showing 13 changed files with 54 additions and 20 deletions.
3 changes: 3 additions & 0 deletions components/canvas/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
5 changes: 3 additions & 2 deletions components/canvas/canvas_paint_task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -515,9 +516,9 @@ impl<'a> CanvasPaintTask<'a> {
self.drawtarget = CanvasPaintTask::create(size);
}

fn send_pixel_contents(&mut self, chan: Sender<Vec<u8>>) {
fn send_pixel_contents(&mut self, chan: Sender<IpcSharedMemory>) {
self.drawtarget.snapshot().get_data_surface().with_data(|element| {
chan.send(element.to_vec()).unwrap();
chan.send(IpcSharedMemory::from_bytes(element)).unwrap();
})
}

Expand Down
1 change: 1 addition & 0 deletions components/canvas/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
9 changes: 6 additions & 3 deletions components/canvas/webgl_paint_task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<i32>,
Expand Down Expand Up @@ -440,9 +441,11 @@ impl WebGLPaintTask {
gl::viewport(x, y, width, height);
}

fn send_pixel_contents(&mut self, chan: Sender<Vec<u8>>) {
fn send_pixel_contents(&mut self, chan: Sender<IpcSharedMemory>) {
// 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,
Expand All @@ -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<NativeSurface>) {
Expand Down
3 changes: 3 additions & 0 deletions components/canvas_traits/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
4 changes: 3 additions & 1 deletion components/canvas_traits/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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 {
Expand All @@ -41,7 +43,7 @@ pub enum CanvasMsg {
pub enum CanvasCommonMsg {
Close,
Recreate(Size2D<i32>),
SendPixelContents(Sender<Vec<u8>>),
SendPixelContents(Sender<IpcSharedMemory>),
SendNativeSurface(Sender<NativeSurface>),
}

Expand Down
5 changes: 3 additions & 2 deletions components/layout/display_list_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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::<Vec<u8>>();
let (sender, receiver) = channel::<IpcSharedMemory>();
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,
Expand Down
3 changes: 3 additions & 0 deletions components/net_traits/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
7 changes: 4 additions & 3 deletions components/net_traits/image/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -23,7 +24,7 @@ pub struct Image {
pub width: u32,
pub height: u32,
pub format: PixelFormat,
pub bytes: Vec<u8>,
pub bytes: IpcSharedMemory,
}

// TODO(pcwalton): Speed up with SIMD, or better yet, find some way to not do this.
Expand Down Expand Up @@ -66,7 +67,7 @@ pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
};

let bytes = mem::replace(bytes, Vec::new());

let bytes = IpcSharedMemory::from_bytes(&bytes[..]);
let image = Image {
width: png_image.width,
height: png_image.height,
Expand Down Expand Up @@ -96,7 +97,7 @@ pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
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) => {
Expand Down
1 change: 1 addition & 0 deletions components/net_traits/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

extern crate euclid;
extern crate hyper;
extern crate ipc_channel;
#[macro_use]
extern crate log;
extern crate png;
Expand Down
11 changes: 8 additions & 3 deletions components/servo/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 8 additions & 3 deletions ports/cef/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 8 additions & 3 deletions ports/gonk/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit ace452d

Please sign in to comment.