diff options
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | src/components/gfx/opts.rs | 4 | ||||
-rw-r--r-- | src/components/gfx/render_task.rs | 7 | ||||
-rw-r--r-- | src/components/main/compositing/mod.rs | 8 | ||||
-rw-r--r-- | src/components/main/compositing/run_headless.rs | 41 |
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(()) +} |