From 5752ae6783890ea71cdf1c6a4aa9018acff2508d Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 11 Oct 2012 17:45:10 -0700 Subject: [PATCH] Stub RenderLayers. This is a step on the way toward window resizing. --- src/servo/gfx/render_layers.rs | 36 ++++++++++++++++++++++++++++++++++ src/servo/gfx/render_task.rs | 28 +++++++++++++++++++------- src/servo/servo.rc | 1 + 3 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 src/servo/gfx/render_layers.rs diff --git a/src/servo/gfx/render_layers.rs b/src/servo/gfx/render_layers.rs new file mode 100644 index 00000000000..7e2cc12abc7 --- /dev/null +++ b/src/servo/gfx/render_layers.rs @@ -0,0 +1,36 @@ +use gfx::display_list::DisplayList; +use gfx::render_task::LayerBuffer; + +use azure::azure_hl::DrawTarget; +use azure::cairo::CAIRO_FORMAT_RGB24; +use azure::cairo_hl::ImageSurface; +use core::libc::c_int; +use geom::size::Size2D; + +pub struct RenderLayer { + display_list: DisplayList, + size: Size2D +} + +/// 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: &RenderLayer, + buffer: LayerBuffer, + f: &fn(layer: &RenderLayer, buffer: &LayerBuffer) -> bool) -> LayerBuffer { + let mut buffer = buffer; + if buffer.size != layer.size { + // Create a new buffer. + io::println("making new buffer size!"); + let cairo_surface = ImageSurface(CAIRO_FORMAT_RGB24, + layer.size.width as c_int, + layer.size.height as c_int); + let draw_target = DrawTarget(&cairo_surface); + buffer = LayerBuffer { draw_target: move draw_target, size: copy layer.size }; + } + + let _ = f(layer, &buffer); + return move buffer; +} + diff --git a/src/servo/gfx/render_task.rs b/src/servo/gfx/render_task.rs index 7422429991a..4be2a956111 100644 --- a/src/servo/gfx/render_task.rs +++ b/src/servo/gfx/render_task.rs @@ -14,6 +14,8 @@ use dl = display_list; use geom::point::Point2D; use geom::rect::Rect; use geom::size::Size2D; +use mod gfx::render_layers; +use gfx::render_layers::RenderLayer; use image::base::Image; use libc::size_t; use pipes::{Port, Chan}; @@ -58,29 +60,41 @@ pub fn RenderTask(compositor: C) -> RenderTask { loop { match po.recv() { - RenderMsg(display_list) => { + RenderMsg(move display_list) => { #debug("renderer: got render request"); - let layer_buffer = Cell(layer_buffer_port.recv()); + let layer_buffer_cell = Cell(layer_buffer_port.recv()); let (layer_buffer_channel, new_layer_buffer_port) = pipes::stream(); let layer_buffer_channel = Cell(move layer_buffer_channel); layer_buffer_port = new_layer_buffer_port; + let display_list = Cell(move display_list); + #debug("renderer: rendering"); do util::time::time(~"rendering") { - do layer_buffer.with_ref |layer_buffer_ref| { + let layer_buffer = layer_buffer_cell.take(); + let display_list = move display_list.take(); + + let render_layer = RenderLayer { + display_list: move display_list, + size: Size2D(800u, 600u) + }; + + let layer_buffer = + for render_layers::render_layers(&render_layer, move layer_buffer) + |render_layer, layer_buffer| { let ctx = RenderContext { - canvas: layer_buffer_ref, + canvas: layer_buffer, font_cache: font_cache }; clear(&ctx); - display_list.draw(&ctx) - } + render_layer.display_list.draw(&ctx); + }; #debug("renderer: returning surface"); - compositor.draw(layer_buffer_channel.take(), layer_buffer.take()); + compositor.draw(layer_buffer_channel.take(), move layer_buffer); } } ExitMsg(response_ch) => { diff --git a/src/servo/servo.rc b/src/servo/servo.rc index 653b1caabd7..d147accf9a6 100755 --- a/src/servo/servo.rc +++ b/src/servo/servo.rc @@ -76,6 +76,7 @@ pub mod gfx { pub mod compositor; pub mod png_compositor; pub mod display_list; + pub mod render_layers; } pub mod image {