aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md1
-rw-r--r--src/components/gfx/opts.rs4
-rw-r--r--src/components/gfx/render_task.rs7
-rw-r--r--src/components/main/compositing/mod.rs8
-rw-r--r--src/components/main/compositing/run_headless.rs41
5 files changed, 60 insertions, 1 deletions
diff --git a/README.md b/README.md
index 366835a217d..24dea8ca179 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/src/components/gfx/opts.rs b/src/components/gfx/opts.rs
index c2accbf0054..862d22e2138 100644
--- a/src/components/gfx/opts.rs
+++ b/src/components/gfx/opts.rs
@@ -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,
}
}
diff --git a/src/components/gfx/render_task.rs b/src/components/gfx/render_task.rs
index 26ac7186fda..5cb8742d8b5 100644
--- a/src/components/gfx/render_task.rs
+++ b/src/components/gfx/render_task.rs
@@ -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) => {
diff --git a/src/components/main/compositing/mod.rs b/src/components/main/compositing/mod.rs
index 1575e60f975..ea1225e6798 100644
--- a/src/components/main/compositing/mod.rs
+++ b/src/components/main/compositing/mod.rs
@@ -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);
+ }
}
}
diff --git a/src/components/main/compositing/run_headless.rs b/src/components/main/compositing/run_headless.rs
new file mode 100644
index 00000000000..477c6d22891
--- /dev/null
+++ b/src/components/main/compositing/run_headless.rs
@@ -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(())
+}