aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2019-11-11 14:47:56 -0500
committerGitHub <noreply@github.com>2019-11-11 14:47:56 -0500
commit905f714bb4b2959f1735cc7469969696eac56d47 (patch)
tree39073c7c0990269cd976fe0be6da6156b2992065
parent06e58212cbca2ff6b24f0ad6e1e1c01237da480d (diff)
parentec2961920b74fbe0345f72e6007c6d42ae852019 (diff)
downloadservo-905f714bb4b2959f1735cc7469969696eac56d47.tar.gz
servo-905f714bb4b2959f1735cc7469969696eac56d47.zip
Auto merge of #24524 - bblanke:consolidate-size-helpers, r=jdm
Make offscreen canvas rendering context use offscreen canvas' size; Consolidate size helpers <!-- Please describe your changes on the following line: --> Addresses issues raised in the review of PR #24518 and includes changes to 17 tests' metadata for those that now PASS. Contains fixes in PR #24518: 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. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #24465 and fix #24536 <!-- Either: --> - [X] There are tests for these changes – 17 were updated to PASS
-rw-r--r--Cargo.lock4
-rw-r--r--components/canvas/canvas_data.rs46
-rw-r--r--components/canvas/canvas_paint_thread.rs2
-rw-r--r--components/canvas_traits/canvas.rs6
-rw-r--r--components/pixels/lib.rs15
-rw-r--r--components/script/canvas_state.rs26
-rw-r--r--components/script/dom/canvasrenderingcontext2d.rs28
-rw-r--r--components/script/dom/htmlcanvaselement.rs5
-rw-r--r--components/script/dom/imagedata.rs14
-rw-r--r--components/script/dom/offscreencanvas.rs18
-rw-r--r--components/script/dom/offscreencanvasrenderingcontext2d.rs46
-rw-r--r--components/script/dom/paintrenderingcontext2d.rs3
-rw-r--r--components/script/dom/webglrenderingcontext.rs17
-rw-r--r--components/script/euclidext.rs43
-rw-r--r--components/script/lib.rs1
-rw-r--r--tests/wpt/metadata/offscreen-canvas/fill-and-stroke-styles/2d.gradient.interpolate.multiple.html.ini3
-rw-r--r--tests/wpt/metadata/offscreen-canvas/fill-and-stroke-styles/2d.gradient.interpolate.multiple.worker.js.ini3
-rw-r--r--tests/wpt/metadata/offscreen-canvas/fill-and-stroke-styles/2d.gradient.interpolate.overlap.html.ini4
-rw-r--r--tests/wpt/metadata/offscreen-canvas/fill-and-stroke-styles/2d.gradient.interpolate.overlap.worker.js.ini4
-rw-r--r--tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.2dstate.html.ini4
-rw-r--r--tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.2dstate.worker.js.ini4
-rw-r--r--tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.clip.html.ini4
-rw-r--r--tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.clip.worker.js.ini4
-rw-r--r--tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.different.html.ini4
-rw-r--r--tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.different.worker.js.ini4
-rw-r--r--tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.gradient.html.ini4
-rw-r--r--tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.gradient.worker.js.ini4
-rw-r--r--tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.same.html.ini4
-rw-r--r--tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.same.worker.js.ini4
-rw-r--r--tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.transform.html.ini4
-rw-r--r--tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.transform.worker.js.ini4
-rw-r--r--tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/offscreencanvas.resize.html.ini6
32 files changed, 211 insertions, 131 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 26c8c4db824..8a3b1ca0c36 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1307,9 +1307,9 @@ dependencies = [
[[package]]
name = "euclid"
-version = "0.20.1"
+version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89c879a4e57d6a2785d517b0771ea6857916173debef0102bf81142d36ca9254"
+checksum = "f46a3516f04c5e05870f71ae6242a97e8f72ee12cfc2f7f5deb16111a98b0670"
dependencies = [
"num-traits",
"serde",
diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs
index 78c32b4d813..29dd1743b46 100644
--- a/components/canvas/canvas_data.rs
+++ b/components/canvas/canvas_data.rs
@@ -13,7 +13,7 @@ use std::marker::PhantomData;
use std::mem;
use std::sync::Arc;
use webrender::api::DirtyRect;
-use webrender_api::units::RectExt;
+use webrender_api::units::RectExt as RectExt_;
/// The canvas data stores a state machine for the current status of
/// the path data and any relevant transformations that are
@@ -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()
};
@@ -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.
@@ -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);
@@ -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)
@@ -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()
})
}
}
@@ -1189,3 +1189,35 @@ 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> {
+ self.cast()
+ }
+}
+
+impl Size2DExt for Size2D<u32> {
+ fn to_u64(&self) -> Size2D<u64> {
+ self.cast()
+ }
+}
+
+pub trait RectExt {
+ fn to_u64(&self) -> Rect<u64>;
+}
+
+impl RectExt for Rect<f64> {
+ fn to_u64(&self) -> Rect<u64> {
+ self.cast()
+ }
+}
+
+impl RectExt for Rect<u32> {
+ fn to_u64(&self) -> Rect<u64> {
+ self.cast()
+ }
+}
diff --git a/components/canvas/canvas_paint_thread.rs b/components/canvas/canvas_paint_thread.rs
index e324c213d6e..a249080cdfd 100644
--- a/components/canvas/canvas_paint_thread.rs
+++ b/components/canvas/canvas_paint_thread.rs
@@ -144,7 +144,7 @@ impl<'a> CanvasPaintThread<'a> {
) => {
let image_data = self
.canvas(canvas_id)
- .read_pixels(source_rect.to_u32(), image_size.to_u32());
+ .read_pixels(source_rect.to_u64(), image_size.to_u64());
self.canvas(other_canvas_id).draw_image(
image_data.into(),
source_rect.size,
diff --git a/components/canvas_traits/canvas.rs b/components/canvas_traits/canvas.rs
index ff7e65722e3..db678b42572 100644
--- a/components/canvas_traits/canvas.rs
+++ b/components/canvas_traits/canvas.rs
@@ -29,7 +29,7 @@ pub enum CanvasMsg {
),
FromLayout(FromLayoutMsg, CanvasId),
FromScript(FromScriptMsg, CanvasId),
- Recreate(Size2D<u32>, CanvasId),
+ Recreate(Size2D<u64>, CanvasId),
Close(CanvasId),
Exit,
}
@@ -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,
diff --git a/components/pixels/lib.rs b/components/pixels/lib.rs
index 68b22abb11d..88d845a3033 100644
--- a/components/pixels/lib.rs
+++ b/components/pixels/lib.rs
@@ -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);
@@ -85,18 +85,19 @@ 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);
+ Rect::new(origin, size)
.intersection(&Rect::from_size(surface))
.filter(|rect| !rect.is_empty())
}
diff --git a/components/script/canvas_state.rs b/components/script/canvas_state.rs
index 90630fb07c3..4b47308fa46 100644
--- a/components/script/canvas_state.rs
+++ b/components/script/canvas_state.rs
@@ -24,6 +24,7 @@ use crate::dom::imagedata::ImageData;
use crate::dom::node::{Node, NodeDamage};
use crate::dom::paintworkletglobalscope::PaintWorkletGlobalScope;
use crate::dom::textmetrics::TextMetrics;
+use crate::euclidext::Size2DExt;
use crate::unpremultiplytable::UNPREMULTIPLY_TABLE;
use canvas_traits::canvas::{Canvas2dMsg, CanvasId, CanvasMsg};
use canvas_traits::canvas::{CompositionOrBlending, FillOrStrokeStyle, FillRule};
@@ -180,6 +181,19 @@ impl CanvasState {
.unwrap()
}
+ // https://html.spec.whatwg.org/multipage/#concept-canvas-set-bitmap-dimensions
+ pub fn set_bitmap_dimensions(&self, size: Size2D<u64>) {
+ self.reset_to_initial_state();
+ self.ipc_renderer
+ .send(CanvasMsg::Recreate(size, 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;
@@ -300,7 +314,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));
@@ -1019,7 +1033,7 @@ impl CanvasState {
// https://html.spec.whatwg.org/multipage/#dom-context-2d-getimagedata
pub fn get_image_data(
&self,
- canvas_size: Size2D<u32>,
+ canvas_size: Size2D<u64>,
global: &GlobalScope,
sx: i32,
sy: i32,
@@ -1038,7 +1052,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.
@@ -1057,7 +1071,7 @@ impl CanvasState {
// https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
pub fn put_image_data(
&self,
- canvas_size: Size2D<u32>,
+ canvas_size: Size2D<u64>,
imagedata: &ImageData,
dx: i32,
dy: i32,
@@ -1078,7 +1092,7 @@ impl CanvasState {
#[allow(unsafe_code)]
pub fn put_image_data_(
&self,
- canvas_size: Size2D<u32>,
+ canvas_size: Size2D<u64>,
imagedata: &ImageData,
dx: i32,
dy: i32,
@@ -1106,7 +1120,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,
};
diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs
index 9f6403bec5c..371b31bbdb0 100644
--- a/components/script/dom/canvasrenderingcontext2d.rs
+++ b/components/script/dom/canvasrenderingcontext2d.rs
@@ -22,9 +22,10 @@ use crate::dom::globalscope::GlobalScope;
use crate::dom::htmlcanvaselement::HTMLCanvasElement;
use crate::dom::imagedata::ImageData;
use crate::dom::textmetrics::TextMetrics;
+use crate::euclidext::Size2DExt;
use canvas_traits::canvas::{Canvas2dMsg, CanvasId, CanvasMsg};
use dom_struct::dom_struct;
-use euclid::default::{Rect, Size2D};
+use euclid::default::{Point2D, Rect, Size2D};
use ipc_channel::ipc::IpcSender;
use servo_url::ServoUrl;
use std::mem;
@@ -75,12 +76,13 @@ impl CanvasRenderingContext2D {
.borrow()
.get_ipc_renderer()
.send(CanvasMsg::Recreate(
- size,
+ size.to_u64(),
self.canvas_state.borrow().get_canvas_id(),
))
.unwrap();
}
+ // TODO: This duplicates functionality in canvas state
// https://html.spec.whatwg.org/multipage/#reset-the-rendering-context-to-its-default-state
fn reset_to_initial_state(&self) {
self.canvas_state
@@ -90,6 +92,15 @@ impl CanvasRenderingContext2D {
.clear();
*self.canvas_state.borrow().get_state().borrow_mut() = CanvasContextState::new();
}
+ /*
+ pub fn get_canvas_state(&self) -> Ref<CanvasState> {
+ self.canvas_state.borrow()
+ }
+ */
+
+ pub fn set_canvas_bitmap_dimensions(&self, size: Size2D<u64>) {
+ self.canvas_state.borrow().set_bitmap_dimensions(size);
+ }
pub fn mark_as_dirty(&self) {
self.canvas_state
@@ -116,6 +127,7 @@ impl CanvasRenderingContext2D {
self.canvas_state.borrow().send_canvas_2d_msg(msg)
}
+ // TODO: Remove this
pub fn get_ipc_renderer(&self) -> IpcSender<CanvasMsg> {
self.canvas_state.borrow().get_ipc_renderer().clone()
}
@@ -125,10 +137,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,
)
}
@@ -469,7 +485,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
self.canvas_state.borrow().get_image_data(
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,
@@ -483,7 +499,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
self.canvas_state.borrow().put_image_data(
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,
@@ -505,7 +521,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
self.canvas_state.borrow().put_image_data_(
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,
diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs
index 9e638539995..8924f8ddd1c 100644
--- a/components/script/dom/htmlcanvaselement.rs
+++ b/components/script/dom/htmlcanvaselement.rs
@@ -28,6 +28,7 @@ use crate::dom::webgl2renderingcontext::WebGL2RenderingContext;
use crate::dom::webglrenderingcontext::{
LayoutCanvasWebGLRenderingContextHelpers, WebGLRenderingContext,
};
+use crate::euclidext::Size2DExt;
use crate::script_runtime::JSContext;
use base64;
use canvas_traits::canvas::{CanvasId, CanvasMsg, FromScriptMsg};
@@ -94,7 +95,9 @@ impl HTMLCanvasElement {
let size = self.get_size();
if let Some(ref context) = *self.context.borrow() {
match *context {
- CanvasContext::Context2d(ref context) => context.set_bitmap_dimensions(size),
+ CanvasContext::Context2d(ref context) => {
+ context.set_canvas_bitmap_dimensions(size.to_u64())
+ },
CanvasContext::WebGL(ref context) => context.recreate(size),
CanvasContext::WebGL2(ref context) => context.recreate(size),
}
diff --git a/components/script/dom/imagedata.rs b/components/script/dom/imagedata.rs
index d89e5e36d1b..b09984e267f 100644
--- a/components/script/dom/imagedata.rs
+++ b/components/script/dom/imagedata.rs
@@ -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> {
@@ -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);
+ }
+}
diff --git a/components/script/dom/offscreencanvas.rs b/components/script/dom/offscreencanvas.rs
index 142379519fb..69c1114768c 100644
--- a/components/script/dom/offscreencanvas.rs
+++ b/components/script/dom/offscreencanvas.rs
@@ -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(
@@ -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_canvas_bitmap_dimensions(self.get_size());
+ },
+ }
+ }
}
// https://html.spec.whatwg.org/multipage/#dom-offscreencanvas-height
@@ -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_canvas_bitmap_dimensions(self.get_size());
+ },
+ }
+ }
}
}
diff --git a/components/script/dom/offscreencanvasrenderingcontext2d.rs b/components/script/dom/offscreencanvasrenderingcontext2d.rs
index 04e0a13032c..077752d9d6e 100644
--- a/components/script/dom/offscreencanvasrenderingcontext2d.rs
+++ b/components/script/dom/offscreencanvasrenderingcontext2d.rs
@@ -30,44 +30,32 @@ use euclid::default::Size2D;
#[dom_struct]
pub struct OffscreenCanvasRenderingContext2D {
reflector_: Reflector,
- canvas: Option<Dom<OffscreenCanvas>>,
+ canvas: Dom<OffscreenCanvas>,
canvas_state: DomRefCell<CanvasState>,
htmlcanvas: Option<Dom<HTMLCanvasElement>>,
- width: u32,
- height: u32,
}
impl OffscreenCanvasRenderingContext2D {
fn new_inherited(
global: &GlobalScope,
- canvas: Option<&OffscreenCanvas>,
- size: Size2D<u64>,
+ canvas: &OffscreenCanvas,
htmlcanvas: Option<&HTMLCanvasElement>,
) -> OffscreenCanvasRenderingContext2D {
OffscreenCanvasRenderingContext2D {
reflector_: Reflector::new(),
- canvas: canvas.map(Dom::from_ref),
+ canvas: Dom::from_ref(canvas),
htmlcanvas: htmlcanvas.map(Dom::from_ref),
- canvas_state: DomRefCell::new(CanvasState::new(
- global,
- Size2D::new(size.width as u64, size.height as u64),
- )),
- width: size.width as u32,
- height: size.height as u32,
+ canvas_state: DomRefCell::new(CanvasState::new(global, canvas.get_size())),
}
}
pub fn new(
global: &GlobalScope,
canvas: &OffscreenCanvas,
- size: Size2D<u64>,
htmlcanvas: Option<&HTMLCanvasElement>,
) -> DomRoot<OffscreenCanvasRenderingContext2D> {
let boxed = Box::new(OffscreenCanvasRenderingContext2D::new_inherited(
- global,
- Some(canvas),
- size,
- htmlcanvas,
+ global, canvas, htmlcanvas,
));
reflect_dom_object(
boxed,
@@ -75,12 +63,21 @@ impl OffscreenCanvasRenderingContext2D {
OffscreenCanvasRenderingContext2DBinding::Wrap,
)
}
+ /*
+ pub fn get_canvas_state(&self) -> Ref<CanvasState> {
+ self.canvas_state.borrow()
+ }
+ */
+
+ pub fn set_canvas_bitmap_dimensions(&self, size: Size2D<u64>) {
+ self.canvas_state.borrow().set_bitmap_dimensions(size);
+ }
}
impl OffscreenCanvasRenderingContext2DMethods for OffscreenCanvasRenderingContext2D {
// https://html.spec.whatwg.org/multipage/offscreencontext2d-canvas
fn Canvas(&self) -> DomRoot<OffscreenCanvas> {
- DomRoot::from_ref(self.canvas.as_ref().expect("No canvas."))
+ DomRoot::from_ref(&self.canvas)
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-fillrect
@@ -315,7 +312,7 @@ impl OffscreenCanvasRenderingContext2DMethods for OffscreenCanvasRenderingContex
// https://html.spec.whatwg.org/multipage/#dom-context-2d-getimagedata
fn GetImageData(&self, sx: i32, sy: i32, sw: i32, sh: i32) -> Fallible<DomRoot<ImageData>> {
self.canvas_state.borrow().get_image_data(
- Size2D::new(self.width, self.height),
+ self.canvas.get_size(),
&self.global(),
sx,
sy,
@@ -326,12 +323,9 @@ impl OffscreenCanvasRenderingContext2DMethods for OffscreenCanvasRenderingContex
// https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
fn PutImageData(&self, imagedata: &ImageData, dx: i32, dy: i32) {
- self.canvas_state.borrow().put_image_data(
- Size2D::new(self.width, self.height),
- imagedata,
- dx,
- dy,
- )
+ self.canvas_state
+ .borrow()
+ .put_image_data(self.canvas.get_size(), imagedata, dx, dy)
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
@@ -347,7 +341,7 @@ impl OffscreenCanvasRenderingContext2DMethods for OffscreenCanvasRenderingContex
dirty_height: i32,
) {
self.canvas_state.borrow().put_image_data_(
- Size2D::new(self.width, self.height),
+ self.canvas.get_size(),
imagedata,
dx,
dy,
diff --git a/components/script/dom/paintrenderingcontext2d.rs b/components/script/dom/paintrenderingcontext2d.rs
index 1bbb52d05fe..e4b0a3cf71e 100644
--- a/components/script/dom/paintrenderingcontext2d.rs
+++ b/components/script/dom/paintrenderingcontext2d.rs
@@ -21,6 +21,7 @@ use crate::dom::canvasgradient::CanvasGradient;
use crate::dom::canvaspattern::CanvasPattern;
use crate::dom::canvasrenderingcontext2d::CanvasRenderingContext2D;
use crate::dom::paintworkletglobalscope::PaintWorkletGlobalScope;
+use crate::euclidext::Size2DExt;
use canvas_traits::canvas::CanvasImageData;
use canvas_traits::canvas::CanvasMsg;
use canvas_traits::canvas::FromLayoutMsg;
@@ -75,7 +76,7 @@ impl PaintRenderingContext2D {
let size = size * device_pixel_ratio;
self.device_pixel_ratio.set(device_pixel_ratio);
self.context
- .set_bitmap_dimensions(size.to_untyped().to_u32());
+ .set_canvas_bitmap_dimensions(size.to_untyped().to_u64());
self.scale_by_device_pixel_ratio();
}
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index 228ccd491b9..c843ab578d1 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -2963,11 +2963,16 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
let src_origin = Point2D::new(x, y);
let src_size = Size2D::new(width as u32, height as u32);
let fb_size = Size2D::new(fb_width as u32, fb_height as u32);
- let src_rect = match pixels::clip(src_origin, src_size, fb_size) {
+ let src_rect = match pixels::clip(src_origin, src_size.to_u64(), fb_size.to_u64()) {
Some(rect) => rect,
None => return,
};
+ // Note: we're casting a Rect<u64> back into a Rect<u32> here, but it's okay because
+ // it used u32 data types to begin with. It just got converted to Rect<u64> in
+ // pixels::clip
+ let src_rect = src_rect.to_u32();
+
let mut dest_offset = 0;
if x < 0 {
dest_offset += -x * bytes_per_pixel;
@@ -4485,3 +4490,13 @@ impl WebGLMessageSender {
self.wake_after_send(|| self.sender.send_dom_to_texture(command))
}
}
+
+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);
+ }
+}
diff --git a/components/script/euclidext.rs b/components/script/euclidext.rs
new file mode 100644
index 00000000000..39de2aa2ccb
--- /dev/null
+++ b/components/script/euclidext.rs
@@ -0,0 +1,43 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+use euclid::default::{Rect, Size2D};
+
+pub trait Size2DExt {
+ fn to_u64(&self) -> Size2D<u64>;
+}
+
+impl Size2DExt for Size2D<f32> {
+ fn to_u64(&self) -> Size2D<u64> {
+ self.cast()
+ }
+}
+
+impl Size2DExt for Size2D<f64> {
+ fn to_u64(&self) -> Size2D<u64> {
+ self.cast()
+ }
+}
+
+impl Size2DExt for Size2D<u32> {
+ fn to_u64(&self) -> Size2D<u64> {
+ self.cast()
+ }
+}
+
+pub trait RectExt {
+ fn to_u64(&self) -> Rect<u64>;
+}
+
+impl RectExt for Rect<f64> {
+ fn to_u64(&self) -> Rect<u64> {
+ self.cast()
+ }
+}
+
+impl RectExt for Rect<u32> {
+ fn to_u64(&self) -> Rect<u64> {
+ self.cast()
+ }
+}
diff --git a/components/script/lib.rs b/components/script/lib.rs
index 250f860eda2..87eec7cab02 100644
--- a/components/script/lib.rs
+++ b/components/script/lib.rs
@@ -65,6 +65,7 @@ mod dom;
mod canvas_state;
#[warn(deprecated)]
mod compartments;
+mod euclidext;
#[warn(deprecated)]
pub mod fetch;
#[warn(deprecated)]
diff --git a/tests/wpt/metadata/offscreen-canvas/fill-and-stroke-styles/2d.gradient.interpolate.multiple.html.ini b/tests/wpt/metadata/offscreen-canvas/fill-and-stroke-styles/2d.gradient.interpolate.multiple.html.ini
index 19172f06169..2b4b3558760 100644
--- a/tests/wpt/metadata/offscreen-canvas/fill-and-stroke-styles/2d.gradient.interpolate.multiple.html.ini
+++ b/tests/wpt/metadata/offscreen-canvas/fill-and-stroke-styles/2d.gradient.interpolate.multiple.html.ini
@@ -1,4 +1,3 @@
[2d.gradient.interpolate.multiple.html]
[OffscreenCanvas test: 2d.gradient.interpolate.multiple]
- expected: FAIL
-
+ expected: PASS
diff --git a/tests/wpt/metadata/offscreen-canvas/fill-and-stroke-styles/2d.gradient.interpolate.multiple.worker.js.ini b/tests/wpt/metadata/offscreen-canvas/fill-and-stroke-styles/2d.gradient.interpolate.multiple.worker.js.ini
index d2000f8aae4..4ef93cea653 100644
--- a/tests/wpt/metadata/offscreen-canvas/fill-and-stroke-styles/2d.gradient.interpolate.multiple.worker.js.ini
+++ b/tests/wpt/metadata/offscreen-canvas/fill-and-stroke-styles/2d.gradient.interpolate.multiple.worker.js.ini
@@ -1,4 +1,3 @@
[2d.gradient.interpolate.multiple.worker.html]
[2d]
- expected: FAIL
-
+ expected: PASS
diff --git a/tests/wpt/metadata/offscreen-canvas/fill-and-stroke-styles/2d.gradient.interpolate.overlap.html.ini b/tests/wpt/metadata/offscreen-canvas/fill-and-stroke-styles/2d.gradient.interpolate.overlap.html.ini
deleted file mode 100644
index b0891336db1..00000000000
--- a/tests/wpt/metadata/offscreen-canvas/fill-and-stroke-styles/2d.gradient.interpolate.overlap.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[2d.gradient.interpolate.overlap.html]
- [OffscreenCanvas test: 2d.gradient.interpolate.overlap]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/offscreen-canvas/fill-and-stroke-styles/2d.gradient.interpolate.overlap.worker.js.ini b/tests/wpt/metadata/offscreen-canvas/fill-and-stroke-styles/2d.gradient.interpolate.overlap.worker.js.ini
deleted file mode 100644
index 30b1c8e6cde..00000000000
--- a/tests/wpt/metadata/offscreen-canvas/fill-and-stroke-styles/2d.gradient.interpolate.overlap.worker.js.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[2d.gradient.interpolate.overlap.worker.html]
- [2d]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.2dstate.html.ini b/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.2dstate.html.ini
deleted file mode 100644
index 6bb1b2ab136..00000000000
--- a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.2dstate.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[initial.reset.2dstate.html]
- [Resetting the canvas state resets 2D state variables]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.2dstate.worker.js.ini b/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.2dstate.worker.js.ini
deleted file mode 100644
index 65b5e704ef8..00000000000
--- a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.2dstate.worker.js.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[initial.reset.2dstate.worker.html]
- [Resetting the canvas state resets 2D state variables]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.clip.html.ini b/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.clip.html.ini
deleted file mode 100644
index 831dfb2521c..00000000000
--- a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.clip.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[initial.reset.clip.html]
- [Resetting the canvas state resets the current clip region]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.clip.worker.js.ini b/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.clip.worker.js.ini
deleted file mode 100644
index 24edd2020ce..00000000000
--- a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.clip.worker.js.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[initial.reset.clip.worker.html]
- [Resetting the canvas state resets the current clip region]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.different.html.ini b/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.different.html.ini
deleted file mode 100644
index 061e290fcd5..00000000000
--- a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.different.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[initial.reset.different.html]
- [Changing size resets canvas to transparent black]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.different.worker.js.ini b/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.different.worker.js.ini
deleted file mode 100644
index 247627d6ce7..00000000000
--- a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.different.worker.js.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[initial.reset.different.worker.html]
- [Changing size resets canvas to transparent black]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.gradient.html.ini b/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.gradient.html.ini
deleted file mode 100644
index dcfe0bf696b..00000000000
--- a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.gradient.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[initial.reset.gradient.html]
- [Resetting the canvas state does not invalidate any existing gradients]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.gradient.worker.js.ini b/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.gradient.worker.js.ini
deleted file mode 100644
index 7876111284e..00000000000
--- a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.gradient.worker.js.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[initial.reset.gradient.worker.html]
- [Resetting the canvas state does not invalidate any existing gradients]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.same.html.ini b/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.same.html.ini
deleted file mode 100644
index 5a08092726b..00000000000
--- a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.same.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[initial.reset.same.html]
- [Setting size (not changing the value) resets canvas to transparent black]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.same.worker.js.ini b/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.same.worker.js.ini
deleted file mode 100644
index f11136a04df..00000000000
--- a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.same.worker.js.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[initial.reset.same.worker.html]
- [Setting size (not changing the value) resets canvas to transparent black]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.transform.html.ini b/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.transform.html.ini
deleted file mode 100644
index 8dc1ce9f0f2..00000000000
--- a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.transform.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[initial.reset.transform.html]
- [Resetting the canvas state resets the current transformation matrix]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.transform.worker.js.ini b/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.transform.worker.js.ini
deleted file mode 100644
index 62bfb15adf0..00000000000
--- a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/initial.reset.transform.worker.js.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[initial.reset.transform.worker.html]
- [Resetting the canvas state resets the current transformation matrix]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/offscreencanvas.resize.html.ini b/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/offscreencanvas.resize.html.ini
index 30cc4c73ed2..bb34106d98d 100644
--- a/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/offscreencanvas.resize.html.ini
+++ b/tests/wpt/metadata/offscreen-canvas/the-offscreen-canvas/offscreencanvas.resize.html.ini
@@ -1,6 +1,4 @@
[offscreencanvas.resize.html]
- [Verify that resizing a 2d context resets its state.]
- expected: FAIL
[Verify that writing to the width and height attributes of an OffscreenCanvas works when there is a 2d context attached.]
expected: FAIL
@@ -8,9 +6,6 @@
[Verify that resizing an OffscreenCanvas with a webgl context propagates the new size to its placeholder canvas asynchronously.]
expected: FAIL
- [Verify that setting the size of a 2d context to the same size it already had resets its state.]
- expected: FAIL
-
[Verify that resizing an OffscreenCanvas with a 2d context propagates the new size to its placeholder canvas asynchronously.]
expected: FAIL
@@ -25,4 +20,3 @@
[Verify that writing to the width or height attribute of a placeholder canvas throws an exception even when not changing the value of the attribute.]
expected: FAIL
-