diff --git a/Cargo.lock b/Cargo.lock index 396a84ecf5ac..311b77ced25e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2889,6 +2889,7 @@ version = "0.0.1" dependencies = [ "app_units", "atomic_refcell", + "canvas_traits", "cssparser", "embedder_traits", "euclid", diff --git a/components/layout_2020/Cargo.toml b/components/layout_2020/Cargo.toml index 51c08c19e349..7d2f9e3311ee 100644 --- a/components/layout_2020/Cargo.toml +++ b/components/layout_2020/Cargo.toml @@ -15,6 +15,7 @@ doctest = false [dependencies] app_units = "0.7" atomic_refcell = "0.1" +canvas_traits = {path = "../canvas_traits"} cssparser = "0.27" embedder_traits = {path = "../embedder_traits"} euclid = "0.20" diff --git a/components/layout_2020/dom_traversal.rs b/components/layout_2020/dom_traversal.rs index e67f06eb7f95..1a3a969919c0 100644 --- a/components/layout_2020/dom_traversal.rs +++ b/components/layout_2020/dom_traversal.rs @@ -5,7 +5,7 @@ use crate::context::LayoutContext; use crate::element_data::{LayoutBox, LayoutDataForElement}; use crate::geom::PhysicalSize; -use crate::replaced::ReplacedContent; +use crate::replaced::{CanvasInfo, CanvasSource, ReplacedContent}; use crate::style_ext::{Display, DisplayGeneratingBox, DisplayInside, DisplayOutside}; use crate::wrapper::GetRawData; use atomic_refcell::{AtomicRefCell, AtomicRefMut}; @@ -14,9 +14,10 @@ use net_traits::image::base::Image as NetImage; use script_layout_interface::wrapper_traits::{ LayoutNode, ThreadSafeLayoutElement, ThreadSafeLayoutNode, }; +use script_layout_interface::HTMLCanvasDataSource; use servo_arc::Arc as ServoArc; use std::marker::PhantomData as marker; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use style::dom::{OpaqueNode, TNode}; use style::properties::ComputedValues; use style::selector_parser::PseudoElement; @@ -354,6 +355,7 @@ pub(crate) trait NodeExt<'dom>: 'dom + Copy + LayoutNode + Send + Sync { /// Returns the image if it’s loaded, and its size in image pixels /// adjusted for `image_density`. fn as_image(self) -> Option<(Option>, PhysicalSize)>; + fn as_canvas(self) -> Option<(CanvasInfo, PhysicalSize)>; fn first_child(self) -> Option; fn next_sibling(self) -> Option; fn parent_node(self) -> Option; @@ -399,6 +401,24 @@ where Some((resource, PhysicalSize::new(width, height))) } + fn as_canvas(self) -> Option<(CanvasInfo, PhysicalSize)> { + let node = self.to_threadsafe(); + let canvas_data = node.canvas_data()?; + let source = match canvas_data.source { + HTMLCanvasDataSource::WebGL(texture_id) => CanvasSource::WebGL(texture_id), + HTMLCanvasDataSource::Image(ipc_sender) => { + CanvasSource::Image(ipc_sender.map(|renderer| Arc::new(Mutex::new(renderer)))) + }, + }; + Some(( + CanvasInfo { + source, + canvas_id: canvas_data.canvas_id, + }, + PhysicalSize::new(canvas_data.width.into(), canvas_data.height.into()), + )) + } + fn first_child(self) -> Option { TNode::first_child(&self) } diff --git a/components/layout_2020/replaced.rs b/components/layout_2020/replaced.rs index b9e53bec772c..1d7557b06415 100644 --- a/components/layout_2020/replaced.rs +++ b/components/layout_2020/replaced.rs @@ -10,15 +10,19 @@ use crate::geom::PhysicalSize; use crate::sizing::ContentSizes; use crate::style_ext::ComputedValuesExt; use crate::ContainingBlock; +use canvas_traits::canvas::{CanvasId, CanvasMsg, FromLayoutMsg}; +use ipc_channel::ipc::{self, IpcSender}; use net_traits::image::base::Image; use net_traits::image_cache::{ImageOrMetadataAvailable, UsePlaceholder}; use servo_arc::Arc as ServoArc; -use std::sync::Arc; +use std::fmt; +use std::sync::{Arc, Mutex}; use style::properties::ComputedValues; use style::servo::url::ComputedUrl; use style::values::computed::{Length, LengthOrAuto}; use style::values::CSSFloat; use style::Zero; +use webrender_api::ImageKey; #[derive(Debug, Serialize)] pub(crate) struct ReplacedContent { @@ -44,33 +48,69 @@ pub(crate) struct IntrinsicSizes { pub ratio: Option, } +#[derive(Serialize)] +pub(crate) enum CanvasSource { + WebGL(ImageKey), + Image(Option>>>), +} + +impl fmt::Debug for CanvasSource { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "{}", + match *self { + CanvasSource::WebGL(_) => "WebGL", + CanvasSource::Image(_) => "Image", + } + ) + } +} + +#[derive(Debug, Serialize)] +pub(crate) struct CanvasInfo { + pub source: CanvasSource, + pub canvas_id: CanvasId, +} + #[derive(Debug, Serialize)] pub(crate) enum ReplacedContentKind { Image(Option>), + Canvas(CanvasInfo), } impl ReplacedContent { pub fn for_element<'dom>(element: impl NodeExt<'dom>) -> Option { - if let Some((image, intrinsic_size_in_dots)) = element.as_image() { - // FIXME: should 'image-resolution' (when implemented) be used *instead* of - // `script::dom::htmlimageelement::ImageRequest::current_pixel_density`? + let (kind, intrinsic_size_in_dots) = { + if let Some((image, intrinsic_size_in_dots)) = element.as_image() { + (ReplacedContentKind::Image(image), intrinsic_size_in_dots) + } else if let Some((canvas_info, intrinsic_size_in_dots)) = element.as_canvas() { + ( + ReplacedContentKind::Canvas(canvas_info), + intrinsic_size_in_dots, + ) + } else { + return None; + } + }; - // https://drafts.csswg.org/css-images-4/#the-image-resolution - let dppx = 1.0; + // FIXME: should 'image-resolution' (when implemented) be used *instead* of + // `script::dom::htmlimageelement::ImageRequest::current_pixel_density`? - let width = (intrinsic_size_in_dots.width as CSSFloat) / dppx; - let height = (intrinsic_size_in_dots.height as CSSFloat) / dppx; - return Some(Self { - kind: ReplacedContentKind::Image(image), - intrinsic: IntrinsicSizes { - width: Some(Length::new(width)), - height: Some(Length::new(height)), - // FIXME https://github.com/w3c/csswg-drafts/issues/4572 - ratio: Some(width / height), - }, - }); - } - None + // https://drafts.csswg.org/css-images-4/#the-image-resolution + let dppx = 1.0; + + let width = (intrinsic_size_in_dots.width as CSSFloat) / dppx; + let height = (intrinsic_size_in_dots.height as CSSFloat) / dppx; + return Some(Self { + kind, + intrinsic: IntrinsicSizes { + width: Some(Length::new(width)), + height: Some(Length::new(height)), + // FIXME https://github.com/w3c/csswg-drafts/issues/4572 + ratio: Some(width / height), + }, + }); } pub fn from_image_url<'dom>( @@ -160,6 +200,34 @@ impl ReplacedContent { }) .into_iter() .collect(), + ReplacedContentKind::Canvas(canvas_info) => { + let image_key = match canvas_info.source { + CanvasSource::WebGL(image_key) => image_key, + CanvasSource::Image(ref ipc_renderer) => match *ipc_renderer { + Some(ref ipc_renderer) => { + let ipc_renderer = ipc_renderer.lock().unwrap(); + let (sender, receiver) = ipc::channel().unwrap(); + ipc_renderer + .send(CanvasMsg::FromLayout( + FromLayoutMsg::SendData(sender), + canvas_info.canvas_id, + )) + .unwrap(); + receiver.recv().unwrap().image_key + }, + None => return vec![], + }, + }; + vec![Fragment::Image(ImageFragment { + debug_id: DebugId::new(), + style: style.clone(), + rect: Rect { + start_corner: Vec2::zero(), + size, + }, + image_key, + })] + }, } } diff --git a/tests/wpt/metadata-layout-2020/2dcontext/building-paths/canvas_complexshapes_arcto_001.htm.ini b/tests/wpt/metadata-layout-2020/2dcontext/building-paths/canvas_complexshapes_arcto_001.htm.ini deleted file mode 100644 index a36c1a6220df..000000000000 --- a/tests/wpt/metadata-layout-2020/2dcontext/building-paths/canvas_complexshapes_arcto_001.htm.ini +++ /dev/null @@ -1,2 +0,0 @@ -[canvas_complexshapes_arcto_001.htm] - expected: FAIL diff --git a/tests/wpt/metadata-layout-2020/2dcontext/building-paths/canvas_complexshapes_beziercurveto_001.htm.ini b/tests/wpt/metadata-layout-2020/2dcontext/building-paths/canvas_complexshapes_beziercurveto_001.htm.ini deleted file mode 100644 index b65812a6287a..000000000000 --- a/tests/wpt/metadata-layout-2020/2dcontext/building-paths/canvas_complexshapes_beziercurveto_001.htm.ini +++ /dev/null @@ -1,2 +0,0 @@ -[canvas_complexshapes_beziercurveto_001.htm] - expected: FAIL diff --git a/tests/wpt/metadata-layout-2020/2dcontext/compositing/canvas_compositing_globalcompositeoperation_001.htm.ini b/tests/wpt/metadata-layout-2020/2dcontext/compositing/canvas_compositing_globalcompositeoperation_001.htm.ini deleted file mode 100644 index 583b4d64b2e1..000000000000 --- a/tests/wpt/metadata-layout-2020/2dcontext/compositing/canvas_compositing_globalcompositeoperation_001.htm.ini +++ /dev/null @@ -1,2 +0,0 @@ -[canvas_compositing_globalcompositeoperation_001.htm] - expected: FAIL diff --git a/tests/wpt/metadata-layout-2020/2dcontext/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-orientation-none.html.ini b/tests/wpt/metadata-layout-2020/2dcontext/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-orientation-none.html.ini deleted file mode 100644 index 3ccbbdb32884..000000000000 --- a/tests/wpt/metadata-layout-2020/2dcontext/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-orientation-none.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[drawImage-from-bitmap-orientation-none.html] - expected: FAIL diff --git a/tests/wpt/metadata-layout-2020/2dcontext/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap.html.ini b/tests/wpt/metadata-layout-2020/2dcontext/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap.html.ini deleted file mode 100644 index acd05100f92a..000000000000 --- a/tests/wpt/metadata-layout-2020/2dcontext/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[drawImage-from-bitmap.html] - expected: FAIL diff --git a/tests/wpt/metadata-layout-2020/2dcontext/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-orientation-none.html.ini b/tests/wpt/metadata-layout-2020/2dcontext/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-orientation-none.html.ini deleted file mode 100644 index e39fd7c45216..000000000000 --- a/tests/wpt/metadata-layout-2020/2dcontext/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-orientation-none.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[drawImage-from-element-orientation-none.html] - expected: FAIL diff --git a/tests/wpt/metadata-layout-2020/2dcontext/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height-orientation-none.html.ini b/tests/wpt/metadata-layout-2020/2dcontext/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height-orientation-none.html.ini deleted file mode 100644 index 133ffdac56e6..000000000000 --- a/tests/wpt/metadata-layout-2020/2dcontext/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height-orientation-none.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[drawImage-from-element-swap-width-height-orientation-none.html] - expected: FAIL diff --git a/tests/wpt/metadata-layout-2020/2dcontext/drawing-images-to-the-canvas/image-orientation/drawImage-from-element.html.ini b/tests/wpt/metadata-layout-2020/2dcontext/drawing-images-to-the-canvas/image-orientation/drawImage-from-element.html.ini deleted file mode 100644 index 068dcbf2e831..000000000000 --- a/tests/wpt/metadata-layout-2020/2dcontext/drawing-images-to-the-canvas/image-orientation/drawImage-from-element.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[drawImage-from-element.html] - expected: FAIL diff --git a/tests/wpt/metadata-layout-2020/2dcontext/line-styles/canvas_linestyles_linecap_001.htm.ini b/tests/wpt/metadata-layout-2020/2dcontext/line-styles/canvas_linestyles_linecap_001.htm.ini deleted file mode 100644 index 3375eeff92ff..000000000000 --- a/tests/wpt/metadata-layout-2020/2dcontext/line-styles/canvas_linestyles_linecap_001.htm.ini +++ /dev/null @@ -1,2 +0,0 @@ -[canvas_linestyles_linecap_001.htm] - expected: FAIL diff --git a/tests/wpt/metadata-layout-2020/2dcontext/shadows/canvas_shadows_002.htm.ini b/tests/wpt/metadata-layout-2020/2dcontext/shadows/canvas_shadows_002.htm.ini new file mode 100644 index 000000000000..b8702bdbec59 --- /dev/null +++ b/tests/wpt/metadata-layout-2020/2dcontext/shadows/canvas_shadows_002.htm.ini @@ -0,0 +1,2 @@ +[canvas_shadows_002.htm] + expected: FAIL diff --git a/tests/wpt/metadata-layout-2020/2dcontext/the-canvas-state/canvas_state_restore_001.htm.ini b/tests/wpt/metadata-layout-2020/2dcontext/the-canvas-state/canvas_state_restore_001.htm.ini deleted file mode 100644 index cbd47a3e334f..000000000000 --- a/tests/wpt/metadata-layout-2020/2dcontext/the-canvas-state/canvas_state_restore_001.htm.ini +++ /dev/null @@ -1,2 +0,0 @@ -[canvas_state_restore_001.htm] - expected: FAIL diff --git a/tests/wpt/metadata-layout-2020/2dcontext/transformations/canvas_transformations_scale_001.htm.ini b/tests/wpt/metadata-layout-2020/2dcontext/transformations/canvas_transformations_scale_001.htm.ini deleted file mode 100644 index 3a1492ff5ff2..000000000000 --- a/tests/wpt/metadata-layout-2020/2dcontext/transformations/canvas_transformations_scale_001.htm.ini +++ /dev/null @@ -1,2 +0,0 @@ -[canvas_transformations_scale_001.htm] - expected: FAIL diff --git a/tests/wpt/metadata-layout-2020/css/cssom-view/elementFromPosition.html.ini b/tests/wpt/metadata-layout-2020/css/cssom-view/elementFromPosition.html.ini index c131078eaceb..23c61ede1a13 100644 --- a/tests/wpt/metadata-layout-2020/css/cssom-view/elementFromPosition.html.ini +++ b/tests/wpt/metadata-layout-2020/css/cssom-view/elementFromPosition.html.ini @@ -17,3 +17,6 @@ [test the top of layer] expected: FAIL + [test some point of the element: top left corner] + expected: FAIL + diff --git a/tests/wpt/mozilla/meta-layout-2020/css/canvas_as_block_element_a.html.ini b/tests/wpt/mozilla/meta-layout-2020/css/canvas_as_block_element_a.html.ini deleted file mode 100644 index ec277801e55b..000000000000 --- a/tests/wpt/mozilla/meta-layout-2020/css/canvas_as_block_element_a.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[canvas_as_block_element_a.html] - expected: FAIL diff --git a/tests/wpt/mozilla/meta-layout-2020/css/canvas_over_area.html.ini b/tests/wpt/mozilla/meta-layout-2020/css/canvas_over_area.html.ini deleted file mode 100644 index 15dfca6355de..000000000000 --- a/tests/wpt/mozilla/meta-layout-2020/css/canvas_over_area.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[canvas_over_area.html] - expected: FAIL diff --git a/tests/wpt/mozilla/meta-layout-2020/css/max_inline_block_size_canvas.html.ini b/tests/wpt/mozilla/meta-layout-2020/css/max_inline_block_size_canvas.html.ini deleted file mode 100644 index bc00f7498f74..000000000000 --- a/tests/wpt/mozilla/meta-layout-2020/css/max_inline_block_size_canvas.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[max_inline_block_size_canvas.html] - expected: FAIL diff --git a/tests/wpt/mozilla/meta-layout-2020/mozilla/webgl/clearcolor.html.ini b/tests/wpt/mozilla/meta-layout-2020/mozilla/webgl/clearcolor.html.ini deleted file mode 100644 index 0af2f792e3fa..000000000000 --- a/tests/wpt/mozilla/meta-layout-2020/mozilla/webgl/clearcolor.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[clearcolor.html] - expected: FAIL diff --git a/tests/wpt/mozilla/meta-layout-2020/mozilla/webgl/draw_arrays_simple.html.ini b/tests/wpt/mozilla/meta-layout-2020/mozilla/webgl/draw_arrays_simple.html.ini deleted file mode 100644 index 3c62e9e6d4d1..000000000000 --- a/tests/wpt/mozilla/meta-layout-2020/mozilla/webgl/draw_arrays_simple.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[draw_arrays_simple.html] - expected: FAIL diff --git a/tests/wpt/mozilla/meta-layout-2020/mozilla/webgl/tex_image_2d_abv.html.ini b/tests/wpt/mozilla/meta-layout-2020/mozilla/webgl/tex_image_2d_abv.html.ini deleted file mode 100644 index 2182851af6b1..000000000000 --- a/tests/wpt/mozilla/meta-layout-2020/mozilla/webgl/tex_image_2d_abv.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[tex_image_2d_abv.html] - expected: FAIL diff --git a/tests/wpt/mozilla/meta-layout-2020/mozilla/webgl/tex_image_2d_canvas2d.html.ini b/tests/wpt/mozilla/meta-layout-2020/mozilla/webgl/tex_image_2d_canvas2d.html.ini deleted file mode 100644 index 439a3324829a..000000000000 --- a/tests/wpt/mozilla/meta-layout-2020/mozilla/webgl/tex_image_2d_canvas2d.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[tex_image_2d_canvas2d.html] - expected: FAIL diff --git a/tests/wpt/mozilla/meta-layout-2020/mozilla/webgl/tex_image_2d_mipmap.html.ini b/tests/wpt/mozilla/meta-layout-2020/mozilla/webgl/tex_image_2d_mipmap.html.ini deleted file mode 100644 index da08a2c6a225..000000000000 --- a/tests/wpt/mozilla/meta-layout-2020/mozilla/webgl/tex_image_2d_mipmap.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[tex_image_2d_mipmap.html] - expected: FAIL diff --git a/tests/wpt/mozilla/meta-layout-2020/mozilla/webgl/tex_image_2d_simple.html.ini b/tests/wpt/mozilla/meta-layout-2020/mozilla/webgl/tex_image_2d_simple.html.ini deleted file mode 100644 index 7abe554c4325..000000000000 --- a/tests/wpt/mozilla/meta-layout-2020/mozilla/webgl/tex_image_2d_simple.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[tex_image_2d_simple.html] - expected: FAIL