mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
auto merge of #590 : metajack/servo/png-output, r=metajack,me
This enables the `-o FILE` command line option to render the window contents to a PNG after rendering and exit Servo.
This commit is contained in:
commit
21fa57c93e
10 changed files with 64 additions and 16 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -103,3 +103,6 @@
|
||||||
[submodule "src/support/css/rust-cssparser"]
|
[submodule "src/support/css/rust-cssparser"]
|
||||||
path = src/support/css/rust-cssparser
|
path = src/support/css/rust-cssparser
|
||||||
url = https://github.com/mozilla-servo/rust-cssparser.git
|
url = https://github.com/mozilla-servo/rust-cssparser.git
|
||||||
|
[submodule "src/support/png/rust-png"]
|
||||||
|
path = src/support/png/rust-png
|
||||||
|
url = https://github.com/mozilla-servo/rust-png.git
|
||||||
|
|
|
@ -9,8 +9,7 @@ On OS X (homebrew):
|
||||||
|
|
||||||
``` sh
|
``` sh
|
||||||
brew install https://raw.github.com/Homebrew/homebrew-versions/master/autoconf213.rb
|
brew install https://raw.github.com/Homebrew/homebrew-versions/master/autoconf213.rb
|
||||||
brew install automake libtool
|
brew install automake libtool pkg-config libpng
|
||||||
brew install pkg-config
|
|
||||||
```
|
```
|
||||||
|
|
||||||
On OS X (MacPorts):
|
On OS X (MacPorts):
|
||||||
|
@ -24,7 +23,7 @@ On Debian-based Linuxes:
|
||||||
``` sh
|
``` sh
|
||||||
sudo apt-get install autoconf2.13 curl freeglut3-dev libtool \
|
sudo apt-get install autoconf2.13 curl freeglut3-dev libtool \
|
||||||
libfreetype6-dev libfontconfig1-dev libgl1-mesa-dri libglib2.0-dev \
|
libfreetype6-dev libfontconfig1-dev libgl1-mesa-dri libglib2.0-dev \
|
||||||
xorg-dev
|
xorg-dev libpng-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
Servo builds its own copy of Rust, so there is no need to provide a Rust
|
Servo builds its own copy of Rust, so there is no need to provide a Rust
|
||||||
|
@ -59,6 +58,7 @@ make && make check
|
||||||
- `Ctrl-=` zooms in
|
- `Ctrl-=` zooms in
|
||||||
- `Backspace` goes backwards in the history
|
- `Backspace` goes backwards in the history
|
||||||
- `Shift-Backspace` goes forwards in the history
|
- `Shift-Backspace` goes forwards in the history
|
||||||
|
- `Esc` exits servo
|
||||||
|
|
||||||
## Developing
|
## Developing
|
||||||
|
|
||||||
|
|
1
configure
vendored
1
configure
vendored
|
@ -422,6 +422,7 @@ CFG_SUBMODULES="\
|
||||||
support/spidermonkey/mozjs \
|
support/spidermonkey/mozjs \
|
||||||
support/spidermonkey/rust-mozjs \
|
support/spidermonkey/rust-mozjs \
|
||||||
support/stb-image/rust-stb-image \
|
support/stb-image/rust-stb-image \
|
||||||
|
support/png/rust-png \
|
||||||
support/wapcaplet/libwapcaplet \
|
support/wapcaplet/libwapcaplet \
|
||||||
support/wapcaplet/rust-wapcaplet"
|
support/wapcaplet/rust-wapcaplet"
|
||||||
|
|
||||||
|
|
11
mk/check.mk
11
mk/check.mk
|
@ -1,5 +1,6 @@
|
||||||
define DEF_SUBMODULE_TEST_RULES
|
define DEF_SUBMODULE_TEST_RULES
|
||||||
# check target
|
# check target
|
||||||
|
.PHONY: check-$(1)
|
||||||
check-$(1) : $$(DONE_$(1))
|
check-$(1) : $$(DONE_$(1))
|
||||||
@$$(call E, make check: $(1))
|
@$$(call E, make check: $(1))
|
||||||
|
|
||||||
|
@ -31,20 +32,28 @@ DEPS_CHECK_TESTABLE = $(filter-out $(NO_TESTS),$(DEPS_CHECK_ALL))
|
||||||
DEPS_CHECK_TARGETS_ALL = $(addprefix check-,$(DEPS_CHECK_TESTABLE))
|
DEPS_CHECK_TARGETS_ALL = $(addprefix check-,$(DEPS_CHECK_TESTABLE))
|
||||||
DEPS_CHECK_TARGETS_FAST = $(addprefix check-,$(filter-out $(SLOW_TESTS),$(DEPS_CHECK_TESTABLE)))
|
DEPS_CHECK_TARGETS_FAST = $(addprefix check-,$(filter-out $(SLOW_TESTS),$(DEPS_CHECK_TESTABLE)))
|
||||||
|
|
||||||
.PHONY: check $(DEPS_CHECK_TARGETS_ALL)
|
.PHONY: check-test
|
||||||
|
check-test:
|
||||||
|
echo $(DEPS_CHECK_TARGETS_ALL)
|
||||||
|
|
||||||
|
.PHONY: check
|
||||||
check: $(DEPS_CHECK_TARGETS_FAST) check-servo tidy
|
check: $(DEPS_CHECK_TARGETS_FAST) check-servo tidy
|
||||||
|
|
||||||
|
.PHONY: check-all
|
||||||
check-all: $(DEPS_CHECK_TARGETS_ALL) check-servo tidy
|
check-all: $(DEPS_CHECK_TARGETS_ALL) check-servo tidy
|
||||||
|
|
||||||
|
.PHONY: check-servo
|
||||||
check-servo: servo-test
|
check-servo: servo-test
|
||||||
./servo-test $(TESTNAME)
|
./servo-test $(TESTNAME)
|
||||||
|
|
||||||
|
.PHONY: check-ref
|
||||||
check-ref: reftest
|
check-ref: reftest
|
||||||
./reftest --source-dir=$(S)/src/test/html/ref --work-dir=src/test/html/ref $(TESTNAME)
|
./reftest --source-dir=$(S)/src/test/html/ref --work-dir=src/test/html/ref $(TESTNAME)
|
||||||
|
|
||||||
|
.PHONY: check-content
|
||||||
check-content: contenttest
|
check-content: contenttest
|
||||||
./contenttest --source-dir=$(S)/src/test/html/content $(TESTNAME)
|
./contenttest --source-dir=$(S)/src/test/html/content $(TESTNAME)
|
||||||
|
|
||||||
|
.PHONY: tidy
|
||||||
tidy:
|
tidy:
|
||||||
python $(S)src/etc/tidy.py $(S)src
|
python $(S)src/etc/tidy.py $(S)src
|
||||||
|
|
|
@ -20,6 +20,7 @@ pub struct Opts {
|
||||||
tile_size: uint,
|
tile_size: uint,
|
||||||
profiler_period: Option<float>,
|
profiler_period: Option<float>,
|
||||||
exit_after_load: bool,
|
exit_after_load: bool,
|
||||||
|
output_file: Option<~str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_implicitly_copyable_typarams)]
|
#[allow(non_implicitly_copyable_typarams)]
|
||||||
|
@ -48,10 +49,6 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
|
||||||
copy opt_match.free
|
copy opt_match.free
|
||||||
};
|
};
|
||||||
|
|
||||||
if getopts::opt_present(&opt_match, "o") {
|
|
||||||
fail!(~"servo cannot treat 'o' option now.")
|
|
||||||
}
|
|
||||||
|
|
||||||
let render_backend = match getopts::opt_maybe_str(&opt_match, "r") {
|
let render_backend = match getopts::opt_maybe_str(&opt_match, "r") {
|
||||||
Some(backend_str) => {
|
Some(backend_str) => {
|
||||||
if backend_str == ~"direct2d" {
|
if backend_str == ~"direct2d" {
|
||||||
|
@ -90,6 +87,8 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
|
||||||
|
|
||||||
let exit_after_load = getopts::opt_present(&opt_match, "x");
|
let exit_after_load = getopts::opt_present(&opt_match, "x");
|
||||||
|
|
||||||
|
let output_file = getopts::opt_maybe_str(&opt_match, "o");
|
||||||
|
|
||||||
Opts {
|
Opts {
|
||||||
urls: urls,
|
urls: urls,
|
||||||
render_backend: render_backend,
|
render_backend: render_backend,
|
||||||
|
@ -97,5 +96,6 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
|
||||||
tile_size: tile_size,
|
tile_size: tile_size,
|
||||||
profiler_period: profiler_period,
|
profiler_period: profiler_period,
|
||||||
exit_after_load: exit_after_load,
|
exit_after_load: exit_after_load,
|
||||||
|
output_file: output_file,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ use std::comm;
|
||||||
use std::comm::{Chan, SharedChan, Port};
|
use std::comm::{Chan, SharedChan, Port};
|
||||||
use std::num::Orderable;
|
use std::num::Orderable;
|
||||||
use std::task;
|
use std::task;
|
||||||
|
use std::uint;
|
||||||
|
use std::vec;
|
||||||
use extra::uv_global_loop;
|
use extra::uv_global_loop;
|
||||||
use extra::timer;
|
use extra::timer;
|
||||||
use geom::matrix::identity;
|
use geom::matrix::identity;
|
||||||
|
@ -35,6 +37,8 @@ use layers::layers::{ImageData, WithDataFn};
|
||||||
use layers::layers::{TextureLayerKind, TextureLayer, TextureManager};
|
use layers::layers::{TextureLayerKind, TextureLayer, TextureManager};
|
||||||
use layers::rendergl;
|
use layers::rendergl;
|
||||||
use layers::scene::Scene;
|
use layers::scene::Scene;
|
||||||
|
use opengles::gl2;
|
||||||
|
use png;
|
||||||
use servo_util::{time, url};
|
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;
|
||||||
|
@ -464,6 +468,8 @@ impl CompositorTask {
|
||||||
};
|
};
|
||||||
|
|
||||||
let profiler_chan = self.profiler_chan.clone();
|
let profiler_chan = self.profiler_chan.clone();
|
||||||
|
let write_png = self.opts.output_file.is_some();
|
||||||
|
let exit = self.opts.exit_after_load;
|
||||||
let composite = || {
|
let composite = || {
|
||||||
do profile(time::CompositingCategory, profiler_chan.clone()) {
|
do profile(time::CompositingCategory, profiler_chan.clone()) {
|
||||||
debug!("compositor: compositing");
|
debug!("compositor: compositing");
|
||||||
|
@ -474,7 +480,40 @@ impl CompositorTask {
|
||||||
rendergl::render_scene(context, scene);
|
rendergl::render_scene(context, scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render to PNG. We must read from the back buffer (ie, before
|
||||||
|
// window.present()) as OpenGL ES 2 does not have glReadBuffer().
|
||||||
|
if write_png {
|
||||||
|
let (width, height) = (window_size.width as uint, window_size.height as uint);
|
||||||
|
let path = Path(*self.opts.output_file.get_ref());
|
||||||
|
let mut pixels = gl2::read_pixels(0, 0,
|
||||||
|
width as gl2::GLsizei,
|
||||||
|
height as gl2::GLsizei,
|
||||||
|
gl2::RGB, gl2::UNSIGNED_BYTE);
|
||||||
|
// flip image vertically (texture is upside down)
|
||||||
|
let orig_pixels = pixels.clone();
|
||||||
|
let stride = width * 3;
|
||||||
|
for uint::range(0, height) |y| {
|
||||||
|
let dst_start = y * stride;
|
||||||
|
let src_start = (height - y - 1) * stride;
|
||||||
|
vec::bytes::copy_memory(pixels.mut_slice(dst_start, dst_start + stride),
|
||||||
|
orig_pixels.slice(src_start, src_start + stride),
|
||||||
|
stride);
|
||||||
|
}
|
||||||
|
let img = png::Image {
|
||||||
|
width: width as u32,
|
||||||
|
height: height as u32,
|
||||||
|
color_type: png::RGB8,
|
||||||
|
pixels: pixels,
|
||||||
|
};
|
||||||
|
let res = png::store_png(&img, &path);
|
||||||
|
assert!(res.is_ok());
|
||||||
|
|
||||||
|
*done = true;
|
||||||
|
}
|
||||||
|
|
||||||
window.present();
|
window.present();
|
||||||
|
|
||||||
|
if exit { *done = true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// When the user scrolls, move the layer around.
|
// When the user scrolls, move the layer around.
|
||||||
|
@ -548,12 +587,6 @@ impl CompositorTask {
|
||||||
*recomposite = true;
|
*recomposite = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.opts.exit_after_load {
|
|
||||||
do window.set_finished_callback || {
|
|
||||||
*done = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enter the main event loop.
|
// Enter the main event loop.
|
||||||
while !*done {
|
while !*done {
|
||||||
// Check for new messages coming from the rendering task.
|
// Check for new messages coming from the rendering task.
|
||||||
|
|
|
@ -21,6 +21,7 @@ extern mod js;
|
||||||
extern mod layers;
|
extern mod layers;
|
||||||
extern mod newcss (name = "css");
|
extern mod newcss (name = "css");
|
||||||
extern mod opengles;
|
extern mod opengles;
|
||||||
|
extern mod png;
|
||||||
extern mod script;
|
extern mod script;
|
||||||
extern mod servo_net (name = "net");
|
extern mod servo_net (name = "net");
|
||||||
extern mod servo_msg (name = "msg");
|
extern mod servo_msg (name = "msg");
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit ae7c99be106e5767b0384f16887579d55e222e71
|
Subproject commit c6774cb3ebdb20b1736fa3e8b5e8348fefbc987f
|
|
@ -1 +1 @@
|
||||||
Subproject commit 17bd4bbc04942e7de9eae76c0f8a76dfcb3dc9fc
|
Subproject commit b5cb5593f4938a578eebda56c905bbaff33efe66
|
1
src/support/png/rust-png
Submodule
1
src/support/png/rust-png
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 1d24ffad5caed4c2b28240f78f3e036558a97912
|
Loading…
Add table
Add a link
Reference in a new issue