зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #8995 - gfx: Measure text shaping time in the time profiler (from pcwalton:measure-text-shaping); r=mbrubeck
r? @mbrubeck Source-Repo: https://github.com/servo/servo Source-Revision: 338f66003e78250ce141584e87190661249c5589
This commit is contained in:
Родитель
e2cd3f51e6
Коммит
9964a8693a
|
@ -14,14 +14,18 @@ use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::sync::Arc;
|
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::computed_values::{font_stretch, font_variant, font_weight};
|
||||||
use style::properties::style_structs::Font as FontStyle;
|
use style::properties::style_structs::Font as FontStyle;
|
||||||
use text::Shaper;
|
use text::Shaper;
|
||||||
use text::glyph::{GlyphId, GlyphStore};
|
use text::glyph::{GlyphId, GlyphStore};
|
||||||
use text::shaping::ShaperMethods;
|
use text::shaping::ShaperMethods;
|
||||||
|
use time;
|
||||||
use unicode_script::Script;
|
use unicode_script::Script;
|
||||||
use util::cache::HashCache;
|
use util::cache::HashCache;
|
||||||
|
|
||||||
|
static TEXT_SHAPING_PERFORMANCE_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;
|
||||||
|
|
||||||
// FontHandle encapsulates access to the platform's font API,
|
// FontHandle encapsulates access to the platform's font API,
|
||||||
// e.g. quartz, FreeType. It provides access to metrics and tables
|
// e.g. quartz, FreeType. It provides access to metrics and tables
|
||||||
// needed by the text shaper as well as access to the underlying font
|
// needed by the text shaper as well as access to the underlying font
|
||||||
|
@ -145,6 +149,8 @@ impl Font {
|
||||||
return glyphs.clone();
|
return glyphs.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let start_time = time::precise_time_ns();
|
||||||
|
|
||||||
let mut glyphs = GlyphStore::new(text.chars().count(),
|
let mut glyphs = GlyphStore::new(text.chars().count(),
|
||||||
options.flags.contains(IS_WHITESPACE_SHAPING_FLAG),
|
options.flags.contains(IS_WHITESPACE_SHAPING_FLAG),
|
||||||
options.flags.contains(RTL_FLAG));
|
options.flags.contains(RTL_FLAG));
|
||||||
|
@ -155,6 +161,11 @@ impl Font {
|
||||||
text: text.to_owned(),
|
text: text.to_owned(),
|
||||||
options: *options,
|
options: *options,
|
||||||
}, glyphs.clone());
|
}, glyphs.clone());
|
||||||
|
|
||||||
|
let end_time = time::precise_time_ns();
|
||||||
|
TEXT_SHAPING_PERFORMANCE_COUNTER.fetch_add((end_time - start_time) as usize,
|
||||||
|
Ordering::Relaxed);
|
||||||
|
|
||||||
glyphs
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ use flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUti
|
||||||
use flow_ref::{self, FlowRef};
|
use flow_ref::{self, FlowRef};
|
||||||
use fnv::FnvHasher;
|
use fnv::FnvHasher;
|
||||||
use gfx::display_list::{ClippingRegion, DisplayList, LayerInfo, OpaqueNode, StackingContext};
|
use gfx::display_list::{ClippingRegion, DisplayList, LayerInfo, OpaqueNode, StackingContext};
|
||||||
|
use gfx::font;
|
||||||
use gfx::font_cache_task::FontCacheTask;
|
use gfx::font_cache_task::FontCacheTask;
|
||||||
use gfx::font_context;
|
use gfx::font_context;
|
||||||
use gfx::paint_task::{LayoutToPaintMsg, PaintLayer};
|
use gfx::paint_task::{LayoutToPaintMsg, PaintLayer};
|
||||||
|
@ -1034,6 +1035,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.
|
// Retrieve the (possibly rebuilt) root flow.
|
||||||
self.root_flow = self.try_get_layout_root(node);
|
self.root_flow = self.try_get_layout_root(node);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ pub fn init() {
|
||||||
maybe_create_heartbeat(&mut hbs, ProfilerCategory::Compositing);
|
maybe_create_heartbeat(&mut hbs, ProfilerCategory::Compositing);
|
||||||
maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutPerform);
|
maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutPerform);
|
||||||
maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutStyleRecalc);
|
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::LayoutRestyleDamagePropagation);
|
||||||
maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutNonIncrementalReset);
|
maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutNonIncrementalReset);
|
||||||
maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutSelectorMatch);
|
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::LayoutGeneratedContent);
|
||||||
maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutMain);
|
maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutMain);
|
||||||
maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutParallelWarmup);
|
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::LayoutDispListBuild);
|
||||||
maybe_create_heartbeat(&mut hbs, ProfilerCategory::PaintingPerTile);
|
maybe_create_heartbeat(&mut hbs, ProfilerCategory::PaintingPerTile);
|
||||||
maybe_create_heartbeat(&mut hbs, ProfilerCategory::PaintingPrepBuff);
|
maybe_create_heartbeat(&mut hbs, ProfilerCategory::PaintingPrepBuff);
|
||||||
|
|
|
@ -60,19 +60,20 @@ impl Formattable for ProfilerCategory {
|
||||||
ProfilerCategory::LayoutGeneratedContent |
|
ProfilerCategory::LayoutGeneratedContent |
|
||||||
ProfilerCategory::LayoutMain |
|
ProfilerCategory::LayoutMain |
|
||||||
ProfilerCategory::LayoutDispListBuild |
|
ProfilerCategory::LayoutDispListBuild |
|
||||||
ProfilerCategory::LayoutShaping |
|
|
||||||
ProfilerCategory::LayoutDamagePropagate |
|
ProfilerCategory::LayoutDamagePropagate |
|
||||||
ProfilerCategory::PaintingPerTile |
|
ProfilerCategory::PaintingPerTile |
|
||||||
ProfilerCategory::PaintingPrepBuff => "+ ",
|
ProfilerCategory::PaintingPrepBuff => "+ ",
|
||||||
ProfilerCategory::LayoutParallelWarmup |
|
ProfilerCategory::LayoutParallelWarmup |
|
||||||
ProfilerCategory::LayoutSelectorMatch |
|
ProfilerCategory::LayoutSelectorMatch |
|
||||||
ProfilerCategory::LayoutTreeBuilder => "| + ",
|
ProfilerCategory::LayoutTreeBuilder |
|
||||||
|
ProfilerCategory::LayoutTextShaping => "| + ",
|
||||||
_ => ""
|
_ => ""
|
||||||
};
|
};
|
||||||
let name = match *self {
|
let name = match *self {
|
||||||
ProfilerCategory::Compositing => "Compositing",
|
ProfilerCategory::Compositing => "Compositing",
|
||||||
ProfilerCategory::LayoutPerform => "Layout",
|
ProfilerCategory::LayoutPerform => "Layout",
|
||||||
ProfilerCategory::LayoutStyleRecalc => "Style Recalc",
|
ProfilerCategory::LayoutStyleRecalc => "Style Recalc",
|
||||||
|
ProfilerCategory::LayoutTextShaping => "Text Shaping",
|
||||||
ProfilerCategory::LayoutRestyleDamagePropagation => "Restyle Damage Propagation",
|
ProfilerCategory::LayoutRestyleDamagePropagation => "Restyle Damage Propagation",
|
||||||
ProfilerCategory::LayoutNonIncrementalReset => "Non-incremental reset (temporary)",
|
ProfilerCategory::LayoutNonIncrementalReset => "Non-incremental reset (temporary)",
|
||||||
ProfilerCategory::LayoutSelectorMatch => "Selector Matching",
|
ProfilerCategory::LayoutSelectorMatch => "Selector Matching",
|
||||||
|
@ -81,7 +82,6 @@ impl Formattable for ProfilerCategory {
|
||||||
ProfilerCategory::LayoutGeneratedContent => "Generated Content Resolution",
|
ProfilerCategory::LayoutGeneratedContent => "Generated Content Resolution",
|
||||||
ProfilerCategory::LayoutMain => "Primary Layout Pass",
|
ProfilerCategory::LayoutMain => "Primary Layout Pass",
|
||||||
ProfilerCategory::LayoutParallelWarmup => "Parallel Warmup",
|
ProfilerCategory::LayoutParallelWarmup => "Parallel Warmup",
|
||||||
ProfilerCategory::LayoutShaping => "Shaping",
|
|
||||||
ProfilerCategory::LayoutDispListBuild => "Display List Construction",
|
ProfilerCategory::LayoutDispListBuild => "Display List Construction",
|
||||||
ProfilerCategory::PaintingPerTile => "Painting Per Tile",
|
ProfilerCategory::PaintingPerTile => "Painting Per Tile",
|
||||||
ProfilerCategory::PaintingPrepBuff => "Buffer Prep",
|
ProfilerCategory::PaintingPrepBuff => "Buffer Prep",
|
||||||
|
|
|
@ -41,6 +41,7 @@ pub enum ProfilerCategory {
|
||||||
Compositing,
|
Compositing,
|
||||||
LayoutPerform,
|
LayoutPerform,
|
||||||
LayoutStyleRecalc,
|
LayoutStyleRecalc,
|
||||||
|
LayoutTextShaping,
|
||||||
LayoutRestyleDamagePropagation,
|
LayoutRestyleDamagePropagation,
|
||||||
LayoutNonIncrementalReset,
|
LayoutNonIncrementalReset,
|
||||||
LayoutSelectorMatch,
|
LayoutSelectorMatch,
|
||||||
|
@ -49,7 +50,6 @@ pub enum ProfilerCategory {
|
||||||
LayoutGeneratedContent,
|
LayoutGeneratedContent,
|
||||||
LayoutMain,
|
LayoutMain,
|
||||||
LayoutParallelWarmup,
|
LayoutParallelWarmup,
|
||||||
LayoutShaping,
|
|
||||||
LayoutDispListBuild,
|
LayoutDispListBuild,
|
||||||
PaintingPerTile,
|
PaintingPerTile,
|
||||||
PaintingPrepBuff,
|
PaintingPrepBuff,
|
||||||
|
@ -99,8 +99,25 @@ pub fn profile<T, F>(category: ProfilerCategory,
|
||||||
let val = callback();
|
let val = callback();
|
||||||
let end_time = precise_time_ns();
|
let end_time = precise_time_ns();
|
||||||
let end_energy = read_energy_uj();
|
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<TimerMetadata>,
|
||||||
|
profiler_chan: ProfilerChan,
|
||||||
|
start_time: u64,
|
||||||
|
end_time: u64,
|
||||||
|
start_energy: u64,
|
||||||
|
end_energy: u64) {
|
||||||
profiler_chan.send(ProfilerMsg::Time((category, meta),
|
profiler_chan.send(ProfilerMsg::Time((category, meta),
|
||||||
(start_time, end_time),
|
(start_time, end_time),
|
||||||
(start_energy, end_energy)));
|
(start_energy, end_energy)));
|
||||||
val
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче