aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-10-25 16:20:39 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-10-25 16:20:39 -0700
commit5c373c21d83cfb537c79e854d72544c0835cec2e (patch)
treef51ad45c250d3eb64a3ca9e38e5fd29ae9799298
parent467c79953277971854604ea53f50b2b0766b50c5 (diff)
downloadservo-5c373c21d83cfb537c79e854d72544c0835cec2e.tar.gz
servo-5c373c21d83cfb537c79e854d72544c0835cec2e.zip
gfx: Use layer buffer sets instead of a single layer buffer
-rw-r--r--src/servo/gfx/compositor.rs10
-rw-r--r--src/servo/gfx/png_compositor.rs29
-rw-r--r--src/servo/gfx/render_layers.rs11
-rw-r--r--src/servo/gfx/render_task.rs30
-rw-r--r--src/servo/platform/osmain.rs78
5 files changed, 87 insertions, 71 deletions
diff --git a/src/servo/gfx/compositor.rs b/src/servo/gfx/compositor.rs
index f434564dd41..f704132dddf 100644
--- a/src/servo/gfx/compositor.rs
+++ b/src/servo/gfx/compositor.rs
@@ -16,12 +16,18 @@ struct LayerBuffer {
stride: uint
}
+/// A set of layer buffers. This is an atomic unit used to switch between the front and back
+/// buffers.
+struct LayerBufferSet {
+ buffers: ~[LayerBuffer]
+}
+
/**
The interface used to by the renderer to aquire draw targets for
each rendered frame and submit them to be drawn to the display
*/
trait Compositor {
- fn begin_drawing(next_dt: pipes::Chan<LayerBuffer>);
- fn draw(next_dt: pipes::Chan<LayerBuffer>, +draw_me: LayerBuffer);
+ fn begin_drawing(next_dt: pipes::Chan<LayerBufferSet>);
+ fn draw(next_dt: pipes::Chan<LayerBufferSet>, +draw_me: LayerBufferSet);
}
diff --git a/src/servo/gfx/png_compositor.rs b/src/servo/gfx/png_compositor.rs
index 094a4181479..bd0f108feb2 100644
--- a/src/servo/gfx/png_compositor.rs
+++ b/src/servo/gfx/png_compositor.rs
@@ -12,8 +12,8 @@ use azure::azure_hl::DrawTarget;
use cairo::cairo_hl::ImageSurface;
use cairo::{CAIRO_FORMAT_ARGB32, cairo_surface_t, cairo_status_t, CAIRO_STATUS_SUCCESS};
use cairo_bg = cairo::bindgen;
-use cairo_bg::{cairo_image_surface_create, cairo_surface_destroy,
- cairo_surface_write_to_png_stream};
+use cairo_bg::{cairo_image_surface_create, cairo_surface_destroy};
+use cairo_bg::{cairo_surface_write_to_png_stream};
use compositor::Compositor;
use render_task::{RenderTask, RenderMsg};
use task::spawn_listener;
@@ -25,23 +25,23 @@ use dvec::DVec;
use display_list::DisplayList;
use std::cell::Cell;
use core::io::BytesWriter;
-use gfx::compositor::LayerBuffer;
+use gfx::compositor::{LayerBuffer, LayerBufferSet};
use geom::size::Size2D;
use gfx::render_layers::RenderLayer;
pub type PngCompositor = Chan<Msg>;
pub enum Msg {
- BeginDrawing(pipes::Chan<LayerBuffer>),
- Draw(pipes::Chan<LayerBuffer>, LayerBuffer),
+ BeginDrawing(pipes::Chan<LayerBufferSet>),
+ Draw(pipes::Chan<LayerBufferSet>, LayerBufferSet),
Exit
}
impl Chan<Msg> : Compositor {
- fn begin_drawing(next_dt: pipes::Chan<LayerBuffer>) {
+ fn begin_drawing(next_dt: pipes::Chan<LayerBufferSet>) {
self.send(BeginDrawing(move next_dt))
}
- fn draw(next_dt: pipes::Chan<LayerBuffer>, draw_me: LayerBuffer) {
+ fn draw(next_dt: pipes::Chan<LayerBufferSet>, draw_me: LayerBufferSet) {
self.send(Draw(move next_dt, move draw_me))
}
}
@@ -56,17 +56,18 @@ pub fn PngCompositor(output: Chan<~[u8]>) -> PngCompositor {
size: Size2D(800u, 600u),
stride: 800
};
- let layer_buffer = Cell(move layer_buffer);
+ let layer_buffer_set = LayerBufferSet { buffers: ~[ move layer_buffer ] };
+ let layer_buffer_set = Cell(move layer_buffer_set);
loop {
match po.recv() {
BeginDrawing(sender) => {
debug!("png_compositor: begin_drawing");
- sender.send(layer_buffer.take());
+ sender.send(layer_buffer_set.take());
}
- Draw(move sender, move layer_buffer) => {
+ Draw(move sender, move layer_buffer_set) => {
debug!("png_compositor: draw");
- do_draw(move sender, move layer_buffer, output, &cairo_surface);
+ do_draw(move sender, move layer_buffer_set, output, &cairo_surface);
}
Exit => break
}
@@ -74,8 +75,8 @@ pub fn PngCompositor(output: Chan<~[u8]>) -> PngCompositor {
}
}
-fn do_draw(sender: pipes::Chan<LayerBuffer>,
- layer_buffer: LayerBuffer,
+fn do_draw(sender: pipes::Chan<LayerBufferSet>,
+ layer_buffer_set: LayerBufferSet,
output: Chan<~[u8]>,
cairo_surface: &ImageSurface) {
let buffer = BytesWriter();
@@ -83,7 +84,7 @@ fn do_draw(sender: pipes::Chan<LayerBuffer>,
output.send(buffer.bytes.get());
// Send the next draw target to the renderer
- sender.send(move layer_buffer);
+ sender.send(move layer_buffer_set);
}
#[test]
diff --git a/src/servo/gfx/render_layers.rs b/src/servo/gfx/render_layers.rs
index bd24bcd813c..8d155a23cea 100644
--- a/src/servo/gfx/render_layers.rs
+++ b/src/servo/gfx/render_layers.rs
@@ -1,5 +1,5 @@
use gfx::display_list::DisplayList;
-use gfx::compositor::LayerBuffer;
+use gfx::compositor::{LayerBuffer, LayerBufferSet};
use azure::azure_hl::DrawTarget;
use cairo::CAIRO_FORMAT_RGB24;
@@ -17,9 +17,10 @@ pub struct RenderLayer {
/// 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 = move buffer;
+ buffer_set: LayerBufferSet,
+ f: &fn(layer: &RenderLayer, buffer: &LayerBuffer) -> bool) -> LayerBufferSet {
+ let mut buffers = match move buffer_set { LayerBufferSet { buffers: move b } => move b };
+ let mut buffer = buffers.pop();
if buffer.size != layer.size {
// Create a new buffer.
@@ -44,6 +45,6 @@ pub fn render_layers(layer: &RenderLayer,
}
let _ = f(layer, &buffer);
- return move buffer;
+ return LayerBufferSet { buffers: ~[ move buffer ] };
}
diff --git a/src/servo/gfx/render_task.rs b/src/servo/gfx/render_task.rs
index d762ffbf2ce..52ab43717e4 100644
--- a/src/servo/gfx/render_task.rs
+++ b/src/servo/gfx/render_task.rs
@@ -1,7 +1,7 @@
use au = gfx::geometry;
use au::Au;
use comm::*;
-use compositor::{Compositor, LayerBuffer};
+use compositor::{Compositor, LayerBufferSet};
use dl = display_list;
use mod gfx::render_layers;
use render_layers::render_layers;
@@ -24,7 +24,7 @@ pub type RenderTask = comm::Chan<Msg>;
pub fn RenderTask<C: Compositor Send>(compositor: C) -> RenderTask {
let compositor_cell = Cell(move compositor);
do task::spawn_listener |po: comm::Port<Msg>, move compositor_cell| {
- let (layer_buffer_channel, layer_buffer_port) = pipes::stream();
+ let (layer_buffer_channel, layer_buffer_set_port) = pipes::stream();
let compositor = compositor_cell.take();
compositor.begin_drawing(move layer_buffer_channel);
@@ -32,7 +32,7 @@ pub fn RenderTask<C: Compositor Send>(compositor: C) -> RenderTask {
Renderer {
port: po,
compositor: move compositor,
- mut layer_buffer_port: Cell(move layer_buffer_port),
+ mut layer_buffer_set_port: Cell(move layer_buffer_set_port),
font_cache: FontCache(),
}.start();
}
@@ -41,7 +41,7 @@ pub fn RenderTask<C: Compositor Send>(compositor: C) -> RenderTask {
priv struct Renderer<C: Compositor Send> {
port: comm::Port<Msg>,
compositor: C,
- layer_buffer_port: Cell<pipes::Port<LayerBuffer>>,
+ layer_buffer_set_port: Cell<pipes::Port<LayerBufferSet>>,
font_cache: @FontCache
}
@@ -63,28 +63,28 @@ impl<C: Compositor Send> Renderer<C> {
fn render(render_layer: RenderLayer) {
debug!("renderer: got render request");
- let layer_buffer_port = self.layer_buffer_port.take();
+ let layer_buffer_set_port = self.layer_buffer_set_port.take();
- if !layer_buffer_port.peek() {
+ if !layer_buffer_set_port.peek() {
warn!("renderer: waiting on layer buffer");
}
- let layer_buffer = layer_buffer_port.recv();
- let (layer_buffer_channel, new_layer_buffer_port) = pipes::stream();
- self.layer_buffer_port.put_back(move new_layer_buffer_port);
+ let layer_buffer_set = layer_buffer_set_port.recv();
+ let (layer_buffer_set_channel, new_layer_buffer_set_port) = pipes::stream();
+ self.layer_buffer_set_port.put_back(move new_layer_buffer_set_port);
let render_layer_cell = Cell(move render_layer);
- let layer_buffer_cell = Cell(move layer_buffer);
- let layer_buffer_channel_cell = Cell(move layer_buffer_channel);
+ let layer_buffer_set_cell = Cell(move layer_buffer_set);
+ let layer_buffer_set_channel_cell = Cell(move layer_buffer_set_channel);
#debug("renderer: rendering");
do util::time::time(~"rendering") {
let render_layer = render_layer_cell.take();
- let layer_buffer = layer_buffer_cell.take();
- let layer_buffer_channel = layer_buffer_channel_cell.take();
+ let layer_buffer_set = layer_buffer_set_cell.take();
+ let layer_buffer_set_channel = layer_buffer_set_channel_cell.take();
- let layer_buffer = for render_layers(&render_layer, move layer_buffer)
+ let layer_buffer_set = for render_layers(&render_layer, move layer_buffer_set)
|render_layer, layer_buffer| {
let ctx = RenderContext {
canvas: layer_buffer,
@@ -96,7 +96,7 @@ impl<C: Compositor Send> Renderer<C> {
};
#debug("renderer: returning surface");
- self.compositor.draw(move layer_buffer_channel, move layer_buffer);
+ self.compositor.draw(move layer_buffer_set_channel, move layer_buffer_set);
}
}
}
diff --git a/src/servo/platform/osmain.rs b/src/servo/platform/osmain.rs
index 167d51d4def..0db894cdf05 100644
--- a/src/servo/platform/osmain.rs
+++ b/src/servo/platform/osmain.rs
@@ -1,20 +1,21 @@
-use mod azure::azure_hl;
+use ShareGlContext = sharegl::platform::Context;
+use azure::azure_hl;
use azure::azure_hl::DrawTarget;
-use cairo::cairo_surface_t;
use cairo::cairo_hl::ImageSurface;
-use dvec::DVec;
-use gfx::compositor::{LayerBuffer, Compositor};
+use cairo::cairo_surface_t;
+use core::util::replace;
use dom::event::{Event, ResizeEvent};
-use layers::ImageLayer;
+use dvec::DVec;
use geom::matrix::{Matrix4, identity};
use geom::size::Size2D;
-use ShareGlContext = sharegl::platform::Context;
+use gfx::compositor::{Compositor, LayerBuffer, LayerBufferSet};
+use layers::ImageLayer;
+use pipes::Chan;
+use resize_rate_limiter::ResizeRateLimiter;
+use std::cell::Cell;
use std::cmp::FuzzyEq;
use task::TaskBuilder;
use vec::push;
-use pipes::Chan;
-use std::cell::Cell;
-use resize_rate_limiter::ResizeRateLimiter;
pub type OSMain = comm::Chan<Msg>;
@@ -30,8 +31,8 @@ enum Window {
}
pub enum Msg {
- BeginDrawing(pipes::Chan<LayerBuffer>),
- Draw(pipes::Chan<LayerBuffer>, LayerBuffer),
+ BeginDrawing(pipes::Chan<LayerBufferSet>),
+ Draw(pipes::Chan<LayerBufferSet>, LayerBufferSet),
AddKeyHandler(pipes::Chan<()>),
Exit
}
@@ -120,11 +121,12 @@ fn mainloop(mode: Mode, po: comm::Port<Msg>, dom_event_chan: pipes::SharedChan<E
return_surface(surfaces, move dt);
lend_surface(surfaces, move sender);
- let width = surfaces.front.layer_buffer.size.width as uint;
- let height = surfaces.front.layer_buffer.size.height as uint;
+ let buffers = &mut surfaces.front.layer_buffer_set.buffers;
+ let width = buffers[0].size.width as uint;
+ let height = buffers[0].size.height as uint;
let image_data = @CairoSurfaceImageData {
- cairo_surface: surfaces.front.layer_buffer.cairo_surface.clone(),
+ cairo_surface: buffers[0].cairo_surface.clone(),
size: Size2D(width, height)
};
let image = @layers::layers::Image::new(
@@ -142,7 +144,6 @@ fn mainloop(mode: Mode, po: comm::Port<Msg>, dom_event_chan: pipes::SharedChan<E
};
let adjust_for_window_resizing: fn@() = || {
- let height = surfaces.front.layer_buffer.size.height as uint;
let window_width = glut::get(glut::WindowWidth) as uint;
let window_height = glut::get(glut::WindowHeight) as uint;
@@ -167,15 +168,14 @@ fn mainloop(mode: Mode, po: comm::Port<Msg>, dom_event_chan: pipes::SharedChan<E
match window {
GlutWindow(window) => {
do glut::reshape_func(window) |width, height| {
- check_for_messages();
-
#debug("osmain: window resized to %d,%d", width as int, height as int);
+ check_for_messages();
resize_rate_limiter.window_resized(width as uint, height as uint);
-
- composite();
+ //composite();
}
do glut::display_func() {
+ debug!("osmain: display func");
check_for_messages();
composite();
}
@@ -203,10 +203,10 @@ Implementation to allow the osmain channel to be used as a graphics
compositor for the renderer
*/
impl OSMain : Compositor {
- fn begin_drawing(next_dt: pipes::Chan<LayerBuffer>) {
+ fn begin_drawing(next_dt: pipes::Chan<LayerBufferSet>) {
self.send(BeginDrawing(move next_dt))
}
- fn draw(next_dt: pipes::Chan<LayerBuffer>, draw_me: LayerBuffer) {
+ fn draw(next_dt: pipes::Chan<LayerBufferSet>, draw_me: LayerBufferSet) {
self.send(Draw(move next_dt, move draw_me))
}
}
@@ -216,19 +216,26 @@ struct SurfaceSet {
mut back: Surface,
}
-fn lend_surface(surfaces: &SurfaceSet, receiver: pipes::Chan<LayerBuffer>) {
+fn lend_surface(surfaces: &SurfaceSet, receiver: pipes::Chan<LayerBufferSet>) {
// We are in a position to lend out the surface?
assert surfaces.front.have;
// Ok then take it
- let draw_target_ref = &mut surfaces.front.layer_buffer.draw_target;
- let layer_buffer = LayerBuffer {
- cairo_surface: surfaces.front.layer_buffer.cairo_surface.clone(),
- draw_target: azure_hl::clone_mutable_draw_target(draw_target_ref),
- size: copy surfaces.front.layer_buffer.size,
- stride: surfaces.front.layer_buffer.stride
+ let old_layer_buffers = replace(&mut surfaces.front.layer_buffer_set.buffers, ~[]);
+ let new_layer_buffers = do old_layer_buffers.map |layer_buffer| {
+ let draw_target_ref = &layer_buffer.draw_target;
+ let layer_buffer = LayerBuffer {
+ cairo_surface: layer_buffer.cairo_surface.clone(),
+ draw_target: draw_target_ref.clone(),
+ size: copy layer_buffer.size,
+ stride: layer_buffer.stride
+ };
+ #debug("osmain: lending surface %?", layer_buffer);
+ move layer_buffer
};
- #debug("osmain: lending surface %?", layer_buffer);
- receiver.send(move layer_buffer);
+ surfaces.front.layer_buffer_set.buffers = move old_layer_buffers;
+
+ let new_layer_buffer_set = LayerBufferSet { buffers: move new_layer_buffers };
+ receiver.send(move new_layer_buffer_set);
// Now we don't have it
surfaces.front.have = false;
// But we (hopefully) have another!
@@ -237,13 +244,13 @@ fn lend_surface(surfaces: &SurfaceSet, receiver: pipes::Chan<LayerBuffer>) {
assert surfaces.front.have;
}
-fn return_surface(surfaces: &SurfaceSet, layer_buffer: LayerBuffer) {
- #debug("osmain: returning surface %?", layer_buffer);
+fn return_surface(surfaces: &SurfaceSet, layer_buffer_set: LayerBufferSet) {
+ #debug("osmain: returning surface %?", layer_buffer_set);
// We have room for a return
assert surfaces.front.have;
assert !surfaces.back.have;
- surfaces.back.layer_buffer = move layer_buffer;
+ surfaces.back.layer_buffer_set = move layer_buffer_set;
// Now we have it again
surfaces.back.have = true;
@@ -254,7 +261,7 @@ fn SurfaceSet() -> SurfaceSet {
}
struct Surface {
- layer_buffer: LayerBuffer,
+ layer_buffer_set: LayerBufferSet,
mut have: bool,
}
@@ -267,7 +274,8 @@ fn Surface() -> Surface {
size: Size2D(800u, 600u),
stride: 800
};
- Surface { layer_buffer: move layer_buffer, have: true }
+ let layer_buffer_set = LayerBufferSet { buffers: ~[ move layer_buffer ] };
+ Surface { layer_buffer_set: move layer_buffer_set, have: true }
}
/// A function for spawning into the platform's main thread