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);