From d1070da33827e92e872c5e53575eb09819c4eb02 Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Fri, 20 Jan 2017 10:44:19 -0500 Subject: [PATCH 1/2] Remove replay --- .travis.yml | 1 - appveyor.yml | 2 - replay/Cargo.toml | 19 ----- replay/README.md | 7 -- replay/src/main.rs | 169 --------------------------------------------- 5 files changed, 198 deletions(-) delete mode 100644 replay/Cargo.toml delete mode 100644 replay/README.md delete mode 100644 replay/src/main.rs diff --git a/.travis.yml b/.travis.yml index 153da8d02c..27869a5158 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,6 @@ script: - (cd webrender_traits && cargo test --verbose) - (cd webrender && cargo test --verbose) - (cd sample && cargo test --verbose) - - (cd replay && cargo test --verbose) - (cd wrench && cargo test --verbose) - (cd wrench && cargo build --release --verbose --features headless) - (cd wrench && python run_tests.py res/rect.yaml) diff --git a/appveyor.yml b/appveyor.yml index ff51a4131d..bafa65762e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,7 +17,5 @@ test_script: - cargo test --verbose - cd ../sample - cargo test --verbose - - cd ../replay - - cargo test --verbose - cd ../wrench - cargo test --verbose diff --git a/replay/Cargo.toml b/replay/Cargo.toml deleted file mode 100644 index 34209302bc..0000000000 --- a/replay/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "wr-replay" -version = "0.1.0" -authors = ["lana "] -workspace = ".." - -[dependencies.webrender] -path = "../webrender" - -[dependencies.webrender_traits] -path = "../webrender_traits" -default_features = false - -[dependencies] -bincode = "0.6" -byteorder = "0.5" -euclid = "0.10" -gleam = "0.2" -glutin = "0.6" diff --git a/replay/README.md b/replay/README.md deleted file mode 100644 index 4d49d3d0f4..0000000000 --- a/replay/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# wr-replay -Replay tool for the [WebRender](https://github.com/servo/webrender). - -Usage: - - in the WebRender client (be it [servo]() or [wr-sample]()), enable the recording option: `RendererOptions::enable_recording` when initializing the renderer - - run the client normally for a few frames, the frame dumps will be stored in `record` folder - - run the replay with `cargo run ` diff --git a/replay/src/main.rs b/replay/src/main.rs deleted file mode 100644 index fae756e138..0000000000 --- a/replay/src/main.rs +++ /dev/null @@ -1,169 +0,0 @@ -extern crate bincode; -extern crate byteorder; -extern crate euclid; -extern crate glutin; -extern crate gleam; -extern crate webrender; -extern crate webrender_traits; - -use bincode::serde::deserialize; -use byteorder::{LittleEndian, ReadBytesExt}; -use gleam::gl; -use std::any::TypeId; -use std::mem; -use std::io::Read; -use std::fs::File; -use std::path::{Path, PathBuf}; -use std::env; -use webrender_traits::{ApiMsg, RenderApi, PipelineId, LayerSize, DeviceUintSize, ColorF}; -use webrender_traits::channel::PayloadHelperMethods; -use glutin::{Event, ElementState, VirtualKeyCode as Key}; - - -struct Notifier { - window_proxy: glutin::WindowProxy, -} - -impl Notifier { - fn new(window_proxy: glutin::WindowProxy) -> Notifier { - Notifier { - window_proxy: window_proxy, - } - } -} - -impl webrender_traits::RenderNotifier for Notifier { - fn new_frame_ready(&mut self) { - self.window_proxy.wakeup_event_loop(); - } - - fn pipeline_size_changed(&mut self, - _pid: PipelineId, - _size: Option) { - } - - fn new_scroll_frame_ready(&mut self, _composite_needed: bool) { - } -} - -fn read_file(dir: &Path, frame: i32, api: &RenderApi) -> bool { - let mut filename = PathBuf::from(dir); - filename.push(format!("frame_{}.bin", frame)); - let mut file = match File::open(&filename) { - Ok(file) => file, - Err(_e) => { - //println!("Failed to open `{}`: {:?}", filename, e); - return false - } - }; - - let apimsg_type_id = unsafe { - assert!(mem::size_of::() == mem::size_of::()); - mem::transmute::(TypeId::of::()) - }; - let written_apimsg_type_id = file.read_u64::().unwrap(); - if written_apimsg_type_id != apimsg_type_id { - panic!("Binary file ApiMsg enum type mismatch: expected 0x{:x}, found 0x{:x}", apimsg_type_id, written_apimsg_type_id); - } - - while let Ok(mut len) = file.read_u32::() { - if len > 0 { - let mut buffer = vec![0; len as usize]; - file.read_exact(&mut buffer).unwrap(); - let msg = deserialize(&buffer).unwrap(); - api.api_sender.send(msg).unwrap(); - } else { - len = file.read_u32::().unwrap(); - let mut buffer = vec![0; len as usize]; - file.read_exact(&mut buffer).unwrap(); - api.payload_sender.send_vec(buffer).unwrap(); - } - } - true -} - - -fn main() { - let args: Vec = env::args().collect(); - if args.len() != 2 && args.len() != 3 { - println!("{} [] ", args[0]); - return; - } - - let (resource_path, dir) = if args.len() == 3 { - (Some(PathBuf::from(&args[1])), PathBuf::from(&args[2])) - } else { - (None, PathBuf::from(&args[1])) - }; - - let window = glutin::WindowBuilder::new() - .with_title("WebRender Replay") - .with_gl(glutin::GlRequest::Specific(glutin::Api::OpenGl, (3,2))) - .build() - .unwrap(); - - unsafe { - window.make_current().unwrap(); - gl::load_with(|symbol| window.get_proc_address(symbol) as *const _); - } - - let opts = webrender::RendererOptions { - device_pixel_ratio: window.hidpi_factor(), - resource_override_path: resource_path, - enable_aa: false, - enable_profiler: false, - enable_recording: false, - enable_scrollbars: false, - precache_shaders: false, - renderer_kind: webrender_traits::RendererKind::Native, - debug: false, - enable_subpixel_aa: false, - clear_framebuffer: true, - clear_color: ColorF::new(1.0, 1.0, 1.0, 1.0), - render_target_debug: false, - }; - - let (mut renderer, sender) = webrender::renderer::Renderer::new(opts); - let api = sender.create_api(); - let notifier = Box::new(Notifier::new(window.create_window_proxy())); - renderer.set_render_notifier(notifier); - let (mut width, mut height) = window.get_inner_size().unwrap(); - - //read and send the resources file - let mut frame_num = 0; - read_file(&dir, frame_num, &api); - - for event in window.wait_events() { - match event { - Event::KeyboardInput(ElementState::Pressed, _, Some(Key::Escape)) | - Event::Closed => break, - Event::Resized(w, h) => { - width = w; - height = h; - } - //Event::Refresh | - Event::Awakened => { - println!("Rendering frame {}.", frame_num); - gl::clear(gl::COLOR_BUFFER_BIT); - renderer.update(); - renderer.render(DeviceUintSize::new(width, height)); - window.swap_buffers().unwrap(); - } - Event::KeyboardInput(ElementState::Pressed, _, Some(Key::Right)) =>{ - frame_num += 1; - if !read_file(&dir, frame_num, &api) { - frame_num -= 1; - println!("At last frame."); - } - } - Event::KeyboardInput(ElementState::Pressed, _, Some(Key::Left)) => { - frame_num -= 1; - if frame_num < 0 || !read_file(&dir, frame_num, &api) { - frame_num +=1; - println!("At first frame."); - } - } - _ => () - } - } -} From 1df751bd60813e55f3afe2b1e8d899ee941eda32 Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Fri, 20 Jan 2017 14:30:37 -0500 Subject: [PATCH 2/2] Move binary recordings to a single file --- Cargo.lock | 123 +-------------------------- Cargo.toml | 1 - webrender/Cargo.toml | 2 +- webrender/src/lib.rs | 2 +- webrender/src/record.rs | 88 ++++++++++---------- webrender/src/render_backend.rs | 21 ++--- webrender/src/renderer.rs | 11 +-- webrender_traits/src/types.rs | 29 +++++++ wrench/src/args.yaml | 2 +- wrench/src/binary_frame_reader.rs | 134 +++++++++++++----------------- wrench/src/json_frame_writer.rs | 21 +++-- wrench/src/main.rs | 3 +- wrench/src/wrench.rs | 30 ++++--- wrench/src/yaml_frame_writer.rs | 23 ++--- wrench/src/yaml_helper.rs | 4 +- 15 files changed, 196 insertions(+), 298 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9bb32d5573..f60f8eccff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ "serde 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender 0.11.1", + "webrender 0.12.0", "webrender_traits 0.11.0", "yaml-rust 0.3.4 (git+https://github.com/vvuk/yaml-rust)", ] @@ -393,34 +393,6 @@ name = "glob" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "glutin" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "android_glue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "cocoa 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "core-graphics 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "dwmapi-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "gdi32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", - "objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wayland-client 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)", - "wayland-kbd 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "wayland-window 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "x11-dl 2.11.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "glutin" version = "0.7.2" @@ -519,11 +491,6 @@ name = "khronos_api" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "lazy_static" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "lazy_static" version = "0.2.2" @@ -563,17 +530,6 @@ dependencies = [ "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "memmap" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fs2 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "memmap" version = "0.4.0" @@ -1038,19 +994,6 @@ name = "vec_map" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "wayland-client" -version = "0.5.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "dlib 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", - "wayland-scanner 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", - "wayland-sys 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "wayland-client" version = "0.7.6" @@ -1062,18 +1005,6 @@ dependencies = [ "wayland-sys 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "wayland-kbd" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dlib 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "memmap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "wayland-client 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "wayland-kbd" version = "0.6.2" @@ -1086,14 +1017,6 @@ dependencies = [ "wayland-client 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "wayland-scanner" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "xml-rs 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "wayland-scanner" version = "0.7.6" @@ -1102,15 +1025,6 @@ dependencies = [ "xml-rs 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "wayland-sys" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "dlib 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "wayland-sys" version = "0.7.6" @@ -1120,16 +1034,6 @@ dependencies = [ "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "wayland-window" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wayland-client 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "wayland-window" version = "0.4.3" @@ -1142,7 +1046,7 @@ dependencies = [ [[package]] name = "webrender" -version = "0.11.1" +version = "0.12.0" dependencies = [ "angle 0.1.2 (git+https://github.com/servo/angle?branch=servo)", "app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1221,19 +1125,6 @@ dependencies = [ "x11-dl 2.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "wr-replay" -version = "0.1.0" -dependencies = [ - "bincode 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", - "gleam 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)", - "glutin 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender 0.11.1", - "webrender_traits 0.11.0", -] - [[package]] name = "wr-sample" version = "0.1.0" @@ -1242,7 +1133,7 @@ dependencies = [ "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)", "glutin 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender 0.11.1", + "webrender 0.12.0", "webrender_traits 0.11.0", ] @@ -1328,7 +1219,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1d8edc81c5ae84605a62f5dac661a2313003b26d59839f81d47d46cf0f16a55" "checksum gleam 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)" = "6af023107aa969ccf8868a0304fead4b2f813c19aa9a6a243fddc041f3e51da5" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" -"checksum glutin 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "06786fae66e7aa8464b3d8d3fb7a7c470f89d62ae511f9613ea7fbbeef61d680" "checksum glutin 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f10fe6cb2f7e559e470cc0dfa2c89a4f476fc99ec1862632b057e68c3831eb7a" "checksum heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8c80e194758495a9109566134dc06e42ea0423987d6ceca016edaa90381b3549" "checksum image 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "76df2dce95fef56fd35dbc41c36e37b19aede703c6be7739e8b65d5788ffc728" @@ -1338,14 +1228,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum jpeg-decoder 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "4be50b418a1fc5d198588d9a4f682ef808a55db4084dce39d09bb0562525bb8c" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum khronos_api 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "09c9d3760673c427d46f91a0350f0a84a52e6bc5a84adf26dc610b6c52436630" -"checksum lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "cf186d1a8aa5f5bee5fd662bc9c1b949e0259e1bcc379d1f006847b0080c7417" "checksum lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6abe0ee2e758cd6bc8a2cd56726359007748fbf4128da998b65d0b70f881e19b" "checksum libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "044d1360593a78f5c8e5e710beccdc24ab71d1f01bc19a29bcacdba22e8475d8" "checksum libloading 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "84816a8c6ed8163dfe0dbdd2b09d35c6723270ea77a4c7afa4bedf038a36cb99" "checksum log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ab83497bf8bf4ed2a74259c1c802351fcd67a65baa86394b6ba73c36f4838054" "checksum lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" "checksum malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -"checksum memmap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f20f72ed93291a72e22e8b16bb18762183bb4943f0f483da5b8be1a9e8192752" "checksum memmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "69253224aa10070855ea8fe9dbe94a03fc2b1d7930bb340c9e586a7513716fea" "checksum miniz-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d1f4d337a01c32e1f2122510fed46393d53ca35a7f429cb0450abaedfa3ed54" "checksum num 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "bde7c03b09e7c6a301ee81f6ddf66d7a28ec305699e3d3b056d2fc56470e3120" @@ -1401,15 +1289,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ef4711d107b21b410a3a974b1204d9accc8b10dad75d8324b5d755de1617d47" "checksum uuid 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a9ff57156caf7e22f37baf3c9d8f6ce8194842c23419dafcb0716024514d162" "checksum vec_map 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cac5efe5cb0fa14ec2f84f83c701c562ee63f6dcc680861b21d65c682adfb05f" -"checksum wayland-client 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ced3094c157b5cc0a08d40530e1a627d9f88b9a436971338d2646439128a559e" "checksum wayland-client 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8c3e3edc131b755a1c6ab9873ce27557f5c5f075959597cd201bc00019555c9e" -"checksum wayland-kbd 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "73bc10e84c1da90777beffecd24742baea17564ffc2a9918af41871c748eb050" "checksum wayland-kbd 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7707deadab966d6ea58651f4150add1fc442058a9598c3da11f0ce27c99f440f" -"checksum wayland-scanner 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "5a1869370d6bafcbabae8724511d803f4e209a70e94ad94a4249269534364f66" "checksum wayland-scanner 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c7459efa4b7bab8f34657ce6167ff470871cc7932d75cfc8db7e2ef99f81397b" -"checksum wayland-sys 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9633f7fe5de56544215f82eaf1b76bf1b584becf7f08b58cbef4c2c7d10e803a" "checksum wayland-sys 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "bb879ab3916b7bbacda1258df0bc78eaa12b483f377a73ecc40b9f0b24f15465" -"checksum wayland-window 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "309b69d3a863c9c21422d889fb7d98cf02f8a2ca054960a49243ce5b67ad884c" "checksum wayland-window 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "58f705c7b57886d3e708c02ba9b26924f6db6f869aa108bf621731a7d900799f" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/Cargo.toml b/Cargo.toml index 67f2958cbf..ed5cf190b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,6 @@ members = [ "webrender", "webrender_traits", "sample", - "replay", "wrench", ] diff --git a/webrender/Cargo.toml b/webrender/Cargo.toml index de468d2ca2..a8b1ef66bd 100644 --- a/webrender/Cargo.toml +++ b/webrender/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "webrender" -version = "0.11.1" +version = "0.12.0" authors = ["Glenn Watson "] license = "MPL-2.0" repository = "https://github.com/servo/webrender" diff --git a/webrender/src/lib.rs b/webrender/src/lib.rs index 26a8e392fb..6af1235d82 100644 --- a/webrender/src/lib.rs +++ b/webrender/src/lib.rs @@ -77,7 +77,7 @@ mod shader_source { include!(concat!(env!("OUT_DIR"), "/shaders.rs")); } -pub use record::{ApiRecordingReceiver, set_recording_detour, WEBRENDER_RECORDING_HEADER}; +pub use record::{ApiRecordingReceiver, BinaryRecorder, WEBRENDER_RECORDING_HEADER}; mod platform { #[cfg(target_os="macos")] diff --git a/webrender/src/record.rs b/webrender/src/record.rs index 55baa51c07..c4b69f3638 100644 --- a/webrender/src/record.rs +++ b/webrender/src/record.rs @@ -4,83 +4,79 @@ use bincode::serde::serialize; use bincode; +use std::fmt::Debug; use std::mem; use std::any::TypeId; -use std::fs::{File, OpenOptions}; +use std::fs::File; use std::io::Write; -use std::ops::DerefMut; -use std::sync::Mutex; +use std::path::PathBuf; use webrender_traits::ApiMsg; use byteorder::{LittleEndian, WriteBytesExt}; -lazy_static! { - static ref WEBRENDER_RECORDING_DETOUR: Mutex>> = Mutex::new(None); -} - pub static WEBRENDER_RECORDING_HEADER: u64 = 0xbeefbeefbeefbe01u64; -static mut CURRENT_FRAME_NUMBER: u32 = 0xffffffffu32; -pub trait ApiRecordingReceiver: Send { +pub trait ApiRecordingReceiver: Send + Debug { fn write_msg(&mut self, frame: u32, msg: &ApiMsg); fn write_payload(&mut self, frame: u32, data: &[u8]); } -pub fn set_recording_detour(detour: Option>) { - let mut recorder = WEBRENDER_RECORDING_DETOUR.lock(); - *recorder.as_mut().unwrap().deref_mut() = detour; +#[derive(Debug)] +pub struct BinaryRecorder { + file: File, } -fn write_data(frame: u32, data: &[u8]) { - let filename = format!("record/frame_{}.bin", frame); - let mut file = if unsafe { CURRENT_FRAME_NUMBER != frame } { - unsafe { CURRENT_FRAME_NUMBER = frame; } +impl BinaryRecorder { + pub fn new(dest: &PathBuf) -> BinaryRecorder { + let mut file = File::create(dest).unwrap(); - let mut file = File::create(filename).unwrap(); + // write the header let apimsg_type_id = unsafe { assert!(mem::size_of::() == mem::size_of::()); mem::transmute::(TypeId::of::()) }; - file.write_u64::(WEBRENDER_RECORDING_HEADER).ok(); file.write_u64::(apimsg_type_id).ok(); - file - } else { - OpenOptions::new().append(true).create(false).open(filename).unwrap() - }; - file.write_u32::(data.len() as u32).ok(); - file.write(data).ok(); + + BinaryRecorder { + file: file, + } + } + + fn write_length_and_data(&mut self, data: &[u8]) { + self.file.write_u32::(data.len() as u32).ok(); + self.file.write(data).ok(); + } } -pub fn write_msg(frame: u32, msg: &ApiMsg) { +impl ApiRecordingReceiver for BinaryRecorder { + fn write_msg(&mut self, _: u32, msg: &ApiMsg) { + if should_record_msg(msg) { + let buf = serialize(msg, bincode::SizeLimit::Infinite).unwrap(); + self.write_length_and_data(&buf); + } + } + + fn write_payload(&mut self, _: u32, data: &[u8]) { + // signal payload with a 0 length + self.file.write_u32::(0).ok(); + self.write_length_and_data(data); + } +} + +pub fn should_record_msg(msg: &ApiMsg) -> bool { match msg { &ApiMsg::AddRawFont(..) | &ApiMsg::AddNativeFont(..) | &ApiMsg::AddImage(..) | + &ApiMsg::GenerateFrame | &ApiMsg::UpdateImage(..) | - &ApiMsg::DeleteImage(..)| + &ApiMsg::DeleteImage(..) | &ApiMsg::SetRootDisplayList(..) | &ApiMsg::SetRootPipeline(..) | &ApiMsg::Scroll(..) | &ApiMsg::TickScrollingBounce | - &ApiMsg::WebGLCommand(..) => { - let mut recorder = WEBRENDER_RECORDING_DETOUR.lock(); - if let Some(ref mut recorder) = recorder.as_mut().unwrap().as_mut() { - recorder.write_msg(frame, &msg); - } else { - let buff = serialize(msg, bincode::SizeLimit::Infinite).unwrap(); - write_data(frame, &buff); - } - } - _ => {} - } -} - -pub fn write_payload(frame: u32, data: &[u8]) { - let mut recorder = WEBRENDER_RECORDING_DETOUR.lock(); - if let Some(ref mut recorder) = recorder.as_mut().unwrap().as_mut() { - recorder.write_payload(frame, data); - } else { - write_data(frame, &[]); //signal the payload - write_data(frame, data); + &ApiMsg::WebGLCommand(..) => + true, + _ => false } } diff --git a/webrender/src/render_backend.rs b/webrender/src/render_backend.rs index c67cfb1a8a..709485c3b5 100644 --- a/webrender/src/render_backend.rs +++ b/webrender/src/render_backend.rs @@ -7,11 +7,10 @@ use frame::Frame; use internal_types::{FontTemplate, GLContextHandleWrapper, GLContextWrapper}; use internal_types::{SourceTexture, ResultMsg, RendererFrame}; use profiler::BackendProfileCounters; -use record; +use record::ApiRecordingReceiver; use resource_cache::ResourceCache; use scene::Scene; use std::collections::HashMap; -use std::fs; use std::io::{Cursor, Read}; use std::sync::{Arc, Mutex}; use std::sync::mpsc::Sender; @@ -45,7 +44,7 @@ pub struct RenderBackend { webrender_context_handle: Option, webgl_contexts: HashMap, current_bound_webgl_context_id: Option, - enable_recording: bool, + recorder: Option>, main_thread_dispatcher: Arc>>>, next_webgl_id: usize, @@ -65,7 +64,7 @@ impl RenderBackend { webrender_context_handle: Option, config: FrameBuilderConfig, debug: bool, - enable_recording:bool, + recorder: Option>, main_thread_dispatcher: Arc>>>, vr_compositor_handler: Arc>>>) -> RenderBackend { @@ -86,7 +85,7 @@ impl RenderBackend { webrender_context_handle: webrender_context_handle, webgl_contexts: HashMap::new(), current_bound_webgl_context_id: None, - enable_recording:enable_recording, + recorder: recorder, main_thread_dispatcher: main_thread_dispatcher, next_webgl_id: 0, vr_compositor_handler: vr_compositor_handler @@ -96,16 +95,13 @@ impl RenderBackend { pub fn run(&mut self) { let mut profile_counters = BackendProfileCounters::new(); let mut frame_counter: u32 = 0; - if self.enable_recording { - fs::create_dir("record").ok(); - } loop { let msg = self.api_rx.recv(); match msg { Ok(msg) => { - if self.enable_recording { - record::write_msg(frame_counter, &msg); + if let Some(ref mut r) = self.recorder { + r.write_msg(frame_counter, &msg); } match msg { ApiMsg::AddRawFont(id, bytes) => { @@ -168,8 +164,8 @@ impl RenderBackend { for leftover_auxiliary_data in leftover_auxiliary_data { self.payload_tx.send_vec(leftover_auxiliary_data).unwrap() } - if self.enable_recording { - record::write_payload(frame_counter, &auxiliary_data); + if let Some(ref mut r) = self.recorder { + r.write_payload(frame_counter, &auxiliary_data); } let mut auxiliary_data = Cursor::new(&mut auxiliary_data[4..]); @@ -179,7 +175,6 @@ impl RenderBackend { let built_display_list = BuiltDisplayList::from_data(built_display_list_data, display_list_descriptor); - let mut auxiliary_lists_data = vec![0; auxiliary_lists_descriptor.size()]; auxiliary_data.read_exact(&mut auxiliary_lists_data[..]).unwrap(); diff --git a/webrender/src/renderer.rs b/webrender/src/renderer.rs index 626793baeb..a671c0f1a8 100644 --- a/webrender/src/renderer.rs +++ b/webrender/src/renderer.rs @@ -21,6 +21,7 @@ use internal_types::{ORTHO_NEAR_PLANE, ORTHO_FAR_PLANE, SourceTexture}; use internal_types::{BatchTextures, TextureSampler, GLContextHandleWrapper}; use profiler::{Profiler, BackendProfileCounters}; use profiler::{GpuProfileTag, RendererProfileTimers, RendererProfileCounters}; +use record::ApiRecordingReceiver; use render_backend::RenderBackend; use std::cmp; use std::collections::HashMap; @@ -647,7 +648,7 @@ impl Renderer { let (device_pixel_ratio, enable_aa) = (options.device_pixel_ratio, options.enable_aa); let render_target_debug = options.render_target_debug; let payload_tx_for_backend = payload_tx.clone(); - let enable_recording = options.enable_recording; + let recorder = options.recorder; thread::Builder::new().name("RenderBackend".to_string()).spawn(move || { let mut backend = RenderBackend::new(api_rx, payload_rx, @@ -660,7 +661,7 @@ impl Renderer { context_handle, config, debug, - enable_recording, + recorder, backend_main_thread_dispatcher, backend_vr_compositor); backend.run(); @@ -1545,14 +1546,13 @@ pub trait ExternalImageHandler { fn release(&mut self, key: ExternalImageId); } -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct RendererOptions { pub device_pixel_ratio: f32, pub resource_override_path: Option, pub enable_aa: bool, pub enable_profiler: bool, pub debug: bool, - pub enable_recording: bool, pub enable_scrollbars: bool, pub precache_shaders: bool, pub renderer_kind: RendererKind, @@ -1560,6 +1560,7 @@ pub struct RendererOptions { pub clear_framebuffer: bool, pub clear_color: ColorF, pub render_target_debug: bool, + pub recorder: Option>, } impl Default for RendererOptions { @@ -1570,7 +1571,6 @@ impl Default for RendererOptions { enable_aa: true, enable_profiler: false, debug: false, - enable_recording: false, enable_scrollbars: false, precache_shaders: false, renderer_kind: RendererKind::Native, @@ -1578,6 +1578,7 @@ impl Default for RendererOptions { clear_framebuffer: true, clear_color: ColorF::new(1.0, 1.0, 1.0, 1.0), render_target_debug: false, + recorder: None, } } } diff --git a/webrender_traits/src/types.rs b/webrender_traits/src/types.rs index d65f016490..540dfca109 100644 --- a/webrender_traits/src/types.rs +++ b/webrender_traits/src/types.rs @@ -10,6 +10,7 @@ use channel::{PayloadSender, MsgSender}; #[cfg(feature = "nightly")] use core::nonzero::NonZero; use offscreen_gl_context::{GLContextAttributes, GLLimits}; +use std::fmt; use std::sync::Arc; #[cfg(target_os = "macos")] use core_graphics::font::CGFont; @@ -962,3 +963,31 @@ pub enum VRCompositorCommand { pub trait VRCompositorHandler: Send { fn handle(&mut self, command: VRCompositorCommand, texture_id: Option); } + +impl fmt::Debug for ApiMsg { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + &ApiMsg::AddRawFont(..) => { write!(f, "ApiMsg::AddRawFont") } + &ApiMsg::AddNativeFont(..) => { write!(f, "ApiMsg::AddNativeFont") } + &ApiMsg::GetGlyphDimensions(..) => { write!(f, "ApiMsg::GetGlyphDimensions") } + &ApiMsg::AddImage(..) => { write!(f, "ApiMsg::AddImage") } + &ApiMsg::UpdateImage(..) => { write!(f, "ApiMsg::UpdateImage") } + &ApiMsg::DeleteImage(..) => { write!(f, "ApiMsg::DeleteImage") } + &ApiMsg::CloneApi(..) => { write!(f, "ApiMsg::CloneApi") } + &ApiMsg::SetRootDisplayList(..) => { write!(f, "ApiMsg::SetRootDisplayList") } + &ApiMsg::SetRootPipeline(..) => { write!(f, "ApiMsg::SetRootPipeline") } + &ApiMsg::Scroll(..) => { write!(f, "ApiMsg::Scroll") } + &ApiMsg::ScrollLayersWithScrollId(..) => { write!(f, "ApiMsg::ScrollLayersWithScrollId") } + &ApiMsg::TickScrollingBounce => { write!(f, "ApiMsg::TickScrollingBounce") } + &ApiMsg::TranslatePointToLayerSpace(..) => { write!(f, "ApiMsg::TranslatePointToLayerSpace") } + &ApiMsg::GetScrollLayerState(..) => { write!(f, "ApiMsg::GetScrollLayerState") } + &ApiMsg::RequestWebGLContext(..) => { write!(f, "ApiMsg::RequestWebGLContext") } + &ApiMsg::ResizeWebGLContext(..) => { write!(f, "ApiMsg::ResizeWebGLContext") } + &ApiMsg::WebGLCommand(..) => { write!(f, "ApiMsg::WebGLCommand") } + &ApiMsg::GenerateFrame => { write!(f, "ApiMsg::GenerateFrame") } + &ApiMsg::VRCompositorCommand(..) => { write!(f, "ApiMsg::VRCompositorCommand") } + &ApiMsg::ExternalEvent(..) => { write!(f, "ApiMsg::ExternalEvent") } + &ApiMsg::ShutDown => { write!(f, "ApiMsg::ShutDown") } + } + } +} diff --git a/wrench/src/args.yaml b/wrench/src/args.yaml index 17a4fa7397..5669ca5b45 100644 --- a/wrench/src/args.yaml +++ b/wrench/src/args.yaml @@ -22,7 +22,7 @@ args: help: Rebuild display list from scratch every frame - save: long: save - help: 'Save frames, either "yaml" or "json"' + help: 'Save frames, one of: yaml, json, or binary' takes_value: true - subpixel_aa: short: a diff --git a/wrench/src/binary_frame_reader.rs b/wrench/src/binary_frame_reader.rs index 181a12cf5e..c092a202ab 100644 --- a/wrench/src/binary_frame_reader.rs +++ b/wrench/src/binary_frame_reader.rs @@ -22,8 +22,9 @@ enum Item { } pub struct BinaryFrameReader { - file_base: PathBuf, - is_dir: bool, + file: File, + eof: bool, + frame_offsets: Vec, skip_uploads: bool, replay_api: bool, @@ -31,16 +32,31 @@ pub struct BinaryFrameReader { frame_data: Vec, frame_num: u32, - frame_built: bool, - - check_apimsg: Option, + frame_read: bool, } impl BinaryFrameReader { pub fn new(file_path: &Path) -> BinaryFrameReader { + let mut file = File::open(&file_path).expect("Can't open recording file"); + let header = file.read_u64::().unwrap(); + if header != WEBRENDER_RECORDING_HEADER { + panic!("Binary recording is missing recording header!"); + } + + let apimsg_type_id = unsafe { + assert!(mem::size_of::() == mem::size_of::()); + mem::transmute::(TypeId::of::()) + }; + + let written_apimsg_type_id = file.read_u64::().unwrap(); + if written_apimsg_type_id != apimsg_type_id { + println!("Warning: binary file ApiMsg enum type mismatch: expected 0x{:x}, found 0x{:x}", apimsg_type_id, written_apimsg_type_id); + } + BinaryFrameReader { - file_base: file_path.to_owned(), - is_dir: file_path.is_dir(), + file: file, + eof: false, + frame_offsets: vec![], skip_uploads: false, replay_api: false, @@ -48,9 +64,7 @@ impl BinaryFrameReader { frame_data: vec![], frame_num: 0, - frame_built: false, - - check_apimsg: None, + frame_read: false, } } @@ -89,88 +103,63 @@ impl BinaryFrameReader { } } - fn frame_exists(&self, frame_num: u32) -> bool { - let mut file_name = self.file_base.clone(); - file_name.push(format!("frame_{}.bin", frame_num)); - file_name.exists() + // a frame exists if we either haven't hit eof yet, or if + // we have, then if we've seen its offset. + fn frame_exists(&self, frame: u32) -> bool { + !self.eof || (frame as usize) < self.frame_offsets.len() } } impl WrenchThing for BinaryFrameReader { fn do_frame(&mut self, wrench: &mut Wrench) -> u32 { - let first_time = !self.frame_built; - if first_time { - wrench.set_title(&format!("frame {}", self.frame_num)); - - // TODO mmap instead of read - let mut file = if self.is_dir { - let mut file_name = self.file_base.clone(); - file_name.push(format!("frame_{}.bin", self.frame_num)); - File::open(&file_name).expect("Frame file not found!") - } else { - File::open(&self.file_base).expect("Frame file not found!") - }; - - let check_apimsg = if let Some(check_apimsg) = self.check_apimsg { - check_apimsg - } else { - let header = file.read_u64::().unwrap(); - let check_apimsg = header == WEBRENDER_RECORDING_HEADER; - if !check_apimsg { - println!("Note: Binary file is old-style recording without ApiMsg TypeId"); - } - - // reset the file back to the start - file.seek(SeekFrom::Start(0)).ok(); - self.check_apimsg = Some(check_apimsg); - check_apimsg - }; - - if check_apimsg { - let apimsg_type_id = unsafe { - assert!(mem::size_of::() == mem::size_of::()); - mem::transmute::(TypeId::of::()) - }; + // save where the frame begins as we read through the file + if self.frame_num as usize == self.frame_offsets.len() { + let pos = self.file.seek(SeekFrom::Current(0)).unwrap(); + println!("Frame {} offset: {}", self.frame_offsets.len(), pos); + self.frame_offsets.push(pos); + } - let header = file.read_u64::().unwrap(); - assert!(header == WEBRENDER_RECORDING_HEADER); + let first_time = !self.frame_read; + if first_time { + let offset = self.frame_offsets[self.frame_num as usize]; + self.file.seek(SeekFrom::Start(offset)).unwrap(); - let written_apimsg_type_id = file.read_u64::().unwrap(); - if written_apimsg_type_id != apimsg_type_id { - println!("Binary file ApiMsg enum type mismatch: expected 0x{:x}, found 0x{:x}", apimsg_type_id, written_apimsg_type_id); - } - } + wrench.set_title(&format!("frame {}", self.frame_num)); self.frame_data.clear(); - while let Ok(mut len) = file.read_u32::() { + while let Ok(mut len) = self.file.read_u32::() { if len > 0 { let mut buffer = vec![0; len as usize]; - file.read_exact(&mut buffer).unwrap(); + self.file.read_exact(&mut buffer).unwrap(); let msg = deserialize(&buffer).unwrap(); + let found_frame_marker = match &msg { &ApiMsg::GenerateFrame => true, _ => false }; self.frame_data.push(Item::Message(msg)); + if found_frame_marker { + break; + } } else { - len = file.read_u32::().unwrap(); + len = self.file.read_u32::().unwrap(); let mut buffer = vec![0; len as usize]; - file.read_exact(&mut buffer).unwrap(); + self.file.read_exact(&mut buffer).unwrap(); self.frame_data.push(Item::Data(buffer)); } } - self.frame_built = true; + if self.eof == false && + self.file.seek(SeekFrom::Current(0)).unwrap() == self.file.metadata().unwrap().len() { + self.eof = true; + } + + self.frame_read = true; } if first_time || self.replay_api { - let mut seen_set_root_dl = false; wrench.begin_frame(); let frame_items = self.frame_data.clone(); for item in frame_items { match item { Item::Message(msg) => { if !self.should_skip_upload_msg(&msg) { - match &msg { - &ApiMsg::SetRootDisplayList(..) => { seen_set_root_dl = true; } - _ => { } - } wrench.api.api_sender.send(msg).unwrap(); } } @@ -179,10 +168,6 @@ impl WrenchThing for BinaryFrameReader { } } } - if !seen_set_root_dl && self.frame_num != 0 { - println!("Frame {} didn't contain a SetRootDisplayList message!", self.frame_num); - wrench.refresh(); - } } else if self.play_through { if !self.frame_exists(self.frame_num + 1) { process::exit(0); @@ -193,14 +178,7 @@ impl WrenchThing for BinaryFrameReader { wrench.refresh(); } - // Frame 0 is.. weird. It's always empty, but we can't skip it - // or everything else breaks. - if self.frame_num == 0 { - self.next_frame(); - self.do_frame(wrench) - } else { - self.frame_num - } + self.frame_num } // note that we don't loop here; we could, but that'll require @@ -209,14 +187,14 @@ impl WrenchThing for BinaryFrameReader { fn next_frame(&mut self) { if self.frame_exists(self.frame_num + 1) { self.frame_num += 1; - self.frame_built = false; + self.frame_read = false; } } fn prev_frame(&mut self) { if self.frame_num > 0 { self.frame_num -= 1; - self.frame_built = false; + self.frame_read = false; } } } diff --git a/wrench/src/json_frame_writer.rs b/wrench/src/json_frame_writer.rs index a0af383722..cfa4893a2b 100644 --- a/wrench/src/json_frame_writer.rs +++ b/wrench/src/json_frame_writer.rs @@ -7,6 +7,7 @@ extern crate yaml_rust; use image::{ColorType, save_buffer}; use std::borrow::BorrowMut; use std::collections::HashMap; +use std::fmt; use std::fs; use std::fs::File; use std::io::{Cursor, Read, Write}; @@ -95,16 +96,14 @@ impl JsonFrameWriter { let dl_desc = self.dl_descriptor.take().unwrap(); let aux_desc = self.aux_descriptor.take().unwrap(); - let mut auxiliary_data = Cursor::new(&data[4..]); + assert_eq!(data.len(), dl_desc.size() + aux_desc.size() + 4); - let mut built_display_list_data = vec![0; dl_desc.size()]; - let mut aux_list_data = vec![0; aux_desc.size()]; + // there's a 4 byte epoch header that we skip + let dl_data = data[4..dl_desc.size()+4].to_vec(); + let aux_data = data[dl_desc.size()+4..].to_vec(); - auxiliary_data.read_exact(&mut built_display_list_data[..]).unwrap(); - auxiliary_data.read_exact(&mut aux_list_data[..]).unwrap(); - - let dl = BuiltDisplayList::from_data(built_display_list_data, dl_desc); - let aux = AuxiliaryLists::from_data(aux_list_data, aux_desc); + let dl = BuiltDisplayList::from_data(dl_data, dl_desc); + let aux = AuxiliaryLists::from_data(aux_data, aux_desc); let mut frame_file_name = self.frame_base.clone(); let current_shown_frame = unsafe { CURRENT_FRAME_NUMBER }; @@ -186,6 +185,12 @@ impl JsonFrameWriter { } } +impl fmt::Debug for JsonFrameWriter { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "JsonFrameWriter") + } +} + impl webrender::ApiRecordingReceiver for JsonFrameWriter { fn write_msg(&mut self, _: u32, msg: &ApiMsg) { match msg { diff --git a/wrench/src/main.rs b/wrench/src/main.rs index 14b16efc32..968296e1b0 100644 --- a/wrench/src/main.rs +++ b/wrench/src/main.rs @@ -269,7 +269,8 @@ fn main() { let save_type = args.value_of("save").map(|s| { if s == "yaml" { wrench::SaveType::Yaml } else if s == "json" { wrench::SaveType::Json } - else { panic!("Save type must be json or yaml"); } + else if s == "binary" { wrench::SaveType::Binary } + else { panic!("Save type must be json, yaml, or binary"); } }); let size = args.value_of("size").map(|s| { if s == "720p" { diff --git a/wrench/src/wrench.rs b/wrench/src/wrench.rs index 853fee9788..211adc7bcf 100644 --- a/wrench/src/wrench.rs +++ b/wrench/src/wrench.rs @@ -29,6 +29,7 @@ use {WHITE_COLOR, BLACK_COLOR}; pub enum SaveType { Yaml, Json, + Binary, } struct Notifier { @@ -153,20 +154,21 @@ impl Wrench { { println!("Shader override path: {:?}", shader_override_path); - if let Some(ref save_type) = save_type { - let recorder = match save_type { - &SaveType::Yaml => Box::new(YamlFrameWriterReceiver::new(&PathBuf::from("yaml_frames"))) - as Box, - &SaveType::Json => Box::new(JsonFrameWriter::new(&PathBuf::from("json_frames"))) - as Box, - }; - webrender::set_recording_detour(Some(recorder)); - } + let recorder = save_type.map(|save_type| { + match save_type { + SaveType::Yaml => + Box::new(YamlFrameWriterReceiver::new(&PathBuf::from("yaml_frames"))) as Box, + SaveType::Json => + Box::new(JsonFrameWriter::new(&PathBuf::from("json_frames"))) as Box, + SaveType::Binary => + Box::new(webrender::BinaryRecorder::new(&PathBuf::from("wr-record.bin"))) as Box, + } + }); let opts = webrender::RendererOptions { device_pixel_ratio: dp_ratio, resource_override_path: shader_override_path, - enable_recording: save_type.is_some(), + recorder: recorder, enable_subpixel_aa: subpixel_aa, debug: debug, .. Default::default() @@ -175,8 +177,14 @@ impl Wrench { let (renderer, sender) = webrender::renderer::Renderer::new(opts); let api = sender.create_api(); + let proxy = window.create_window_proxy(); + // put an Awakened event into the queue to kick off the first frame + if let Some(ref wp) = proxy { + wp.wakeup_event_loop(); + } + let (timing_sender, timing_receiver) = chase_lev::deque(); - let notifier = Box::new(Notifier::new(window.create_window_proxy(), timing_receiver, verbose)); + let notifier = Box::new(Notifier::new(proxy, timing_receiver, verbose)); renderer.set_render_notifier(notifier); let gl_version = gl::get_string(gl::VERSION); diff --git a/wrench/src/yaml_frame_writer.rs b/wrench/src/yaml_frame_writer.rs index d768b4304c..8ec60271a0 100644 --- a/wrench/src/yaml_frame_writer.rs +++ b/wrench/src/yaml_frame_writer.rs @@ -5,6 +5,7 @@ use euclid::{TypedPoint2D, TypedSize2D, TypedRect, TypedMatrix4D}; use image::{ColorType, save_buffer}; use std::borrow::BorrowMut; use std::collections::HashMap; +use std::fmt; use std::fs; use std::fs::File; use std::io::{Cursor, Read, Write}; @@ -239,6 +240,11 @@ impl YamlFrameWriterReceiver { } } +impl fmt::Debug for YamlFrameWriterReceiver { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "YamlFrameWriterReceiver") + } +} impl YamlFrameWriter { pub fn new(path: &Path) -> YamlFrameWriter { @@ -298,16 +304,14 @@ impl YamlFrameWriter { let dl_desc = self.dl_descriptor.take().unwrap(); let aux_desc = self.aux_descriptor.take().unwrap(); - let mut auxiliary_data = Cursor::new(&data[4..]); + assert_eq!(data.len(), dl_desc.size() + aux_desc.size() + 4); - let mut built_display_list_data = vec![0; dl_desc.size()]; - let mut aux_list_data = vec![0; aux_desc.size()]; + // skip 4-byte epoch header + let dl_data = data[4..dl_desc.size()+4].to_vec(); + let aux_data = data[dl_desc.size()+4..].to_vec(); - auxiliary_data.read_exact(&mut built_display_list_data[..]).unwrap(); - auxiliary_data.read_exact(&mut aux_list_data[..]).unwrap(); - - let dl = BuiltDisplayList::from_data(built_display_list_data, dl_desc); - let aux = AuxiliaryLists::from_data(aux_list_data, aux_desc); + let dl = BuiltDisplayList::from_data(dl_data, dl_desc); + let aux = AuxiliaryLists::from_data(aux_data, aux_desc); let mut root_dl_table = new_table(); { @@ -430,7 +434,7 @@ impl YamlFrameWriter { rect_node(&mut complex_table, "rect", &clip.main); if complex.len() > 0 { - let mut complex_items = complex.iter().map(|ccx| + let complex_items = complex.iter().map(|ccx| if ccx.radii.is_zero() { rect_yaml(&ccx.rect) } else { @@ -440,7 +444,6 @@ impl YamlFrameWriter { Yaml::Hash(t) } ).collect(); - vec_node(&mut complex_table, "complex", complex_items); } diff --git a/wrench/src/yaml_helper.rs b/wrench/src/yaml_helper.rs index 227e971bae..ebbac06b25 100644 --- a/wrench/src/yaml_helper.rs +++ b/wrench/src/yaml_helper.rs @@ -132,7 +132,7 @@ impl YamlHelper for Yaml { } fn as_pipeline_id(&self) -> Option { - if let Some(mut v) = self.as_vec() { + if let Some(v) = self.as_vec() { let a = v.get(0).and_then(|v| v.as_i64()).map(|v| v as u32); let b = v.get(1).and_then(|v| v.as_i64()).map(|v| v as u32); match (a, b) { @@ -197,7 +197,7 @@ impl YamlHelper for Yaml { } fn as_matrix4d(&self, transform_origin: &LayoutPoint) -> Option { - if let Some(mut nums) = self.as_vec_f32() { + if let Some(nums) = self.as_vec_f32() { if nums.len() != 16 { panic!("expected 16 floats, got '{:?}'", self); }