From 923676d443be04bafcc0ce95bcd29243f20a16e3 Mon Sep 17 00:00:00 2001 From: Jack Moffitt Date: Wed, 18 Feb 2015 20:19:12 -0700 Subject: [PATCH 1/2] Added overlay for demoing parallel painting. --- components/gfx/paint_task.rs | 32 ++++++++++++++++++++++++++------ components/util/opts.rs | 6 ++++++ ports/cef/core.rs | 1 + 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/components/gfx/paint_task.rs b/components/gfx/paint_task.rs index 807e3aeb2d8..1f5c439a0d2 100644 --- a/components/gfx/paint_task.rs +++ b/components/gfx/paint_task.rs @@ -355,7 +355,8 @@ impl PaintTask where C: PaintListener + Send { for (i, tile) in tiles.into_iter().enumerate() { let thread_id = i % self.worker_threads.len(); let layer_buffer = self.find_or_create_layer_buffer_for_tile(&tile, scale); - self.worker_threads[thread_id].paint_tile(tile, + self.worker_threads[thread_id].paint_tile(thread_id, + tile, layer_buffer, stacking_context.clone(), scale); @@ -447,11 +448,12 @@ impl WorkerThreadProxy { } fn paint_tile(&mut self, + thread_id: usize, tile: BufferRequest, layer_buffer: Option>, stacking_context: Arc, scale: f32) { - self.sender.send(MsgToWorkerThread::PaintTile(tile, layer_buffer, stacking_context, scale)).unwrap() + self.sender.send(MsgToWorkerThread::PaintTile(thread_id, tile, layer_buffer, stacking_context, scale)).unwrap() } fn get_painted_tile_buffer(&mut self) -> Box { @@ -495,8 +497,8 @@ impl WorkerThread { loop { match self.receiver.recv().unwrap() { MsgToWorkerThread::Exit => break, - MsgToWorkerThread::PaintTile(tile, layer_buffer, stacking_context, scale) => { - let draw_target = self.optimize_and_paint_tile(&tile, stacking_context, scale); + MsgToWorkerThread::PaintTile(thread_id, tile, layer_buffer, stacking_context, scale) => { + let draw_target = self.optimize_and_paint_tile(thread_id, &tile, stacking_context, scale); let buffer = self.create_layer_buffer_for_painted_tile(&tile, layer_buffer, draw_target, @@ -508,6 +510,7 @@ impl WorkerThread { } fn optimize_and_paint_tile(&mut self, + thread_id: usize, tile: &BufferRequest, stacking_context: Arc, scale: f32) @@ -563,7 +566,24 @@ impl WorkerThread { &matrix, None); paint_context.draw_target.flush(); - }); + }); + + if opts::get().show_debug_parallel_paint { + // Overlay a transparent solid color to identify the thread that + // painted this tile. + let colors = [Color { r: 6.0/255.0, g: 153.0/255.0, b: 198.0/255.0, a: 0.7 }, + Color { r: 255.0/255.0, g: 212.0/255.0, b: 83.0/255.0, a: 0.7 }, + Color { r: 116.0/255.0, g: 29.0/255.0, b: 109.0/255.0, a: 0.7 }, + Color { r: 204.0/255.0, g: 158.0/255.0, b: 199.0/255.0, a: 0.7 }, + Color { r: 242.0/255.0, g: 46.0/255.0, b: 121.0/255.0, a: 0.7 }, + Color { r: 116.0/255.0, g: 203.0/255.0, b: 196.0/255.0, a: 0.7 }, + Color { r: 255.0/255.0, g: 249.0/255.0, b: 201.0/255.0, a: 0.7 }, + Color { r: 137.0/255.0, g: 196.0/255.0, b: 78.0/255.0, a: 0.7 }]; + paint_context.draw_solid_color(&Rect(Point2D(Au(0), Au(0)), + Size2D(Au::from_px(size.width as isize), + Au::from_px(size.height as isize))), + colors[thread_id % colors.len()]); + } } draw_target @@ -613,7 +633,7 @@ impl WorkerThread { enum MsgToWorkerThread { Exit, - PaintTile(BufferRequest, Option>, Arc, f32), + PaintTile(usize, BufferRequest, Option>, Arc, f32), } enum MsgFromWorkerThread { diff --git a/components/util/opts.rs b/components/util/opts.rs index aeee40ac249..b420207bbbe 100644 --- a/components/util/opts.rs +++ b/components/util/opts.rs @@ -75,6 +75,9 @@ pub struct Opts { /// True if we should show borders on all fragments for debugging purposes (`--show-debug-fragment-borders`). pub show_debug_fragment_borders: bool, + /// True if we should paint tiles with overlays based on which thread painted them. + pub show_debug_parallel_paint: bool, + /// If set with --disable-text-aa, disable antialiasing on fonts. This is primarily useful for reftests /// where pixel perfect results are required when using fonts such as the Ahem /// font for layout tests. @@ -128,6 +131,7 @@ pub fn print_debug_usage(app: &str) { print_option("profile-tasks", "Instrument each task, writing the output to a file."); print_option("show-compositor-borders", "Paint borders along layer and tile boundaries."); print_option("show-fragment-borders", "Paint borders along fragment boundaries."); + print_option("show-parallel-paint", "Overlay tiles with colors showing which thread painted them."); print_option("trace-layout", "Write layout trace to an external file for debugging."); print_option("validate-display-list-geometry", "Display an error when display list geometry escapes overflow region."); @@ -166,6 +170,7 @@ pub fn default_opts() -> Opts { bubble_inline_sizes_separately: false, show_debug_borders: false, show_debug_fragment_borders: false, + show_debug_parallel_paint: false, enable_text_antialiasing: false, trace_layout: false, devtools_port: None, @@ -315,6 +320,7 @@ pub fn from_cmdline_args(args: &[String]) -> bool { user_agent: opt_match.opt_str("u"), show_debug_borders: debug_options.contains(&"show-compositor-borders"), show_debug_fragment_borders: debug_options.contains(&"show-fragment-borders"), + show_debug_parallel_paint: debug_options.contains(&"show-parallel-paint"), enable_text_antialiasing: !debug_options.contains(&"disable-text-aa"), dump_flow_tree: debug_options.contains(&"dump-flow-tree"), validate_display_list_geometry: debug_options.contains(&"validate-display-list-geometry"), diff --git a/ports/cef/core.rs b/ports/cef/core.rs index a5c22fc6faf..3250922305e 100644 --- a/ports/cef/core.rs +++ b/ports/cef/core.rs @@ -86,6 +86,7 @@ pub extern "C" fn cef_initialize(args: *const cef_main_args_t, bubble_inline_sizes_separately: false, show_debug_borders: false, show_debug_fragment_borders: false, + show_debug_parallel_paint: false, enable_text_antialiasing: true, trace_layout: false, devtools_port: None, From 7acc0619e6d40cf6a425ceafbde21ff4461f0b5a Mon Sep 17 00:00:00 2001 From: Jack Moffitt Date: Thu, 19 Feb 2015 15:57:54 -0700 Subject: [PATCH 2/2] Correct usage of number of painting threads. Previously this used the number of layout threads to allocate the threadpool. This also makes the member name consistent with the rest of the structure. --- components/gfx/paint_task.rs | 2 +- components/util/opts.rs | 16 ++++++++-------- ports/cef/core.rs | 22 ++++++++++++---------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/components/gfx/paint_task.rs b/components/gfx/paint_task.rs index 1f5c439a0d2..bab531c3a0e 100644 --- a/components/gfx/paint_task.rs +++ b/components/gfx/paint_task.rs @@ -424,7 +424,7 @@ impl WorkerThreadProxy { let thread_count = if opts::get().gpu_painting { 1 } else { - opts::get().layout_threads + opts::get().paint_threads }; (0..thread_count).map(|_| { let (from_worker_sender, from_worker_receiver) = channel(); diff --git a/components/util/opts.rs b/components/util/opts.rs index b420207bbbe..d868d47dd92 100644 --- a/components/util/opts.rs +++ b/components/util/opts.rs @@ -27,8 +27,8 @@ pub struct Opts { /// How many threads to use for CPU painting (`-t`). /// - /// FIXME(pcwalton): This is not currently used. All painting is sequential. - pub n_paint_threads: uint, + /// Note that painting is sequentialized when using GPU painting. + pub paint_threads: uint, /// True to use GPU painting via Skia-GL, false to use CPU painting via Skia (`-g`). Note that /// compositing is always done on the GPU. @@ -155,7 +155,7 @@ static FORCE_CPU_PAINTING: bool = false; pub fn default_opts() -> Opts { Opts { urls: vec!(), - n_paint_threads: 1, + paint_threads: 1, gpu_painting: false, tile_size: 512, device_pixels_per_px: None, @@ -254,9 +254,9 @@ pub fn from_cmdline_args(args: &[String]) -> bool { ScaleFactor(dppx_str.parse().unwrap()) ); - let mut n_paint_threads: uint = match opt_match.opt_str("t") { - Some(n_paint_threads_str) => n_paint_threads_str.parse().unwrap(), - None => 1, // FIXME: Number of cores. + let mut paint_threads: uint = match opt_match.opt_str("t") { + Some(paint_threads_str) => paint_threads_str.parse().unwrap(), + None => cmp::max(rt::default_sched_threads() * 3 / 4, 1), }; // If only the flag is present, default to a 5 second period for both profilers. @@ -279,7 +279,7 @@ pub fn from_cmdline_args(args: &[String]) -> bool { let mut bubble_inline_sizes_separately = debug_options.contains(&"bubble-widths"); let trace_layout = debug_options.contains(&"trace-layout"); if trace_layout { - n_paint_threads = 1; + paint_threads = 1; layout_threads = 1; bubble_inline_sizes_separately = true; } @@ -300,7 +300,7 @@ pub fn from_cmdline_args(args: &[String]) -> bool { let opts = Opts { urls: urls, - n_paint_threads: n_paint_threads, + paint_threads: paint_threads, gpu_painting: gpu_painting, tile_size: tile_size, device_pixels_per_px: device_pixels_per_px, diff --git a/ports/cef/core.rs b/ports/cef/core.rs index 3250922305e..4db155b36b3 100644 --- a/ports/cef/core.rs +++ b/ports/cef/core.rs @@ -60,10 +60,20 @@ pub extern "C" fn cef_initialize(args: *const cef_main_args_t, } } + let rendering_threads = unsafe { + if ((*settings).rendering_threads as uint) < 1 { + 1 + } else if (*settings).rendering_threads as uint > MAX_RENDERING_THREADS { + MAX_RENDERING_THREADS + } else { + (*settings).rendering_threads as uint + } + }; + let urls = vec![HOME_URL.to_owned()]; opts::set_opts(opts::Opts { urls: urls, - n_paint_threads: 1, + paint_threads: rendering_threads, gpu_painting: false, tile_size: 512, device_pixels_per_px: None, @@ -71,15 +81,7 @@ pub extern "C" fn cef_initialize(args: *const cef_main_args_t, memory_profiler_period: None, enable_experimental: false, nonincremental_layout: false, - layout_threads: unsafe { - if ((*settings).rendering_threads as uint) < 1 { - 1 - } else if (*settings).rendering_threads as uint > MAX_RENDERING_THREADS { - MAX_RENDERING_THREADS - } else { - (*settings).rendering_threads as uint - } - }, + layout_threads: rendering_threads, output_file: None, headless: false, hard_fail: false,