mirror of
https://github.com/servo/servo.git
synced 2025-09-27 23:30:08 +01:00
layout: Use ServoThreadSafeLayoutNode
in more places (#38626)
Use `ServoThreadSafeLayoutNode` in more places in layout rather than `ServoLayoutNode`. The former is meant to be used during layout, but layout 2020 was written against the latter. In general, this reduces the amount of conversion to the thread-safe version in many places in layout. In addition, an unused iterator from the `script` crate `ServoThreadSafeLayoutNodeChildrenIterator` is replaced with the child iterator from `layout`. The `layout` version must be directly in `script` now as it uses the dangerous variants of `next_sibling` and `first_child`, which allow encapsulating the unsafe bits into one module. This will ultimately be useful for storing the layout data of pseudo-element children of pseudo-elements properly. Testing: This should not change any behavior and thus is covered by existing tests. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
20ad1ce84e
commit
ee7c1d9109
20 changed files with 258 additions and 321 deletions
|
@ -2,22 +2,19 @@
|
|||
* 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 std::any::Any;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
|
||||
use base::id::{BrowsingContextId, PipelineId};
|
||||
use html5ever::{local_name, ns};
|
||||
use layout_api::wrapper_traits::{
|
||||
LayoutDataTrait, LayoutNode, ThreadSafeLayoutElement, ThreadSafeLayoutNode,
|
||||
};
|
||||
use layout_api::wrapper_traits::{LayoutDataTrait, ThreadSafeLayoutElement, ThreadSafeLayoutNode};
|
||||
use layout_api::{
|
||||
GenericLayoutDataTrait, LayoutDamage, LayoutElementType,
|
||||
LayoutNodeType as ScriptLayoutNodeType, SVGElementData,
|
||||
};
|
||||
use malloc_size_of_derive::MallocSizeOf;
|
||||
use net_traits::image_cache::Image;
|
||||
use script::layout_dom::ServoLayoutNode;
|
||||
use script::layout_dom::ServoThreadSafeLayoutNode;
|
||||
use servo_arc::Arc as ServoArc;
|
||||
use smallvec::SmallVec;
|
||||
use style::context::SharedStyleContext;
|
||||
|
@ -116,13 +113,13 @@ impl LayoutBox {
|
|||
fn repair_style(
|
||||
&self,
|
||||
context: &SharedStyleContext,
|
||||
node: &ServoLayoutNode,
|
||||
node: &ServoThreadSafeLayoutNode,
|
||||
new_style: &ServoArc<ComputedValues>,
|
||||
) {
|
||||
match self {
|
||||
LayoutBox::DisplayContents(inline_shared_styles) => {
|
||||
*inline_shared_styles.style.borrow_mut() = new_style.clone();
|
||||
*inline_shared_styles.selected.borrow_mut() = node.to_threadsafe().selected_style();
|
||||
*inline_shared_styles.selected.borrow_mut() = node.selected_style();
|
||||
},
|
||||
LayoutBox::BlockLevel(block_level_box) => {
|
||||
block_level_box
|
||||
|
@ -172,7 +169,7 @@ pub struct DOMLayoutData(AtomicRefCell<InnerDOMLayoutData>);
|
|||
// The implementation of this trait allows the data to be stored in the DOM.
|
||||
impl LayoutDataTrait for DOMLayoutData {}
|
||||
impl GenericLayoutDataTrait for DOMLayoutData {
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
@ -235,7 +232,6 @@ pub(crate) trait NodeExt<'dom> {
|
|||
fn as_video(&self) -> Option<(Option<webrender_api::ImageKey>, Option<PhysicalSize<f64>>)>;
|
||||
fn as_svg(&self) -> Option<SVGElementData>;
|
||||
fn as_typeless_object_with_data_attribute(&self) -> Option<String>;
|
||||
fn style(&self, context: &SharedStyleContext) -> ServoArc<ComputedValues>;
|
||||
|
||||
fn layout_data_mut(&self) -> AtomicRefMut<'dom, InnerDOMLayoutData>;
|
||||
fn layout_data(&self) -> Option<AtomicRef<'dom, InnerDOMLayoutData>>;
|
||||
|
@ -255,10 +251,9 @@ pub(crate) trait NodeExt<'dom> {
|
|||
fn take_restyle_damage(&self) -> LayoutDamage;
|
||||
}
|
||||
|
||||
impl<'dom> NodeExt<'dom> for ServoLayoutNode<'dom> {
|
||||
impl<'dom> NodeExt<'dom> for ServoThreadSafeLayoutNode<'dom> {
|
||||
fn as_image(&self) -> Option<(Option<Image>, PhysicalSize<f64>)> {
|
||||
let node = self.to_threadsafe();
|
||||
let (resource, metadata) = node.image_data()?;
|
||||
let (resource, metadata) = self.image_data()?;
|
||||
let (width, height) = resource
|
||||
.as_ref()
|
||||
.map(|image| {
|
||||
|
@ -268,7 +263,7 @@ impl<'dom> NodeExt<'dom> for ServoLayoutNode<'dom> {
|
|||
.or_else(|| metadata.map(|metadata| (metadata.width, metadata.height)))
|
||||
.unwrap_or((0, 0));
|
||||
let (mut width, mut height) = (width as f64, height as f64);
|
||||
if let Some(density) = node.image_density().filter(|density| *density != 1.) {
|
||||
if let Some(density) = self.image_density().filter(|density| *density != 1.) {
|
||||
width /= density;
|
||||
height /= density;
|
||||
}
|
||||
|
@ -276,12 +271,11 @@ impl<'dom> NodeExt<'dom> for ServoLayoutNode<'dom> {
|
|||
}
|
||||
|
||||
fn as_svg(&self) -> Option<SVGElementData> {
|
||||
self.to_threadsafe().svg_data()
|
||||
self.svg_data()
|
||||
}
|
||||
|
||||
fn as_video(&self) -> Option<(Option<webrender_api::ImageKey>, Option<PhysicalSize<f64>>)> {
|
||||
let node = self.to_threadsafe();
|
||||
let data = node.media_data()?;
|
||||
let data = self.media_data()?;
|
||||
let natural_size = if let Some(frame) = data.current_frame {
|
||||
Some(PhysicalSize::new(frame.width.into(), frame.height.into()))
|
||||
} else {
|
||||
|
@ -295,8 +289,7 @@ impl<'dom> NodeExt<'dom> for ServoLayoutNode<'dom> {
|
|||
}
|
||||
|
||||
fn as_canvas(&self) -> Option<(CanvasInfo, PhysicalSize<f64>)> {
|
||||
let node = self.to_threadsafe();
|
||||
let canvas_data = node.canvas_data()?;
|
||||
let canvas_data = self.canvas_data()?;
|
||||
let source = canvas_data.source;
|
||||
Some((
|
||||
CanvasInfo { source },
|
||||
|
@ -305,8 +298,7 @@ impl<'dom> NodeExt<'dom> for ServoLayoutNode<'dom> {
|
|||
}
|
||||
|
||||
fn as_iframe(&self) -> Option<(PipelineId, BrowsingContextId)> {
|
||||
let node = self.to_threadsafe();
|
||||
match (node.iframe_pipeline_id(), node.iframe_browsing_context_id()) {
|
||||
match (self.iframe_pipeline_id(), self.iframe_browsing_context_id()) {
|
||||
(Some(pipeline_id), Some(browsing_context_id)) => {
|
||||
Some((pipeline_id, browsing_context_id))
|
||||
},
|
||||
|
@ -315,8 +307,10 @@ impl<'dom> NodeExt<'dom> for ServoLayoutNode<'dom> {
|
|||
}
|
||||
|
||||
fn as_typeless_object_with_data_attribute(&self) -> Option<String> {
|
||||
if LayoutNode::type_id(self) !=
|
||||
ScriptLayoutNodeType::Element(LayoutElementType::HTMLObjectElement)
|
||||
if self.type_id() !=
|
||||
Some(ScriptLayoutNodeType::Element(
|
||||
LayoutElementType::HTMLObjectElement,
|
||||
))
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
@ -324,7 +318,7 @@ impl<'dom> NodeExt<'dom> for ServoLayoutNode<'dom> {
|
|||
// TODO: This is the what the legacy layout system did, but really if Servo
|
||||
// supports any `<object>` that's an image, it should support those with URLs
|
||||
// and `type` attributes with image mime types.
|
||||
let element = self.to_threadsafe().as_element()?;
|
||||
let element = self.as_element()?;
|
||||
if element.get_attr(&ns!(), &local_name!("type")).is_some() {
|
||||
return None;
|
||||
}
|
||||
|
@ -333,15 +327,11 @@ impl<'dom> NodeExt<'dom> for ServoLayoutNode<'dom> {
|
|||
.map(|string| string.to_owned())
|
||||
}
|
||||
|
||||
fn style(&self, context: &SharedStyleContext) -> ServoArc<ComputedValues> {
|
||||
self.to_threadsafe().style(context)
|
||||
}
|
||||
|
||||
fn layout_data_mut(&self) -> AtomicRefMut<'dom, InnerDOMLayoutData> {
|
||||
if LayoutNode::layout_data(self).is_none() {
|
||||
if ThreadSafeLayoutNode::layout_data(self).is_none() {
|
||||
self.initialize_layout_data::<DOMLayoutData>();
|
||||
}
|
||||
LayoutNode::layout_data(self)
|
||||
ThreadSafeLayoutNode::layout_data(self)
|
||||
.unwrap()
|
||||
.as_any()
|
||||
.downcast_ref::<DOMLayoutData>()
|
||||
|
@ -351,7 +341,7 @@ impl<'dom> NodeExt<'dom> for ServoLayoutNode<'dom> {
|
|||
}
|
||||
|
||||
fn layout_data(&self) -> Option<AtomicRef<'dom, InnerDOMLayoutData>> {
|
||||
LayoutNode::layout_data(self).map(|data| {
|
||||
ThreadSafeLayoutNode::layout_data(self).map(|data| {
|
||||
data.as_any()
|
||||
.downcast_ref::<DOMLayoutData>()
|
||||
.unwrap()
|
||||
|
@ -416,13 +406,13 @@ impl<'dom> NodeExt<'dom> for ServoLayoutNode<'dom> {
|
|||
fn repair_style(&self, context: &SharedStyleContext) {
|
||||
let data = self.layout_data_mut();
|
||||
if let Some(layout_object) = &*data.self_box.borrow() {
|
||||
let style = self.to_threadsafe().style(context);
|
||||
let style = self.style(context);
|
||||
layout_object.repair_style(context, self, &style);
|
||||
}
|
||||
|
||||
for pseudo_layout_data in data.pseudo_boxes.iter() {
|
||||
if let Some(layout_box) = pseudo_layout_data.box_slot.borrow().as_ref() {
|
||||
if let Some(node) = self.to_threadsafe().with_pseudo(pseudo_layout_data.pseudo) {
|
||||
if let Some(node) = self.with_pseudo(pseudo_layout_data.pseudo) {
|
||||
layout_box.repair_style(context, self, &node.style(context));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue