style: Expose the traversal kind to the style system.

This way we'll be able to take different paths for the sequential and parallel
traversals in some concrete cases.

This is a preliminar patch to fix bug 1332525.
This commit is contained in:
Emilio Cobos Álvarez 2017-01-23 19:55:06 +01:00
parent 7e2329ea4e
commit f00b628c3a
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
7 changed files with 64 additions and 13 deletions

View file

@ -9,19 +9,21 @@ use context::{SharedStyleContext, StyleContext, ThreadLocalStyleContext};
use data::ElementData;
use dom::{NodeInfo, TNode};
use gecko::wrapper::{GeckoElement, GeckoNode};
use traversal::{DomTraversal, PerLevelTraversalData, recalc_style_at};
use traversal::{DomTraversal, PerLevelTraversalData, TraversalDriver, recalc_style_at};
/// This is the simple struct that Gecko uses to encapsulate a DOM traversal for
/// styling.
pub struct RecalcStyleOnly {
shared: SharedStyleContext,
driver: TraversalDriver,
}
impl RecalcStyleOnly {
/// Create a `RecalcStyleOnly` traversal from a `SharedStyleContext`.
pub fn new(shared: SharedStyleContext) -> Self {
pub fn new(shared: SharedStyleContext, driver: TraversalDriver) -> Self {
RecalcStyleOnly {
shared: shared,
driver: driver,
}
}
}
@ -66,4 +68,8 @@ impl<'le> DomTraversal<GeckoElement<'le>> for RecalcStyleOnly {
fn create_thread_local_context(&self) -> Self::ThreadLocalContext {
ThreadLocalStyleContext::new(&self.shared)
}
fn is_parallel(&self) -> bool {
self.driver.is_parallel()
}
}

View file

@ -45,6 +45,7 @@ pub fn traverse_dom<E, D>(traversal: &D,
where E: TElement,
D: DomTraversal<E>,
{
debug_assert!(traversal.is_parallel());
// Handle Gecko's eager initial styling. We don't currently support it
// in conjunction with bottom-up traversal. If we did, we'd need to put
// it on the context to make it available to the bottom-up phase.

View file

@ -18,6 +18,7 @@ pub fn traverse_dom<E, D>(traversal: &D,
where E: TElement,
D: DomTraversal<E>,
{
debug_assert!(!traversal.is_parallel());
debug_assert!(token.should_traverse());
fn doit<E, D>(traversal: &D, traversal_data: &mut PerLevelTraversalData,

View file

@ -62,6 +62,23 @@ impl LogBehavior {
fn allow(&self) -> bool { matches!(*self, MayLog) }
}
/// The kind of traversals we could perform.
#[derive(Debug, Copy, Clone)]
pub enum TraversalDriver {
/// A potentially parallel traversal.
Parallel,
/// A sequential traversal.
Sequential,
}
impl TraversalDriver {
/// Returns whether this represents a parallel traversal or not.
#[inline]
pub fn is_parallel(&self) -> bool {
matches!(*self, TraversalDriver::Parallel)
}
}
/// A DOM Traversal trait, that is used to generically implement styling for
/// Gecko and Servo.
pub trait DomTraversal<E: TElement> : Sync {
@ -284,6 +301,14 @@ pub trait DomTraversal<E: TElement> : Sync {
/// Creates a thread-local context.
fn create_thread_local_context(&self) -> Self::ThreadLocalContext;
/// Whether we're performing a parallel traversal.
///
/// NB: We do this check on runtime. We could guarantee correctness in this
/// regard via the type system via a `TraversalDriver` trait for this trait,
/// that could be one of two concrete types. It's not clear whether the
/// potential code size impact of that is worth it.
fn is_parallel(&self) -> bool;
}
/// Helper for the function below.