servo/components/style/gecko/traversal.rs
Bobby Holley 3f52052cf9 Do the sequential traversal breadth-first.
While we're at it, we also eliminate the 'unknown' dom depth for the
bloom filter. Computing depth has negligible cost relative to the
amount of work we do setting up the bloom filter at a given depth.
Doing it once per traversal should be totally fine.

I originally separated the elimination of unknown dom depth from the
traversal changes, but I got bloom filter crashes on the intermediate
patch, presumably because I didn't properly fix the sequential traversal
for this case. Given that the final state is green, I just decided to
squash and move on.
2017-04-09 14:52:49 +08:00

76 lines
2.5 KiB
Rust

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! Gecko-specific bits for the styling DOM traversal.
use atomic_refcell::AtomicRefCell;
use context::{SharedStyleContext, StyleContext, ThreadLocalStyleContext};
use data::ElementData;
use dom::{NodeInfo, TNode};
use gecko::wrapper::{GeckoElement, GeckoNode};
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<'a> {
shared: SharedStyleContext<'a>,
driver: TraversalDriver,
}
impl<'a> RecalcStyleOnly<'a> {
/// Create a `RecalcStyleOnly` traversal from a `SharedStyleContext`.
pub fn new(shared: SharedStyleContext<'a>, driver: TraversalDriver) -> Self {
RecalcStyleOnly {
shared: shared,
driver: driver,
}
}
}
impl<'recalc, 'le> DomTraversal<GeckoElement<'le>> for RecalcStyleOnly<'recalc> {
type ThreadLocalContext = ThreadLocalStyleContext<GeckoElement<'le>>;
fn process_preorder(&self,
traversal_data: &PerLevelTraversalData,
thread_local: &mut Self::ThreadLocalContext,
node: GeckoNode<'le>)
{
if node.is_element() {
let el = node.as_element().unwrap();
let mut data = unsafe { el.ensure_data() }.borrow_mut();
let mut context = StyleContext {
shared: &self.shared,
thread_local: thread_local,
};
recalc_style_at(self, traversal_data, &mut context, el, &mut data);
}
}
fn process_postorder(&self, _: &mut Self::ThreadLocalContext, _: GeckoNode<'le>) {
unreachable!();
}
/// We don't use the post-order traversal for anything.
fn needs_postorder_traversal() -> bool { false }
unsafe fn ensure_element_data<'a>(element: &'a GeckoElement<'le>) -> &'a AtomicRefCell<ElementData> {
element.ensure_data()
}
unsafe fn clear_element_data<'a>(element: &'a GeckoElement<'le>) {
element.clear_data()
}
fn shared_context(&self) -> &SharedStyleContext {
&self.shared
}
fn create_thread_local_context(&self) -> Self::ThreadLocalContext {
ThreadLocalStyleContext::new(&self.shared)
}
fn is_parallel(&self) -> bool {
self.driver.is_parallel()
}
}