Skip to content

Commit

Permalink
Auto merge of #24518 - bblanke:update-data-sizes, r=<try>
Browse files Browse the repository at this point in the history
Make offscreen canvas rendering context use offscreen canvas' size

Updated the offscreen canvas rendering context to use the offscreen canvas' size. This involved upgrading several methods to accept u64 sizes.

Additionally, the code in OffscreenCanvas::SetWidth() and OffscreenCanvas::SetHeight() was updated to send CanvasMsg::Recreate to the canvas paint thread.

---
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #24465

- [X] These changes do not require tests because the purpose of this was to tidy up code
  • Loading branch information
bors-servo committed Oct 21, 2019
2 parents 5011e9c + 5ad0303 commit e773ed0
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 60 deletions.
35 changes: 29 additions & 6 deletions components/canvas/canvas_data.rs
Expand Up @@ -449,7 +449,7 @@ impl<'a> CanvasData<'a> {
let source_rect = source_rect.ceil();
// It discards the extra pixels (if any) that won't be painted
let image_data = if Rect::from_size(image_size).contains_rect(&source_rect) {
pixels::rgba8_get_rect(&image_data, image_size.to_u32(), source_rect.to_u32()).into()
pixels::rgba8_get_rect(&image_data, image_size.to_u64(), source_rect.to_u64()).into()
} else {
image_data.into()
};
Expand Down Expand Up @@ -927,10 +927,10 @@ impl<'a> CanvasData<'a> {
self.backend.set_global_composition(op, &mut self.state);
}

pub fn recreate(&mut self, size: Size2D<u32>) {
pub fn recreate(&mut self, size: Size2D<u64>) {
self.drawtarget = self
.backend
.create_drawtarget(Size2D::new(size.width as u64, size.height as u64));
.create_drawtarget(Size2D::new(size.width, size.height));
self.state = self.backend.recreate_paint_state(&self.state);
self.saved_states.clear();
// Webrender doesn't let images change size, so we clear the webrender image key.
Expand Down Expand Up @@ -997,7 +997,7 @@ impl<'a> CanvasData<'a> {
}

// https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
pub fn put_image_data(&mut self, mut imagedata: Vec<u8>, rect: Rect<u32>) {
pub fn put_image_data(&mut self, mut imagedata: Vec<u8>, rect: Rect<u64>) {
assert_eq!(imagedata.len() % 4, 0);
assert_eq!(rect.size.area() as usize, imagedata.len() / 4);
pixels::rgba8_byte_swap_and_premultiply_inplace(&mut imagedata);
Expand Down Expand Up @@ -1082,7 +1082,7 @@ impl<'a> CanvasData<'a> {
/// canvas_size: The size of the canvas we're reading from
/// read_rect: The area of the canvas we want to read from
#[allow(unsafe_code)]
pub fn read_pixels(&self, read_rect: Rect<u32>, canvas_size: Size2D<u32>) -> Vec<u8> {
pub fn read_pixels(&self, read_rect: Rect<u64>, canvas_size: Size2D<u64>) -> Vec<u8> {
let canvas_rect = Rect::from_size(canvas_size);
if canvas_rect
.intersection(&read_rect)
Expand All @@ -1092,7 +1092,7 @@ impl<'a> CanvasData<'a> {
}

self.drawtarget.snapshot_data(&|bytes| {
pixels::rgba8_get_rect(bytes, canvas_size.to_u32(), read_rect.to_u32()).into_owned()
pixels::rgba8_get_rect(bytes, canvas_size, read_rect).into_owned()
})
}
}
Expand Down Expand Up @@ -1189,3 +1189,26 @@ impl RectToi32 for Rect<f64> {
)
}
}

pub trait Size2DExt {
fn to_u64(&self) -> Size2D<u64>;
}

impl Size2DExt for Size2D<f64> {
fn to_u64(&self) -> Size2D<u64> {
return Size2D::new(self.width as u64, self.height as u64);
}
}

pub trait RectExt_ {
fn to_u64(&self) -> Rect<u64>;
}

impl RectExt_ for Rect<f64> {
fn to_u64(&self) -> Rect<u64> {
return Rect::new(
Point2D::new(self.origin.x as u64, self.origin.y as u64),
Size2D::new(self.size.width as u64, self.size.height as u64),
);
}
}
18 changes: 16 additions & 2 deletions components/canvas/canvas_paint_thread.rs
Expand Up @@ -4,7 +4,7 @@

use crate::canvas_data::*;
use canvas_traits::canvas::*;
use euclid::default::Size2D;
use euclid::default::{Point2D, Rect, Size2D};
use ipc_channel::ipc::{self, IpcSender};
use std::borrow::ToOwned;
use std::collections::HashMap;
Expand Down Expand Up @@ -142,9 +142,13 @@ impl<'a> CanvasPaintThread<'a> {
source_rect,
smoothing,
) => {
let source_rect_u64 = Rect::new(
Point2D::new(source_rect.origin.x as u64, source_rect.origin.y as u64),
Size2D::new(source_rect.size.width as u64, source_rect.size.width as u64),
);
let image_data = self
.canvas(canvas_id)
.read_pixels(source_rect.to_u32(), image_size.to_u32());
.read_pixels(source_rect_u64, image_size.to_u64());
self.canvas(other_canvas_id).draw_image(
image_data.into(),
source_rect.size,
Expand Down Expand Up @@ -207,3 +211,13 @@ impl<'a> CanvasPaintThread<'a> {
self.canvases.get_mut(&canvas_id).expect("Bogus canvas id")
}
}

pub trait Size2DExt {
fn to_u64(&self) -> Size2D<u64>;
}

impl Size2DExt for Size2D<f64> {
fn to_u64(&self) -> Size2D<u64> {
return Size2D::new(self.width as u64, self.height as u64);
}
}
6 changes: 3 additions & 3 deletions components/canvas_traits/canvas.rs
Expand Up @@ -29,7 +29,7 @@ pub enum CanvasMsg {
),
FromLayout(FromLayoutMsg, CanvasId),
FromScript(FromScriptMsg, CanvasId),
Recreate(Size2D<u32>, CanvasId),
Recreate(Size2D<u64>, CanvasId),
Close(CanvasId),
Exit,
}
Expand All @@ -54,11 +54,11 @@ pub enum Canvas2dMsg {
Fill,
FillText(String, f64, f64, Option<f64>),
FillRect(Rect<f32>),
GetImageData(Rect<u32>, Size2D<u32>, IpcBytesSender),
GetImageData(Rect<u64>, Size2D<u64>, IpcBytesSender),
IsPointInPath(f64, f64, FillRule, IpcSender<bool>),
LineTo(Point2D<f32>),
MoveTo(Point2D<f32>),
PutImageData(Rect<u32>, IpcBytesReceiver),
PutImageData(Rect<u64>, IpcBytesReceiver),
QuadraticCurveTo(Point2D<f32>, Point2D<f32>),
Rect(Rect<f32>),
RestoreContext,
Expand Down
16 changes: 9 additions & 7 deletions components/pixels/lib.rs
Expand Up @@ -23,7 +23,7 @@ pub enum PixelFormat {
BGRA8,
}

pub fn rgba8_get_rect(pixels: &[u8], size: Size2D<u32>, rect: Rect<u32>) -> Cow<[u8]> {
pub fn rgba8_get_rect(pixels: &[u8], size: Size2D<u64>, rect: Rect<u64>) -> Cow<[u8]> {
assert!(!rect.is_empty());
assert!(Rect::from_size(size).contains_rect(&rect));
assert_eq!(pixels.len() % 4, 0);
Expand Down Expand Up @@ -85,18 +85,20 @@ pub fn multiply_u8_color(a: u8, b: u8) -> u8 {

pub fn clip(
mut origin: Point2D<i32>,
mut size: Size2D<u32>,
surface: Size2D<u32>,
) -> Option<Rect<u32>> {
mut size: Size2D<u64>,
surface: Size2D<u64>,
) -> Option<Rect<u64>> {
if origin.x < 0 {
size.width = size.width.saturating_sub(-origin.x as u32);
size.width = size.width.saturating_sub(-origin.x as u64);
origin.x = 0;
}
if origin.y < 0 {
size.height = size.height.saturating_sub(-origin.y as u32);
size.height = size.height.saturating_sub(-origin.y as u64);
origin.y = 0;
}
Rect::new(origin.to_u32(), size)
let origin = Point2D::new(origin.x as u64, origin.y as u64);
let size = Size2D::new(size.width as u64, size.height as u64);
Rect::new(origin, size)
.intersection(&Rect::from_size(surface))
.filter(|rect| !rect.is_empty())
}
45 changes: 34 additions & 11 deletions components/script/dom/canvasrenderingcontext2d.rs
Expand Up @@ -172,12 +172,21 @@ impl CanvasState {
self.canvas_id.clone()
}

pub fn get_ipc_renderer(&self) -> IpcSender<CanvasMsg> {
self.ipc_renderer.clone()
}

pub fn send_canvas_2d_msg(&self, msg: Canvas2dMsg) {
self.ipc_renderer
.send(CanvasMsg::Canvas2d(msg, self.get_canvas_id()))
.unwrap()
}

pub fn reset_to_initial_state(&self) {
self.saved_states.borrow_mut().clear();
*self.state.borrow_mut() = CanvasContextState::new();
}

fn create_drawable_rect(&self, x: f64, y: f64, w: f64, h: f64) -> Option<Rect<f32>> {
if !([x, y, w, h].iter().all(|val| val.is_finite())) {
return None;
Expand Down Expand Up @@ -298,7 +307,7 @@ impl CanvasState {
}
}

pub fn get_rect(&self, canvas_size: Size2D<u32>, rect: Rect<u32>) -> Vec<u8> {
pub fn get_rect(&self, canvas_size: Size2D<u64>, rect: Rect<u64>) -> Vec<u8> {
assert!(self.origin_is_clean());

assert!(Rect::from_size(canvas_size).contains_rect(&rect));
Expand Down Expand Up @@ -1017,7 +1026,7 @@ impl CanvasState {
// https://html.spec.whatwg.org/multipage/#dom-context-2d-getimagedata
pub fn GetImageData(
&self,
canvas_size: Size2D<u32>,
canvas_size: Size2D<u64>,
global: &GlobalScope,
sx: i32,
sy: i32,
Expand All @@ -1036,7 +1045,7 @@ impl CanvasState {
}

let (origin, size) = adjust_size_sign(Point2D::new(sx, sy), Size2D::new(sw, sh));
let read_rect = match pixels::clip(origin, size, canvas_size) {
let read_rect = match pixels::clip(origin, size.to_u64(), canvas_size) {
Some(rect) => rect,
None => {
// All the pixels are outside the canvas surface.
Expand All @@ -1053,7 +1062,7 @@ impl CanvasState {
}

// https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
pub fn PutImageData(&self, canvas_size: Size2D<u32>, imagedata: &ImageData, dx: i32, dy: i32) {
pub fn PutImageData(&self, canvas_size: Size2D<u64>, imagedata: &ImageData, dx: i32, dy: i32) {
self.PutImageData_(
canvas_size,
imagedata,
Expand All @@ -1070,7 +1079,7 @@ impl CanvasState {
#[allow(unsafe_code)]
pub fn PutImageData_(
&self,
canvas_size: Size2D<u32>,
canvas_size: Size2D<u64>,
imagedata: &ImageData,
dx: i32,
dy: i32,
Expand Down Expand Up @@ -1098,7 +1107,7 @@ impl CanvasState {
Point2D::new(dirty_x, dirty_y),
Size2D::new(dirty_width, dirty_height),
);
let src_rect = match pixels::clip(src_origin, src_size, imagedata_size) {
let src_rect = match pixels::clip(src_origin, src_size.to_u64(), imagedata_size.to_u64()) {
Some(rect) => rect,
None => return,
};
Expand Down Expand Up @@ -1495,7 +1504,7 @@ impl CanvasRenderingContext2D {
.borrow()
.ipc_renderer
.send(CanvasMsg::Recreate(
size,
size.to_u64(),
self.canvas_state.borrow().get_canvas_id(),
))
.unwrap();
Expand Down Expand Up @@ -1537,10 +1546,14 @@ impl CanvasRenderingContext2D {
}

pub fn get_rect(&self, rect: Rect<u32>) -> Vec<u8> {
let rect = Rect::new(
Point2D::new(rect.origin.x as u64, rect.origin.y as u64),
Size2D::new(rect.size.width as u64, rect.size.height as u64),
);
self.canvas_state.borrow().get_rect(
self.canvas
.as_ref()
.map_or(Size2D::zero(), |c| c.get_size()),
.map_or(Size2D::zero(), |c| c.get_size().to_u64()),
rect,
)
}
Expand Down Expand Up @@ -1875,7 +1888,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
self.canvas_state.borrow().GetImageData(
self.canvas
.as_ref()
.map_or(Size2D::zero(), |c| c.get_size()),
.map_or(Size2D::zero(), |c| c.get_size().to_u64()),
&self.global(),
sx,
sy,
Expand All @@ -1889,7 +1902,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
self.canvas_state.borrow().PutImageData(
self.canvas
.as_ref()
.map_or(Size2D::zero(), |c| c.get_size()),
.map_or(Size2D::zero(), |c| c.get_size().to_u64()),
imagedata,
dx,
dy,
Expand All @@ -1911,7 +1924,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
self.canvas_state.borrow().PutImageData_(
self.canvas
.as_ref()
.map_or(Size2D::zero(), |c| c.get_size()),
.map_or(Size2D::zero(), |c| c.get_size().to_u64()),
imagedata,
dx,
dy,
Expand Down Expand Up @@ -2123,3 +2136,13 @@ fn adjust_size_sign(
}
(origin, size.to_u32())
}

pub trait Size2DExt {
fn to_u64(&self) -> Size2D<u64>;
}

impl Size2DExt for Size2D<u32> {
fn to_u64(&self) -> Size2D<u64> {
return Size2D::new(self.width as u64, self.height as u64);
}
}
14 changes: 12 additions & 2 deletions components/script/dom/imagedata.rs
Expand Up @@ -169,8 +169,8 @@ impl ImageData {
}

#[allow(unsafe_code)]
pub unsafe fn get_rect(&self, rect: Rect<u32>) -> Cow<[u8]> {
pixels::rgba8_get_rect(self.as_slice(), self.get_size(), rect)
pub unsafe fn get_rect(&self, rect: Rect<u64>) -> Cow<[u8]> {
pixels::rgba8_get_rect(self.as_slice(), self.get_size().to_u64(), rect)
}

pub fn get_size(&self) -> Size2D<u32> {
Expand All @@ -194,3 +194,13 @@ impl ImageDataMethods for ImageData {
NonNull::new(self.data.get()).expect("got a null pointer")
}
}

pub trait Size2DExt {
fn to_u64(&self) -> Size2D<u64>;
}

impl Size2DExt for Size2D<u32> {
fn to_u64(&self) -> Size2D<u64> {
return Size2D::new(self.width as u64, self.height as u64);
}
}
18 changes: 16 additions & 2 deletions components/script/dom/offscreencanvas.rs
Expand Up @@ -92,11 +92,9 @@ impl OffscreenCanvas {
OffscreenCanvasContext::OffscreenContext2d(ref ctx) => Some(DomRoot::from_ref(ctx)),
};
}
let size = self.get_size();
let context = OffscreenCanvasRenderingContext2D::new(
&self.global(),
self,
size,
self.placeholder.as_ref().map(|c| &**c),
);
*self.context.borrow_mut() = Some(OffscreenCanvasContext::OffscreenContext2d(
Expand Down Expand Up @@ -136,6 +134,14 @@ impl OffscreenCanvasMethods for OffscreenCanvas {
// https://html.spec.whatwg.org/multipage/#dom-offscreencanvas-width
fn SetWidth(&self, value: u64) {
self.width.set(value);

if let Some(canvas_context) = self.context() {
match &*canvas_context {
OffscreenCanvasContext::OffscreenContext2d(rendering_context) => {
rendering_context.set_bitmap_dimensions(self.get_size());
},
}
}
}

// https://html.spec.whatwg.org/multipage/#dom-offscreencanvas-height
Expand All @@ -146,5 +152,13 @@ impl OffscreenCanvasMethods for OffscreenCanvas {
// https://html.spec.whatwg.org/multipage/#dom-offscreencanvas-height
fn SetHeight(&self, value: u64) {
self.height.set(value);

if let Some(canvas_context) = self.context() {
match &*canvas_context {
OffscreenCanvasContext::OffscreenContext2d(rendering_context) => {
rendering_context.set_bitmap_dimensions(self.get_size());
},
}
}
}
}

0 comments on commit e773ed0

Please sign in to comment.