From c07a2be6e76f777a266d988cdc8fd976b21ce8a3 Mon Sep 17 00:00:00 2001 From: Jack Moffitt Date: Mon, 17 Jun 2013 10:01:45 -0600 Subject: [PATCH 1/5] Propagate debug flag in Makefiles. --- Makefile.in | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.in b/Makefile.in index dad52716089..90adb878799 100644 --- a/Makefile.in +++ b/Makefile.in @@ -49,6 +49,7 @@ endif export CFG_RUSTC export CFG_RUSTC_FLAGS export CFG_LOCAL_RUSTC +export CFG_ENABLE_DEBUG export RUSTC=$(CFG_RUSTC) export RUSTFLAGS=$(CFG_RUSTC_FLAGS) From 1eea39a808df8a2cd37030b32fded7c3e900bd68 Mon Sep 17 00:00:00 2001 From: Jack Moffitt Date: Mon, 17 Jun 2013 10:02:29 -0600 Subject: [PATCH 2/5] Adding renderer drawing category to profiler. --- src/components/util/time.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/util/time.rs b/src/components/util/time.rs index 95bdc207e34..deaec504286 100644 --- a/src/components/util/time.rs +++ b/src/components/util/time.rs @@ -37,6 +37,7 @@ pub enum ProfilerCategory { LayoutShapingCategory, LayoutDispListBuildCategory, GfxRegenAvailableFontsCategory, + RenderingDrawingCategory, RenderingPrepBuffCategory, RenderingWaitSubtasksCategory, RenderingCategory, @@ -81,6 +82,7 @@ impl ProfilerCategory { vec.push((LayoutShapingCategory, ~[])); vec.push((LayoutDispListBuildCategory, ~[])); vec.push((GfxRegenAvailableFontsCategory, ~[])); + vec.push((RenderingDrawingCategory, ~[])); vec.push((RenderingPrepBuffCategory, ~[])); vec.push((RenderingWaitSubtasksCategory, ~[])); vec.push((RenderingCategory, ~[])); From ece8791c26134d359c6a9466cf45214445b8a01a Mon Sep 17 00:00:00 2001 From: Jack Moffitt Date: Mon, 17 Jun 2013 13:54:42 -0600 Subject: [PATCH 3/5] Warning police. --- src/components/gfx/display_list.rs | 1 - src/components/main/compositing/mod.rs | 9 +++------ src/components/main/layout/aux.rs | 12 ++++++------ .../main/platform/common/glut_windowing.rs | 5 +++-- src/components/script/script_task.rs | 2 +- src/support/azure/rust-azure | 2 +- src/support/netsurfcss/libcss | 2 +- src/support/skia/skia | 2 +- 8 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/components/gfx/display_list.rs b/src/components/gfx/display_list.rs index 8a7d5135242..508bd32a013 100644 --- a/src/components/gfx/display_list.rs +++ b/src/components/gfx/display_list.rs @@ -24,7 +24,6 @@ use geom::{Point2D, Rect, Size2D}; use servo_net::image::base::Image; use servo_util::range::Range; use std::arc::ARC; -use std::arc; /// A list of rendering operations to be performed. pub struct DisplayList { diff --git a/src/components/main/compositing/mod.rs b/src/components/main/compositing/mod.rs index ba32b706c41..7e6a83c373c 100644 --- a/src/components/main/compositing/mod.rs +++ b/src/components/main/compositing/mod.rs @@ -3,15 +3,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use platform::{Application, Window}; +use script::dom::event::{Event, ClickEvent, MouseDownEvent, MouseUpEvent, ResizeEvent}; use script::script_task::{LoadMsg, SendEventMsg}; +use script::layout_interface::{LayoutChan, RouteScriptMsg}; +use script::compositor_interface::{ReadyState, ScriptListener}; use windowing::{ApplicationMethods, WindowMethods, WindowMouseEvent, WindowClickEvent}; use windowing::{WindowMouseDownEvent, WindowMouseUpEvent}; - -use script::dom::event::{Event, ClickEvent, MouseDownEvent, MouseUpEvent, ResizeEvent}; -use script::compositor_interface::{ReadyState, ScriptListener}; -use script::script_task::{ScriptChan, SendEventMsg}; -use script::layout_interface::{LayoutChan, RouteScriptMsg}; - use azure::azure_hl::{DataSourceSurface, DrawTarget, SourceSurfaceMethods, current_gl_context}; use azure::azure::AzGLContext; use core::cell::Cell; diff --git a/src/components/main/layout/aux.rs b/src/components/main/layout/aux.rs index 59682ef20b7..11a878246ea 100644 --- a/src/components/main/layout/aux.rs +++ b/src/components/main/layout/aux.rs @@ -42,19 +42,19 @@ pub trait LayoutAuxMethods { impl LayoutAuxMethods for AbstractNode { // FIXME (Rust #3080): These unsafe blocks are *not* unused! pub fn layout_data(self) -> @mut LayoutData { - unsafe { + /*unsafe {*/ self.unsafe_layout_data() - } + /*}*/ } pub fn has_layout_data(self) -> bool { - unsafe { + /*unsafe {*/ self.unsafe_has_layout_data() - } + /*}*/ } pub fn set_layout_data(self, data: @mut LayoutData) { - unsafe { + /*unsafe {*/ self.unsafe_set_layout_data(data) - } + /*}*/ } /// If none exists, creates empty layout data for the node (the reader-auxiliary diff --git a/src/components/main/platform/common/glut_windowing.rs b/src/components/main/platform/common/glut_windowing.rs index 50e67d6e541..d633bb55056 100644 --- a/src/components/main/platform/common/glut_windowing.rs +++ b/src/components/main/platform/common/glut_windowing.rs @@ -59,7 +59,8 @@ impl WindowMethods for Window { /// Creates a new window. pub fn new(_: &Application) -> @mut Window { // Create the GLUT window. - unsafe { glut::bindgen::glutInitWindowSize(800, 600); } + // FIXME (Rust #3080): These unsafe blocks are *not* unused! + /*unsafe { */glut::bindgen::glutInitWindowSize(800, 600);/* }*/ let glut_window = glut::create_window(~"Servo"); // Create our window object. @@ -117,7 +118,7 @@ impl WindowMethods for Window { window.handle_mouse(button, state, x, y); } } - do glut::mouse_wheel_func |wheel, direction, x, y| { + do glut::mouse_wheel_func |wheel, direction, _x, _y| { let delta = if HAVE_PRECISE_MOUSE_WHEEL { (direction as f32) / 10000.0 } else { diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs index 39ef337b2f1..6eddd9d6335 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -546,7 +546,7 @@ impl ScriptContext { } } - ClickEvent(button, point) => { + ClickEvent(_button, point) => { debug!("ClickEvent: clicked at %?", point); let root = match self.root_frame { Some(ref frame) => frame.document.root, diff --git a/src/support/azure/rust-azure b/src/support/azure/rust-azure index 04976e3fae0..b754fd3d16f 160000 --- a/src/support/azure/rust-azure +++ b/src/support/azure/rust-azure @@ -1 +1 @@ -Subproject commit 04976e3fae0ef0332036082ab8770fb1ad2c10ca +Subproject commit b754fd3d16f6acc80ae2252a310f8c71070366c3 diff --git a/src/support/netsurfcss/libcss b/src/support/netsurfcss/libcss index d722188de38..da248d3f5b3 160000 --- a/src/support/netsurfcss/libcss +++ b/src/support/netsurfcss/libcss @@ -1 +1 @@ -Subproject commit d722188de3876ed748382965eb4f300fc1b78bf8 +Subproject commit da248d3f5b3ed6d9e804c543563be8e34baf1673 diff --git a/src/support/skia/skia b/src/support/skia/skia index 7415c2829e7..5c00e2b7f47 160000 --- a/src/support/skia/skia +++ b/src/support/skia/skia @@ -1 +1 @@ -Subproject commit 7415c2829e77812411a2ae9cf448c0e288035463 +Subproject commit 5c00e2b7f471e70a892aeae36b4c77b78227823f From a9e1354118341b3b74399171e222eace676252d2 Mon Sep 17 00:00:00 2001 From: Jack Moffitt Date: Mon, 17 Jun 2013 14:17:06 -0600 Subject: [PATCH 4/5] Refactor renderer into single function. This removes the task per tile rendering and instead renders tiles serially. This also unwraps the rendering into a single function so that it's much clearer. --- src/components/gfx/gfx.rc | 1 - src/components/gfx/render_layers.rs | 113 ----------------- src/components/gfx/render_task.rs | 145 +++++++++++----------- src/components/main/layout/layout_task.rs | 3 +- src/components/util/time.rs | 2 - 5 files changed, 75 insertions(+), 189 deletions(-) delete mode 100644 src/components/gfx/render_layers.rs diff --git a/src/components/gfx/gfx.rc b/src/components/gfx/gfx.rc index eae2328152a..c96e4e4b8da 100644 --- a/src/components/gfx/gfx.rc +++ b/src/components/gfx/gfx.rc @@ -42,7 +42,6 @@ pub mod color; pub mod compositor; pub mod display_list; pub mod geometry; -pub mod render_layers; pub mod render_task; pub mod surface; diff --git a/src/components/gfx/render_layers.rs b/src/components/gfx/render_layers.rs deleted file mode 100644 index fd8bdb03e86..00000000000 --- a/src/components/gfx/render_layers.rs +++ /dev/null @@ -1,113 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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 compositor::{LayerBuffer, LayerBufferSet}; -use display_list::DisplayList; -use opts::Opts; -use servo_util::time; -use servo_util::time::ProfilerChan; - -use azure::azure_hl::{B8G8R8A8, DrawTarget}; -use azure::azure::{AzGLContext}; -use core::comm::Chan; -use geom::point::Point2D; -use geom::rect::Rect; -use geom::size::Size2D; - -/// The type representing the lack of extra display list data. This is used when sending display -/// list data off to be rendered. -pub type Nothing = (); - -pub struct RenderLayer { - display_list: DisplayList, - size: Size2D -} - -type RenderFn<'self> = &'self fn(layer: *RenderLayer, - buffer: LayerBuffer, - return_buffer: Chan); - -/// Given a layer and a buffer, either reuses the buffer (if it's of the right size and format) -/// or creates a new buffer (if it's not of the appropriate size and format) and invokes the -/// given callback with the render layer and the buffer. Returns the resulting layer buffer (which -/// might be the old layer buffer if it had the appropriate size and format). -pub fn render_layers(layer_ref: *RenderLayer, - opts: &Opts, - prof_chan: ProfilerChan, - share_gl_context: AzGLContext, - f: RenderFn) - -> LayerBufferSet { - let tile_size = opts.tile_size; - let scale = opts.zoom; - - // FIXME: Try not to create a new array here. - let mut new_buffer_ports = ~[]; - - // Divide up the layer into tiles. - do time::profile(time::RenderingPrepBuffCategory, prof_chan.clone()) { - let layer: &RenderLayer = unsafe { cast::transmute(layer_ref) }; - let mut y = 0; - while y < layer.size.height * scale { - let mut x = 0; - while x < layer.size.width * scale { - // Figure out the dimension of this tile. - let right = uint::min(x + tile_size, layer.size.width * scale); - let bottom = uint::min(y + tile_size, layer.size.height * scale); - let width = right - x; - let height = bottom - y; - - let tile_rect = Rect(Point2D(x / scale, y / scale), Size2D(width, height)); //change this - let screen_rect = Rect(Point2D(x, y), Size2D(width, height)); //change this - - let buffer; - // FIXME: Try harder to search for a matching tile. - // FIXME: Don't use shift; it's bad for perf. Maybe reverse and pop. - /*if buffers.len() != 0 && buffers[0].rect == tile_rect { - debug!("reusing tile, (%u, %u)", x, y); - buffer = buffers.shift(); - } else {*/ - // Create a new buffer. - debug!("creating tile, (%u, %u)", x, y); - - // FIXME: This may not be always true. - let stride = width * 4; - - buffer = LayerBuffer { - draw_target: DrawTarget::new_with_fbo(opts.render_backend, - share_gl_context, - Size2D(width as i32, height as i32), - B8G8R8A8), - rect: tile_rect, - screen_pos: screen_rect, - stride: stride as uint - }; - //} - - // Create a port and channel pair to receive the new buffer. - let (new_buffer_port, new_buffer_chan) = comm::stream(); - - // Send the buffer to the child. - f(layer_ref, buffer, new_buffer_chan); - - // Enqueue the port. - new_buffer_ports.push(new_buffer_port); - - x += tile_size; - } - y += tile_size; - } - } - - let mut new_buffers = ~[]; - do time::profile(time::RenderingWaitSubtasksCategory, prof_chan.clone()) { - for new_buffer_ports.each |new_buffer_port| { - new_buffers.push(new_buffer_port.recv()); - } - } - - LayerBufferSet { - buffers: new_buffers, - } -} - diff --git a/src/components/gfx/render_task.rs b/src/components/gfx/render_task.rs index 8cb63f885f1..07c530bf2e1 100644 --- a/src/components/gfx/render_task.rs +++ b/src/components/gfx/render_task.rs @@ -5,23 +5,28 @@ // The task that handles all rendering/painting. use azure::{AzFloat, AzGLContext}; -use compositor::{RenderListener, IdleRenderState, RenderingRenderState}; +use azure::azure_hl::{B8G8R8A8, DrawTarget}; +use compositor::{RenderListener, IdleRenderState, RenderingRenderState, LayerBuffer, LayerBufferSet}; +use display_list::DisplayList; use font_context::FontContext; use geom::matrix2d::Matrix2D; +use geom::point::Point2D; +use geom::size::Size2D; +use geom::rect::Rect; use opts::Opts; use render_context::RenderContext; -use render_layers::{RenderLayer, render_layers}; use core::cell::Cell; use core::comm::{Chan, Port, SharedChan}; -use core::task::SingleThreaded; -use std::task_pool::TaskPool; - -use servo_net::util::spawn_listener; use servo_util::time::{ProfilerChan, profile}; use servo_util::time; +pub struct RenderLayer { + display_list: DisplayList<()>, + size: Size2D +} + pub enum Msg { AttachCompositorMsg(C), RenderMsg(RenderLayer), @@ -62,38 +67,17 @@ pub fn create_render_task(port: Port>, do spawn { let compositor = compositor_cell.take(); let share_gl_context = compositor.get_gl_context(); - - // FIXME: Annoying three-cell dance here. We need one-shot closures. let opts = opts_cell.with_ref(|o| copy *o); - let n_threads = opts.n_render_threads; - let new_opts_cell = Cell(opts); - let profiler_chan = profiler_chan.clone(); let profiler_chan_copy = profiler_chan.clone(); - let thread_pool = do TaskPool::new(n_threads, Some(SingleThreaded)) { - let opts_cell = Cell(new_opts_cell.with_ref(|o| copy *o)); - let profiler_chan = Cell(profiler_chan.clone()); - - let f: ~fn(uint) -> ThreadRenderContext = |thread_index| { - let opts = opts_cell.with_ref(|opts| copy *opts); - - ThreadRenderContext { - thread_index: thread_index, - font_ctx: @mut FontContext::new(opts.render_backend, - false, - profiler_chan.take()), - opts: opts, - } - }; - f - }; - // FIXME: rust/#5967 let mut renderer = Renderer { port: port.take(), compositor: compositor, - thread_pool: thread_pool, + font_ctx: @mut FontContext::new(opts.render_backend, + false, + profiler_chan), opts: opts_cell.take(), profiler_chan: profiler_chan_copy, share_gl_context: share_gl_context, @@ -103,17 +87,10 @@ pub fn create_render_task(port: Port>, } } -/// Data that needs to be kept around for each render thread. -priv struct ThreadRenderContext { - thread_index: uint, - font_ctx: @mut FontContext, - opts: Opts, -} - priv struct Renderer { port: Port>, compositor: C, - thread_pool: TaskPool, + font_ctx: @mut FontContext, opts: Opts, /// A channel to the profiler. @@ -142,48 +119,74 @@ impl Renderer { debug!("renderer: rendering"); self.compositor.set_render_state(RenderingRenderState); do profile(time::RenderingCategory, self.profiler_chan.clone()) { - let layer_buffer_set = do render_layers(&render_layer, - &self.opts, - self.profiler_chan.clone(), - self.share_gl_context) |render_layer_ref, - layer_buffer, - buffer_chan| { - let layer_buffer_cell = Cell(layer_buffer); - do self.thread_pool.execute |thread_render_context| { - do layer_buffer_cell.with_ref |layer_buffer| { - // Build the render context. - let ctx = RenderContext { - canvas: layer_buffer, - font_ctx: thread_render_context.font_ctx, - opts: &thread_render_context.opts + let tile_size = self.opts.tile_size; + let scale = self.opts.zoom; + + // FIXME: Try not to create a new array here. + let mut new_buffers = ~[]; + + // Divide up the layer into tiles. + do time::profile(time::RenderingPrepBuffCategory, self.profiler_chan.clone()) { + let mut y = 0; + while y < render_layer.size.height * scale { + let mut x = 0; + while x < render_layer.size.width * scale { + // Figure out the dimension of this tile. + let right = uint::min(x + tile_size, render_layer.size.width * scale); + let bottom = uint::min(y + tile_size, render_layer.size.height * scale); + let width = right - x; + let height = bottom - y; + + let tile_rect = Rect(Point2D(x / scale, y / scale), Size2D(width, height)); //change this + let screen_rect = Rect(Point2D(x, y), Size2D(width, height)); //change this + + let buffer = LayerBuffer { + draw_target: DrawTarget::new_with_fbo(self.opts.render_backend, + self.share_gl_context, + Size2D(width as i32, height as i32), + B8G8R8A8), + rect: tile_rect, + screen_pos: screen_rect, + stride: (width * 4) as uint }; - // Apply the translation to render the tile we want. - let matrix: Matrix2D = Matrix2D::identity(); - let scale = thread_render_context.opts.zoom as f32; + { + // Build the render context. + let ctx = RenderContext { + canvas: &buffer, + font_ctx: self.font_ctx, + opts: &self.opts + }; - let matrix = matrix.scale(scale as AzFloat, scale as AzFloat); - let matrix = matrix.translate(-(layer_buffer.rect.origin.x as f32) as AzFloat, - -(layer_buffer.rect.origin.y as f32) as AzFloat); + // Apply the translation to render the tile we want. + let matrix: Matrix2D = Matrix2D::identity(); + let matrix = matrix.scale(scale as AzFloat, scale as AzFloat); + let matrix = matrix.translate(-(buffer.rect.origin.x as f32) as AzFloat, + -(buffer.rect.origin.y as f32) as AzFloat); - layer_buffer.draw_target.set_transform(&matrix); + ctx.canvas.draw_target.set_transform(&matrix); - // Clear the buffer. - ctx.clear(); - + // Clear the buffer. + ctx.clear(); - // Draw the display list. - let render_layer: &RenderLayer = unsafe { - cast::transmute(render_layer_ref) - }; - - render_layer.display_list.draw_into_context(&ctx); - ctx.canvas.draw_target.flush(); + // Draw the display list. + do profile(time::RenderingDrawingCategory, self.profiler_chan.clone()) { + render_layer.display_list.draw_into_context(&ctx); + ctx.canvas.draw_target.flush(); + } + } + + new_buffers.push(buffer); + + x += tile_size; } - // Send back the buffer. - buffer_chan.send(layer_buffer_cell.take()); + y += tile_size; } + } + + let layer_buffer_set = LayerBufferSet { + buffers: new_buffers, }; debug!("renderer: returning surface"); diff --git a/src/components/main/layout/layout_task.rs b/src/components/main/layout/layout_task.rs index fcdc8cc6b24..0389f7135ce 100644 --- a/src/components/main/layout/layout_task.rs +++ b/src/components/main/layout/layout_task.rs @@ -25,8 +25,7 @@ use gfx::display_list::DisplayList; use gfx::font_context::FontContext; use gfx::geometry::Au; use gfx::opts::Opts; -use gfx::render_layers::RenderLayer; -use gfx::render_task::{RenderMsg, RenderChan}; +use gfx::render_task::{RenderMsg, RenderChan, RenderLayer}; use newcss::select::SelectCtx; use newcss::stylesheet::Stylesheet; use newcss::types::OriginAuthor; diff --git a/src/components/util/time.rs b/src/components/util/time.rs index deaec504286..d5312bc58fa 100644 --- a/src/components/util/time.rs +++ b/src/components/util/time.rs @@ -39,7 +39,6 @@ pub enum ProfilerCategory { GfxRegenAvailableFontsCategory, RenderingDrawingCategory, RenderingPrepBuffCategory, - RenderingWaitSubtasksCategory, RenderingCategory, // hackish but helps prevent errors when adding new categories NUM_BUCKETS, @@ -84,7 +83,6 @@ impl ProfilerCategory { vec.push((GfxRegenAvailableFontsCategory, ~[])); vec.push((RenderingDrawingCategory, ~[])); vec.push((RenderingPrepBuffCategory, ~[])); - vec.push((RenderingWaitSubtasksCategory, ~[])); vec.push((RenderingCategory, ~[])); ProfilerCategory::check_order(vec); From 73ed0c6cbfe22971111d6aa0f9e57889e67a8c60 Mon Sep 17 00:00:00 2001 From: Jack Moffitt Date: Wed, 19 Jun 2013 19:54:01 -0600 Subject: [PATCH 5/5] Update nss to fix build issues. --- src/support/nss/nss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/support/nss/nss b/src/support/nss/nss index 8ba903a1af2..0824ca28956 160000 --- a/src/support/nss/nss +++ b/src/support/nss/nss @@ -1 +1 @@ -Subproject commit 8ba903a1af20ce461d4f4033ec1092a229bc7482 +Subproject commit 0824ca2895668b6ac1751871d7360bc484afb930