mirror of
https://github.com/servo/servo.git
synced 2025-06-11 10:00:18 +00:00
script: Improve dirty propagation and fix script-layout synchronization.
This fixes race conditions whereby layout and script could be running simultaneously.
This commit is contained in:
parent
1bc2c8a639
commit
d101c1dd91
8 changed files with 220 additions and 257 deletions
|
@ -23,8 +23,7 @@ use dom::event::{Event, EventHelpers, Bubbles, DoesNotBubble, Cancelable, NotCan
|
|||
use dom::uievent::UIEvent;
|
||||
use dom::eventtarget::{EventTarget, EventTargetHelpers};
|
||||
use dom::keyboardevent::KeyboardEvent;
|
||||
use dom::node;
|
||||
use dom::node::{ElementNodeTypeId, Node, NodeHelpers};
|
||||
use dom::node::{mod, ElementNodeTypeId, Node, NodeHelpers, OtherNodeDamage};
|
||||
use dom::window::{Window, WindowHelpers};
|
||||
use dom::worker::{Worker, TrustedWorkerAddress};
|
||||
use dom::xmlhttprequest::{TrustedXHRAddress, XMLHttpRequest, XHRProgress};
|
||||
|
@ -40,10 +39,9 @@ use devtools_traits::{DevtoolScriptControlMsg, EvaluateJS, GetDocumentElement};
|
|||
use devtools_traits::{GetChildren, GetLayout, ModifyAttribute};
|
||||
use script_traits::{CompositorEvent, ResizeEvent, ReflowEvent, ClickEvent, MouseDownEvent};
|
||||
use script_traits::{MouseMoveEvent, MouseUpEvent, ConstellationControlMsg, ScriptTaskFactory};
|
||||
use script_traits::{ResizeMsg, AttachLayoutMsg, LoadMsg, ViewportMsg, SendEventMsg};
|
||||
use script_traits::{ResizeMsg, AttachLayoutMsg, GetTitleMsg, KeyEvent, LoadMsg, ViewportMsg};
|
||||
use script_traits::{ResizeInactiveMsg, ExitPipelineMsg, NewLayoutInfo, OpaqueScriptLayoutChannel};
|
||||
use script_traits::{ScriptControlChan, ReflowCompleteMsg, UntrustedNodeAddress, KeyEvent};
|
||||
use script_traits::{GetTitleMsg};
|
||||
use script_traits::{ScriptControlChan, ReflowCompleteMsg, SendEventMsg};
|
||||
use servo_msg::compositor_msg::{FinishedLoading, LayerId, Loading, PerformingLayout};
|
||||
use servo_msg::compositor_msg::{ScriptListener};
|
||||
use servo_msg::constellation_msg::{ConstellationChan, LoadCompleteMsg};
|
||||
|
@ -496,11 +494,7 @@ impl ScriptTask {
|
|||
let page = page.find(id).expect("resize sent to nonexistent pipeline");
|
||||
page.resize_event.set(Some(size));
|
||||
}
|
||||
FromConstellation(SendEventMsg(id, ReflowEvent(node_addresses))) => {
|
||||
let page = self.page.borrow_mut();
|
||||
let inner_page = page.find(id).expect("Reflow sent to nonexistent pipeline");
|
||||
let mut pending = inner_page.pending_dirty_nodes.borrow_mut();
|
||||
pending.push_all_move(node_addresses);
|
||||
FromConstellation(SendEventMsg(id, ReflowEvent(_))) => {
|
||||
needs_reflow.insert(id);
|
||||
}
|
||||
FromConstellation(ViewportMsg(id, rect)) => {
|
||||
|
@ -666,11 +660,6 @@ impl ScriptTask {
|
|||
}
|
||||
|
||||
self.compositor.borrow_mut().set_ready_state(pipeline_id, FinishedLoading);
|
||||
|
||||
if page.pending_reflows.get() > 0 {
|
||||
page.pending_reflows.set(0);
|
||||
self.force_reflow(&*page);
|
||||
}
|
||||
}
|
||||
|
||||
/// Handles a navigate forward or backward message.
|
||||
|
@ -838,8 +827,12 @@ impl ScriptTask {
|
|||
|
||||
// Kick off the initial reflow of the page.
|
||||
debug!("kicking off initial reflow of {}", final_url);
|
||||
document.content_changed(NodeCast::from_ref(*document));
|
||||
window.flush_layout();
|
||||
{
|
||||
let document_js_ref = (&*document).clone();
|
||||
let document_as_node = NodeCast::from_ref(document_js_ref);
|
||||
document.content_changed(document_as_node, OtherNodeDamage);
|
||||
}
|
||||
window.flush_layout(ReflowForDisplay, NoQuery);
|
||||
|
||||
{
|
||||
// No more reflow required
|
||||
|
@ -895,18 +888,9 @@ impl ScriptTask {
|
|||
self.compositor.borrow_mut().scroll_fragment_point(pipeline_id, LayerId::null(), point);
|
||||
}
|
||||
|
||||
/// Reflows non-incrementally.
|
||||
fn force_reflow(&self, page: &Page) {
|
||||
{
|
||||
let mut pending = page.pending_dirty_nodes.borrow_mut();
|
||||
let js_runtime = self.js_runtime.deref().ptr;
|
||||
|
||||
for untrusted_node in pending.into_iter() {
|
||||
let node = node::from_untrusted_node_address(js_runtime, untrusted_node).root();
|
||||
node.dirty();
|
||||
}
|
||||
}
|
||||
|
||||
page.damage();
|
||||
page.dirty_all_nodes();
|
||||
page.reflow(ReflowForDisplay,
|
||||
self.control_chan.clone(),
|
||||
&mut **self.compositor.borrow_mut(),
|
||||
|
@ -1020,7 +1004,7 @@ impl ScriptTask {
|
|||
_ => ()
|
||||
}
|
||||
|
||||
window.flush_layout();
|
||||
window.flush_layout(ReflowForDisplay, NoQuery);
|
||||
}
|
||||
|
||||
/// The entry point for content to notify that a new load has been requested
|
||||
|
@ -1090,12 +1074,7 @@ impl ScriptTask {
|
|||
let page = get_page(&*self.page.borrow(), pipeline_id);
|
||||
let frame = page.frame();
|
||||
if frame.is_some() {
|
||||
let in_layout = page.layout_join_port.borrow().is_some();
|
||||
if in_layout {
|
||||
page.pending_reflows.set(page.pending_reflows.get() + 1);
|
||||
} else {
|
||||
self.force_reflow(&*page);
|
||||
}
|
||||
self.force_reflow(&*page);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1138,7 +1117,7 @@ impl ScriptTask {
|
|||
el.authentic_click_activation(*event);
|
||||
|
||||
doc.commit_focus_transaction();
|
||||
window.flush_layout();
|
||||
window.flush_layout(ReflowForDisplay, NoQuery);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
@ -1220,8 +1199,6 @@ impl ScriptTask {
|
|||
/// Shuts down layout for the given page tree.
|
||||
fn shut_down_layout(page_tree: &Rc<Page>, rt: *mut JSRuntime) {
|
||||
for page in page_tree.iter() {
|
||||
page.join_layout();
|
||||
|
||||
// Tell the layout task to begin shutting down, and wait until it
|
||||
// processed this message.
|
||||
let (response_chan, response_port) = channel();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue