Pass the document instead of the documentElement to reflow.

This commit is contained in:
Bobby Holley 2015-10-12 17:43:49 -07:00
parent 85596b5510
commit 441c84d75d
5 changed files with 51 additions and 26 deletions

View file

@ -52,6 +52,7 @@ use query::{LayoutRPCImpl, process_content_box_request, process_content_boxes_re
use query::{MarginPadding, MarginRetrievingFragmentBorderBoxIterator, PositionProperty}; use query::{MarginPadding, MarginRetrievingFragmentBorderBoxIterator, PositionProperty};
use query::{PositionRetrievingFragmentBorderBoxIterator, Side}; use query::{PositionRetrievingFragmentBorderBoxIterator, Side};
use script::dom::bindings::js::LayoutJS; use script::dom::bindings::js::LayoutJS;
use script::dom::document::Document;
use script::dom::node::{LayoutData, Node}; use script::dom::node::{LayoutData, Node};
use script::layout_interface::Animation; use script::layout_interface::Animation;
use script::layout_interface::{LayoutChan, LayoutRPC, OffsetParentResponse}; use script::layout_interface::{LayoutChan, LayoutRPC, OffsetParentResponse};
@ -89,8 +90,7 @@ use util::opts;
use util::task::spawn_named_with_send_on_failure; use util::task::spawn_named_with_send_on_failure;
use util::task_state; use util::task_state;
use util::workqueue::WorkQueue; use util::workqueue::WorkQueue;
use wrapper::LayoutNode; use wrapper::{LayoutDocument, LayoutNode, ThreadSafeLayoutNode};
use wrapper::ThreadSafeLayoutNode;
/// The number of screens of data we're allowed to generate display lists for in each direction. /// The number of screens of data we're allowed to generate display lists for in each direction.
pub const DISPLAY_PORT_SIZE_FACTOR: i32 = 8; pub const DISPLAY_PORT_SIZE_FACTOR: i32 = 8;
@ -1137,13 +1137,16 @@ impl LayoutTask {
let _ajst = AutoJoinScriptTask { data: data }; let _ajst = AutoJoinScriptTask { data: data };
// FIXME: Isolate this transmutation into a "bridge" module. // FIXME: Isolate this transmutation into a "bridge" module.
// FIXME(rust#16366): The following line had to be moved because of a let mut doc: LayoutJS<Document> = unsafe {
// rustc bug. It should be in the next unsafe block. LayoutJS::from_trusted_node_address(data.document).downcast::<Document>().unwrap()
let mut node: LayoutJS<Node> = unsafe {
LayoutJS::from_trusted_node_address(data.document_root)
}; };
let node: &mut LayoutNode = unsafe { let doc: &mut LayoutDocument = unsafe {
transmute(&mut node) transmute(&mut doc)
};
let mut node: LayoutNode = match doc.root_node() {
None => return,
Some(x) => x,
}; };
debug!("layout: received layout request for: {}", self.url.serialize()); debug!("layout: received layout request for: {}", self.url.serialize());
@ -1187,11 +1190,11 @@ impl LayoutTask {
let needs_reflow = screen_size_changed && !needs_dirtying; let needs_reflow = screen_size_changed && !needs_dirtying;
unsafe { unsafe {
if needs_dirtying { if needs_dirtying {
LayoutTask::dirty_all_nodes(node); LayoutTask::dirty_all_nodes(&mut node);
} }
} }
if needs_reflow { if needs_reflow {
if let Some(mut flow) = self.try_get_layout_root(*node) { if let Some(mut flow) = self.try_get_layout_root(node) {
LayoutTask::reflow_all_nodes(flow_ref::deref_mut(&mut flow)); LayoutTask::reflow_all_nodes(flow_ref::deref_mut(&mut flow));
} }
} }
@ -1213,16 +1216,16 @@ impl LayoutTask {
let rw_data = &mut *rw_data; let rw_data = &mut *rw_data;
match rw_data.parallel_traversal { match rw_data.parallel_traversal {
None => { None => {
sequential::traverse_dom_preorder(*node, &shared_layout_context); sequential::traverse_dom_preorder(node, &shared_layout_context);
} }
Some(ref mut traversal) => { Some(ref mut traversal) => {
parallel::traverse_dom_preorder(*node, &shared_layout_context, traversal); parallel::traverse_dom_preorder(node, &shared_layout_context, traversal);
} }
} }
}); });
// Retrieve the (possibly rebuilt) root flow. // Retrieve the (possibly rebuilt) root flow.
rw_data.root_flow = self.try_get_layout_root((*node).clone()); rw_data.root_flow = self.try_get_layout_root(node.clone());
} }
// Send new canvas renderers to the paint task // Send new canvas renderers to the paint task

View file

@ -43,6 +43,7 @@ use script::dom::bindings::codegen::InheritTypes::{HTMLElementTypeId, NodeTypeId
use script::dom::bindings::conversions::Castable; use script::dom::bindings::conversions::Castable;
use script::dom::bindings::js::LayoutJS; use script::dom::bindings::js::LayoutJS;
use script::dom::characterdata::LayoutCharacterDataHelpers; use script::dom::characterdata::LayoutCharacterDataHelpers;
use script::dom::document::{Document, LayoutDocumentHelpers};
use script::dom::element; use script::dom::element;
use script::dom::element::{Element, LayoutElementHelpers, RawLayoutElementHelpers}; use script::dom::element::{Element, LayoutElementHelpers, RawLayoutElementHelpers};
use script::dom::htmlcanvaselement::{LayoutHTMLCanvasElementHelpers, HTMLCanvasData}; use script::dom::htmlcanvaselement::{LayoutHTMLCanvasElementHelpers, HTMLCanvasData};
@ -105,6 +106,12 @@ impl<'ln> LayoutNode<'ln> {
} }
} }
pub fn is_element(&self) -> bool {
unsafe {
self.node.is_element_for_layout()
}
}
pub fn dump(self) { pub fn dump(self) {
self.dump_indent(0); self.dump_indent(0);
} }
@ -336,6 +343,30 @@ impl<'a> Iterator for LayoutTreeIterator<'a> {
} }
} }
// A wrapper around documents that ensures ayout can only ever access safe properties.
#[derive(Copy, Clone)]
pub struct LayoutDocument<'le> {
document: LayoutJS<Document>,
chain: PhantomData<&'le ()>,
}
impl<'le> LayoutDocument<'le> {
pub fn as_node(&self) -> LayoutNode<'le> {
LayoutNode {
node: self.document.upcast(),
chain: PhantomData,
}
}
pub fn root_node(&self) -> Option<LayoutNode<'le>> {
let mut node = self.as_node().first_child();
while node.is_some() && !node.unwrap().is_element() {
node = node.unwrap().next_sibling();
}
node
}
}
/// A wrapper around elements that ensures layout can only ever access safe properties. /// A wrapper around elements that ensures layout can only ever access safe properties.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct LayoutElement<'le> { pub struct LayoutElement<'le> {

View file

@ -1175,15 +1175,14 @@ pub enum DocumentSource {
NotFromParser, NotFromParser,
} }
#[allow(unsafe_code)]
pub trait LayoutDocumentHelpers { pub trait LayoutDocumentHelpers {
#[allow(unsafe_code)]
unsafe fn is_html_document_for_layout(&self) -> bool; unsafe fn is_html_document_for_layout(&self) -> bool;
} }
#[allow(unsafe_code)]
impl LayoutDocumentHelpers for LayoutJS<Document> { impl LayoutDocumentHelpers for LayoutJS<Document> {
#[allow(unrooted_must_root)]
#[inline] #[inline]
#[allow(unsafe_code)]
unsafe fn is_html_document_for_layout(&self) -> bool { unsafe fn is_html_document_for_layout(&self) -> bool {
(*self.unsafe_get()).is_html_document (*self.unsafe_get()).is_html_document
} }

View file

@ -885,14 +885,6 @@ impl Window {
/// ///
/// TODO(pcwalton): Only wait for style recalc, since we have off-main-thread layout. /// TODO(pcwalton): Only wait for style recalc, since we have off-main-thread layout.
pub fn force_reflow(&self, goal: ReflowGoal, query_type: ReflowQueryType, reason: ReflowReason) { pub fn force_reflow(&self, goal: ReflowGoal, query_type: ReflowQueryType, reason: ReflowReason) {
let document = self.Document();
let root = document.r().GetDocumentElement();
let root = match root.r() {
Some(root) => root,
None => return,
};
let root = root.upcast::<Node>();
let window_size = match self.window_size.get() { let window_size = match self.window_size.get() {
Some(window_size) => window_size, Some(window_size) => window_size,
None => return, None => return,
@ -923,7 +915,7 @@ impl Window {
goal: goal, goal: goal,
page_clip_rect: self.page_clip_rect.get(), page_clip_rect: self.page_clip_rect.get(),
}, },
document_root: root.to_trusted_node_address(), document: self.Document().r().upcast::<Node>().to_trusted_node_address(),
window_size: window_size, window_size: window_size,
script_chan: self.control_chan.clone(), script_chan: self.control_chan.clone(),
script_join_chan: join_chan, script_join_chan: join_chan,

View file

@ -174,7 +174,7 @@ pub struct ScriptReflow {
/// General reflow data. /// General reflow data.
pub reflow_info: Reflow, pub reflow_info: Reflow,
/// The document node. /// The document node.
pub document_root: TrustedNodeAddress, pub document: TrustedNodeAddress,
/// The channel through which messages can be sent back to the script task. /// The channel through which messages can be sent back to the script task.
pub script_chan: Sender<ConstellationControlMsg>, pub script_chan: Sender<ConstellationControlMsg>,
/// The current window size. /// The current window size.