mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
Pass the document instead of the documentElement to reflow.
This commit is contained in:
parent
85596b5510
commit
441c84d75d
5 changed files with 51 additions and 26 deletions
|
@ -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
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue