servo: Merge #20423 - Use ByteBuf for the canvas messages (from servo:bytes); r=emilio

Source-Repo: https://github.com/servo/servo
Source-Revision: 9c5bdd932e4ce8720e25241cb1bbdd85be3c92a5

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 7b8308996554fb4f295cd7ea12ced2b59eb68975
This commit is contained in:
Anthony Ramine 2018-03-26 14:49:16 -04:00
parent bc58be9238
commit 321b823f45
19 changed files with 170 additions and 62 deletions

4
servo/Cargo.lock generated
View File

@ -274,6 +274,7 @@ dependencies = [
"log 0.3.9 (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.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bytes 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"servo_config 0.0.1",
"webrender 0.57.0 (git+https://github.com/servo/webrender)",
"webrender_api 0.57.0 (git+https://github.com/servo/webrender)",
@ -292,6 +293,7 @@ dependencies = [
"nonzero 0.0.1",
"offscreen_gl_context 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bytes 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"servo_config 0.0.1",
"webrender_api 0.57.0 (git+https://github.com/servo/webrender)",
]
@ -1628,6 +1630,7 @@ dependencies = [
"hashglobe 0.1.0",
"mozjs 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.19.0",
"serde_bytes 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"servo_arc 0.1.1",
"smallbitvec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2509,6 +2512,7 @@ dependencies = [
"script_traits 0.0.1",
"selectors 0.19.0",
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bytes 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"servo_allocator 0.0.1",
"servo_arc 0.1.1",

View File

@ -21,6 +21,7 @@ ipc-channel = "0.10"
log = "0.3.5"
num-traits = "0.1.32"
offscreen_gl_context = { version = "0.15", features = ["serde", "osmesa"] }
serde_bytes = "0.10"
servo_config = {path = "../config"}
webrender = {git = "https://github.com/servo/webrender"}
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}

View File

@ -13,6 +13,7 @@ use cssparser::RGBA;
use euclid::{Transform2D, Point2D, Vector2D, Rect, Size2D};
use ipc_channel::ipc::{self, IpcSender};
use num_traits::ToPrimitive;
use serde_bytes::ByteBuf;
use std::borrow::ToOwned;
use std::mem;
use std::sync::Arc;
@ -145,9 +146,20 @@ impl<'a> CanvasPaintThread<'a> {
Canvas2dMsg::IsPointInPath(x, y, fill_rule, chan) => {
painter.is_point_in_path(x, y, fill_rule, chan)
},
Canvas2dMsg::DrawImage(imagedata, image_size, dest_rect, source_rect,
smoothing_enabled) => {
painter.draw_image(imagedata, image_size, dest_rect, source_rect, smoothing_enabled)
Canvas2dMsg::DrawImage(
imagedata,
image_size,
dest_rect,
source_rect,
smoothing_enabled,
) => {
painter.draw_image(
imagedata.into(),
image_size,
dest_rect,
source_rect,
smoothing_enabled,
)
}
Canvas2dMsg::DrawImageSelf(image_size, dest_rect, source_rect, smoothing_enabled) => {
painter.draw_image_self(image_size, dest_rect, source_rect, smoothing_enabled)
@ -189,8 +201,19 @@ impl<'a> CanvasPaintThread<'a> {
Canvas2dMsg::SetGlobalComposition(op) => painter.set_global_composition(op),
Canvas2dMsg::GetImageData(dest_rect, canvas_size, chan)
=> painter.image_data(dest_rect, canvas_size, chan),
Canvas2dMsg::PutImageData(imagedata, offset, image_data_size, dirty_rect)
=> painter.put_image_data(imagedata, offset, image_data_size, dirty_rect),
Canvas2dMsg::PutImageData(
imagedata,
offset,
image_data_size,
dirty_rect,
) => {
painter.put_image_data(
imagedata.into(),
offset,
image_data_size,
dirty_rect,
)
}
Canvas2dMsg::SetShadowOffsetX(value) => painter.set_shadow_offset_x(value),
Canvas2dMsg::SetShadowOffsetY(value) => painter.set_shadow_offset_y(value),
Canvas2dMsg::SetShadowBlur(value) => painter.set_shadow_blur(value),
@ -402,7 +425,12 @@ impl<'a> CanvasPaintThread<'a> {
byte_swap(&mut image_data);
let msg = CanvasMsg::Canvas2d(Canvas2dMsg::DrawImage(
image_data, source_rect.size, dest_rect, source_rect, smoothing_enabled));
image_data.into(),
source_rect.size,
dest_rect,
source_rect,
smoothing_enabled,
));
renderer.send(msg).unwrap();
// We acknowledge to the caller here that the data was sent to the
// other canvas so that if JS immediately afterwards try to get the
@ -578,9 +606,9 @@ impl<'a> CanvasPaintThread<'a> {
}
}
fn send_pixels(&mut self, chan: IpcSender<Option<Vec<u8>>>) {
fn send_pixels(&mut self, chan: IpcSender<Option<ByteBuf>>) {
self.drawtarget.snapshot().get_data_surface().with_data(|element| {
chan.send(Some(element.into())).unwrap();
chan.send(Some(Vec::from(element).into())).unwrap();
})
}
@ -632,12 +660,17 @@ impl<'a> CanvasPaintThread<'a> {
})
}
fn image_data(&self, dest_rect: Rect<i32>, canvas_size: Size2D<f64>, chan: IpcSender<Vec<u8>>) {
fn image_data(
&self,
dest_rect: Rect<i32>,
canvas_size: Size2D<f64>,
chan: IpcSender<ByteBuf>,
) {
let mut dest_data = self.read_pixels(dest_rect, canvas_size);
// bgra -> rgba
byte_swap(&mut dest_data);
chan.send(dest_data).unwrap();
chan.send(dest_data.into()).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata

View File

@ -15,6 +15,7 @@ extern crate ipc_channel;
#[macro_use] extern crate log;
extern crate num_traits;
extern crate offscreen_gl_context;
extern crate serde_bytes;
extern crate servo_config;
extern crate webrender;
extern crate webrender_api;

View File

@ -8,6 +8,7 @@ use euclid::Size2D;
use fnv::FnvHashMap;
use gleam::gl;
use offscreen_gl_context::{GLContext, GLContextAttributes, GLLimits, NativeGLContextMethods};
use serde_bytes::ByteBuf;
use std::thread;
use super::gl_context::{GLContextFactory, GLContextWrapper};
use webrender;
@ -904,10 +905,18 @@ impl WebGLImpl {
//}
}
fn read_pixels(gl: &gl::Gl, x: i32, y: i32, width: i32, height: i32, format: u32, pixel_type: u32,
chan: WebGLSender<Vec<u8>>) {
fn read_pixels(
gl: &gl::Gl,
x: i32,
y: i32,
width: i32,
height: i32,
format: u32,
pixel_type: u32,
chan: WebGLSender<ByteBuf>,
) {
let result = gl.read_pixels(x, y, width, height, format, pixel_type);
chan.send(result).unwrap()
chan.send(result.into()).unwrap()
}
fn active_attrib(gl: &gl::Gl,

View File

@ -19,5 +19,6 @@ malloc_size_of_derive = { path = "../malloc_size_of_derive" }
nonzero = {path = "../nonzero"}
offscreen_gl_context = { version = "0.15", features = ["serde"] }
serde = "1.0"
serde_bytes = "0.10"
servo_config = {path = "../config"}
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}

View File

@ -5,6 +5,7 @@
use cssparser::RGBA;
use euclid::{Transform2D, Point2D, Vector2D, Rect, Size2D};
use ipc_channel::ipc::IpcSender;
use serde_bytes::ByteBuf;
use std::default::Default;
use std::str::FromStr;
use webrender_api;
@ -33,7 +34,7 @@ pub struct CanvasImageData {
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),
DrawImage(ByteBuf, 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<()>),
@ -46,11 +47,11 @@ pub enum Canvas2dMsg {
Fill,
FillText(String, f64, f64, Option<f64>),
FillRect(Rect<f32>),
GetImageData(Rect<i32>, Size2D<f64>, IpcSender<Vec<u8>>),
GetImageData(Rect<i32>, Size2D<f64>, IpcSender<ByteBuf>),
IsPointInPath(f64, f64, FillRule, IpcSender<bool>),
LineTo(Point2D<f32>),
MoveTo(Point2D<f32>),
PutImageData(Vec<u8>, Vector2D<f64>, Size2D<f64>, Rect<f64>),
PutImageData(ByteBuf, Vector2D<f64>, Size2D<f64>, Rect<f64>),
QuadraticCurveTo(Point2D<f32>, Point2D<f32>),
Rect(Rect<f32>),
RestoreContext,
@ -79,7 +80,7 @@ pub enum FromLayoutMsg {
#[derive(Clone, Deserialize, Serialize)]
pub enum FromScriptMsg {
SendPixels(IpcSender<Option<Vec<u8>>>),
SendPixels(IpcSender<Option<ByteBuf>>),
}
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
@ -138,20 +139,24 @@ impl RadialGradientStyle {
#[derive(Clone, Deserialize, Serialize)]
pub struct SurfaceStyle {
pub surface_data: Vec<u8>,
pub surface_data: ByteBuf,
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,
pub fn new(
surface_data: Vec<u8>,
surface_size: Size2D<i32>,
repeat_x: bool,
repeat_y: bool,
) -> Self {
Self {
surface_data: surface_data.into(),
surface_size,
repeat_x,
repeat_y,
}
}
}

View File

@ -16,6 +16,7 @@ extern crate malloc_size_of;
extern crate nonzero;
extern crate offscreen_gl_context;
#[macro_use] extern crate serde;
extern crate serde_bytes;
extern crate servo_config;
extern crate webrender_api;

View File

@ -5,6 +5,7 @@
use euclid::Size2D;
use nonzero::NonZero;
use offscreen_gl_context::{GLContextAttributes, GLLimits};
use serde_bytes::ByteBuf;
use std::fmt;
use webrender_api::{DocumentId, ImageKey, PipelineId};
@ -165,8 +166,8 @@ pub enum WebGLCommand {
AttachShader(WebGLProgramId, WebGLShaderId),
DetachShader(WebGLProgramId, WebGLShaderId),
BindAttribLocation(WebGLProgramId, u32, String),
BufferData(u32, Vec<u8>, u32),
BufferSubData(u32, isize, Vec<u8>),
BufferData(u32, ByteBuf, u32),
BufferSubData(u32, isize, ByteBuf),
Clear(u32),
ClearColor(f32, f32, f32, f32),
ClearDepth(f64),
@ -222,7 +223,7 @@ pub enum WebGLCommand {
GetFramebufferAttachmentParameter(u32, u32, u32, WebGLSender<i32>),
PolygonOffset(f32, f32),
RenderbufferStorage(u32, u32, i32, i32),
ReadPixels(i32, i32, i32, i32, u32, u32, WebGLSender<Vec<u8>>),
ReadPixels(i32, i32, i32, i32, u32, u32, WebGLSender<ByteBuf>),
SampleCoverage(f32, bool),
Scissor(i32, i32, i32, i32),
StencilFunc(u32, i32, u32),
@ -262,10 +263,10 @@ pub enum WebGLCommand {
VertexAttribPointer2f(u32, i32, bool, i32, u32),
GetViewport(WebGLSender<(i32, i32, i32, i32)>),
SetViewport(i32, i32, i32, i32),
TexImage2D(u32, i32, i32, i32, i32, u32, u32, Vec<u8>),
TexImage2D(u32, i32, i32, i32, i32, u32, u32, ByteBuf),
TexParameteri(u32, u32, i32),
TexParameterf(u32, u32, f32),
TexSubImage2D(u32, i32, i32, i32, i32, i32, u32, u32, Vec<u8>),
TexSubImage2D(u32, i32, i32, i32, i32, i32, u32, u32, ByteBuf),
DrawingBufferWidth(WebGLSender<i32>),
DrawingBufferHeight(WebGLSender<i32>),
Finish(WebGLSender<()>),
@ -401,7 +402,7 @@ 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>, ()>>),
SyncPoses(WebVRDeviceId, f64, f64, WebGLSender<Result<ByteBuf, ()>>),
/// Submit the frame to a VR device using the specified texture coordinates.
SubmitFrame(WebVRDeviceId, [f32; 4], [f32; 4]),
/// Stop presenting to a VR device

View File

@ -9,7 +9,14 @@ publish = false
path = "lib.rs"
[features]
servo = ["mozjs", "string_cache", "url", "webrender_api", "xml5ever"]
servo = [
"mozjs",
"serde_bytes",
"string_cache",
"url",
"webrender_api",
"xml5ever",
]
[dependencies]
app_units = "0.6"
@ -18,6 +25,7 @@ euclid = "0.17"
hashglobe = { path = "../hashglobe" }
mozjs = { version = "0.4", features = ["promises"], optional = true }
selectors = { path = "../selectors" }
serde_bytes = { version = "0.10", optional = true }
servo_arc = { path = "../servo_arc" }
smallbitvec = "1.0.3"
smallvec = "0.6"

View File

@ -50,6 +50,8 @@ extern crate hashglobe;
#[cfg(feature = "servo")]
extern crate mozjs as js;
extern crate selectors;
#[cfg(feature = "servo")]
extern crate serde_bytes;
extern crate servo_arc;
extern crate smallbitvec;
extern crate smallvec;
@ -63,6 +65,8 @@ extern crate webrender_api;
#[cfg(feature = "servo")]
extern crate xml5ever;
#[cfg(feature = "servo")]
use serde_bytes::ByteBuf;
use std::hash::{BuildHasher, Hash};
use std::mem::size_of;
use std::ops::Range;
@ -300,6 +304,24 @@ impl<T: MallocSizeOf> MallocSizeOf for [T] {
}
}
#[cfg(feature = "servo")]
impl MallocShallowSizeOf for ByteBuf {
fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
unsafe { ops.malloc_size_of(self.as_ptr()) }
}
}
#[cfg(feature = "servo")]
impl MallocSizeOf for ByteBuf {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
let mut n = self.shallow_size_of(ops);
for elem in self.iter() {
n += elem.size_of(ops);
}
n
}
}
impl<T> MallocShallowSizeOf for Vec<T> {
fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
unsafe { ops.malloc_size_of(self.as_ptr()) }

View File

@ -78,6 +78,7 @@ script_plugins = {path = "../script_plugins"}
script_traits = {path = "../script_traits"}
selectors = { path = "../selectors" }
serde = "1.0"
serde_bytes = "0.10"
servo_allocator = {path = "../allocator"}
servo_arc = {path = "../servo_arc"}
servo_atoms = {path = "../atoms"}

View File

@ -453,13 +453,13 @@ impl CanvasRenderingContext2D {
}
let smoothing_enabled = self.state.borrow().image_smoothing_enabled;
self.ipc_renderer
.send(CanvasMsg::Canvas2d(Canvas2dMsg::DrawImage(image_data,
image_size,
dest_rect,
source_rect,
smoothing_enabled)))
.unwrap();
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::DrawImage(
image_data.into(),
image_size,
dest_rect,
source_rect,
smoothing_enabled,
))).unwrap();
self.mark_as_dirty();
Ok(())
}
@ -1127,7 +1127,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
let sh = cmp::max(1, sh.to_u32().unwrap());
let sw = cmp::max(1, sw.to_u32().unwrap());
let (sender, receiver) = ipc::channel::<Vec<u8>>(self.global().time_profiler_chan().clone()).unwrap();
let (sender, receiver) = ipc::channel(self.global().time_profiler_chan().clone()).unwrap();
let dest_rect = Rect::new(Point2D::new(sx.to_i32().unwrap(), sy.to_i32().unwrap()),
Size2D::new(sw as i32, sh as i32));
let canvas_size = self.canvas.as_ref().map(|c| c.get_size()).unwrap_or(Size2D::zero());
@ -1135,7 +1135,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
self.ipc_renderer
.send(CanvasMsg::Canvas2d(Canvas2dMsg::GetImageData(dest_rect, canvas_size, sender)))
.unwrap();
let mut data = receiver.recv().unwrap();
let mut data = Vec::from(receiver.recv().unwrap());
// Un-premultiply alpha
for chunk in data.chunks_mut(4) {
@ -1174,10 +1174,12 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
let dirty_rect = Rect::new(Point2D::new(*dirty_x, *dirty_y),
Size2D::new(*dirty_width, *dirty_height));
let msg = CanvasMsg::Canvas2d(Canvas2dMsg::PutImageData(data,
offset,
image_data_size,
dirty_rect));
let msg = CanvasMsg::Canvas2d(Canvas2dMsg::PutImageData(
data.into(),
offset,
image_data_size,
dirty_rect,
));
self.ipc_renderer.send(msg).unwrap();
self.mark_as_dirty();
}

View File

@ -263,7 +263,7 @@ impl HTMLCanvasElement {
let msg = CanvasMsg::FromScript(FromScriptMsg::SendPixels(sender));
context.get_ipc_renderer().send(msg).unwrap();
receiver.recv().unwrap()?
receiver.recv().unwrap()?.into()
},
Some(&CanvasContext::WebGL(_)) => {
// TODO: add a method in WebGLRenderingContext to get the pixels.

View File

@ -35,6 +35,7 @@ use ipc_channel::ipc::IpcSender;
use profile_traits::ipc;
use script_runtime::CommonScriptMsg;
use script_runtime::ScriptThreadEventCategory::WebVREvent;
use serde_bytes::ByteBuf;
use std::cell::Cell;
use std::mem;
use std::ops::Deref;
@ -68,7 +69,7 @@ pub struct VRDisplay {
// Compositor VRFrameData synchonization
frame_data_status: Cell<VRFrameDataStatus>,
#[ignore_malloc_size_of = "closures are hard"]
frame_data_receiver: DomRefCell<Option<WebGLReceiver<Result<Vec<u8>, ()>>>>,
frame_data_receiver: DomRefCell<Option<WebGLReceiver<Result<ByteBuf, ()>>>>,
running_display_raf: Cell<bool>,
paused: Cell<bool>,
stopped_on_pause: Cell<bool>,

View File

@ -93,7 +93,11 @@ impl WebGLBuffer {
}
}
self.capacity.set(data.len());
self.renderer.send(WebGLCommand::BufferData(target, data.to_vec(), usage)).unwrap();
self.renderer.send(WebGLCommand::BufferData(
target,
data.to_vec().into(),
usage,
)).unwrap();
Ok(())
}

View File

@ -1050,12 +1050,15 @@ impl WebGLRenderingContext {
let internal_format = self.extension_manager.get_effective_tex_internal_format(format, data_type);
// TODO(emilio): convert colorspace if requested
let msg = WebGLCommand::TexImage2D(target.as_gl_constant(), level as i32,
internal_format as i32,
width as i32, height as i32,
format,
data_type,
pixels);
let msg = WebGLCommand::TexImage2D(
target.as_gl_constant(),
level as i32,
internal_format as i32,
width as i32, height as i32,
format,
data_type,
pixels.into(),
);
self.send_command(msg);
@ -1102,11 +1105,17 @@ impl WebGLRenderingContext {
self.send_command(WebGLCommand::PixelStorei(constants::UNPACK_ALIGNMENT, unpacking_alignment as i32));
// TODO(emilio): convert colorspace if requested
let msg = WebGLCommand::TexSubImage2D(target.as_gl_constant(),
level as i32, xoffset, yoffset,
width as i32, height as i32,
format.as_gl_constant(),
data_type.as_gl_constant(), pixels);
let msg = WebGLCommand::TexSubImage2D(
target.as_gl_constant(),
level as i32,
xoffset,
yoffset,
width as i32,
height as i32,
format.as_gl_constant(),
data_type.as_gl_constant(),
pixels.into(),
);
self.send_command(msg);
}
@ -1182,7 +1191,7 @@ impl WebGLRenderingContext {
constants::UNSIGNED_BYTE,
sender,
));
Some(receiver.recv().unwrap())
Some(receiver.recv().unwrap().into())
}
}
@ -1759,7 +1768,11 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if (offset as usize) + data_vec.len() > bound_buffer.capacity() {
return self.webgl_error(InvalidValue);
}
self.send_command(WebGLCommand::BufferSubData(target, offset as isize, data_vec));
self.send_command(WebGLCommand::BufferSubData(
target,
offset as isize,
data_vec.into(),
));
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8

View File

@ -81,6 +81,7 @@ extern crate script_layout_interface;
extern crate script_traits;
extern crate selectors;
extern crate serde;
extern crate serde_bytes;
extern crate servo_allocator;
extern crate servo_arc;
#[macro_use] extern crate servo_atoms;

View File

@ -344,7 +344,7 @@ impl webgl::WebVRRenderHandler for WebVRCompositorHandler {
(*compositor.0).sync_poses();
(*compositor.0).synced_frame_data(near, far).to_bytes()
};
let _ = sender.send(Ok(pose));
let _ = sender.send(Ok(pose.into()));
} else {
let _ = sender.send(Err(()));
}