mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
Accumulate transitioning nodes inside the layout context.
This commit is contained in:
parent
dabebdfbf5
commit
c3b9714ab7
3 changed files with 40 additions and 17 deletions
|
@ -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())
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue