mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Cache font style struct addresses in a separate font group cache.
On http://en.wikipedia.org/wiki/Spotted_hyena, I was seeing a 100% miss rate in the first fast cache lookup and 45% of total layout time in this function. After making this change, the first cache lookup almost always succeeds, and the time spent in this function drops to 8%.
This commit is contained in:
parent
d6708a2fea
commit
b31a3b3883
1 changed files with 8 additions and 10 deletions
|
@ -82,6 +82,8 @@ pub struct FontContext {
|
||||||
/// per frame. TODO: Make this weak when incremental redraw is done.
|
/// per frame. TODO: Make this weak when incremental redraw is done.
|
||||||
paint_font_cache: Vec<PaintFontCacheEntry>,
|
paint_font_cache: Vec<PaintFontCacheEntry>,
|
||||||
|
|
||||||
|
layout_font_group_address_cache: HashMap<usize, Rc<FontGroup>, DefaultState<FnvHasher>>,
|
||||||
|
|
||||||
layout_font_group_cache:
|
layout_font_group_cache:
|
||||||
HashMap<LayoutFontGroupCacheKey, Rc<FontGroup>, DefaultState<FnvHasher>>,
|
HashMap<LayoutFontGroupCacheKey, Rc<FontGroup>, DefaultState<FnvHasher>>,
|
||||||
|
|
||||||
|
@ -97,6 +99,7 @@ impl FontContext {
|
||||||
layout_font_cache: vec!(),
|
layout_font_cache: vec!(),
|
||||||
fallback_font_cache: vec!(),
|
fallback_font_cache: vec!(),
|
||||||
paint_font_cache: vec!(),
|
paint_font_cache: vec!(),
|
||||||
|
layout_font_group_address_cache: HashMap::with_hash_state(Default::default()),
|
||||||
layout_font_group_cache: HashMap::with_hash_state(Default::default()),
|
layout_font_group_cache: HashMap::with_hash_state(Default::default()),
|
||||||
epoch: 0,
|
epoch: 0,
|
||||||
}
|
}
|
||||||
|
@ -144,6 +147,7 @@ impl FontContext {
|
||||||
self.layout_font_cache.clear();
|
self.layout_font_cache.clear();
|
||||||
self.fallback_font_cache.clear();
|
self.fallback_font_cache.clear();
|
||||||
self.paint_font_cache.clear();
|
self.paint_font_cache.clear();
|
||||||
|
self.layout_font_group_address_cache.clear();
|
||||||
self.layout_font_group_cache.clear();
|
self.layout_font_group_cache.clear();
|
||||||
self.epoch = current_epoch
|
self.epoch = current_epoch
|
||||||
}
|
}
|
||||||
|
@ -152,21 +156,21 @@ impl FontContext {
|
||||||
/// a cached font if this font instance has already been used by
|
/// a cached font if this font instance has already been used by
|
||||||
/// this context.
|
/// this context.
|
||||||
pub fn layout_font_group_for_style(&mut self, style: Arc<SpecifiedFontStyle>)
|
pub fn layout_font_group_for_style(&mut self, style: Arc<SpecifiedFontStyle>)
|
||||||
-> Rc<FontGroup> {
|
-> Rc<FontGroup> {
|
||||||
self.expire_font_caches_if_necessary();
|
self.expire_font_caches_if_necessary();
|
||||||
|
|
||||||
let address = &*style as *const SpecifiedFontStyle as usize;
|
let address = &*style as *const SpecifiedFontStyle as usize;
|
||||||
if let Some(ref cached_font_group) = self.layout_font_group_cache.get(&address) {
|
if let Some(ref cached_font_group) = self.layout_font_group_address_cache.get(&address) {
|
||||||
return (*cached_font_group).clone()
|
return (*cached_font_group).clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
let layout_font_group_cache_key = LayoutFontGroupCacheKey {
|
let layout_font_group_cache_key = LayoutFontGroupCacheKey {
|
||||||
pointer: style.clone(),
|
pointer: style.clone(),
|
||||||
size: style.font_size,
|
size: style.font_size,
|
||||||
address: address,
|
|
||||||
};
|
};
|
||||||
if let Some(ref cached_font_group) = self.layout_font_group_cache.get(
|
if let Some(ref cached_font_group) = self.layout_font_group_cache.get(
|
||||||
&layout_font_group_cache_key) {
|
&layout_font_group_cache_key) {
|
||||||
|
self.layout_font_group_address_cache.insert(address, (*cached_font_group).clone());
|
||||||
return (*cached_font_group).clone()
|
return (*cached_font_group).clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,6 +279,7 @@ impl FontContext {
|
||||||
|
|
||||||
let font_group = Rc::new(FontGroup::new(fonts));
|
let font_group = Rc::new(FontGroup::new(fonts));
|
||||||
self.layout_font_group_cache.insert(layout_font_group_cache_key, font_group.clone());
|
self.layout_font_group_cache.insert(layout_font_group_cache_key, font_group.clone());
|
||||||
|
self.layout_font_group_address_cache.insert(address, font_group.clone());
|
||||||
font_group
|
font_group
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,7 +321,6 @@ impl HeapSizeOf for FontContext {
|
||||||
struct LayoutFontGroupCacheKey {
|
struct LayoutFontGroupCacheKey {
|
||||||
pointer: Arc<SpecifiedFontStyle>,
|
pointer: Arc<SpecifiedFontStyle>,
|
||||||
size: Au,
|
size: Au,
|
||||||
address: usize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for LayoutFontGroupCacheKey {
|
impl PartialEq for LayoutFontGroupCacheKey {
|
||||||
|
@ -333,12 +337,6 @@ impl Hash for LayoutFontGroupCacheKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl borrow::Borrow<usize> for LayoutFontGroupCacheKey {
|
|
||||||
fn borrow(&self) -> &usize {
|
|
||||||
&self.address
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn invalidate_font_caches() {
|
pub fn invalidate_font_caches() {
|
||||||
FONT_CACHE_EPOCH.fetch_add(1, Ordering::SeqCst);
|
FONT_CACHE_EPOCH.fetch_add(1, Ordering::SeqCst);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue