mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
Auto merge of #12645 - emilio:stylo, r=bholley
stylo: Allow computing change hints during the traversal. <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors <!-- Either: --> - [x] These changes do not require tests because geckolib :-( <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> r? @bholley cc @heycam <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/12645) <!-- Reviewable:end -->
This commit is contained in:
commit
cbf71a2cf3
19 changed files with 446 additions and 100 deletions
|
@ -6,7 +6,7 @@
|
|||
|
||||
use bezier::Bezier;
|
||||
use context::SharedStyleContext;
|
||||
use dom::{OpaqueNode, TRestyleDamage};
|
||||
use dom::OpaqueNode;
|
||||
use euclid::point::Point2D;
|
||||
use keyframes::{KeyframesStep, KeyframesStepValue};
|
||||
use properties::animated_properties::{AnimatedProperty, TransitionProperty};
|
||||
|
@ -490,13 +490,12 @@ pub fn update_style_for_animation_frame(mut new_style: &mut Arc<ComputedValues>,
|
|||
}
|
||||
/// Updates a single animation and associated style based on the current time.
|
||||
/// If `damage` is provided, inserts the appropriate restyle damage.
|
||||
pub fn update_style_for_animation<Damage>(context: &SharedStyleContext,
|
||||
animation: &Animation,
|
||||
style: &mut Arc<ComputedValues>,
|
||||
damage: Option<&mut Damage>)
|
||||
where Damage: TRestyleDamage {
|
||||
pub fn update_style_for_animation(context: &SharedStyleContext,
|
||||
animation: &Animation,
|
||||
style: &mut Arc<ComputedValues>) {
|
||||
debug!("update_style_for_animation: entering");
|
||||
debug_assert!(!animation.is_expired());
|
||||
|
||||
match *animation {
|
||||
Animation::Transition(_, start_time, ref frame, _) => {
|
||||
debug!("update_style_for_animation: transition found");
|
||||
|
@ -506,10 +505,6 @@ where Damage: TRestyleDamage {
|
|||
now, start_time,
|
||||
frame);
|
||||
if updated_style {
|
||||
if let Some(damage) = damage {
|
||||
*damage = *damage | Damage::compute(Some(style), &new_style);
|
||||
}
|
||||
|
||||
*style = new_style
|
||||
}
|
||||
}
|
||||
|
@ -660,10 +655,6 @@ where Damage: TRestyleDamage {
|
|||
}
|
||||
|
||||
debug!("update_style_for_animation: got style change in animation \"{}\"", name);
|
||||
if let Some(damage) = damage {
|
||||
*damage = *damage | Damage::compute(Some(style), &new_style);
|
||||
}
|
||||
|
||||
*style = new_style;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,19 @@ impl OpaqueNode {
|
|||
}
|
||||
|
||||
pub trait TRestyleDamage : BitOr<Output=Self> + Copy {
|
||||
fn compute(old: Option<&Arc<ComputedValues>>, new: &ComputedValues) -> Self;
|
||||
/// The source for our current computed values in the cascade. This is a
|
||||
/// ComputedValues in Servo and a StyleContext in Gecko.
|
||||
///
|
||||
/// This is needed because Gecko has a few optimisations for the calculation
|
||||
/// of the difference depending on which values have been used during
|
||||
/// layout.
|
||||
///
|
||||
/// This should be obtained via TNode::existing_style_for_restyle_damage
|
||||
type PreExistingComputedValues;
|
||||
|
||||
fn compute(old: Option<&Self::PreExistingComputedValues>,
|
||||
new: &Arc<ComputedValues>) -> Self;
|
||||
|
||||
fn rebuild_and_reflow() -> Self;
|
||||
}
|
||||
|
||||
|
@ -159,6 +171,13 @@ pub trait TNode : Sized + Copy + Clone {
|
|||
fn unstyle(self) {
|
||||
self.mutate_data().unwrap().style = None;
|
||||
}
|
||||
|
||||
/// XXX: It's a bit unfortunate we need to pass the current computed values
|
||||
/// as an argument here, but otherwise Servo would crash due to double
|
||||
/// borrows to return it.
|
||||
fn existing_style_for_restyle_damage<'a>(&'a self,
|
||||
current_computed_values: Option<&'a Arc<ComputedValues>>)
|
||||
-> Option<&'a <Self::ConcreteRestyleDamage as TRestyleDamage>::PreExistingComputedValues>;
|
||||
}
|
||||
|
||||
pub trait TDocument : Sized + Copy + Clone {
|
||||
|
|
|
@ -13,7 +13,6 @@ pub struct ArcHelpers<GeckoType, ServoType> {
|
|||
phantom2: PhantomData<ServoType>,
|
||||
}
|
||||
|
||||
|
||||
impl<GeckoType, ServoType> ArcHelpers<GeckoType, ServoType> {
|
||||
pub fn with<F, Output>(raw: *mut GeckoType, cb: F) -> Output
|
||||
where F: FnOnce(&Arc<ServoType>) -> Output {
|
||||
|
@ -47,6 +46,15 @@ impl<GeckoType, ServoType> ArcHelpers<GeckoType, ServoType> {
|
|||
unsafe { transmute(owned) }
|
||||
}
|
||||
|
||||
pub fn borrow<F, Output>(borrowed: &Arc<ServoType>, cb: F) -> Output
|
||||
where F: FnOnce(&mut GeckoType) -> Output
|
||||
{
|
||||
let borrowed_gecko_type: *const &mut GeckoType =
|
||||
unsafe { transmute(borrowed) };
|
||||
|
||||
unsafe { cb(*borrowed_gecko_type) }
|
||||
}
|
||||
|
||||
pub unsafe fn addref(ptr: *mut GeckoType) {
|
||||
Self::with(ptr, |arc| forget(arc.clone()));
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#![allow(unsafe_code)]
|
||||
|
||||
use animation::{self, Animation};
|
||||
use animation;
|
||||
use arc_ptr_eq;
|
||||
use cache::{LRUCache, SimpleHashCache};
|
||||
use context::{StyleContext, SharedStyleContext};
|
||||
|
@ -442,8 +442,13 @@ trait PrivateMatchMethods: TNode
|
|||
cacheable = cacheable && !animations_started
|
||||
}
|
||||
|
||||
|
||||
let existing_style =
|
||||
self.existing_style_for_restyle_damage(style.map(|s| &*s));
|
||||
|
||||
// Calculate style difference.
|
||||
let damage = Self::ConcreteRestyleDamage::compute(style.map(|s| &*s), &*this_style);
|
||||
let damage =
|
||||
Self::ConcreteRestyleDamage::compute(existing_style, &this_style);
|
||||
|
||||
// Cache the resolved style if it was cacheable.
|
||||
if cacheable {
|
||||
|
@ -490,8 +495,9 @@ trait PrivateMatchMethods: TNode
|
|||
// See #12171 and the associated PR for an example where this
|
||||
// happened while debugging other release panic.
|
||||
if !running_animation.is_expired() {
|
||||
animation::update_style_for_animation::<Self::ConcreteRestyleDamage>(
|
||||
context, running_animation, style, None);
|
||||
animation::update_style_for_animation(context,
|
||||
running_animation,
|
||||
style);
|
||||
running_animation.mark_as_expired();
|
||||
}
|
||||
}
|
||||
|
@ -585,9 +591,17 @@ pub trait ElementMatchMethods : TElement {
|
|||
if let Some(shared_style) = self.share_style_with_candidate_if_possible(parent.clone(), candidate) {
|
||||
// Yay, cache hit. Share the style.
|
||||
let node = self.as_node();
|
||||
|
||||
let style = &mut node.mutate_data().unwrap().style;
|
||||
let damage = <<Self as TElement>::ConcreteNode as TNode>
|
||||
::ConcreteRestyleDamage::compute((*style).as_ref(), &*shared_style);
|
||||
|
||||
let damage = {
|
||||
let source =
|
||||
node.existing_style_for_restyle_damage((*style).as_ref());
|
||||
let damage = <<Self as TElement>::ConcreteNode as TNode>
|
||||
::ConcreteRestyleDamage::compute(source, &shared_style);
|
||||
damage
|
||||
};
|
||||
|
||||
*style = Some(shared_style);
|
||||
return StyleSharingResult::StyleWasShared(i, damage)
|
||||
}
|
||||
|
@ -675,8 +689,14 @@ pub trait MatchMethods : TNode {
|
|||
let mut data_ref = self.mutate_data().unwrap();
|
||||
let mut data = &mut *data_ref;
|
||||
let cloned_parent_style = ComputedValues::style_for_child_text_node(parent_style.unwrap());
|
||||
damage = Self::ConcreteRestyleDamage::compute(data.style.as_ref(),
|
||||
&*cloned_parent_style);
|
||||
|
||||
{
|
||||
let existing_style =
|
||||
self.existing_style_for_restyle_damage(data.style.as_ref());
|
||||
damage = Self::ConcreteRestyleDamage::compute(existing_style,
|
||||
&cloned_parent_style);
|
||||
}
|
||||
|
||||
data.style = Some(cloned_parent_style);
|
||||
} else {
|
||||
damage = {
|
||||
|
@ -697,7 +717,6 @@ pub trait MatchMethods : TNode {
|
|||
let applicable_declarations_for_this_pseudo =
|
||||
applicable_declarations.per_pseudo.get(&pseudo).unwrap();
|
||||
|
||||
|
||||
if !applicable_declarations_for_this_pseudo.is_empty() {
|
||||
// NB: Transitions and animations should only work for
|
||||
// pseudo-elements ::before and ::after
|
||||
|
|
|
@ -28,7 +28,7 @@ bitflags! {
|
|||
// of a good reason for that.
|
||||
const RESTYLE_DESCENDANTS = 0x02,
|
||||
#[doc = "Rerun selector matching on all later siblings of the element and all of their descendants."]
|
||||
const RESTYLE_LATER_SIBLINGS = 0x04,
|
||||
const RESTYLE_LATER_SIBLINGS = 0x08,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ pub fn traverse_dom<N, C>(root: N,
|
|||
|
||||
for kid in node.children() {
|
||||
context.pre_process_child_hook(node, kid);
|
||||
if context.should_process(node) {
|
||||
if context.should_process(kid) {
|
||||
doit::<N, C>(context, kid);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ use selector_impl::SelectorImplExt;
|
|||
use selectors::Element;
|
||||
use selectors::bloom::BloomFilter;
|
||||
use std::cell::RefCell;
|
||||
use std::sync::Arc;
|
||||
use tid::tid;
|
||||
use util::opts;
|
||||
use values::HasViewportPercentage;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue