render task no longer copies the layer buffer sets before sending paint messages -- uses an ARC instead

This commit is contained in:
Tim Kuehn 2013-07-03 16:28:26 -07:00
parent 6ba2f8d535
commit dc8e3cbf9b
3 changed files with 30 additions and 23 deletions

View file

@ -25,6 +25,8 @@ use std::uint;
use servo_util::time::{ProfilerChan, profile}; use servo_util::time::{ProfilerChan, profile};
use servo_util::time; use servo_util::time;
use extra::arc;
pub struct RenderLayer { pub struct RenderLayer {
display_list: DisplayList<()>, display_list: DisplayList<()>,
size: Size2D<uint> size: Size2D<uint>
@ -73,7 +75,7 @@ priv struct RenderTask<C> {
/// Permission to send paint messages to the compositor /// Permission to send paint messages to the compositor
paint_permission: bool, paint_permission: bool,
/// Cached copy of last layers rendered /// Cached copy of last layers rendered
last_paint_msg: Option<(LayerBufferSet, Size2D<uint>)>, last_paint_msg: Option<(arc::ARC<LayerBufferSet>, Size2D<uint>)>,
} }
impl<C: RenderListener + Owned> RenderTask<C> { impl<C: RenderListener + Owned> RenderTask<C> {
@ -83,32 +85,33 @@ impl<C: RenderListener + Owned> RenderTask<C> {
opts: Opts, opts: Opts,
constellation_chan: ConstellationChan, constellation_chan: ConstellationChan,
profiler_chan: ProfilerChan) { profiler_chan: ProfilerChan) {
let compositor_cell = Cell::new(compositor); let compositor = Cell::new(compositor);
let opts_cell = Cell::new(opts); let opts = Cell::new(opts);
let port = Cell::new(port); let port = Cell::new(port);
let constellation_chan = Cell::new(constellation_chan); let constellation_chan = Cell::new(constellation_chan);
let profiler_chan = Cell::new(profiler_chan);
do spawn { do spawn {
let compositor = compositor_cell.take(); let compositor = compositor.take();
let share_gl_context = compositor.get_gl_context(); let share_gl_context = compositor.get_gl_context();
let opts = opts_cell.with_ref(|o| copy *o); let opts = opts.take();
let profiler_chan = profiler_chan.clone(); let constellation_chan = constellation_chan.take();
let profiler_chan_clone = profiler_chan.clone(); let profiler_chan = profiler_chan.take();
// FIXME: rust/#5967 // FIXME: rust/#5967
let mut render_task = RenderTask { let mut render_task = RenderTask {
id: id, id: id,
port: port.take(), port: port.take(),
compositor: compositor, compositor: compositor,
font_ctx: @mut FontContext::new(opts.render_backend, font_ctx: @mut FontContext::new(copy opts.render_backend,
false, false,
profiler_chan), profiler_chan.clone()),
opts: opts_cell.take(), opts: opts,
profiler_chan: profiler_chan_clone, profiler_chan: profiler_chan,
share_gl_context: share_gl_context, share_gl_context: share_gl_context,
render_layer: None, render_layer: None,
constellation_chan: constellation_chan.take(), constellation_chan: constellation_chan,
paint_permission: false, paint_permission: false,
last_paint_msg: None, last_paint_msg: None,
}; };
@ -232,6 +235,7 @@ impl<C: RenderListener + Owned> RenderTask<C> {
let layer_buffer_set = LayerBufferSet { let layer_buffer_set = LayerBufferSet {
buffers: new_buffers, buffers: new_buffers,
}; };
let layer_buffer_set = arc::ARC(layer_buffer_set);
debug!("render_task: returning surface"); debug!("render_task: returning surface");
if self.paint_permission { if self.paint_permission {

View file

@ -36,6 +36,7 @@ use servo_util::{time, url};
use servo_util::time::profile; use servo_util::time::profile;
use servo_util::time::ProfilerChan; use servo_util::time::ProfilerChan;
use extra::arc;
pub use windowing; pub use windowing;
/// The implementation of the layers-based compositor. /// The implementation of the layers-based compositor.
@ -47,28 +48,34 @@ pub struct CompositorChan {
/// Implementation of the abstract `ScriptListener` interface. /// Implementation of the abstract `ScriptListener` interface.
impl ScriptListener for CompositorChan { impl ScriptListener for CompositorChan {
fn set_ready_state(&self, ready_state: ReadyState) { fn set_ready_state(&self, ready_state: ReadyState) {
let msg = ChangeReadyState(ready_state); let msg = ChangeReadyState(ready_state);
self.chan.send(msg); self.chan.send(msg);
} }
} }
/// Implementation of the abstract `RenderListener` interface. /// Implementation of the abstract `RenderListener` interface.
impl RenderListener for CompositorChan { impl RenderListener for CompositorChan {
fn get_gl_context(&self) -> AzGLContext { fn get_gl_context(&self) -> AzGLContext {
let (port, chan) = comm::stream(); let (port, chan) = comm::stream();
self.chan.send(GetGLContext(chan)); self.chan.send(GetGLContext(chan));
port.recv() port.recv()
} }
fn paint(&self, id: uint, layer_buffer_set: LayerBufferSet, new_size: Size2D<uint>) {
fn paint(&self, id: uint, layer_buffer_set: arc::ARC<LayerBufferSet>, new_size: Size2D<uint>) {
self.chan.send(Paint(id, layer_buffer_set, new_size)) self.chan.send(Paint(id, layer_buffer_set, new_size))
} }
fn set_render_state(&self, render_state: RenderState) { fn set_render_state(&self, render_state: RenderState) {
self.chan.send(ChangeRenderState(render_state)) self.chan.send(ChangeRenderState(render_state))
} }
} }
impl CompositorChan { impl CompositorChan {
pub fn new(chan: Chan<Msg>) -> CompositorChan { pub fn new(chan: Chan<Msg>) -> CompositorChan {
CompositorChan { CompositorChan {
chan: SharedChan::new(chan), chan: SharedChan::new(chan),
@ -86,7 +93,7 @@ pub enum Msg {
/// Requests the compositors GL context. /// Requests the compositors GL context.
GetGLContext(Chan<AzGLContext>), GetGLContext(Chan<AzGLContext>),
/// Requests that the compositor paint the given layer buffer set for the given page size. /// Requests that the compositor paint the given layer buffer set for the given page size.
Paint(uint, LayerBufferSet, Size2D<uint>), Paint(uint, arc::ARC<LayerBufferSet>, Size2D<uint>),
/// Alerts the compositor to the current status of page loading. /// Alerts the compositor to the current status of page loading.
ChangeReadyState(ReadyState), ChangeReadyState(ReadyState),
/// Alerts the compositor to the current status of rendering. /// Alerts the compositor to the current status of rendering.
@ -277,16 +284,12 @@ impl CompositorTask {
*page_size = Size2D(new_size.width as f32, new_size.height as f32); *page_size = Size2D(new_size.width as f32, new_size.height as f32);
let mut new_layer_buffer_set = new_layer_buffer_set; let new_layer_buffer_set = new_layer_buffer_set.get();
// 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;
// Replace the image layer data with the buffer data. Also compute the page for new_layer_buffer_set.buffers.each |buffer| {
// size here.
let buffers = util::replace(&mut new_layer_buffer_set.buffers, ~[]);
for buffers.each |buffer| {
let width = buffer.rect.size.width as uint; let width = buffer.rect.size.width as uint;
let height = buffer.rect.size.height as uint; let height = buffer.rect.size.height as uint;

View file

@ -6,7 +6,8 @@ use azure::azure_hl::DrawTarget;
use azure::azure::AzGLContext; use azure::azure::AzGLContext;
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
use std::util::NonCopyable;
use extra::arc;
#[deriving(Clone)] #[deriving(Clone)]
pub struct LayerBuffer { pub struct LayerBuffer {
@ -24,7 +25,6 @@ pub struct LayerBuffer {
/// A set of layer buffers. This is an atomic unit used to switch between the front and back /// A set of layer buffers. This is an atomic unit used to switch between the front and back
/// buffers. /// buffers.
#[deriving(Clone)]
pub struct LayerBufferSet { pub struct LayerBufferSet {
buffers: ~[LayerBuffer] buffers: ~[LayerBuffer]
} }
@ -49,7 +49,7 @@ pub enum ReadyState {
/// submit them to be drawn to the display. /// submit them to be drawn to the display.
pub trait RenderListener { pub trait RenderListener {
fn get_gl_context(&self) -> AzGLContext; fn get_gl_context(&self) -> AzGLContext;
fn paint(&self, id: uint, layer_buffer_set: LayerBufferSet, new_size: Size2D<uint>); fn paint(&self, id: uint, layer_buffer_set: arc::ARC<LayerBufferSet>, new_size: Size2D<uint>);
fn set_render_state(&self, render_state: RenderState); fn set_render_state(&self, render_state: RenderState);
} }