From a338c76bc6569ce4de39a36f576102b0aff3470a Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 9 Nov 2012 16:35:43 -0800 Subject: [PATCH] gfx: Use pipes to transfer layer buffers between the render supervisor function and the render callback --- src/servo/gfx/render_layers.rs | 23 +++++++++++++++---- src/servo/gfx/render_task.rs | 40 ++++++++++++++++++++-------------- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/servo/gfx/render_layers.rs b/src/servo/gfx/render_layers.rs index fcf49678c16..2a4b0dd380c 100644 --- a/src/servo/gfx/render_layers.rs +++ b/src/servo/gfx/render_layers.rs @@ -5,6 +5,7 @@ use opts::Opts; use azure::AzFloat; use azure::azure_hl::{B8G8R8A8, DrawTarget}; use core::libc::c_int; +use core::pipes::Chan; use geom::matrix2d::Matrix2D; use geom::point::Point2D; use geom::rect::Rect; @@ -17,6 +18,8 @@ pub struct RenderLayer { size: Size2D } +type RenderFn = &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 @@ -24,11 +27,11 @@ pub struct RenderLayer { pub fn render_layers(layer: &RenderLayer, buffer_set: LayerBufferSet, opts: &Opts, - f: &fn(layer: &RenderLayer, buffer: &LayerBuffer) -> bool) -> LayerBufferSet { + f: RenderFn) -> LayerBufferSet { let mut buffers = match move buffer_set { LayerBufferSet { buffers: move b } => move b }; // FIXME: Try not to create a new array here. - let new_buffers = dvec::DVec(); + let new_buffer_ports = dvec::DVec(); // Divide up the layer into tiles. let mut y = 0; @@ -100,14 +103,26 @@ pub fn render_layers(layer: &RenderLayer, }; //} - let _ = f(layer, &buffer); - new_buffers.push(move buffer); + // Create a port and channel pair to receive the new buffer. + let (new_buffer_chan, new_buffer_port) = pipes::stream(); + + // Send the buffer to the child. + f(layer, move buffer, move new_buffer_chan); + + // Enqueue the port. + new_buffer_ports.push(move new_buffer_port); x += TILE_SIZE; } y += TILE_SIZE; } + debug!("servo::gfx::render_layers: waiting on ports..."); + let new_buffers = dvec::DVec(); + for new_buffer_ports.each |new_buffer_port| { + new_buffers.push(new_buffer_port.recv()); + } + return LayerBufferSet { buffers: move dvec::unwrap(move new_buffers) }; } diff --git a/src/servo/gfx/render_task.rs b/src/servo/gfx/render_task.rs index 788faa20451..28d60dc9496 100644 --- a/src/servo/gfx/render_task.rs +++ b/src/servo/gfx/render_task.rs @@ -87,25 +87,33 @@ impl Renderer { let layer_buffer_set = layer_buffer_set_cell.take(); let layer_buffer_set_channel = layer_buffer_set_channel_cell.take(); - let layer_buffer_set = for render_layers(&render_layer, - move layer_buffer_set, - &self.opts) - |render_layer, layer_buffer| { - let ctx = RenderContext { - canvas: layer_buffer, - font_ctx: self.font_ctx, - opts: &self.opts - }; + let layer_buffer_set = do render_layers(&render_layer, + move layer_buffer_set, + &self.opts) + |render_layer, layer_buffer, buffer_chan| { + { + // Build the render context. + let ctx = RenderContext { + canvas: &layer_buffer, + font_ctx: self.font_ctx, + opts: &self.opts + }; - // Apply the translation to render the tile we want. - let matrix: Matrix2D = Matrix2D::identity(); - let matrix = matrix.translate(&-(layer_buffer.rect.origin.x as AzFloat), - &-(layer_buffer.rect.origin.y as AzFloat)); - layer_buffer.draw_target.set_transform(&matrix); + // Apply the translation to render the tile we want. + let matrix: Matrix2D = Matrix2D::identity(); + let matrix = matrix.translate(&-(layer_buffer.rect.origin.x as AzFloat), + &-(layer_buffer.rect.origin.y as AzFloat)); + layer_buffer.draw_target.set_transform(&matrix); - ctx.clear(); + // Clear the buffer. + ctx.clear(); - render_layer.display_list.draw_into_context(&ctx); + // Draw the display list. + render_layer.display_list.draw_into_context(&ctx); + } + + // Send back the buffer. + buffer_chan.send(move layer_buffer); }; #debug("renderer: returning surface");