diff options
author | Anthony Ramine <n.oxyde@gmail.com> | 2018-10-06 01:10:34 +0200 |
---|---|---|
committer | Anthony Ramine <n.oxyde@gmail.com> | 2018-10-06 01:12:05 +0200 |
commit | 19f40cdf0ba09a767e65ee3f0bd37622cc341bde (patch) | |
tree | 5941c56bed71aaf9c33bece5f778c1455ae15926 /components/canvas/canvas_data.rs | |
parent | 784fbb2bc17d311fe3322cc48d2dca8a902161ca (diff) | |
download | servo-19f40cdf0ba09a767e65ee3f0bd37622cc341bde.tar.gz servo-19f40cdf0ba09a767e65ee3f0bd37622cc341bde.zip |
Introduce ImageData::get_rect
We use that to send only the pixels that will be actually drawn to the
canvas thread in CanvasRenderingContext2d::PutImageData.
We also make the canvas thread byte swap and premultiply colours in-place.
Diffstat (limited to 'components/canvas/canvas_data.rs')
-rw-r--r-- | components/canvas/canvas_data.rs | 45 |
1 files changed, 13 insertions, 32 deletions
diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs index d4f083ae1e8..30e6218d604 100644 --- a/components/canvas/canvas_data.rs +++ b/components/canvas/canvas_data.rs @@ -13,6 +13,7 @@ use cssparser::RGBA; use euclid::{Transform2D, Point2D, Vector2D, Rect, Size2D}; use ipc_channel::ipc::{IpcBytesSender, IpcSender}; use num_traits::ToPrimitive; +use pixels; use serde_bytes::ByteBuf; use std::mem; use std::sync::Arc; @@ -451,42 +452,22 @@ impl<'a> CanvasData<'a> { // https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata pub fn put_image_data( &mut self, - imagedata: Vec<u8>, + mut imagedata: Vec<u8>, offset: Vector2D<i32>, - image_data_size: Size2D<i32>, - dest_rect: Rect<i32>, + imagedata_size: Size2D<i32>, ) { - assert_eq!(image_data_size.width * image_data_size.height * 4, imagedata.len() as i32); - - let image_size = image_data_size; - - let first_pixel = dest_rect.origin; - let mut src_line = (first_pixel.y * (image_size.width * 4) + first_pixel.x * 4) as usize; - - let mut dest = - Vec::with_capacity((dest_rect.size.width * dest_rect.size.height * 4) as usize); - - for _ in 0 .. dest_rect.size.height { - let mut src_offset = src_line; - for _ in 0 .. dest_rect.size.width { - let alpha = imagedata[src_offset + 3] as u16; - // add 127 before dividing for more accurate rounding - let premultiply_channel = |channel: u8| (((channel as u16 * alpha) + 127) / 255) as u8; - dest.push(premultiply_channel(imagedata[src_offset + 2])); - dest.push(premultiply_channel(imagedata[src_offset + 1])); - dest.push(premultiply_channel(imagedata[src_offset + 0])); - dest.push(imagedata[src_offset + 3]); - src_offset += 4; - } - src_line += (image_size.width * 4) as usize; - } - + assert_eq!(imagedata_size.area() * 4, imagedata.len() as i32); + pixels::byte_swap_and_premultiply_inplace(&mut imagedata); if let Some(source_surface) = self.drawtarget.create_source_surface_from_data( - &dest, - dest_rect.size, - dest_rect.size.width * 4, + &imagedata, + imagedata_size, + imagedata_size.width * 4, SurfaceFormat::B8G8R8A8) { - self.drawtarget.copy_surface(source_surface, Rect::from_size(dest_rect.size), offset.to_point()); + self.drawtarget.copy_surface( + source_surface, + Rect::from_size(imagedata_size), + offset.to_point(), + ); } } |