diff --git a/components/gfx/font.rs b/components/gfx/font.rs index 2ed72e55203..596933727b2 100644 --- a/components/gfx/font.rs +++ b/components/gfx/font.rs @@ -14,14 +14,18 @@ use std::cell::RefCell; use std::rc::Rc; use std::str; use std::sync::Arc; +use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering}; use style::computed_values::{font_stretch, font_variant, font_weight}; use style::properties::style_structs::Font as FontStyle; use text::Shaper; use text::glyph::{GlyphId, GlyphStore}; use text::shaping::ShaperMethods; +use time; use unicode_script::Script; use util::cache::HashCache; +static TEXT_SHAPING_PERFORMANCE_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT; + // FontHandle encapsulates access to the platform's font API, // e.g. quartz, FreeType. It provides access to metrics and tables // needed by the text shaper as well as access to the underlying font @@ -145,6 +149,8 @@ impl Font { return glyphs.clone(); } + let start_time = time::precise_time_ns(); + let mut glyphs = GlyphStore::new(text.chars().count(), options.flags.contains(IS_WHITESPACE_SHAPING_FLAG), options.flags.contains(RTL_FLAG)); @@ -155,6 +161,11 @@ impl Font { text: text.to_owned(), options: *options, }, glyphs.clone()); + + let end_time = time::precise_time_ns(); + TEXT_SHAPING_PERFORMANCE_COUNTER.fetch_add((end_time - start_time) as usize, + Ordering::Relaxed); + glyphs } @@ -245,3 +256,10 @@ impl RunMetrics { } } } + +pub fn get_and_reset_text_shaping_performance_counter() -> usize { + let value = TEXT_SHAPING_PERFORMANCE_COUNTER.load(Ordering::SeqCst); + TEXT_SHAPING_PERFORMANCE_COUNTER.store(0, Ordering::SeqCst); + value +} + diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 35a78594034..e61c7a0f385 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -24,6 +24,7 @@ use flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUti use flow_ref::{self, FlowRef}; use fnv::FnvHasher; use gfx::display_list::{ClippingRegion, DisplayList, LayerInfo, OpaqueNode, StackingContext}; +use gfx::font; use gfx::font_cache_task::FontCacheTask; use gfx::font_context; use gfx::paint_task::{LayoutToPaintMsg, PaintLayer}; @@ -1027,6 +1028,18 @@ impl LayoutTask { } }); + // TODO(pcwalton): Measure energy usage of text shaping, perhaps? + let text_shaping_time = + (font::get_and_reset_text_shaping_performance_counter() as u64) / + (opts::get().layout_threads as u64); + time::send_profile_data(time::ProfilerCategory::LayoutTextShaping, + self.profiler_metadata(), + self.time_profiler_chan.clone(), + 0, + text_shaping_time, + 0, + 0); + // Retrieve the (possibly rebuilt) root flow. self.root_flow = self.try_get_layout_root(node); } diff --git a/components/profile/heartbeats.rs b/components/profile/heartbeats.rs index c87e9f542a8..bd143d1fdb5 100644 --- a/components/profile/heartbeats.rs +++ b/components/profile/heartbeats.rs @@ -23,6 +23,7 @@ pub fn init() { maybe_create_heartbeat(&mut hbs, ProfilerCategory::Compositing); maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutPerform); maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutStyleRecalc); + maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutTextShaping); maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutRestyleDamagePropagation); maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutNonIncrementalReset); maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutSelectorMatch); @@ -31,7 +32,6 @@ pub fn init() { maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutGeneratedContent); maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutMain); maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutParallelWarmup); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutShaping); maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutDispListBuild); maybe_create_heartbeat(&mut hbs, ProfilerCategory::PaintingPerTile); maybe_create_heartbeat(&mut hbs, ProfilerCategory::PaintingPrepBuff); diff --git a/components/profile/time.rs b/components/profile/time.rs index 71dfc29a519..d4495c48bd4 100644 --- a/components/profile/time.rs +++ b/components/profile/time.rs @@ -60,19 +60,20 @@ impl Formattable for ProfilerCategory { ProfilerCategory::LayoutGeneratedContent | ProfilerCategory::LayoutMain | ProfilerCategory::LayoutDispListBuild | - ProfilerCategory::LayoutShaping | ProfilerCategory::LayoutDamagePropagate | ProfilerCategory::PaintingPerTile | ProfilerCategory::PaintingPrepBuff => "+ ", ProfilerCategory::LayoutParallelWarmup | ProfilerCategory::LayoutSelectorMatch | - ProfilerCategory::LayoutTreeBuilder => "| + ", + ProfilerCategory::LayoutTreeBuilder | + ProfilerCategory::LayoutTextShaping => "| + ", _ => "" }; let name = match *self { ProfilerCategory::Compositing => "Compositing", ProfilerCategory::LayoutPerform => "Layout", ProfilerCategory::LayoutStyleRecalc => "Style Recalc", + ProfilerCategory::LayoutTextShaping => "Text Shaping", ProfilerCategory::LayoutRestyleDamagePropagation => "Restyle Damage Propagation", ProfilerCategory::LayoutNonIncrementalReset => "Non-incremental reset (temporary)", ProfilerCategory::LayoutSelectorMatch => "Selector Matching", @@ -81,7 +82,6 @@ impl Formattable for ProfilerCategory { ProfilerCategory::LayoutGeneratedContent => "Generated Content Resolution", ProfilerCategory::LayoutMain => "Primary Layout Pass", ProfilerCategory::LayoutParallelWarmup => "Parallel Warmup", - ProfilerCategory::LayoutShaping => "Shaping", ProfilerCategory::LayoutDispListBuild => "Display List Construction", ProfilerCategory::PaintingPerTile => "Painting Per Tile", ProfilerCategory::PaintingPrepBuff => "Buffer Prep", diff --git a/components/profile_traits/time.rs b/components/profile_traits/time.rs index c29bbe7993f..44b12ccb63f 100644 --- a/components/profile_traits/time.rs +++ b/components/profile_traits/time.rs @@ -41,6 +41,7 @@ pub enum ProfilerCategory { Compositing, LayoutPerform, LayoutStyleRecalc, + LayoutTextShaping, LayoutRestyleDamagePropagation, LayoutNonIncrementalReset, LayoutSelectorMatch, @@ -49,7 +50,6 @@ pub enum ProfilerCategory { LayoutGeneratedContent, LayoutMain, LayoutParallelWarmup, - LayoutShaping, LayoutDispListBuild, PaintingPerTile, PaintingPrepBuff, @@ -99,8 +99,25 @@ pub fn profile(category: ProfilerCategory, let val = callback(); let end_time = precise_time_ns(); let end_energy = read_energy_uj(); + send_profile_data(category, + meta, + profiler_chan, + start_time, + end_time, + start_energy, + end_energy); + val +} + +pub fn send_profile_data(category: ProfilerCategory, + meta: Option, + profiler_chan: ProfilerChan, + start_time: u64, + end_time: u64, + start_energy: u64, + end_energy: u64) { profiler_chan.send(ProfilerMsg::Time((category, meta), (start_time, end_time), (start_energy, end_energy))); - val } +