mirror of
https://github.com/servo/servo.git
synced 2025-06-19 14:48:59 +01:00
add pipeline.rs, modularized pipelines communicating with constellation
This commit is contained in:
parent
fdb0d820a4
commit
fba7ec423c
19 changed files with 528 additions and 317 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue