Skip to content

Commit ace452d

Browse files
author
bors-servo
committed
Auto merge of #6705 - pcwalton:image-cache-shmem, r=jdm
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 -->
2 parents b386d7a + 0461ae9 commit ace452d

File tree

13 files changed

+54
-20
lines changed

13 files changed

+54
-20
lines changed

components/canvas/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ path = "../gfx_traits"
2727
git = "https://github.com/ecoal95/rust-offscreen-rendering-context"
2828
features = ["texture_surface"]
2929

30+
[dependencies.ipc-channel]
31+
git = "https://github.com/pcwalton/ipc-channel"
32+
3033
[dependencies]
3134
log = "0.3"
3235
cssparser = "0.3.1"

components/canvas/canvas_paint_task.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use euclid::rect::Rect;
1313
use euclid::size::Size2D;
1414
use layers::platform::surface::NativeSurface;
1515
use gfx_traits::color;
16+
use ipc_channel::ipc::IpcSharedMemory;
1617
use num::ToPrimitive;
1718
use util::opts;
1819
use util::task::spawn_named;
@@ -515,9 +516,9 @@ impl<'a> CanvasPaintTask<'a> {
515516
self.drawtarget = CanvasPaintTask::create(size);
516517
}
517518

518-
fn send_pixel_contents(&mut self, chan: Sender<Vec<u8>>) {
519+
fn send_pixel_contents(&mut self, chan: Sender<IpcSharedMemory>) {
519520
self.drawtarget.snapshot().get_data_surface().with_data(|element| {
520-
chan.send(element.to_vec()).unwrap();
521+
chan.send(IpcSharedMemory::from_bytes(element)).unwrap();
521522
})
522523
}
523524

components/canvas/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ extern crate gleam;
1818
extern crate num;
1919
extern crate layers;
2020
extern crate offscreen_gl_context;
21+
extern crate ipc_channel;
2122

2223
#[macro_use]
2324
extern crate log;

components/canvas/webgl_paint_task.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use std::sync::mpsc::{channel, Sender};
1616
use util::vec::byte_swap;
1717
use layers::platform::surface::NativeSurface;
1818
use offscreen_gl_context::{GLContext, GLContextAttributes, ColorAttachmentType};
19+
use ipc_channel::ipc::IpcSharedMemory;
1920

2021
pub struct WebGLPaintTask {
2122
size: Size2D<i32>,
@@ -440,9 +441,11 @@ impl WebGLPaintTask {
440441
gl::viewport(x, y, width, height);
441442
}
442443

443-
fn send_pixel_contents(&mut self, chan: Sender<Vec<u8>>) {
444+
fn send_pixel_contents(&mut self, chan: Sender<IpcSharedMemory>) {
444445
// FIXME(#5652, dmarcos) Instead of a readback strategy we have
445-
// to layerize the canvas
446+
// to layerize the canvas.
447+
// TODO(pcwalton): We'd save a copy if we had an `IpcSharedMemoryBuilder` abstraction that
448+
// allowed you to mutate in-place before freezing the object for sending.
446449
let width = self.size.width as usize;
447450
let height = self.size.height as usize;
448451
let mut pixels = gl::read_pixels(0, 0,
@@ -461,7 +464,7 @@ impl WebGLPaintTask {
461464

462465
// rgba -> bgra
463466
byte_swap(&mut pixels);
464-
chan.send(pixels).unwrap();
467+
chan.send(IpcSharedMemory::from_bytes(&pixels[..])).unwrap();
465468
}
466469

467470
fn send_native_surface(&self, _: Sender<NativeSurface>) {

components/canvas_traits/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ git = "https://github.com/servo/rust-layers"
1919
[dependencies.offscreen_gl_context]
2020
git = "https://github.com/ecoal95/rust-offscreen-rendering-context"
2121

22+
[dependencies.ipc-channel]
23+
git = "https://github.com/pcwalton/ipc-channel"
24+
2225
[dependencies]
2326
cssparser = "0.3.1"
2427
euclid = "0.1"

components/canvas_traits/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ extern crate azure;
1111
extern crate euclid;
1212
extern crate cssparser;
1313
extern crate gfx_traits;
14+
extern crate ipc_channel;
1415
extern crate layers;
1516
extern crate offscreen_gl_context;
1617

@@ -29,6 +30,7 @@ use std::sync::mpsc::{Sender};
2930
use layers::platform::surface::NativeSurface;
3031
use offscreen_gl_context::GLContextAttributes;
3132
use core::nonzero::NonZero;
33+
use ipc_channel::ipc::IpcSharedMemory;
3234

3335
#[derive(Clone)]
3436
pub enum CanvasMsg {
@@ -41,7 +43,7 @@ pub enum CanvasMsg {
4143
pub enum CanvasCommonMsg {
4244
Close,
4345
Recreate(Size2D<i32>),
44-
SendPixelContents(Sender<Vec<u8>>),
46+
SendPixelContents(Sender<IpcSharedMemory>),
4547
SendNativeSurface(Sender<NativeSurface>),
4648
}
4749

components/layout/display_list_builder.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use gfx::display_list::{GradientStop, ImageDisplayItem, LineDisplayItem};
3232
use gfx::display_list::{OpaqueNode, SolidColorDisplayItem};
3333
use gfx::display_list::{StackingContext, TextDisplayItem, TextOrientation};
3434
use gfx::paint_task::{PaintLayer, THREAD_TINT_COLORS};
35+
use ipc_channel::ipc::IpcSharedMemory;
3536
use msg::compositor_msg::{ScrollPolicy, LayerId};
3637
use msg::constellation_msg::ConstellationChan;
3738
use msg::constellation_msg::Msg as ConstellationMsg;
@@ -1098,14 +1099,14 @@ impl FragmentDisplayListBuilding for Fragment {
10981099
.computed_inline_size.map_or(0, |w| w.to_px() as usize);
10991100
let height = canvas_fragment_info.replaced_image_fragment_info
11001101
.computed_block_size.map_or(0, |h| h.to_px() as usize);
1101-
let (sender, receiver) = channel::<Vec<u8>>();
1102+
let (sender, receiver) = channel::<IpcSharedMemory>();
11021103
let canvas_data = match canvas_fragment_info.renderer {
11031104
Some(ref renderer) => {
11041105
renderer.lock().unwrap().send(CanvasMsg::Common(
11051106
CanvasCommonMsg::SendPixelContents(sender))).unwrap();
11061107
receiver.recv().unwrap()
11071108
},
1108-
None => vec![0xFFu8; width * height * 4],
1109+
None => IpcSharedMemory::from_byte(0xFFu8, width * height * 4),
11091110
};
11101111
display_list.content.push_back(DisplayItem::ImageClass(box ImageDisplayItem{
11111112
base: BaseDisplayItem::new(stacking_relative_content_box,

components/net_traits/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ git = "https://github.com/servo/rust-stb-image"
2424
version = "0.6"
2525
features = [ "serde-serialization" ]
2626

27+
[dependencies.ipc-channel]
28+
git = "https://github.com/pcwalton/ipc-channel"
29+
2730
[dependencies]
2831
log = "0.3"
2932
url = "0.2.36"

components/net_traits/image/base.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5+
use ipc_channel::ipc::IpcSharedMemory;
56
use png;
67
use stb_image::image as stb_image2;
78
use std::mem;
@@ -23,7 +24,7 @@ pub struct Image {
2324
pub width: u32,
2425
pub height: u32,
2526
pub format: PixelFormat,
26-
pub bytes: Vec<u8>,
27+
pub bytes: IpcSharedMemory,
2728
}
2829

2930
// 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<Image> {
6667
};
6768

6869
let bytes = mem::replace(bytes, Vec::new());
69-
70+
let bytes = IpcSharedMemory::from_bytes(&bytes[..]);
7071
let image = Image {
7172
width: png_image.width,
7273
height: png_image.height,
@@ -96,7 +97,7 @@ pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
9697
width: image.width as u32,
9798
height: image.height as u32,
9899
format: PixelFormat::RGBA8,
99-
bytes: image.data,
100+
bytes: IpcSharedMemory::from_bytes(&image.data[..]),
100101
})
101102
}
102103
stb_image2::LoadResult::ImageF32(_image) => {

components/net_traits/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
extern crate euclid;
1414
extern crate hyper;
15+
extern crate ipc_channel;
1516
#[macro_use]
1617
extern crate log;
1718
extern crate png;

components/servo/Cargo.lock

+8-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ports/cef/Cargo.lock

+8-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ports/gonk/Cargo.lock

+8-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)