Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Root nodes for the duration of their CSS transitions #16295

Merged
merged 5 commits into from May 15, 2017

Accumulate transitioning nodes inside the layout context.

  • Loading branch information
jdm committed May 15, 2017
commit c3b9714ab79a8230162605236f7c2f5e247707a7
@@ -26,7 +26,7 @@ pub fn update_animation_state(constellation_chan: &IpcSender<ConstellationMsg>,
script_chan: &IpcSender<ConstellationControlMsg>,
running_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>,
pipeline_id: PipelineId,
timer: &Timer) {
@@ -115,8 +115,11 @@ pub fn update_animation_state(constellation_chan: &IpcSender<ConstellationMsg>,

// Add new running animations.
for new_running_animation in new_running_animations {
if new_running_animation.is_transition() {
newly_transitioning_nodes.push(new_running_animation.node().to_untrusted_node_address());
match newly_transitioning_nodes {
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())
@@ -15,6 +15,7 @@ use net_traits::image_cache::{ImageOrMetadataAvailable, UsePlaceholder};
use opaque_node::OpaqueNodeMethods;
use parking_lot::RwLock;
use script_layout_interface::{PendingImage, PendingImageState};
use script_traits::UntrustedNodeAddress;
use servo_url::ServoUrl;
use std::borrow::{Borrow, BorrowMut};
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 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> {
@@ -514,7 +514,7 @@ impl LayoutThread {
// Create a layout context for use in building display lists, hit testing, &c.
fn build_layout_context<'a>(&'a self,
guards: StylesheetGuards<'a>,
request_images: bool,
script_initiated_layout: bool,
snapshot_map: &'a SnapshotMap)
-> LayoutContext<'a> {
let thread_local_style_context_creation_data =
@@ -538,7 +538,8 @@ impl LayoutThread {
image_cache: self.image_cache.clone(),
font_cache_thread: Mutex::new(self.font_cache_thread.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;

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() {
Some(root_flow) => root_flow,
None => return,
@@ -1427,6 +1434,7 @@ impl LayoutThread {
&mut *rw_data,
&mut layout_context);
assert!(layout_context.pending_images.is_none());
assert!(layout_context.newly_transitioning_nodes.is_none());
}
}

@@ -1437,17 +1445,24 @@ impl LayoutThread {
document: Option<&ServoLayoutDocument>,
rw_data: &mut LayoutThreadData,
context: &mut LayoutContext) {
assert!(rw_data.newly_transitioning_nodes.is_empty());

// Kick off animations if any were triggered, expire completed ones.
animation::update_animation_state(&self.constellation_chan,
&self.script_chan,
&mut *self.running_animations.write(),
&mut *self.expired_animations.write(),
&mut rw_data.newly_transitioning_nodes,
&self.new_animations_receiver,
self.id,
&self.timer);
{
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.
animation::update_animation_state(&self.constellation_chan,
&self.script_chan,
&mut *self.running_animations.write(),
&mut *self.expired_animations.write(),
newly_transitioning_nodes,
&self.new_animations_receiver,
self.id,
&self.timer);
}

profile(time::ProfilerCategory::LayoutRestyleDamagePropagation,
self.profiler_metadata(),
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.