add pipeline.rs, modularized pipelines communicating with constellation

This commit is contained in:
Tim Kuehn 2013-06-26 22:42:01 -07:00
parent fdb0d820a4
commit fba7ec423c
19 changed files with 528 additions and 317 deletions

View file

@ -8,7 +8,8 @@ use azure::{AzFloat, AzGLContext};
use azure::azure_hl::{B8G8R8A8, DrawTarget};
use display_list::DisplayList;
use servo_msg::compositor::{RenderListener, IdleRenderState, RenderingRenderState, LayerBuffer};
use servo_msg::compositor::LayerBufferSet;
use servo_msg::compositor::{CompositorToken, LayerBufferSet};
use servo_msg::engine::{EngineChan, TokenSurrenderMsg};
use font_context::FontContext;
use geom::matrix2d::Matrix2D;
use geom::point::Point2D;
@ -20,6 +21,7 @@ use render_context::RenderContext;
use std::cell::Cell;
use std::comm::{Chan, Port, SharedChan};
use std::uint;
use std::util::replace;
use servo_util::time::{ProfilerChan, profile};
use servo_util::time;
@ -29,70 +31,32 @@ pub struct RenderLayer {
size: Size2D<uint>
}
pub enum Msg<C> {
AttachCompositorMsg(C),
pub enum Msg {
RenderMsg(RenderLayer),
ReRenderMsg(f32),
TokenBestowMsg(~CompositorToken),
TokenProcureMsg,
ExitMsg(Chan<()>),
}
pub struct RenderChan<C> {
chan: SharedChan<Msg<C>>,
#[deriving(Clone)]
pub struct RenderChan {
chan: SharedChan<Msg>,
}
impl<C: RenderListener + Owned> Clone for RenderChan<C> {
pub fn clone(&self) -> RenderChan<C> {
RenderChan {
chan: self.chan.clone(),
}
}
}
impl<C: RenderListener + Owned> RenderChan<C> {
pub fn new(chan: Chan<Msg<C>>) -> RenderChan<C> {
impl RenderChan {
pub fn new(chan: Chan<Msg>) -> RenderChan {
RenderChan {
chan: SharedChan::new(chan),
}
}
pub fn send(&self, msg: Msg<C>) {
pub fn send(&self, msg: Msg) {
self.chan.send(msg);
}
}
pub fn create_render_task<C: RenderListener + Owned>(port: Port<Msg<C>>,
compositor: C,
opts: Opts,
profiler_chan: ProfilerChan) {
let compositor_cell = Cell::new(compositor);
let opts_cell = Cell::new(opts);
let port = Cell::new(port);
do spawn {
let compositor = compositor_cell.take();
let share_gl_context = compositor.get_gl_context();
let opts = opts_cell.with_ref(|o| copy *o);
let profiler_chan = profiler_chan.clone();
let profiler_chan_copy = profiler_chan.clone();
// FIXME: rust/#5967
let mut renderer = Renderer {
port: port.take(),
compositor: compositor,
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,
render_layer: None,
};
renderer.start();
}
}
priv struct Renderer<C> {
port: Port<Msg<C>>,
priv struct RenderTask<C> {
port: Port<Msg>,
compositor: C,
font_ctx: @mut FontContext,
opts: Opts,
@ -104,15 +68,58 @@ priv struct Renderer<C> {
/// The layer to be rendered
render_layer: Option<RenderLayer>,
/// A channel to the engine task for surrendering token
engine_chan: EngineChan,
/// A token that grants permission to send paint messages to compositor
compositor_token: Option<~CompositorToken>,
/// Cached copy of last layers rendered
next_paint_msg: Option<(LayerBufferSet, Size2D<uint>)>,
}
impl<C: RenderListener + Owned> Renderer<C> {
impl<C: RenderListener + Owned> RenderTask<C> {
pub fn create(port: Port<Msg>,
compositor: C,
opts: Opts,
engine_chan: EngineChan,
profiler_chan: ProfilerChan) {
let compositor_cell = Cell::new(compositor);
let opts_cell = Cell::new(opts);
let port = Cell::new(port);
let engine_chan = Cell::new(engine_chan);
do spawn {
let compositor = compositor_cell.take();
let share_gl_context = compositor.get_gl_context();
let opts = opts_cell.with_ref(|o| copy *o);
let profiler_chan = profiler_chan.clone();
let profiler_chan_clone = profiler_chan.clone();
// FIXME: rust/#5967
let mut render_task = RenderTask {
port: port.take(),
compositor: compositor,
font_ctx: @mut FontContext::new(opts.render_backend,
false,
profiler_chan),
opts: opts_cell.take(),
profiler_chan: profiler_chan_clone,
share_gl_context: share_gl_context,
render_layer: None,
engine_chan: engine_chan.take(),
compositor_token: None,
next_paint_msg: None,
};
render_task.start();
}
}
fn start(&mut self) {
debug!("renderer: beginning rendering loop");
debug!("render_task: beginning rendering loop");
loop {
match self.port.recv() {
AttachCompositorMsg(compositor) => self.compositor = compositor,
RenderMsg(render_layer) => {
self.render_layer = Some(render_layer);
self.render(1.0);
@ -120,6 +127,21 @@ impl<C: RenderListener + Owned> Renderer<C> {
ReRenderMsg(scale) => {
self.render(scale);
}
TokenBestowMsg(token) => {
self.compositor_token = Some(token);
let next_paint_msg = replace(&mut self.next_paint_msg, None);
match next_paint_msg {
Some((layer_buffer_set, layer_size)) => {
println("retrieving cached paint msg");
self.compositor.paint(layer_buffer_set, layer_size);
self.compositor.set_render_state(IdleRenderState);
}
None => {}
}
}
TokenProcureMsg => {
self.engine_chan.send(TokenSurrenderMsg(self.compositor_token.swap_unwrap()));
}
ExitMsg(response_ch) => {
response_ch.send(());
break;
@ -129,7 +151,7 @@ impl<C: RenderListener + Owned> Renderer<C> {
}
fn render(&mut self, scale: f32) {
debug!("renderer: rendering");
debug!("render_task: rendering");
let render_layer;
match (self.render_layer) {
@ -164,7 +186,8 @@ impl<C: RenderListener + Owned> Renderer<C> {
let buffer = LayerBuffer {
draw_target: DrawTarget::new_with_fbo(self.opts.render_backend,
self.share_gl_context,
Size2D(width as i32, height as i32),
Size2D(width as i32,
height as i32),
B8G8R8A8),
rect: tile_rect,
screen_pos: screen_rect,
@ -210,8 +233,14 @@ impl<C: RenderListener + Owned> Renderer<C> {
buffers: new_buffers,
};
debug!("renderer: returning surface");
self.compositor.paint(layer_buffer_set, render_layer.size);
debug!("render_task: returning surface");
if self.compositor_token.is_some() {
self.compositor.paint(layer_buffer_set, render_layer.size);
}
else {
println("caching paint msg");
self.next_paint_msg = Some((layer_buffer_set, render_layer.size));
}
self.compositor.set_render_state(IdleRenderState);
}
}