Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Several fixes #492

Closed
wants to merge 20 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Next

Reduce the number of messages needed to exchange buffers from 3 to 2

  • Loading branch information
pcwalton committed May 28, 2013
commit 729a5ff44131c8655afb3c35f8f75abf32cf51cf
@@ -24,7 +24,6 @@ pub struct LayerBufferSet {
/// The interface used to by the renderer to acquire draw targets for each rendered frame and
/// submit them to be drawn to the display.
pub trait Compositor {
fn begin_drawing(&self, next_dt: comm::Chan<LayerBufferSet>);
fn draw(&self, next_dt: comm::Chan<LayerBufferSet>, draw_me: LayerBufferSet);
fn paint(&self, layer_buffer_set: LayerBufferSet);
}

@@ -134,6 +134,8 @@ pub fn render_layers(layer_ref: *RenderLayer,
}
}

return LayerBufferSet { buffers: new_buffers };
LayerBufferSet {
buffers: new_buffers,
}
}

@@ -5,75 +5,78 @@
// The task that handles all rendering/painting.

use azure::AzFloat;
use compositor::{Compositor, LayerBufferSet};
use compositor::Compositor;
use font_context::FontContext;
use geom::matrix2d::Matrix2D;
use opts::Opts;
use render_context::RenderContext;
use render_layers::{RenderLayer, render_layers};

use core::cell::Cell;
use core::comm::{Port, SharedChan};
use core::comm::{Chan, Port, SharedChan};
use core::task::SingleThreaded;
use std::task_pool::TaskPool;
use servo_net::util::spawn_listener;

use servo_util::time;
use servo_util::time::time;
use servo_util::time::profile;
use servo_util::time::ProfilerChan;
use servo_util::time::profile;
use servo_util::time::time;
use servo_util::time;

pub enum Msg {
RenderMsg(RenderLayer),
ExitMsg(comm::Chan<()>)
ExitMsg(Chan<()>),
}

pub type RenderTask = SharedChan<Msg>;

pub fn RenderTask<C:Compositor + Owned>(compositor: C,
opts: Opts,
prof_chan: ProfilerChan) -> RenderTask {
let compositor_cell = Cell(compositor);
let opts_cell = Cell(opts);
let render_task = do spawn_listener |po: Port<Msg>| {
let (layer_buffer_set_port, layer_buffer_channel) = comm::stream();

let compositor = compositor_cell.take();
compositor.begin_drawing(layer_buffer_channel);

// FIXME: Annoying three-cell dance here. We need one-shot closures.
let opts = opts_cell.with_ref(|o| copy *o);
let n_threads = opts.n_render_threads;
let new_opts_cell = Cell(opts);
let prof_chan2 = prof_chan.clone();

let thread_pool = do TaskPool::new(n_threads, Some(SingleThreaded)) {
let opts_cell = Cell(new_opts_cell.with_ref(|o| copy *o));
let prof_chan = prof_chan2.clone();
let f: ~fn(uint) -> ThreadRenderContext = |thread_index| {
ThreadRenderContext {
thread_index: thread_index,
font_ctx: @mut FontContext::new(opts_cell.with_ref(|o| o.render_backend),
false,
prof_chan.clone()),
opts: opts_cell.with_ref(|o| copy *o),
}
#[deriving(Clone)]
pub struct RenderTask {
channel: SharedChan<Msg>,
}

impl RenderTask {
pub fn new<C:Compositor + Owned>(compositor: C, opts: Opts) -> RenderTask {
let compositor_cell = Cell(compositor);
let opts_cell = Cell(opts);
let (port, chan) = comm::stream();
let port = Cell(port);

do spawn {
let compositor = compositor_cell.take();

// FIXME: Annoying three-cell dance here. We need one-shot closures.
let opts = opts_cell.with_ref(|o| copy *o);
let n_threads = opts.n_render_threads;
let new_opts_cell = Cell(opts);

let thread_pool = do TaskPool::new(n_threads, Some(SingleThreaded)) {
let opts_cell = Cell(new_opts_cell.with_ref(|o| copy *o));
let f: ~fn(uint) -> ThreadRenderContext = |thread_index| {
let opts = opts_cell.with_ref(|opts| copy *opts);

ThreadRenderContext {
thread_index: thread_index,
font_ctx: @mut FontContext::new(opts.render_backend, false),
opts: opts,
}
};
f
};
f
};

// FIXME: rust/#5967
let mut r = Renderer {
port: po,
compositor: compositor,
layer_buffer_set_port: Cell(layer_buffer_set_port),
thread_pool: thread_pool,
opts: opts_cell.take(),
prof_chan: prof_chan.clone()
};
r.start();
};
SharedChan::new(render_task)

// FIXME: rust/#5967
let mut renderer = Renderer {
port: port.take(),
compositor: compositor,
thread_pool: thread_pool,
opts: opts_cell.take()
};

renderer.start();
}

RenderTask {
channel: SharedChan::new(chan),
}
}
}

/// Data that needs to be kept around for each render thread.
@@ -86,7 +89,6 @@ priv struct ThreadRenderContext {
priv struct Renderer<C> {
port: Port<Msg>,
compositor: C,
layer_buffer_set_port: Cell<comm::Port<LayerBufferSet>>,
thread_pool: TaskPool<ThreadRenderContext>,
opts: Opts,
prof_chan: ProfilerChan,
@@ -108,25 +110,9 @@ impl<C: Compositor + Owned> Renderer<C> {
}

fn render(&mut self, render_layer: RenderLayer) {
debug!("renderer: got render request");

let layer_buffer_set_port = self.layer_buffer_set_port.take();

if !layer_buffer_set_port.peek() {
warn!("renderer: waiting on layer buffer");
}

let (new_layer_buffer_set_port, layer_buffer_set_channel) = comm::stream();
self.layer_buffer_set_port.put_back(new_layer_buffer_set_port);

let layer_buffer_set_channel_cell = Cell(layer_buffer_set_channel);

debug!("renderer: rendering");

do profile(time::RenderingCategory, self.prof_chan.clone()) {
let layer_buffer_set_channel = layer_buffer_set_channel_cell.take();

let layer_buffer_set = do render_layers(&render_layer, &self.opts, self.prof_chan.clone())
do time("rendering") {
let layer_buffer_set = do render_layers(&render_layer, &self.opts)
|render_layer_ref, layer_buffer, buffer_chan| {
let layer_buffer_cell = Cell(layer_buffer);
do self.thread_pool.execute |thread_render_context| {
@@ -160,7 +146,8 @@ impl<C: Compositor + Owned> Renderer<C> {
};

debug!("renderer: returning surface");
self.compositor.draw(layer_buffer_set_channel, layer_buffer_set);
self.compositor.paint(layer_buffer_set);
}
}
}

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.