layout: Implement parallel reflow for the bubble-widths and

assign-heights phases.

This uses the new work-stealing deque. By default, 3/4 of a thread per
logical CPU is used. This can be tuned with the `-y` flag.

I measured a 65% reflow speedup on `perf-rainbow.html` and a 247% reflow
speedup on `http://en.wikipedia.org/wiki/South_China_Sea` on a 4-core
HyperThreaded Core i7. However, numbers were fairly volatile, especially
for the latter.
This commit is contained in:
Patrick Walton 2014-01-14 14:57:40 -08:00
parent 539cf58f73
commit 54f0f17f83
21 changed files with 706 additions and 141 deletions

View file

@ -15,17 +15,17 @@
/// low-level drawing primitives.
use color::Color;
use servo_util::geometry::Au;
use style::computed_values::border_style;
use render_context::RenderContext;
use text::TextRun;
use std::cast::transmute_region;
use std::vec::VecIterator;
use extra::arc::Arc;
use geom::{Point2D, Rect, Size2D, SideOffsets2D};
use servo_net::image::base::Image;
use servo_util::geometry::Au;
use servo_util::range::Range;
use extra::arc::Arc;
use std::cast::transmute_region;
use std::vec::VecIterator;
use style::computed_values::border_style;
/// A list of rendering operations to be performed.
pub struct DisplayList<E> {

View file

@ -15,6 +15,7 @@ use std::cell::RefCell;
use servo_util::cache::{Cache, HashCache};
use servo_util::range::Range;
use style::computed_values::{text_decoration, font_weight, font_style};
use color::Color;
use font_context::FontContext;
use servo_util::geometry::Au;
@ -228,7 +229,6 @@ impl<'a> Font {
};
let metrics = handle.get_metrics();
// TODO(Issue #179): convert between specified and used font style here?
return Ok(Rc::from_mut(RefCell::new(Font {
handle: handle,

View file

@ -2,22 +2,32 @@
* 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/. */
use font::{Font, FontDescriptor, FontGroup, FontHandleMethods,
SelectorPlatformIdentifier};
use font::{Font, FontDescriptor, FontGroup, FontHandleMethods, SelectorPlatformIdentifier};
use font::{SpecifiedFontStyle, UsedFontStyle};
use font_list::FontList;
use servo_util::cache::{Cache, LRUCache};
use servo_util::time::ProfilerChan;
use platform::font::FontHandle;
use platform::font_context::FontContextHandle;
use azure::azure_hl::BackendType;
use servo_util::cache::{Cache, LRUCache};
use servo_util::time::ProfilerChan;
use std::hashmap::HashMap;
use std::rc::Rc;
use std::cell::RefCell;
/// Information needed to create a font context.
#[deriving(Clone)]
pub struct FontContextInfo {
/// The painting backend we're using.
backend: BackendType,
/// Whether we need a font list.
needs_font_list: bool,
/// A channel up to the profiler.
profiler_chan: ProfilerChan,
}
pub trait FontContextHandleMethods {
fn create_font_from_identifier(&self, ~str, UsedFontStyle) -> Result<FontHandle, ()>;
@ -34,14 +44,13 @@ pub struct FontContext {
}
impl FontContext {
pub fn new(backend: BackendType,
needs_font_list: bool,
profiler_chan: ProfilerChan)
-> FontContext {
pub fn new(info: FontContextInfo) -> FontContext {
let handle = FontContextHandle::new();
let font_list = if needs_font_list {
Some(FontList::new(&handle, profiler_chan.clone())) }
else { None };
let font_list = if info.needs_font_list {
Some(FontList::new(&handle, info.profiler_chan.clone()))
} else {
None
};
// TODO: Allow users to specify these.
let mut generic_fonts = HashMap::with_capacity(5);
@ -56,9 +65,9 @@ impl FontContext {
font_list: font_list,
group_cache: LRUCache::new(10),
handle: handle,
backend: backend,
backend: info.backend,
generic_fonts: generic_fonts,
profiler_chan: profiler_chan,
profiler_chan: info.profiler_chan.clone(),
}
}

View file

@ -7,11 +7,10 @@ use gfx_font::FontHandleMethods;
use platform::font::FontHandle;
use platform::font_context::FontContextHandle;
use platform::font_list::FontListHandle;
use servo_util::time;
use servo_util::time::profile;
use servo_util::time::ProfilerChan;
use style::computed_values::{font_weight, font_style};
use servo_util::time::{ProfilerChan, profile};
use servo_util::time;
use std::hashmap::HashMap;
pub type FontFamilyMap = HashMap<~str, FontFamily>;
@ -105,7 +104,7 @@ impl FontFamily {
}
pub fn find_font_for_style<'a>(&'a mut self, list: &FontListHandle, style: &SpecifiedFontStyle)
-> Option<&'a FontEntry> {
-> Option<&'a FontEntry> {
self.load_family_variations(list);
// TODO(Issue #189): optimize lookup for

View file

@ -8,6 +8,8 @@
use azure::azure_hl::{BackendType, CairoBackend, CoreGraphicsBackend};
use azure::azure_hl::{CoreGraphicsAcceleratedBackend, Direct2DBackend, SkiaBackend};
use extra::getopts::groups;
use std::num;
use std::rt;
/// Global flags for Servo, currently set on the command line.
#[deriving(Clone)]
@ -34,6 +36,10 @@ pub struct Opts {
/// it to produce output on that interval (`-p`).
profiler_period: Option<f64>,
/// The number of threads to use for layout (`-y`). Defaults to 1, which results in a recursive
/// sequential algorithm.
layout_threads: uint,
/// True to exit after the page load (`-x`).
exit_after_load: bool,
@ -59,6 +65,7 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
groups::optopt("t", "threads", "Number of render threads", "1"),
groups::optflagopt("p", "profile", "Profiler flag and output interval", "10"),
groups::optflag("x", "exit", "Exit after load flag"),
groups::optopt("y", "layout-threads", "Number of threads to use for layout", "1"),
groups::optflag("z", "headless", "Headless mode"),
groups::optflag("f", "hard-fail", "Exit on task failure instead of displaying about:failure"),
groups::optflag("h", "help", "Print this message")
@ -119,6 +126,11 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
let cpu_painting = opt_match.opt_present("c");
let layout_threads: uint = match opt_match.opt_str("y") {
Some(layout_threads_str) => from_str(layout_threads_str).unwrap(),
None => num::max(rt::default_sched_threads() * 3 / 4, 1),
};
Opts {
urls: urls,
render_backend: render_backend,
@ -126,6 +138,7 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
cpu_painting: cpu_painting,
tile_size: tile_size,
profiler_period: profiler_period,
layout_threads: layout_threads,
exit_after_load: opt_match.opt_present("x"),
output_file: opt_match.opt_str("o"),
headless: opt_match.opt_present("z"),

View file

@ -9,9 +9,8 @@ use platform::macos::font_context::FontContextHandle;
use core_foundation::base::TCFType;
use core_foundation::string::{CFString, CFStringRef};
use core_text;
use core_text::font_descriptor::{CTFontDescriptor, CTFontDescriptorRef};
use core_text;
use std::cast;
use std::hashmap::HashMap;
@ -44,7 +43,8 @@ impl FontListHandle {
pub fn load_variations_for_family(&self, family: &mut FontFamily) {
debug!("Looking for faces of family: {:s}", family.family_name);
let family_collection = core_text::font_collection::create_for_family(family.family_name);
let family_collection =
core_text::font_collection::create_for_family(family.family_name);
let family_descriptors = family_collection.get_descriptors();
for descref in family_descriptors.iter() {
let descref: CTFontDescriptorRef = unsafe { cast::transmute(descref) };

View file

@ -25,7 +25,7 @@ use extra::arc::Arc;
use buffer_map::BufferMap;
use display_list::DisplayList;
use font_context::FontContext;
use font_context::{FontContext, FontContextInfo};
use opts::Opts;
use render_context::RenderContext;
@ -159,9 +159,11 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
port: port,
compositor: compositor,
constellation_chan: constellation_chan,
font_ctx: ~FontContext::new(opts.render_backend.clone(),
false,
profiler_chan.clone()),
font_ctx: ~FontContext::new(FontContextInfo {
backend: opts.render_backend.clone(),
needs_font_list: false,
profiler_chan: profiler_chan.clone(),
}),
opts: opts,
profiler_chan: profiler_chan,

View file

@ -5,45 +5,45 @@
extern mod harfbuzz;
use font::{Font, FontHandleMethods, FontTableMethods, FontTableTag};
use servo_util::geometry::Au;
use platform::font::FontTable;
use text::glyph::{GlyphStore, GlyphIndex, GlyphData};
use text::shaping::ShaperMethods;
use servo_util::range::Range;
use text::util::{float_to_fixed, fixed_to_float};
use std::cast::transmute;
use std::char;
use std::libc::{c_uint, c_int, c_void, c_char};
use std::ptr;
use std::ptr::null;
use std::num;
use std::vec;
use geom::Point2D;
use harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR};
use harfbuzz::{hb_blob_create, hb_face_create_for_tables};
use harfbuzz::{hb_blob_t};
use harfbuzz::{hb_bool_t};
use harfbuzz::{hb_buffer_add_utf8};
use harfbuzz::{hb_buffer_destroy};
use harfbuzz::{hb_buffer_get_glyph_positions};
use harfbuzz::{hb_buffer_set_direction};
use harfbuzz::{hb_buffer_destroy};
use harfbuzz::{hb_face_destroy};
use harfbuzz::{hb_face_t, hb_font_t};
use harfbuzz::{hb_font_create};
use harfbuzz::{hb_font_destroy, hb_buffer_create};
use harfbuzz::{hb_font_funcs_create};
use harfbuzz::{hb_font_funcs_destroy};
use harfbuzz::{hb_font_funcs_set_glyph_func};
use harfbuzz::{hb_font_funcs_set_glyph_h_advance_func};
use harfbuzz::{hb_font_funcs_t, hb_buffer_t, hb_codepoint_t};
use harfbuzz::{hb_font_set_funcs};
use harfbuzz::{hb_font_set_ppem};
use harfbuzz::{hb_font_set_scale};
use harfbuzz::{hb_shape, hb_buffer_get_glyph_infos};
use harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR};
use harfbuzz::{hb_blob_t};
use harfbuzz::{hb_bool_t};
use harfbuzz::{hb_face_t, hb_font_t};
use harfbuzz::{hb_font_funcs_t, hb_buffer_t, hb_codepoint_t};
use harfbuzz::{hb_glyph_info_t};
use harfbuzz::{hb_glyph_position_t};
use harfbuzz::{hb_position_t, hb_tag_t};
use harfbuzz::{hb_shape, hb_buffer_get_glyph_infos};
use servo_util::geometry::Au;
use servo_util::range::Range;
use std::cast::transmute;
use std::char;
use std::libc::{c_uint, c_int, c_void, c_char};
use std::num;
use std::ptr::null;
use std::ptr;
use std::vec;
static NO_GLYPH: i32 = -1;
static CONTINUATION_BYTE: i32 = -2;

View file

@ -2,14 +2,13 @@
* 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/. */
use std::vec::VecIterator;
use servo_util::geometry::Au;
use text::glyph::GlyphStore;
use font::{Font, FontDescriptor, RunMetrics, FontStyle, FontMetrics};
use servo_util::range::Range;
use extra::arc::Arc;
use font::{Font, FontDescriptor, RunMetrics, FontStyle, FontMetrics};
use servo_util::geometry::Au;
use servo_util::range::Range;
use std::vec::VecIterator;
use style::computed_values::text_decoration;
use text::glyph::GlyphStore;
/// A text run.
#[deriving(Clone)]
@ -168,7 +167,7 @@ impl<'a> TextRun {
glyphs
}
pub fn char_len(&self) -> uint {
self.glyphs.get().iter().fold(0u, |len, slice_glyphs| {
len + slice_glyphs.get().char_len()