Refactor compositing a bit to conform to modern Rust style

This commit is contained in:
Patrick Walton 2013-05-17 18:18:57 -07:00
parent 4d7f003cd9
commit 01ce79bc74

View file

@ -17,8 +17,10 @@ use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
use gfx::compositor::{Compositor, LayerBuffer, LayerBufferSet}; use gfx::compositor::{Compositor, LayerBuffer, LayerBufferSet};
use gfx::opts::Opts; use gfx::opts::Opts;
use layers::layers::{Image, ImageData}; use layers::layers::{ARGB32Format, BasicImageData, ContainerLayer, ContainerLayerKind, Format};
use layers; use layers::layers::{Image, ImageData, ImageLayer, ImageLayerKind, RGB24Format, WithDataFn};
use layers::rendergl;
use layers::scene::Scene;
use servo_util::{time, url}; use servo_util::{time, url};
mod resize_rate_limiter; mod resize_rate_limiter;
@ -35,7 +37,7 @@ impl CompositorImpl {
let script_chan = Cell(script_chan); let script_chan = Cell(script_chan);
let chan: Chan<Msg> = do on_osmain |port| { let chan: Chan<Msg> = do on_osmain |port| {
debug!("preparing to enter main loop"); debug!("preparing to enter main loop");
mainloop(port, script_chan.take(), &opts); run_main_loop(port, script_chan.take(), &opts);
}; };
CompositorImpl { CompositorImpl {
@ -59,59 +61,51 @@ struct AzureDrawTargetImageData {
size: Size2D<uint> size: Size2D<uint>
} }
impl layers::layers::ImageData for AzureDrawTargetImageData { impl ImageData for AzureDrawTargetImageData {
fn size(&self) -> Size2D<uint> { fn size(&self) -> Size2D<uint> {
self.size self.size
} }
fn stride(&self) -> uint { fn stride(&self) -> uint {
self.data_source_surface.stride() as uint self.data_source_surface.stride() as uint
} }
fn format(&self) -> layers::layers::Format { fn format(&self) -> Format {
// FIXME: This is not always correct. We should query the Azure draw target for the format. // FIXME: This is not always correct. We should query the Azure draw target for the format.
layers::layers::ARGB32Format ARGB32Format
} }
fn with_data(&self, f: layers::layers::WithDataFn) { fn with_data(&self, f: WithDataFn) {
do self.data_source_surface.with_data |data| { do self.data_source_surface.with_data |data| {
f(data); f(data);
} }
} }
} }
fn mainloop(po: Port<Msg>, script_chan: SharedChan<ScriptMsg>, opts: &Opts) { fn run_main_loop(po: Port<Msg>, script_chan: SharedChan<ScriptMsg>, opts: &Opts) {
let key_handlers: @mut ~[Chan<()>] = @mut ~[];
let app: Application = ApplicationMethods::new(); let app: Application = ApplicationMethods::new();
let window: @mut Window = WindowMethods::new(&app); let window: @mut Window = WindowMethods::new(&app);
let resize_rate_limiter = @mut ResizeRateLimiter(script_chan.clone());
let surfaces = @mut SurfaceSet(opts.render_backend); let surfaces = @mut SurfaceSet::new(opts.render_backend);
let context = rendergl::init_render_context();
let context = layers::rendergl::init_render_context();
// Create an initial layer tree. // Create an initial layer tree.
// //
// TODO: There should be no initial layer tree until the renderer creates one from the display // TODO: There should be no initial layer tree until the renderer creates one from the display
// list. This is only here because we don't have that logic in the renderer yet. // list. This is only here because we don't have that logic in the renderer yet.
let root_layer = @mut layers::layers::ContainerLayer(); let root_layer = @mut ContainerLayer();
let original_layer_transform; let original_layer_transform;
{ {
let image_data = @layers::layers::BasicImageData::new(Size2D(0u, 0u), let image_data = @BasicImageData::new(Size2D(0, 0), 0, RGB24Format, ~[]);
0,
layers::layers::RGB24Format,
~[]);
let image = @mut Image::new(image_data as @ImageData); let image = @mut Image::new(image_data as @ImageData);
let image_layer = @mut layers::layers::ImageLayer(image); let image_layer = @mut ImageLayer(image);
original_layer_transform = image_layer.common.transform; original_layer_transform = image_layer.common.transform;
image_layer.common.set_transform(original_layer_transform.scale(800.0, 600.0, 1.0)); image_layer.common.set_transform(original_layer_transform.scale(800.0, 600.0, 1.0));
root_layer.add_child(layers::layers::ImageLayerKind(image_layer)); root_layer.add_child(ImageLayerKind(image_layer));
} }
let scene = @mut Scene(ContainerLayerKind(root_layer), Size2D(800.0, 600.0), identity());
let scene = @mut layers::scene::Scene(layers::layers::ContainerLayerKind(root_layer), let key_handlers: @mut ~[Chan<()>] = @mut ~[];
Size2D(800.0, 600.0),
identity());
let done = @mut false; let done = @mut false;
let resize_rate_limiter = @mut ResizeRateLimiter(script_chan.clone());
let check_for_messages: @fn() = || { let check_for_messages: @fn() = || {
// Periodically check if the script task responded to our last resize event // Periodically check if the script task responded to our last resize event
resize_rate_limiter.check_resize_response(); resize_rate_limiter.check_resize_response();
@ -120,11 +114,15 @@ fn mainloop(po: Port<Msg>, script_chan: SharedChan<ScriptMsg>, opts: &Opts) {
while po.peek() { while po.peek() {
match po.recv() { match po.recv() {
AddKeyHandler(key_ch) => key_handlers.push(key_ch), AddKeyHandler(key_ch) => key_handlers.push(key_ch),
BeginDrawing(sender) => lend_surface(surfaces, sender), BeginDrawing(sender) => surfaces.lend(sender),
Exit => *done = true,
Draw(sender, draw_target) => { Draw(sender, draw_target) => {
debug!("osmain: received new frame"); debug!("osmain: received new frame");
return_surface(surfaces, draw_target);
lend_surface(surfaces, sender); // Perform a buffer swap.
surfaces.put_back(draw_target);
surfaces.lend(sender);
// Iterate over the children of the container layer. // Iterate over the children of the container layer.
let mut current_layer_child = root_layer.first_child; let mut current_layer_child = root_layer.first_child;
@ -149,11 +147,11 @@ fn mainloop(po: Port<Msg>, script_chan: SharedChan<ScriptMsg>, opts: &Opts) {
current_layer_child = match current_layer_child { current_layer_child = match current_layer_child {
None => { None => {
debug!("osmain: adding new image layer"); debug!("osmain: adding new image layer");
image_layer = @mut layers::layers::ImageLayer(image); image_layer = @mut ImageLayer(image);
root_layer.add_child(layers::layers::ImageLayerKind(image_layer)); root_layer.add_child(ImageLayerKind(image_layer));
None None
} }
Some(layers::layers::ImageLayerKind(existing_image_layer)) => { Some(ImageLayerKind(existing_image_layer)) => {
image_layer = existing_image_layer; image_layer = existing_image_layer;
image_layer.set_image(image); image_layer.set_image(image);
@ -166,16 +164,13 @@ fn mainloop(po: Port<Msg>, script_chan: SharedChan<ScriptMsg>, opts: &Opts) {
}; };
// Set the layer's transform. // Set the layer's transform.
let x = buffer.rect.origin.x as f32; let (x, y) = (buffer.rect.origin.x as f32, buffer.rect.origin.y as f32);
let y = buffer.rect.origin.y as f32; let transform = original_layer_transform.translate(x, y, 0.0);
image_layer.common.set_transform( let transform = transform.scale(width as f32, height as f32, 1.0);
original_layer_transform.translate(x, y, 0.0) image_layer.common.set_transform(transform)
.scale(width as f32, height as f32, 1.0));
} }
surfaces.front.layer_buffer_set.buffers = buffers;
} surfaces.front.layer_buffer_set.buffers = buffers
Exit => {
*done = true;
} }
} }
} }
@ -187,7 +182,7 @@ fn mainloop(po: Port<Msg>, script_chan: SharedChan<ScriptMsg>, opts: &Opts) {
scene.size = window.size(); scene.size = window.size();
// Render the scene. // Render the scene.
layers::rendergl::render_scene(context, scene); rendergl::render_scene(context, scene);
} }
window.present(); window.present();
@ -230,11 +225,20 @@ struct SurfaceSet {
back: Surface, back: Surface,
} }
fn lend_surface(surfaces: &mut SurfaceSet, receiver: Chan<LayerBufferSet>) { impl SurfaceSet {
/// Creates a new surface set.
fn new(backend: BackendType) -> SurfaceSet {
SurfaceSet {
front: Surface::new(backend),
back: Surface::new(backend),
}
}
fn lend(&mut self, receiver: Chan<LayerBufferSet>) {
// We are in a position to lend out the surface? // We are in a position to lend out the surface?
assert!(surfaces.front.have); assert!(self.front.have);
// Ok then take it // Ok then take it
let old_layer_buffers = util::replace(&mut surfaces.front.layer_buffer_set.buffers, ~[]); let old_layer_buffers = util::replace(&mut self.front.layer_buffer_set.buffers, ~[]);
let new_layer_buffers = do old_layer_buffers.map |layer_buffer| { let new_layer_buffers = do old_layer_buffers.map |layer_buffer| {
let draw_target_ref = &layer_buffer.draw_target; let draw_target_ref = &layer_buffer.draw_target;
let layer_buffer = LayerBuffer { let layer_buffer = LayerBuffer {
@ -245,32 +249,28 @@ fn lend_surface(surfaces: &mut SurfaceSet, receiver: Chan<LayerBufferSet>) {
debug!("osmain: lending surface %?", layer_buffer); debug!("osmain: lending surface %?", layer_buffer);
layer_buffer layer_buffer
}; };
surfaces.front.layer_buffer_set.buffers = old_layer_buffers; self.front.layer_buffer_set.buffers = old_layer_buffers;
let new_layer_buffer_set = LayerBufferSet { buffers: new_layer_buffers }; let new_layer_buffer_set = LayerBufferSet { buffers: new_layer_buffers };
receiver.send(new_layer_buffer_set); receiver.send(new_layer_buffer_set);
// Now we don't have it // Now we don't have it
surfaces.front.have = false; self.front.have = false;
// But we (hopefully) have another! // But we (hopefully) have another!
util::swap(&mut surfaces.front, &mut surfaces.back); util::swap(&mut self.front, &mut self.back);
// Let's look // Let's look
assert!(surfaces.front.have); assert!(self.front.have);
} }
fn return_surface(surfaces: &mut SurfaceSet, layer_buffer_set: LayerBufferSet) { fn put_back(&mut self, layer_buffer_set: LayerBufferSet) {
//#debug("osmain: returning surface %?", layer_buffer_set);
// We have room for a return // We have room for a return
assert!(surfaces.front.have); assert!(self.front.have);
assert!(!surfaces.back.have); assert!(!self.back.have);
surfaces.back.layer_buffer_set = layer_buffer_set; self.back.layer_buffer_set = layer_buffer_set;
// Now we have it again // Now we have it again
surfaces.back.have = true; self.back.have = true;
} }
fn SurfaceSet(backend: BackendType) -> SurfaceSet {
SurfaceSet { front: Surface(backend), back: Surface(backend) }
} }
struct Surface { struct Surface {
@ -278,9 +278,10 @@ struct Surface {
have: bool, have: bool,
} }
fn Surface(backend: BackendType) -> Surface { impl Surface {
fn new(backend: BackendType) -> Surface {
let layer_buffer = LayerBuffer { let layer_buffer = LayerBuffer {
draw_target: DrawTarget::new(backend, Size2D(800i32, 600i32), B8G8R8A8), draw_target: DrawTarget::new(backend, Size2D(800, 600), B8G8R8A8),
rect: Rect(Point2D(0u, 0u), Size2D(800u, 600u)), rect: Rect(Point2D(0u, 0u), Size2D(800u, 600u)),
stride: 800 * 4 stride: 800 * 4
}; };
@ -291,6 +292,7 @@ fn Surface(backend: BackendType) -> Surface {
layer_buffer_set: layer_buffer_set, layer_buffer_set: layer_buffer_set,
have: true have: true
} }
}
} }
/// A function for spawning into the platform's main thread. /// A function for spawning into the platform's main thread.