Skip to content

Commit

Permalink
Canvas rendering for layout 2020
Browse files Browse the repository at this point in the history
Update test expectations with layout 2020 canvas support
  • Loading branch information
ferjm committed Mar 6, 2020
1 parent 0bd794a commit f0e30f5
Show file tree
Hide file tree
Showing 26 changed files with 116 additions and 61 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions components/layout_2020/Cargo.toml
Expand Up @@ -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"
Expand Down
24 changes: 22 additions & 2 deletions components/layout_2020/dom_traversal.rs
Expand Up @@ -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};
Expand All @@ -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;
Expand Down Expand Up @@ -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<Arc<NetImage>>, PhysicalSize<f64>)>;
fn as_canvas(self) -> Option<(CanvasInfo, PhysicalSize<f64>)>;
fn first_child(self) -> Option<Self>;
fn next_sibling(self) -> Option<Self>;
fn parent_node(self) -> Option<Self>;
Expand Down Expand Up @@ -399,6 +401,24 @@ where
Some((resource, PhysicalSize::new(width, height)))
}

fn as_canvas(self) -> Option<(CanvasInfo, PhysicalSize<f64>)> {
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<Self> {
TNode::first_child(&self)
}
Expand Down
106 changes: 87 additions & 19 deletions components/layout_2020/replaced.rs
Expand Up @@ -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 {
Expand All @@ -44,33 +48,69 @@ pub(crate) struct IntrinsicSizes {
pub ratio: Option<CSSFloat>,
}

#[derive(Serialize)]
pub(crate) enum CanvasSource {
WebGL(ImageKey),
Image(Option<Arc<Mutex<IpcSender<CanvasMsg>>>>),
}

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<Arc<Image>>),
Canvas(CanvasInfo),
}

impl ReplacedContent {
pub fn for_element<'dom>(element: impl NodeExt<'dom>) -> Option<Self> {
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>(
Expand Down Expand Up @@ -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,
})]
},
}
}

Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

@@ -0,0 +1,2 @@
[canvas_shadows_002.htm]
expected: FAIL

This file was deleted.

This file was deleted.

Expand Up @@ -17,3 +17,6 @@
[test the top of layer]
expected: FAIL

[test some point of the element: top left corner]
expected: FAIL

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

0 comments on commit f0e30f5

Please sign in to comment.