Add a headless null compositor

We also have to disable rendering in headless mode because it uses OpenGL calls
for now.

Fixes #471.
This commit is contained in:
Keegan McAllister 2013-10-18 16:16:48 -07:00
parent ecc3db7b1f
commit 1b785f150c
5 changed files with 60 additions and 1 deletions

View file

@ -72,6 +72,7 @@ make
- `-p INTERVAL` turns on the profiler and dumps info to the console every
`INTERVAL` seconds
- `-s SIZE` sets the tile size for rendering; defaults to 512
- `-z` disables all graphical output; useful for running JS / layout tests
### Keyboard Shortcuts

View file

@ -19,6 +19,7 @@ pub struct Opts {
profiler_period: Option<f64>,
exit_after_load: bool,
output_file: Option<~str>,
headless: bool,
}
pub fn from_cmdline_args(args: &[~str]) -> Opts {
@ -33,6 +34,7 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
getopts::optopt("t"), // threads to render with
getopts::optflagopt("p"), // profiler flag and output interval
getopts::optflag("x"), // exit after load flag
getopts::optflag("z"), // headless mode
];
let opt_match = match getopts::getopts(args, opts) {
@ -81,6 +83,7 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
};
let exit_after_load = opt_match.opt_present("x");
let headless = opt_match.opt_present("z");
let output_file = opt_match.opt_str("o");
@ -92,5 +95,6 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
profiler_period: profiler_period,
exit_after_load: exit_after_load,
output_file: output_file,
headless: headless,
}
}

View file

@ -204,6 +204,13 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
}
fn render(&mut self, tiles: ~[BufferRequest], scale: f32) {
// In headless mode, disable the renderer, because it makes OpenGL
// calls. Once we have CPU rendering we should render in CPU mode and
// just disable texture upload.
if self.opts.headless {
return;
}
let render_layer;
match self.render_layer {
Some(ref r_layer) => {

View file

@ -22,7 +22,9 @@ use constellation::SendableFrameTree;
mod quadtree;
mod compositor_layer;
mod run;
mod run_headless;
/// The implementation of the layers-based compositor.
@ -159,6 +161,10 @@ impl CompositorTask {
}
pub fn run(&self) {
run::run_compositor(self);
if self.opts.headless {
run_headless::run_compositor(self);
} else {
run::run_compositor(self);
}
}
}

View file

@ -0,0 +1,41 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use geom::size::Size2D;
use std::ptr;
use compositing::*;
/// Starts the compositor, which listens for messages on the specified port.
///
/// This is the null compositor which doesn't draw anything to the screen.
/// It's intended for headless testing.
pub fn run_compositor(compositor: &CompositorTask) {
loop {
match compositor.port.recv() {
Exit => break,
GetSize(chan) => {
chan.send(Size2D(500, 500));
}
GetGLContext(chan) => {
chan.send(ptr::null());
}
SetIds(_, response_chan, _) => {
response_chan.send(());
}
// Explicitly list ignored messages so that when we add a new one,
// we'll notice and think about whether it needs a response, like
// SetIds.
NewLayer(*) | SetLayerPageSize(*) | SetLayerClipRect(*) | DeleteLayer(*) |
Paint(*) | InvalidateRect(*) | ChangeReadyState(*) | ChangeRenderState(*)
=> ()
}
}
compositor.shutdown_chan.send(())
}