mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
Use ByteBuf for the canvas messages
The type Vec<u8> is super unefficient to work with in Serde if all you want to represent is a simple blob.
This commit is contained in:
parent
3ce3f39383
commit
ce81420bef
19 changed files with 170 additions and 62 deletions
|
@ -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"]}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue