Accumulate transitioning nodes inside the layout context.

This commit is contained in:
Josh Matthews 2017-04-10 17:02:25 +10:00
parent dabebdfbf5
commit c3b9714ab7
3 changed files with 40 additions and 17 deletions

View file

@ -26,7 +26,7 @@ pub fn update_animation_state(constellation_chan: &IpcSender<ConstellationMsg>,
script_chan: &IpcSender<ConstellationControlMsg>, script_chan: &IpcSender<ConstellationControlMsg>,
running_animations: &mut HashMap<OpaqueNode, Vec<Animation>>, running_animations: &mut HashMap<OpaqueNode, Vec<Animation>>,
expired_animations: &mut HashMap<OpaqueNode, Vec<Animation>>, expired_animations: &mut HashMap<OpaqueNode, Vec<Animation>>,
newly_transitioning_nodes: &mut Vec<UntrustedNodeAddress>, mut newly_transitioning_nodes: Option<&mut Vec<UntrustedNodeAddress>>,
new_animations_receiver: &Receiver<Animation>, new_animations_receiver: &Receiver<Animation>,
pipeline_id: PipelineId, pipeline_id: PipelineId,
timer: &Timer) { timer: &Timer) {
@ -115,8 +115,11 @@ pub fn update_animation_state(constellation_chan: &IpcSender<ConstellationMsg>,
// Add new running animations. // Add new running animations.
for new_running_animation in new_running_animations { for new_running_animation in new_running_animations {
if new_running_animation.is_transition() { match newly_transitioning_nodes {
newly_transitioning_nodes.push(new_running_animation.node().to_untrusted_node_address()); Some(ref mut nodes) if new_running_animation.is_transition() => {
nodes.push(new_running_animation.node().to_untrusted_node_address());
}
_ => ()
} }
running_animations.entry(*new_running_animation.node()) running_animations.entry(*new_running_animation.node())

View file

@ -15,6 +15,7 @@ use net_traits::image_cache::{ImageOrMetadataAvailable, UsePlaceholder};
use opaque_node::OpaqueNodeMethods; use opaque_node::OpaqueNodeMethods;
use parking_lot::RwLock; use parking_lot::RwLock;
use script_layout_interface::{PendingImage, PendingImageState}; use script_layout_interface::{PendingImage, PendingImageState};
use script_traits::UntrustedNodeAddress;
use servo_url::ServoUrl; use servo_url::ServoUrl;
use std::borrow::{Borrow, BorrowMut}; use std::borrow::{Borrow, BorrowMut};
use std::cell::{RefCell, RefMut}; use std::cell::{RefCell, RefMut};
@ -96,7 +97,11 @@ pub struct LayoutContext<'a> {
/// A list of in-progress image loads to be shared with the script thread. /// A list of in-progress image loads to be shared with the script thread.
/// A None value means that this layout was not initiated by the script thread. /// A None value means that this layout was not initiated by the script thread.
pub pending_images: Option<Mutex<Vec<PendingImage>>> pub pending_images: Option<Mutex<Vec<PendingImage>>>,
/// A list of nodes that have just initiated a CSS transition.
/// A None value means that this layout was not initiated by the script thread.
pub newly_transitioning_nodes: Option<Mutex<Vec<UntrustedNodeAddress>>>,
} }
impl<'a> Drop for LayoutContext<'a> { impl<'a> Drop for LayoutContext<'a> {

View file

@ -514,7 +514,7 @@ impl LayoutThread {
// Create a layout context for use in building display lists, hit testing, &c. // Create a layout context for use in building display lists, hit testing, &c.
fn build_layout_context<'a>(&'a self, fn build_layout_context<'a>(&'a self,
guards: StylesheetGuards<'a>, guards: StylesheetGuards<'a>,
request_images: bool, script_initiated_layout: bool,
snapshot_map: &'a SnapshotMap) snapshot_map: &'a SnapshotMap)
-> LayoutContext<'a> { -> LayoutContext<'a> {
let thread_local_style_context_creation_data = let thread_local_style_context_creation_data =
@ -538,7 +538,8 @@ impl LayoutThread {
image_cache: self.image_cache.clone(), image_cache: self.image_cache.clone(),
font_cache_thread: Mutex::new(self.font_cache_thread.clone()), font_cache_thread: Mutex::new(self.font_cache_thread.clone()),
webrender_image_cache: self.webrender_image_cache.clone(), webrender_image_cache: self.webrender_image_cache.clone(),
pending_images: if request_images { Some(Mutex::new(vec![])) } else { None }, pending_images: if script_initiated_layout { Some(Mutex::new(vec![])) } else { None },
newly_transitioning_nodes: if script_initiated_layout { Some(Mutex::new(vec![])) } else { None },
} }
} }
@ -1252,6 +1253,12 @@ impl LayoutThread {
}; };
rw_data.pending_images = pending_images; rw_data.pending_images = pending_images;
let newly_transitioning_nodes = match context.newly_transitioning_nodes {
Some(ref nodes) => std_mem::replace(&mut *nodes.lock().unwrap(), vec![]),
None => vec![],
};
rw_data.newly_transitioning_nodes = newly_transitioning_nodes;
let mut root_flow = match self.root_flow.borrow().clone() { let mut root_flow = match self.root_flow.borrow().clone() {
Some(root_flow) => root_flow, Some(root_flow) => root_flow,
None => return, None => return,
@ -1427,6 +1434,7 @@ impl LayoutThread {
&mut *rw_data, &mut *rw_data,
&mut layout_context); &mut layout_context);
assert!(layout_context.pending_images.is_none()); assert!(layout_context.pending_images.is_none());
assert!(layout_context.newly_transitioning_nodes.is_none());
} }
} }
@ -1437,17 +1445,24 @@ impl LayoutThread {
document: Option<&ServoLayoutDocument>, document: Option<&ServoLayoutDocument>,
rw_data: &mut LayoutThreadData, rw_data: &mut LayoutThreadData,
context: &mut LayoutContext) { context: &mut LayoutContext) {
assert!(rw_data.newly_transitioning_nodes.is_empty()); {
let mut newly_transitioning_nodes = context
.newly_transitioning_nodes
.as_ref()
.map(|nodes| nodes.lock().unwrap());
let newly_transitioning_nodes = newly_transitioning_nodes
.as_mut()
.map(|nodes| &mut **nodes);
// Kick off animations if any were triggered, expire completed ones. // Kick off animations if any were triggered, expire completed ones.
animation::update_animation_state(&self.constellation_chan, animation::update_animation_state(&self.constellation_chan,
&self.script_chan, &self.script_chan,
&mut *self.running_animations.write(), &mut *self.running_animations.write(),
&mut *self.expired_animations.write(), &mut *self.expired_animations.write(),
&mut rw_data.newly_transitioning_nodes, newly_transitioning_nodes,
&self.new_animations_receiver, &self.new_animations_receiver,
self.id, self.id,
&self.timer); &self.timer);
}
profile(time::ProfilerCategory::LayoutRestyleDamagePropagation, profile(time::ProfilerCategory::LayoutRestyleDamagePropagation,
self.profiler_metadata(), self.profiler_metadata(),