From ed673f80708a0a10bef728628c43e975542e4b6c Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Sat, 15 Sep 2018 01:11:53 +0200 Subject: [PATCH 1/9] Mark some canvas methods as unsafe They use raw JS context pointers. --- components/script/dom/htmlcanvaselement.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index cfc1ee9a3db..dd1538b8529 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -188,7 +188,8 @@ impl HTMLCanvasElement { } } - pub fn get_or_init_webgl_context( + #[allow(unsafe_code)] + unsafe fn get_or_init_webgl_context( &self, cx: *mut JSContext, options: HandleValue, @@ -209,7 +210,8 @@ impl HTMLCanvasElement { } } - pub fn get_or_init_webgl2_context( + #[allow(unsafe_code)] + unsafe fn get_or_init_webgl2_context( &self, cx: *mut JSContext, options: HandleValue, @@ -243,11 +245,14 @@ impl HTMLCanvasElement { } #[allow(unsafe_code)] - fn get_gl_attributes(cx: *mut JSContext, options: HandleValue) -> Option { - match unsafe { WebGLContextAttributes::new(cx, options) } { + unsafe fn get_gl_attributes( + cx: *mut JSContext, + options: HandleValue, + ) -> Option { + match WebGLContextAttributes::new(cx, options) { Ok(ConversionResult::Success(ref attrs)) => Some(From::from(attrs)), Ok(ConversionResult::Failure(ref error)) => { - unsafe { throw_type_error(cx, &error); } + throw_type_error(cx, &error); None } _ => { From f1e8eb640cd59864a3f32c0557a35a1c65a2b8d3 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Sat, 15 Sep 2018 12:28:53 +0200 Subject: [PATCH 2/9] Don't create 2D canvas contexts arbitrarily Sometimes, the canvas still has no rendering context, in this case it represents a transparent black rectangle. --- components/canvas/canvas_paint_thread.rs | 12 +- components/canvas_traits/canvas.rs | 2 +- .../script/dom/canvasrenderingcontext2d.rs | 104 ++++++++++-------- components/script/dom/htmlcanvaselement.rs | 79 +++++++------ 4 files changed, 107 insertions(+), 90 deletions(-) diff --git a/components/canvas/canvas_paint_thread.rs b/components/canvas/canvas_paint_thread.rs index 7f0130e8f3e..a6050d93564 100644 --- a/components/canvas/canvas_paint_thread.rs +++ b/components/canvas/canvas_paint_thread.rs @@ -132,15 +132,21 @@ impl<'a> CanvasPaintThread <'a> { self.canvas(canvas_id).is_point_in_path(x, y, fill_rule, chan) }, Canvas2dMsg::DrawImage( - mut imagedata, + imagedata, image_size, dest_rect, source_rect, smoothing_enabled, ) => { - byte_swap(&mut imagedata); + let data = match imagedata { + None => vec![0; image_size.width as usize * image_size.height as usize * 4], + Some(mut data) => { + byte_swap(&mut data); + data.into() + }, + }; self.canvas(canvas_id).draw_image( - imagedata.into(), + data, image_size, dest_rect, source_rect, diff --git a/components/canvas_traits/canvas.rs b/components/canvas_traits/canvas.rs index 661bae6b606..a2af3a70d42 100644 --- a/components/canvas_traits/canvas.rs +++ b/components/canvas_traits/canvas.rs @@ -38,7 +38,7 @@ pub struct CanvasImageData { pub enum Canvas2dMsg { Arc(Point2D, f32, f32, f32, bool), ArcTo(Point2D, Point2D, f32), - DrawImage(ByteBuf, Size2D, Rect, Rect, bool), + DrawImage(Option, Size2D, Rect, Rect, bool), DrawImageSelf(Size2D, Rect, Rect, bool), DrawImageInOther( CanvasId, Size2D, Rect, Rect, bool), diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 24d6af0282d..12e3ad17959 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -27,7 +27,7 @@ use dom::canvasgradient::{CanvasGradient, CanvasGradientStyle, ToFillOrStrokeSty use dom::canvaspattern::CanvasPattern; use dom::element::Element; use dom::globalscope::GlobalScope; -use dom::htmlcanvaselement::HTMLCanvasElement; +use dom::htmlcanvaselement::{CanvasContext, HTMLCanvasElement}; use dom::imagedata::ImageData; use dom::node::{Node, NodeDamage, window_from_node}; use dom_struct::dom_struct; @@ -315,17 +315,18 @@ impl CanvasRenderingContext2D { result } - fn draw_html_canvas_element(&self, - canvas: &HTMLCanvasElement, - sx: f64, - sy: f64, - sw: Option, - sh: Option, - dx: f64, - dy: f64, - dw: Option, - dh: Option) - -> ErrorResult { + fn draw_html_canvas_element( + &self, + canvas: &HTMLCanvasElement, + sx: f64, + sy: f64, + sw: Option, + sh: Option, + dx: f64, + dy: f64, + dw: Option, + dh: Option, + ) -> ErrorResult { // 1. Check the usability of the image argument if !canvas.is_valid() { return Err(Error::InvalidState); @@ -339,15 +340,17 @@ impl CanvasRenderingContext2D { let image_size = Size2D::new(canvas_size.width as f64, canvas_size.height as f64); // 2. Establish the source and destination rectangles - let (source_rect, dest_rect) = self.adjust_source_dest_rects(image_size, - sx, - sy, - sw, - sh, - dx, - dy, - dw, - dh); + let (source_rect, dest_rect) = self.adjust_source_dest_rects( + image_size, + sx, + sy, + sw, + sh, + dx, + dy, + dw, + dh, + ); if !is_rect_valid(source_rect) || !is_rect_valid(dest_rect) { return Ok(()); @@ -355,29 +358,40 @@ impl CanvasRenderingContext2D { let smoothing_enabled = self.state.borrow().image_smoothing_enabled; - if self.canvas.as_ref().map_or(false, |c| &**c == canvas) { - self.send_canvas_2d_msg(Canvas2dMsg::DrawImageSelf( - image_size, dest_rect, source_rect, smoothing_enabled)); + if let Some(context) = canvas.context() { + match *context { + CanvasContext::Context2d(ref context) => { + if self.canvas.as_ref().map_or(false, |c| &**c == canvas) { + self.send_canvas_2d_msg(Canvas2dMsg::DrawImageSelf( + image_size, + dest_rect, + source_rect, + smoothing_enabled, + )); + } else { + context.get_ipc_renderer().send(CanvasMsg::Canvas2d( + Canvas2dMsg::DrawImageInOther( + self.get_canvas_id(), + image_size, + dest_rect, + source_rect, + smoothing_enabled, + ), + context.get_canvas_id(), + )).unwrap(); + } + }, + _ => return Err(Error::InvalidState), + } } else { - let context = match canvas.get_or_init_2d_context() { - Some(context) => context, - None => return Err(Error::InvalidState), - }; - - let msg = CanvasMsg::Canvas2d( - Canvas2dMsg::DrawImageInOther( - self.get_canvas_id(), - image_size, - dest_rect, - source_rect, - smoothing_enabled - ), - context.get_canvas_id() - ); - - let renderer = context.get_ipc_renderer(); - renderer.send(msg).unwrap(); - }; + self.send_canvas_2d_msg(Canvas2dMsg::DrawImage( + None, + image_size, + dest_rect, + source_rect, + smoothing_enabled, + )); + } self.mark_as_dirty(); Ok(()) @@ -447,7 +461,7 @@ impl CanvasRenderingContext2D { let smoothing_enabled = self.state.borrow().image_smoothing_enabled; self.send_canvas_2d_msg(Canvas2dMsg::DrawImage( - image_data.into(), + Some(image_data.into()), image_size, dest_rect, source_rect, @@ -1205,8 +1219,6 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D { .ok_or(Error::InvalidState)? }, CanvasImageSource::HTMLCanvasElement(ref canvas) => { - let _ = canvas.get_or_init_2d_context(); - canvas.fetch_all_data().ok_or(Error::InvalidState)? }, CanvasImageSource::CSSStyleValue(ref value) => { diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index dd1538b8529..7bc6a233e66 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -37,9 +37,10 @@ use js::jsapi::JSContext; use js::rust::HandleValue; use offscreen_gl_context::GLContextAttributes; use profile_traits::ipc; +use ref_filter_map; use script_layout_interface::{HTMLCanvasData, HTMLCanvasDataSource}; use servo_config::prefs::PREFS; -use std::iter::repeat; +use std::cell::Ref; use style::attr::{AttrValue, LengthOrPercentageOrAuto}; const DEFAULT_WIDTH: u32 = 300; @@ -174,18 +175,22 @@ impl LayoutHTMLCanvasElementHelpers for LayoutDom { impl HTMLCanvasElement { - pub fn get_or_init_2d_context(&self) -> Option> { - if self.context.borrow().is_none() { - let window = window_from_node(self); - let size = self.get_size(); - let context = CanvasRenderingContext2D::new(window.upcast::(), self, size); - *self.context.borrow_mut() = Some(CanvasContext::Context2d(Dom::from_ref(&*context))); - } + pub fn context(&self) -> Option> { + ref_filter_map::ref_filter_map(self.context.borrow(), |ctx| ctx.as_ref()) + } - match *self.context.borrow().as_ref().unwrap() { - CanvasContext::Context2d(ref context) => Some(DomRoot::from_ref(&*context)), - _ => None, + fn get_or_init_2d_context(&self) -> Option> { + if let Some(ctx) = self.context() { + return match *ctx { + CanvasContext::Context2d(ref ctx) => Some(DomRoot::from_ref(ctx)), + _ => None, + }; } + let window = window_from_node(self); + let size = self.get_size(); + let context = CanvasRenderingContext2D::new(window.upcast::(), self, size); + *self.context.borrow_mut() = Some(CanvasContext::Context2d(Dom::from_ref(&*context))); + Some(context) } #[allow(unsafe_code)] @@ -194,20 +199,18 @@ impl HTMLCanvasElement { cx: *mut JSContext, options: HandleValue, ) -> Option> { - if self.context.borrow().is_none() { - let window = window_from_node(self); - let size = self.get_size(); - let attrs = Self::get_gl_attributes(cx, options)?; - let maybe_ctx = WebGLRenderingContext::new(&window, self, WebGLVersion::WebGL1, size, attrs); - - *self.context.borrow_mut() = maybe_ctx.map( |ctx| CanvasContext::WebGL(Dom::from_ref(&*ctx))); - } - - if let Some(CanvasContext::WebGL(ref context)) = *self.context.borrow() { - Some(DomRoot::from_ref(&*context)) - } else { - None + if let Some(ctx) = self.context() { + return match *ctx { + CanvasContext::WebGL(ref ctx) => Some(DomRoot::from_ref(ctx)), + _ => None, + }; } + let window = window_from_node(self); + let size = self.get_size(); + let attrs = Self::get_gl_attributes(cx, options)?; + let context = WebGLRenderingContext::new(&window, self, WebGLVersion::WebGL1, size, attrs)?; + *self.context.borrow_mut() = Some(CanvasContext::WebGL(Dom::from_ref(&*context))); + Some(context) } #[allow(unsafe_code)] @@ -219,20 +222,18 @@ impl HTMLCanvasElement { if !PREFS.is_webgl2_enabled() { return None } - if self.context.borrow().is_none() { - let window = window_from_node(self); - let size = self.get_size(); - let attrs = Self::get_gl_attributes(cx, options)?; - let maybe_ctx = WebGL2RenderingContext::new(&window, self, size, attrs); - - *self.context.borrow_mut() = maybe_ctx.map( |ctx| CanvasContext::WebGL2(Dom::from_ref(&*ctx))); - } - - if let Some(CanvasContext::WebGL2(ref context)) = *self.context.borrow() { - Some(DomRoot::from_ref(&*context)) - } else { - None + if let Some(ctx) = self.context() { + return match *ctx { + CanvasContext::WebGL2(ref ctx) => Some(DomRoot::from_ref(ctx)), + _ => None, + }; } + let window = window_from_node(self); + let size = self.get_size(); + let attrs = Self::get_gl_attributes(cx, options)?; + let context = WebGL2RenderingContext::new(&window, self, size, attrs)?; + *self.context.borrow_mut() = Some(CanvasContext::WebGL2(Dom::from_ref(&*context))); + Some(context) } /// Gets the base WebGLRenderingContext for WebGL or WebGL 2, if exists. @@ -289,9 +290,7 @@ impl HTMLCanvasElement { // TODO: add a method in WebGL2RenderingContext to get the pixels. return None; }, - None => { - repeat(0xffu8).take((size.height as usize) * (size.width as usize) * 4).collect() - } + None => vec![0; size.height as usize * size.width as usize * 4] }; Some((data, size)) From 21e992bf40ade83fc3d52719c4b82277db69a6cf Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Sun, 16 Sep 2018 20:53:38 +0200 Subject: [PATCH 3/9] Update azure https://github.com/servo/rust-azure/pull/293 --- Cargo.lock | 10 ++--- components/canvas/canvas_data.rs | 73 ++++++++++++++++---------------- 2 files changed, 42 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c9c0b5fab7e..f4609e1a190 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -109,8 +109,8 @@ dependencies = [ [[package]] name = "azure" -version = "0.33.0" -source = "git+https://github.com/servo/rust-azure#43e61bda11f26e8462cfa63affac17c43df53b84" +version = "0.34.0" +source = "git+https://github.com/servo/rust-azure#1536ca66954356ece017343e3cd30b293134dc3f" dependencies = [ "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -324,7 +324,7 @@ dependencies = [ name = "canvas" version = "0.0.1" dependencies = [ - "azure 0.33.0 (git+https://github.com/servo/rust-azure)", + "azure 0.34.0 (git+https://github.com/servo/rust-azure)", "canvas_traits 0.0.1", "compositing 0.0.1", "cssparser 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2851,7 +2851,7 @@ dependencies = [ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4335,7 +4335,7 @@ dependencies = [ "checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21" "checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860" "checksum audio-video-metadata 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3c23600291b35b9cd381f5cfca636f5d7d75e7d7192eddf867de84a6732cad5c" -"checksum azure 0.33.0 (git+https://github.com/servo/rust-azure)" = "" +"checksum azure 0.34.0 (git+https://github.com/servo/rust-azure)" = "" "checksum backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72f9b4182546f4b04ebc4ab7f84948953a118bd6021a1b6a6c909e3e94f6be76" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" "checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs index 492a8da150a..8146969991b 100644 --- a/components/canvas/canvas_data.rs +++ b/components/canvas/canvas_data.rs @@ -405,51 +405,52 @@ impl<'a> CanvasData<'a> { } } + #[allow(unsafe_code)] pub fn send_pixels(&mut self, chan: IpcSender>) { - self.drawtarget.snapshot().get_data_surface().with_data(|element| { - chan.send(Some(Vec::from(element).into())).unwrap(); - }) + let data = unsafe { self.drawtarget.snapshot().get_data_surface().data().to_vec() }; + chan.send(Some(data.into())).unwrap(); } + #[allow(unsafe_code)] pub fn send_data(&mut self, chan: IpcSender) { - self.drawtarget.snapshot().get_data_surface().with_data(|element| { - let size = self.drawtarget.get_size(); + let size = self.drawtarget.get_size(); - let descriptor = webrender_api::ImageDescriptor { - size: webrender_api::DeviceUintSize::new(size.width as u32, size.height as u32), - stride: None, - format: webrender_api::ImageFormat::BGRA8, - offset: 0, - is_opaque: false, - allow_mipmaps: false, - }; - let data = webrender_api::ImageData::Raw(Arc::new(element.into())); + let descriptor = webrender_api::ImageDescriptor { + size: webrender_api::DeviceUintSize::new(size.width as u32, size.height as u32), + stride: None, + format: webrender_api::ImageFormat::BGRA8, + offset: 0, + is_opaque: false, + allow_mipmaps: false, + }; + let data = webrender_api::ImageData::Raw(Arc::new( + unsafe { self.drawtarget.snapshot().get_data_surface().data().into() }, + )); - let mut txn = webrender_api::Transaction::new(); + let mut txn = webrender_api::Transaction::new(); - match self.image_key { - Some(image_key) => { - debug!("Updating image {:?}.", image_key); - txn.update_image(image_key, descriptor, data, None); - } - None => { - self.image_key = Some(self.webrender_api.generate_image_key()); - debug!("New image {:?}.", self.image_key); - txn.add_image(self.image_key.unwrap(), descriptor, data, None); - } + match self.image_key { + Some(image_key) => { + debug!("Updating image {:?}.", image_key); + txn.update_image(image_key, descriptor, data, None); } - - if let Some(image_key) = mem::replace(&mut self.very_old_image_key, self.old_image_key.take()) { - txn.delete_image(image_key); + None => { + self.image_key = Some(self.webrender_api.generate_image_key()); + debug!("New image {:?}.", self.image_key); + txn.add_image(self.image_key.unwrap(), descriptor, data, None); } + } - self.webrender_api.update_resources(txn.resource_updates); + if let Some(image_key) = mem::replace(&mut self.very_old_image_key, self.old_image_key.take()) { + txn.delete_image(image_key); + } - let data = CanvasImageData { - image_key: self.image_key.unwrap(), - }; - chan.send(data).unwrap(); - }) + self.webrender_api.update_resources(txn.resource_updates); + + let data = CanvasImageData { + image_key: self.image_key.unwrap(), + }; + chan.send(data).unwrap(); } pub fn image_data( @@ -606,6 +607,7 @@ impl<'a> CanvasData<'a> { /// It reads image data from the canvas /// 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, canvas_size: Size2D) -> Vec { let canvas_size = canvas_size.to_i32(); let canvas_rect = Rect::new(Point2D::new(0i32, 0i32), canvas_size); @@ -617,8 +619,7 @@ impl<'a> CanvasData<'a> { } let data_surface = self.drawtarget.snapshot().get_data_surface(); - let mut src_data = Vec::new(); - data_surface.with_data(|element| { src_data = element.to_vec(); }); + let src_data = unsafe { data_surface.data() }; let stride = data_surface.stride(); //start offset of the copyable rectangle From 9f7b7464306c96ba0446ef0c5395325faaad3d5c Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Sun, 16 Sep 2018 22:07:18 +0200 Subject: [PATCH 4/9] Specify capacity in CanvasData::read_pixels --- components/canvas/canvas_data.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs index 8146969991b..bd825af38aa 100644 --- a/components/canvas/canvas_data.rs +++ b/components/canvas/canvas_data.rs @@ -613,9 +613,8 @@ impl<'a> CanvasData<'a> { let canvas_rect = Rect::new(Point2D::new(0i32, 0i32), canvas_size); let src_read_rect = canvas_rect.intersection(&read_rect).unwrap_or(Rect::zero()); - let mut image_data = vec![]; if src_read_rect.is_empty() || canvas_size.width <= 0 && canvas_size.height <= 0 { - return image_data; + return vec![]; } let data_surface = self.drawtarget.snapshot().get_data_surface(); @@ -624,6 +623,9 @@ impl<'a> CanvasData<'a> { //start offset of the copyable rectangle let mut src = (src_read_rect.origin.y * stride + src_read_rect.origin.x * 4) as usize; + let mut image_data = Vec::with_capacity( + (src_read_rect.size.width * src_read_rect.size.height * 4) as usize, + ); //copy the data to the destination vector for _ in 0..src_read_rect.size.height { let row = &src_data[src .. src + (4 * src_read_rect.size.width) as usize]; From 36c8cd229e0734efc374968964c8485ac45bbbf3 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Sun, 16 Sep 2018 22:12:44 +0200 Subject: [PATCH 5/9] Remove Canvas2dMsg::DrawImageSelf Now that all canvas share the same thread, it's useless to have a separate message for that. --- components/canvas/canvas_data.rs | 15 ----------- components/canvas/canvas_paint_thread.rs | 20 +++----------- components/canvas_traits/canvas.rs | 1 - .../script/dom/canvasrenderingcontext2d.rs | 26 +++++-------------- 4 files changed, 11 insertions(+), 51 deletions(-) diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs index bd825af38aa..b1768fe8744 100644 --- a/components/canvas/canvas_data.rs +++ b/components/canvas/canvas_data.rs @@ -85,21 +85,6 @@ impl<'a> CanvasData<'a> { } } - pub fn draw_image_self( - &self, - image_size: Size2D, - dest_rect: Rect, - source_rect: Rect, - smoothing_enabled: bool - ) { - // Reads pixels from source image - // In this case source and target are the same canvas - let image_data = self.read_pixels(source_rect.to_i32(), image_size); - - // The dimensions of image_data are source_rect.size - self.draw_image(image_data, source_rect.size, dest_rect, source_rect, smoothing_enabled); - } - pub fn save_context_state(&mut self) { self.saved_states.push(self.state.clone()); } diff --git a/components/canvas/canvas_paint_thread.rs b/components/canvas/canvas_paint_thread.rs index a6050d93564..3e66194e94c 100644 --- a/components/canvas/canvas_paint_thread.rs +++ b/components/canvas/canvas_paint_thread.rs @@ -153,19 +153,6 @@ impl<'a> CanvasPaintThread <'a> { smoothing_enabled, ) }, - Canvas2dMsg::DrawImageSelf( - image_size, - dest_rect, - source_rect, - smoothing_enabled - ) => { - self.canvas(canvas_id).draw_image_self( - image_size, - dest_rect, - source_rect, - smoothing_enabled - ) - }, Canvas2dMsg::DrawImageInOther( other_canvas_id, image_size, @@ -173,9 +160,10 @@ impl<'a> CanvasPaintThread <'a> { source_rect, smoothing ) => { - let mut image_data = self.canvas(canvas_id).read_pixels( - source_rect.to_i32(), - image_size); + let image_data = self.canvas(canvas_id).read_pixels( + source_rect.to_i32(), + image_size, + ); 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 a2af3a70d42..a9d47d252a4 100644 --- a/components/canvas_traits/canvas.rs +++ b/components/canvas_traits/canvas.rs @@ -39,7 +39,6 @@ pub enum Canvas2dMsg { Arc(Point2D, f32, f32, f32, bool), ArcTo(Point2D, Point2D, f32), DrawImage(Option, Size2D, Rect, Rect, bool), - DrawImageSelf(Size2D, Rect, Rect, bool), DrawImageInOther( CanvasId, Size2D, Rect, Rect, bool), BeginPath, diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 12e3ad17959..0da01cc8453 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -361,25 +361,13 @@ impl CanvasRenderingContext2D { if let Some(context) = canvas.context() { match *context { CanvasContext::Context2d(ref context) => { - if self.canvas.as_ref().map_or(false, |c| &**c == canvas) { - self.send_canvas_2d_msg(Canvas2dMsg::DrawImageSelf( - image_size, - dest_rect, - source_rect, - smoothing_enabled, - )); - } else { - context.get_ipc_renderer().send(CanvasMsg::Canvas2d( - Canvas2dMsg::DrawImageInOther( - self.get_canvas_id(), - image_size, - dest_rect, - source_rect, - smoothing_enabled, - ), - context.get_canvas_id(), - )).unwrap(); - } + context.send_canvas_2d_msg(Canvas2dMsg::DrawImageInOther( + self.get_canvas_id(), + image_size, + dest_rect, + source_rect, + smoothing_enabled, + )); }, _ => return Err(Error::InvalidState), } From e745050f3af38e6328f9ac63fd8abae77a5ec87b Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Mon, 17 Sep 2018 18:05:05 +0200 Subject: [PATCH 6/9] Update some outdated expectations --- .../textures/misc/tex-input-validation.html.ini | 3 --- .../textures/misc/texture-attachment-formats.html.ini | 7 ------- 2 files changed, 10 deletions(-) delete mode 100644 tests/wpt/webgl/meta/conformance/textures/misc/texture-attachment-formats.html.ini diff --git a/tests/wpt/webgl/meta/conformance/textures/misc/tex-input-validation.html.ini b/tests/wpt/webgl/meta/conformance/textures/misc/tex-input-validation.html.ini index cca6d8c125f..a86dfea0c35 100644 --- a/tests/wpt/webgl/meta/conformance/textures/misc/tex-input-validation.html.ini +++ b/tests/wpt/webgl/meta/conformance/textures/misc/tex-input-validation.html.ini @@ -11,6 +11,3 @@ [WebGL test #34: getError expected: INVALID_OPERATION. Was NO_ERROR : colorBufferFormat: RGB565 internalFormat: RGBA target: TEXTURE_2D border: 0] expected: FAIL - [WebGL test #37: getError expected: NO_ERROR. Was INVALID_OPERATION : colorBufferFormat: RGB565 internalFormat: RGB target: TEXTURE_2D border: 0] - expected: FAIL - diff --git a/tests/wpt/webgl/meta/conformance/textures/misc/texture-attachment-formats.html.ini b/tests/wpt/webgl/meta/conformance/textures/misc/texture-attachment-formats.html.ini deleted file mode 100644 index 9ba4addafa9..00000000000 --- a/tests/wpt/webgl/meta/conformance/textures/misc/texture-attachment-formats.html.ini +++ /dev/null @@ -1,7 +0,0 @@ -[texture-attachment-formats.html] - [WebGL test #14: should be 63,63,63,255 with tolerance 2,2,2,0\nat (0, 0) expected: 63,63,63,255 was 64,0,0,255] - expected: FAIL - - [WebGL test #16: should be 63,63,63,63 with tolerance 2,2,2,2\nat (0, 0) expected: 63,63,63,63 was 64,0,0,64] - expected: FAIL - From 8c100b23b1e2d29911f44802adc3b8cdffce38bf Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Mon, 17 Sep 2018 17:56:56 +0200 Subject: [PATCH 7/9] Implement proper origin checks for WebGL textures (fixes #21522) --- .../script/dom/canvasrenderingcontext2d.rs | 3 +- components/script/dom/htmlimageelement.rs | 11 +-- .../script/dom/webglrenderingcontext.rs | 66 ++++++------- .../security.dataURI.html.ini | 5 - .../toDataURL.jpeg.primarycolours.html.ini | 5 - .../toDataURL.png.complexcolours.html.ini | 5 - .../toDataURL.png.primarycolours.html.ini | 5 - .../the-img-element/data-url.html.ini | 5 - .../canvas/to-data-url-test.html.ini | 92 ++++++++++++++++++- .../more/functions/readPixelsBadArgs.html.ini | 8 -- .../more/functions/texImage2DHTML.html.ini | 5 - .../more/functions/texSubImage2DHTML.html.ini | 5 - .../misc/origin-clean-conformance.html.ini | 13 --- 13 files changed, 129 insertions(+), 99 deletions(-) delete mode 100644 tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/security.dataURI.html.ini delete mode 100644 tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.primarycolours.html.ini delete mode 100644 tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.png.complexcolours.html.ini delete mode 100644 tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.png.primarycolours.html.ini delete mode 100644 tests/wpt/metadata/html/semantics/embedded-content/the-img-element/data-url.html.ini delete mode 100644 tests/wpt/webgl/meta/conformance/more/functions/readPixelsBadArgs.html.ini delete mode 100644 tests/wpt/webgl/meta/conformance/more/functions/texImage2DHTML.html.ini delete mode 100644 tests/wpt/webgl/meta/conformance/more/functions/texSubImage2DHTML.html.ini delete mode 100644 tests/wpt/webgl/meta/conformance/textures/misc/origin-clean-conformance.html.ini diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 0da01cc8453..948fd0b9efe 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -247,8 +247,7 @@ impl CanvasRenderingContext2D { canvas.origin_is_clean() } CanvasImageSource::HTMLImageElement(image) => { - let image_origin = image.get_origin().expect("Image's origin is missing"); - image_origin.same_origin(GlobalScope::entry().origin()) + image.same_origin(GlobalScope::entry().origin()) } CanvasImageSource::CSSStyleValue(_) => true, } diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 1c49185ad0d..b665014cdca 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -55,7 +55,7 @@ use network_listener::{NetworkListener, PreInvoke}; use num_traits::ToPrimitive; use script_thread::ScriptThread; use servo_url::ServoUrl; -use servo_url::origin::ImmutableOrigin; +use servo_url::origin::MutableOrigin; use std::cell::{Cell, RefMut}; use std::char; use std::collections::HashSet; @@ -1186,11 +1186,10 @@ impl HTMLImageElement { useMapElements.map(|mapElem| mapElem.get_area_elements()) } - pub fn get_origin(&self) -> Option { - match self.current_request.borrow_mut().final_url { - Some(ref url) => Some(url.origin()), - None => None - } + pub fn same_origin(&self, origin: &MutableOrigin) -> bool { + self.current_request.borrow_mut().final_url.as_ref().map_or(false, |url| { + url.scheme() == "data" || url.origin().same_origin(origin) + }) } } diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 2f3df2adb7c..672ada20b08 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -13,15 +13,16 @@ use canvas_traits::webgl::WebGLError::*; use dom::bindings::codegen::Bindings::ANGLEInstancedArraysBinding::ANGLEInstancedArraysConstants; use dom::bindings::codegen::Bindings::EXTBlendMinmaxBinding::EXTBlendMinmaxConstants; use dom::bindings::codegen::Bindings::OESVertexArrayObjectBinding::OESVertexArrayObjectConstants; -use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{self, WebGLContextAttributes}; +use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding; +use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::TexImageSource; +use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLContextAttributes; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods; use dom::bindings::codegen::UnionTypes::ArrayBufferViewOrArrayBuffer; use dom::bindings::codegen::UnionTypes::Float32ArrayOrUnrestrictedFloatSequence; -use dom::bindings::codegen::UnionTypes::ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement; use dom::bindings::codegen::UnionTypes::Int32ArrayOrLongSequence; use dom::bindings::conversions::{DerivedFrom, ToJSValConvertible}; -use dom::bindings::error::{Error, ErrorResult}; +use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::inheritance::Castable; use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object}; use dom::bindings::root::{Dom, DomOnceCell, DomRoot, LayoutDom, MutNullableDom}; @@ -30,7 +31,7 @@ use dom::event::{Event, EventBubbles, EventCancelable}; use dom::htmlcanvaselement::HTMLCanvasElement; use dom::htmlcanvaselement::utils as canvas_utils; use dom::htmliframeelement::HTMLIFrameElement; -use dom::node::{Node, NodeDamage, window_from_node}; +use dom::node::{Node, NodeDamage, document_from_node, window_from_node}; use dom::webgl_extensions::WebGLExtensions; use dom::webgl_validations::WebGLValidator; use dom::webgl_validations::tex_image_2d::{CommonTexImage2DValidator, CommonTexImage2DValidatorResult}; @@ -76,7 +77,6 @@ pub fn is_gles() -> bool { cfg!(any(target_os = "android", target_os = "ios")) } -type ImagePixelResult = Result<(Vec, Size2D, bool), ()>; pub const MAX_UNIFORM_AND_ATTRIBUTE_LEN: usize = 256; // From the GLES 2.0.25 spec, page 85: @@ -490,21 +490,21 @@ impl WebGLRenderingContext { fn get_image_pixels( &self, - source: ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement, - ) -> ImagePixelResult { - // NOTE: Getting the pixels probably can be short-circuited if some - // parameter is invalid. - // - // Nontheless, since it's the error case, I'm not totally sure the - // complexity is worth it. - let (pixels, size, premultiplied) = match source { - ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement::ImageData(image_data) => { + source: TexImageSource, + ) -> Fallible, Size2D, bool)>> { + Ok(Some(match source { + TexImageSource::ImageData(image_data) => { (image_data.get_data_array(), image_data.get_size(), false) }, - ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement::HTMLImageElement(image) => { + TexImageSource::HTMLImageElement(image) => { + let document = document_from_node(&*self.canvas); + if !image.same_origin(document.origin()) { + return Err(Error::Security); + } + let img_url = match image.get_url() { Some(url) => url, - None => return Err(()), + None => return Ok(None), }; let window = window_from_node(&*self.canvas); @@ -513,7 +513,7 @@ impl WebGLRenderingContext { ImageResponse::Loaded(img, _) => img, ImageResponse::PlaceholderLoaded(_, _) | ImageResponse::None | ImageResponse::MetadataLoaded(_) - => return Err(()), + => return Ok(None), }; let size = Size2D::new(img.width as i32, img.height as i32); @@ -531,22 +531,23 @@ impl WebGLRenderingContext { // TODO(emilio): Getting canvas data is implemented in CanvasRenderingContext2D, // but we need to refactor it moving it to `HTMLCanvasElement` and support // WebGLContext (probably via GetPixels()). - ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement::HTMLCanvasElement(canvas) => { + TexImageSource::HTMLCanvasElement(canvas) => { + if !canvas.origin_is_clean() { + return Err(Error::Security); + } if let Some((mut data, size)) = canvas.fetch_all_data() { // Pixels got from Canvas have already alpha premultiplied byte_swap(&mut data); (data, size, true) } else { - return Err(()); + return Ok(None); } }, - ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement::HTMLVideoElement(_) => { + TexImageSource::HTMLVideoElement(_) => { // TODO: https://github.com/servo/servo/issues/6711 - return Err(()); + return Ok(None); } - }; - - return Ok((pixels, size, premultiplied)); + })) } // TODO(emilio): Move this logic to a validator. @@ -3520,16 +3521,15 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { internal_format: u32, format: u32, data_type: u32, - source: ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement, + source: TexImageSource, ) -> ErrorResult { if !self.extension_manager.is_tex_type_enabled(data_type) { return Ok(self.webgl_error(InvalidEnum)); } - // Get pixels from image source - let (pixels, size, premultiplied) = match self.get_image_pixels(source) { - Ok((pixels, size, premultiplied)) => (pixels, size, premultiplied), - Err(_) => return Ok(()), + let (pixels, size, premultiplied) = match self.get_image_pixels(source)? { + Some(triple) => triple, + None => return Ok(()), }; let validator = TexImage2DValidator::new(self, @@ -3677,11 +3677,11 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { yoffset: i32, format: u32, data_type: u32, - source: ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement, + source: TexImageSource, ) -> ErrorResult { - let (pixels, size, premultiplied) = match self.get_image_pixels(source) { - Ok((pixels, size, premultiplied)) => (pixels, size, premultiplied), - Err(_) => return Ok(()), + let (pixels, size, premultiplied) = match self.get_image_pixels(source)? { + Some(triple) => triple, + None => return Ok(()), }; let validator = TexImage2DValidator::new(self, target, level, format, diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/security.dataURI.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/security.dataURI.html.ini deleted file mode 100644 index be88270e814..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/security.dataURI.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[security.dataURI.html] - type: testharness - [data: URIs do not count as different-origin, and do not taint the canvas] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.primarycolours.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.primarycolours.html.ini deleted file mode 100644 index 17fc0b3f28b..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.primarycolours.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.jpeg.primarycolours.html] - type: testharness - [toDataURL with JPEG handles simple colours correctly] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.png.complexcolours.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.png.complexcolours.html.ini deleted file mode 100644 index 0db84d3a6b4..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.png.complexcolours.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.png.complexcolours.html] - type: testharness - [toDataURL with PNG handles non-primary and non-solid colours correctly] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.png.primarycolours.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.png.primarycolours.html.ini deleted file mode 100644 index 9be12d66b36..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-canvas-element/toDataURL.png.primarycolours.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[toDataURL.png.primarycolours.html] - type: testharness - [toDataURL with PNG handles simple colours correctly] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/data-url.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/data-url.html.ini deleted file mode 100644 index bc3ad74f666..00000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/data-url.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[data-url.html] - type: testharness - [data URL image] - expected: FAIL - diff --git a/tests/wpt/webgl/meta/conformance/canvas/to-data-url-test.html.ini b/tests/wpt/webgl/meta/conformance/canvas/to-data-url-test.html.ini index 9c807cfe763..ed8c57315e8 100644 --- a/tests/wpt/webgl/meta/conformance/canvas/to-data-url-test.html.ini +++ b/tests/wpt/webgl/meta/conformance/canvas/to-data-url-test.html.ini @@ -1,3 +1,91 @@ [to-data-url-test.html] - bug: https://github.com/servo/servo/issues/21132 - expected: ERROR + [WebGL test #12: should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 255,0,0,255] + expected: FAIL + + [WebGL test #18: should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 255,0,0,255] + expected: FAIL + + [WebGL test #1: should be 255,0,0,255\nat (0, 8) expected: 255,0,0,255 was 0,255,0,255] + expected: FAIL + + [WebGL test #4: should be 255,0,0,255\nat (0, 8) expected: 255,0,0,255 was 0,255,0,255] + expected: FAIL + + [WebGL test #34: should be 255,0,0,255\nat (0, 256) expected: 255,0,0,255 was 0,255,0,255] + expected: FAIL + + [WebGL test #24: should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 255,0,0,255] + expected: FAIL + + [WebGL test #31: should be 255,0,0,255\nat (0, 256) expected: 255,0,0,255 was 0,255,0,255] + expected: FAIL + + [WebGL test #10: should be 255,0,0,255\nat (0, 8) expected: 255,0,0,255 was 0,255,0,255] + expected: FAIL + + [WebGL test #25: should be 255,0,0,255\nat (0, 128) expected: 255,0,0,255 was 0,255,0,255] + expected: FAIL + + [WebGL test #40: should be 255,0,0,255\nat (0, 256) expected: 255,0,0,255 was 0,255,0,255] + expected: FAIL + + [WebGL test #19: should be 255,0,0,255\nat (0, 128) expected: 255,0,0,255 was 0,255,0,255] + expected: FAIL + + [WebGL test #9: should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 255,0,0,255] + expected: FAIL + + [WebGL test #3: should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 255,0,0,255] + expected: FAIL + + [WebGL test #43: should be 255,0,0,255\nat (0, 257) expected: 255,0,0,255 was 0,255,0,255] + expected: FAIL + + [WebGL test #15: should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 255,0,0,255] + expected: FAIL + + [WebGL test #16: should be 255,0,0,255\nat (0, 128) expected: 255,0,0,255 was 0,255,0,255] + expected: FAIL + + [WebGL test #21: should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 255,0,0,255] + expected: FAIL + + [WebGL test #33: should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 255,0,0,255] + expected: FAIL + + [WebGL test #0: should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 255,0,0,255] + expected: FAIL + + [WebGL test #30: should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 255,0,0,255] + expected: FAIL + + [WebGL test #22: should be 255,0,0,255\nat (0, 128) expected: 255,0,0,255 was 0,255,0,255] + expected: FAIL + + [WebGL test #39: should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 255,0,0,255] + expected: FAIL + + [WebGL test #28: should be 255,0,0,255\nat (0, 129) expected: 255,0,0,255 was 0,255,0,255] + expected: FAIL + + [WebGL test #7: should be 255,0,0,255\nat (0, 8) expected: 255,0,0,255 was 0,255,0,255] + expected: FAIL + + [WebGL test #36: should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 255,0,0,255] + expected: FAIL + + [WebGL test #42: should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 255,0,0,255] + expected: FAIL + + [WebGL test #27: should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 255,0,0,255] + expected: FAIL + + [WebGL test #13: should be 255,0,0,255\nat (0, 9) expected: 255,0,0,255 was 0,255,0,255] + expected: FAIL + + [WebGL test #37: should be 255,0,0,255\nat (0, 256) expected: 255,0,0,255 was 0,255,0,255] + expected: FAIL + + [WebGL test #6: should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 255,0,0,255] + expected: FAIL + diff --git a/tests/wpt/webgl/meta/conformance/more/functions/readPixelsBadArgs.html.ini b/tests/wpt/webgl/meta/conformance/more/functions/readPixelsBadArgs.html.ini deleted file mode 100644 index ad3520119fa..00000000000 --- a/tests/wpt/webgl/meta/conformance/more/functions/readPixelsBadArgs.html.ini +++ /dev/null @@ -1,8 +0,0 @@ -[readPixelsBadArgs.html] - bug: https://github.com/servo/servo/issues/21522 - [WebGL test #1: testReadPixelsSOPIMG] - expected: FAIL - - [WebGL test #2: testReadPixelsSOPCanvas] - expected: FAIL - diff --git a/tests/wpt/webgl/meta/conformance/more/functions/texImage2DHTML.html.ini b/tests/wpt/webgl/meta/conformance/more/functions/texImage2DHTML.html.ini deleted file mode 100644 index ba52b864738..00000000000 --- a/tests/wpt/webgl/meta/conformance/more/functions/texImage2DHTML.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[texImage2DHTML.html] - bug: https://github.com/servo/servo/issues/21522 - [WebGL test #1: testTexImage2DNonSOP] - expected: FAIL - diff --git a/tests/wpt/webgl/meta/conformance/more/functions/texSubImage2DHTML.html.ini b/tests/wpt/webgl/meta/conformance/more/functions/texSubImage2DHTML.html.ini deleted file mode 100644 index 823e2d127d3..00000000000 --- a/tests/wpt/webgl/meta/conformance/more/functions/texSubImage2DHTML.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[texSubImage2DHTML.html] - bug: https://github.com/servo/servo/issues/21522 - [WebGL test #1: testTexImage2DNonSOP] - expected: FAIL - diff --git a/tests/wpt/webgl/meta/conformance/textures/misc/origin-clean-conformance.html.ini b/tests/wpt/webgl/meta/conformance/textures/misc/origin-clean-conformance.html.ini deleted file mode 100644 index 57bece3c974..00000000000 --- a/tests/wpt/webgl/meta/conformance/textures/misc/origin-clean-conformance.html.ini +++ /dev/null @@ -1,13 +0,0 @@ -[origin-clean-conformance.html] - [WebGL test #3: texSubImage2D with cross-origin image should throw exception.] - expected: FAIL - - [WebGL test #8: texSubImage2D with NON origin clean canvas should throw exception.] - expected: FAIL - - [WebGL test #2: texImage2D with cross-origin image should throw exception.] - expected: FAIL - - [WebGL test #7: texImage2D with NON origin clean canvas should throw exception.] - expected: FAIL - From fe6f53ffb48a62dc8917c5c285e8e6b5626b8d69 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Tue, 18 Sep 2018 10:49:31 +0200 Subject: [PATCH 8/9] Fix a small texSubImage2D bug --- components/script/dom/webglrenderingcontext.rs | 11 ++++++----- .../textures/misc/tex-sub-image-2d-bad-args.html.ini | 3 --- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 672ada20b08..ac2ef4ea218 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -3613,7 +3613,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { height: i32, format: u32, data_type: u32, - mut pixels: CustomAutoRooterGuard>, + pixels: CustomAutoRooterGuard>, ) -> ErrorResult { let validator = TexImage2DValidator::new(self, target, level, format, width, height, @@ -3644,10 +3644,11 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // If data is null, a buffer of sufficient size // initialized to 0 is passed. - let buff = match *pixels { - None => vec![0u8; expected_byte_length as usize], - Some(ref mut data) => data.to_vec(), - }; + let buff = handle_potential_webgl_error!( + self, + pixels.as_ref().map(|p| p.to_vec()).ok_or(InvalidValue), + return Ok(()) + ); // From the WebGL spec: // diff --git a/tests/wpt/webgl/meta/conformance/textures/misc/tex-sub-image-2d-bad-args.html.ini b/tests/wpt/webgl/meta/conformance/textures/misc/tex-sub-image-2d-bad-args.html.ini index ba0e399016a..dc6a8f4d77c 100644 --- a/tests/wpt/webgl/meta/conformance/textures/misc/tex-sub-image-2d-bad-args.html.ini +++ b/tests/wpt/webgl/meta/conformance/textures/misc/tex-sub-image-2d-bad-args.html.ini @@ -1,7 +1,4 @@ [tex-sub-image-2d-bad-args.html] - [WebGL test #9: getError expected: INVALID_VALUE. Was NO_ERROR : null pixels] - expected: FAIL - [WebGL test #0: getError expected: INVALID_OPERATION. Was INVALID_VALUE : no previously defined texture image] expected: FAIL From 900c3cc6b526616d35994fda526e7166f13cd12d Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Tue, 18 Sep 2018 11:48:34 +0200 Subject: [PATCH 9/9] Implement gl.getParameter(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL) --- components/script/dom/webglrenderingcontext.rs | 10 +++++++++- .../meta/conformance/misc/webgl-specific.html.ini | 11 ----------- 2 files changed, 9 insertions(+), 12 deletions(-) delete mode 100644 tests/wpt/webgl/meta/conformance/misc/webgl-specific.html.ini diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index ac2ef4ea218..fadfb42f668 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -1235,7 +1235,15 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { constants::UNPACK_ALIGNMENT => { return UInt32Value(self.texture_unpacking_alignment.get()); }, - _ => {} + constants::UNPACK_COLORSPACE_CONVERSION_WEBGL => { + let unpack = self.texture_unpacking_settings.get(); + return UInt32Value(if unpack.contains(TextureUnpacking::CONVERT_COLORSPACE) { + constants::BROWSER_DEFAULT_WEBGL + } else { + constants::NONE + }); + }, + _ => {}, } // Handle any MAX_ parameters by retrieving the limits that were stored diff --git a/tests/wpt/webgl/meta/conformance/misc/webgl-specific.html.ini b/tests/wpt/webgl/meta/conformance/misc/webgl-specific.html.ini deleted file mode 100644 index 2a09e0f1a62..00000000000 --- a/tests/wpt/webgl/meta/conformance/misc/webgl-specific.html.ini +++ /dev/null @@ -1,11 +0,0 @@ -[webgl-specific.html] - bug: https://github.com/servo/servo/issues/20552 - [WebGL test #25: getError expected: NO_ERROR. Was INVALID_ENUM : set/get UNPACK_COLORSPACE_CONVERSION_WEBGL should generate no error] - expected: FAIL - - [WebGL test #23: gl.getParameter(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL) should be 37444 (of type number). Was null (of type object).] - expected: FAIL - - [WebGL test #24: gl.getParameter(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL) should be 0 (of type number). Was null (of type object).] - expected: FAIL -