From 211185a89c66e762289ad7f2bee274df03eebde8 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Wed, 3 Jul 2019 02:01:08 -0400 Subject: [PATCH 1/4] Bug 1562892 - WR capture native fonts as raw r=lsalzman we save the native fonts by their full path now. On macOS, there is no such thing as a full filesystem path for a CGFont (or at least we don't track it), so loading a capture falls back to the old logic of using the dummy font. Differential Revision: https://phabricator.services.mozilla.com/D36604 [wrupdater] From https://hg.mozilla.org/mozilla-central/rev/dd501b160508c7dedf613941135707435b2e42c1 --- webrender/src/platform/unix/font.rs | 80 +++++++++++++++++------------ webrender/src/resource_cache.rs | 71 +++++++++++++------------ wrench/src/main.rs | 5 ++ wrench/src/wrench.rs | 1 + 4 files changed, 91 insertions(+), 66 deletions(-) diff --git a/webrender/src/platform/unix/font.rs b/webrender/src/platform/unix/font.rs index 87a6a94103..4e5ade14df 100644 --- a/webrender/src/platform/unix/font.rs +++ b/webrender/src/platform/unix/font.rs @@ -309,7 +309,7 @@ impl FontContext { } pub fn add_raw_font(&mut self, font_key: &FontKey, bytes: Arc>, index: u32) { - if !self.faces.contains_key(&font_key) { + if !self.faces.contains_key(font_key) { let file = FontFile::Data(bytes); if let Some(face) = new_ft_face(font_key, self.lib, &file, index) { self.faces.insert(*font_key, FontFace { file, index, face, mm_var: ptr::null_mut() }); @@ -318,7 +318,7 @@ impl FontContext { } pub fn add_native_font(&mut self, font_key: &FontKey, native_font_handle: NativeFontHandle) { - if !self.faces.contains_key(&font_key) { + if !self.faces.contains_key(font_key) { let cstr = CString::new(native_font_handle.path.as_os_str().to_str().unwrap()).unwrap(); let file = FontFile::Pathname(cstr); let index = native_font_handle.index; @@ -467,41 +467,57 @@ impl FontContext { } }; - if succeeded(result) { - result = unsafe { FT_Load_Glyph(face, glyph.index() as FT_UInt, load_flags as FT_Int32) }; - }; - - if succeeded(result) { - let slot = unsafe { (*face).glyph }; - assert!(slot != ptr::null_mut()); - - if font.flags.contains(FontInstanceFlags::SYNTHETIC_BOLD) { - unsafe { FT_GlyphSlot_Embolden(slot) }; - } + if !succeeded(result) { + error!("Unable to set glyph size and transform: {}", result); + //let raw_error = unsafe { FT_Error_String(result) }; + //if !raw_error.is_ptr() { + // error!("\tcode {:?}", CStr::from_ptr(raw_error)); + //} + debug!( + "\t[{}] for size {:?} and scale {:?} from font {:?}", + glyph.index(), + req_size, + (x_scale, y_scale), + font.font_key, + ); + return None; + } - let format = unsafe { (*slot).format }; - match format { - FT_Glyph_Format::FT_GLYPH_FORMAT_BITMAP => { - let y_size = unsafe { (*(*(*slot).face).size).metrics.y_ppem }; - Some((slot, req_size as f32 / y_size as f32)) - } - FT_Glyph_Format::FT_GLYPH_FORMAT_OUTLINE => Some((slot, scale as f32)), - _ => { - error!("Unsupported format"); - debug!("format={:?}", format); - None - } - } - } else { - error!("Unable to load glyph"); + result = unsafe { FT_Load_Glyph(face, glyph.index() as FT_UInt, load_flags as FT_Int32) }; + if !succeeded(result) { + error!("Unable to load glyph: {}", result); + //let raw_error = unsafe { FT_Error_String(result) }; + //if !raw_error.is_ptr() { + // error!("\tcode {:?}", CStr::from_ptr(raw_error)); + //} debug!( - "{} of size {:?} from font {:?}, {:?}", + "\t[{}] with flags {:?} from font {:?}", glyph.index(), - font.size, + load_flags, font.font_key, - result ); - None + return None; + } + + let slot = unsafe { (*face).glyph }; + assert!(slot != ptr::null_mut()); + + if font.flags.contains(FontInstanceFlags::SYNTHETIC_BOLD) { + unsafe { FT_GlyphSlot_Embolden(slot) }; + } + + let format = unsafe { (*slot).format }; + match format { + FT_Glyph_Format::FT_GLYPH_FORMAT_BITMAP => { + let y_size = unsafe { (*(*(*slot).face).size).metrics.y_ppem }; + Some((slot, req_size as f32 / y_size as f32)) + } + FT_Glyph_Format::FT_GLYPH_FORMAT_OUTLINE => Some((slot, scale as f32)), + _ => { + error!("Unsupported format"); + debug!("format={:?}", format); + None + } } } diff --git a/webrender/src/resource_cache.rs b/webrender/src/resource_cache.rs index 87315bf150..bc002a2c5e 100644 --- a/webrender/src/resource_cache.rs +++ b/webrender/src/resource_cache.rs @@ -1900,12 +1900,9 @@ pub fn get_blob_tiling( #[cfg(any(feature = "capture", feature = "replay"))] #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] -enum PlainFontTemplate { - Raw { - data: String, - index: u32, - }, - Native, +struct PlainFontTemplate { + data: String, + index: u32, } #[cfg(any(feature = "capture", feature = "replay"))] @@ -2116,13 +2113,24 @@ impl ResourceCache { .map(|(key, template)| { (*key, match *template { FontTemplate::Raw(ref arc, index) => { - PlainFontTemplate::Raw { + PlainFontTemplate { data: font_paths[&arc.as_ptr()].clone(), index, } } - FontTemplate::Native(_) => { - PlainFontTemplate::Native + #[cfg(not(target_os = "macos"))] + FontTemplate::Native(ref native) => { + PlainFontTemplate { + data: native.path.to_string_lossy().to_string(), + index: native.index, + } + } + #[cfg(target_os = "macos")] + FontTemplate::Native(ref native) => { + PlainFontTemplate { + data: native.0.postscript_name().to_string(), + index: 0, + } } }) }) @@ -2165,8 +2173,7 @@ impl ResourceCache { caches: Option, root: &PathBuf, ) -> Vec { - use std::fs::File; - use std::io::Read; + use std::{fs, path::Path}; info!("loading resource cache"); //TODO: instead of filling the local path to Arc map as we process @@ -2206,29 +2213,28 @@ impl ResourceCache { info!("\tfont templates..."); let native_font_replacement = Arc::new(NATIVE_FONT.to_vec()); for (key, plain_template) in resources.font_templates { - let template = match plain_template { - PlainFontTemplate::Raw { data, index } => { - let arc = match raw_map.entry(data) { - Entry::Occupied(e) => { - e.get().clone() - } - Entry::Vacant(e) => { - let mut buffer = Vec::new(); - File::open(root.join(e.key())) - .expect(&format!("Unable to open {}", e.key())) - .read_to_end(&mut buffer) - .unwrap(); - e.insert(Arc::new(buffer)) - .clone() + let arc = match raw_map.entry(plain_template.data) { + Entry::Occupied(e) => { + e.get().clone() + } + Entry::Vacant(e) => { + let file_path = if Path::new(e.key()).is_absolute() { + PathBuf::from(e.key()) + } else { + root.join(e.key()) + }; + let arc = match fs::read(file_path) { + Ok(buffer) => Arc::new(buffer), + Err(err) => { + error!("Unable to open font template {:?}: {:?}", e.key(), err); + Arc::clone(&native_font_replacement) } }; - FontTemplate::Raw(arc, index) - } - PlainFontTemplate::Native => { - FontTemplate::Raw(native_font_replacement.clone(), 0) + e.insert(arc).clone() } }; + let template = FontTemplate::Raw(arc, plain_template.index); self.glyph_rasterizer.add_font(key, template.clone()); res.font_templates.insert(key, template); } @@ -2248,11 +2254,8 @@ impl ResourceCache { e.get().clone() } Entry::Vacant(e) => { - let mut buffer = Vec::new(); - File::open(root.join(e.key())) - .expect(&format!("Unable to open {}", e.key())) - .read_to_end(&mut buffer) - .unwrap(); + let buffer = fs::read(root.join(e.key())) + .expect(&format!("Unable to open {}", e.key())); e.insert(Arc::new(buffer)) .clone() } diff --git a/wrench/src/main.rs b/wrench/src/main.rs index ad09f595c6..952b79fbd4 100644 --- a/wrench/src/main.rs +++ b/wrench/src/main.rs @@ -778,6 +778,11 @@ fn render<'a>( wrench.api.send_debug_cmd(DebugCommand::SetFlags(debug_flags)); do_render = true; } + VirtualKeyCode::Y => { + println!("Clearing all caches..."); + wrench.api.send_debug_cmd(DebugCommand::ClearCaches(ClearCache::all())); + do_frame = true; + } _ => {} } _ => {} diff --git a/wrench/src/wrench.rs b/wrench/src/wrench.rs index 72da49d583..f8164d23b9 100644 --- a/wrench/src/wrench.rs +++ b/wrench/src/wrench.rs @@ -598,6 +598,7 @@ impl Wrench { "T - Save CPU profile to a file", "C - Save a capture to captures/wrench/", "X - Do a hit test at the current cursor position", + "Y - Clear all caches", ]; let color_and_offset = [(ColorF::BLACK, 2.0), (ColorF::WHITE, 0.0)]; From 4559db685f6779a4311b5c5730d745485b389d0a Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Wed, 3 Jul 2019 02:01:22 -0400 Subject: [PATCH 2/4] Bug 1562788 - Add support for benchmarking llvmpipe and swiftshader in wrench. r=nical * Add a script for running wrench under various software rasterizers. * Add support to wrench for non-blocking event loop. * Add support to wrench for selecting GL/ES rendering API. * Update x11 bindings for wrench, to fix a release only crash. Differential Revision: https://phabricator.services.mozilla.com/D36551 [wrupdater] From https://hg.mozilla.org/mozilla-central/rev/9c6775d713e80c531dcbec5d7985021eeebd251e --- Cargo.lock | 8 ++--- wrench/script/wrench_with_renderer.py | 52 +++++++++++++++++++++++++++ wrench/src/args.yaml | 8 +++++ wrench/src/main.rs | 44 +++++++++++++++++++---- 4 files changed, 101 insertions(+), 11 deletions(-) create mode 100755 wrench/script/wrench_with_renderer.py diff --git a/Cargo.lock b/Cargo.lock index d7151de0d1..f953b3de9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -604,7 +604,7 @@ dependencies = [ "wayland-client 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "winit 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)", - "x11-dl 2.17.5 (registry+https://github.com/rust-lang/crates.io-index)", + "x11-dl 2.18.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1898,7 +1898,7 @@ dependencies = [ "smithay-client-toolkit 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "wayland-client 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "x11-dl 2.17.5 (registry+https://github.com/rust-lang/crates.io-index)", + "x11-dl 2.18.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1971,7 +1971,7 @@ dependencies = [ [[package]] name = "x11-dl" -version = "2.17.5" +version = "2.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2221,7 +2221,7 @@ dependencies = [ "checksum winit 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ec43db5991cc509f5b0c68cb0a0d3614f697c888999990a186a2e895c7f723c0" "checksum ws 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ec91ea61b83ce033c43c06c52ddc7532f465c0153281610d44c58b74083aee1a" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -"checksum x11-dl 2.17.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3235540540fde1ae074c8df49054166c0e070407f1c6e1ee17b8c87c2c7bcc7d" +"checksum x11-dl 2.18.3 (registry+https://github.com/rust-lang/crates.io-index)" = "940586acb859ea05c53971ac231685799a7ec1dee66ac0bccc0e6ad96e06b4e3" "checksum xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2" "checksum xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5" "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" diff --git a/wrench/script/wrench_with_renderer.py b/wrench/script/wrench_with_renderer.py new file mode 100755 index 0000000000..3d296ebc53 --- /dev/null +++ b/wrench/script/wrench_with_renderer.py @@ -0,0 +1,52 @@ +#!/usr/bin/python + +# 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/. + +import os +import subprocess +import sys + + +def is_linux(): + return sys.platform.startswith('linux') + + +if is_linux(): + requested_renderer = sys.argv[1] + renderer = "default" + + if requested_renderer == 'hardware': + pass + elif requested_renderer == 'llvmpipe': + os.environ["LIBGL_ALWAYS_SOFTWARE"] = "1" + os.environ["GALLIUM_DRIVER"] = "llvmpipe" + elif requested_renderer == 'softpipe': + os.environ["LIBGL_ALWAYS_SOFTWARE"] = "1" + os.environ["GALLIUM_DRIVER"] = "softpipe" + elif requested_renderer == 'swiftshader': + # TODO: Set up LD_LIBRARY_PATH to SwiftShader libraries automatically. + renderer = 'es3' + else: + print('Unknown renderer ' + requested_renderer) + sys.exit(1) + + cmd = [ + 'cargo', + 'run', + '--release', + '--', + '--no-block', # Run as fast as possible, for benchmarking + '--no-picture-caching', # Disable picture caching, to test rasterization performance + '--no-subpixel-aa', # SwiftShader doesn't support dual source blending, disable subpixel AA for fairer comparisons + '--renderer', # Select GL3/ES3 renderer API + renderer, + 'load' + ] + + cmd += sys.argv[2:] + print('Running: ' + ' '.join(cmd)) + subprocess.check_call(cmd) +else: + print('This script is only supported on Linux') diff --git a/wrench/src/args.yaml b/wrench/src/args.yaml index da5733ffc9..0024a891c4 100644 --- a/wrench/src/args.yaml +++ b/wrench/src/args.yaml @@ -79,6 +79,14 @@ args: help: Dump the source of the specified shader takes_value: true global: true + - renderer: + long: renderer + help: Select rendering API (gl3, es3) + takes_value: true + global: true + - no_block: + long: no-block + help: Don't block on UI events - run event loop as fast as possible. subcommands: - png: diff --git a/wrench/src/main.rs b/wrench/src/main.rs index 952b79fbd4..ba1b1a33cb 100644 --- a/wrench/src/main.rs +++ b/wrench/src/main.rs @@ -246,14 +246,12 @@ fn make_window( vsync: bool, events_loop: &Option, angle: bool, + gl_request: glutin::GlRequest, ) -> WindowWrapper { let wrapper = match *events_loop { Some(ref events_loop) => { let context_builder = glutin::ContextBuilder::new() - .with_gl(glutin::GlRequest::GlThenGles { - opengl_version: (3, 2), - opengles_version: (3, 0), - }) + .with_gl(gl_request) .with_vsync(vsync); let window_builder = winit::WindowBuilder::new() .with_title("WRench") @@ -484,8 +482,31 @@ fn main() { Some(winit::EventsLoop::new()) }; + let gl_request = match args.value_of("renderer") { + Some("es3") => { + glutin::GlRequest::Specific(glutin::Api::OpenGlEs, (3, 0)) + } + Some("gl3") => { + glutin::GlRequest::Specific(glutin::Api::OpenGl, (3, 2)) + } + Some("default") | None => { + glutin::GlRequest::GlThenGles { + opengl_version: (3, 2), + opengles_version: (3, 0), + } + } + Some(api) => { + panic!("Unexpected renderer string {}", api); + } + }; + let mut window = make_window( - size, dp_ratio, args.is_present("vsync"), &events_loop, args.is_present("angle"), + size, + dp_ratio, + args.is_present("vsync"), + &events_loop, + args.is_present("angle"), + gl_request, ); let dp_ratio = dp_ratio.unwrap_or(window.hidpi_factor()); let dim = window.get_inner_size(); @@ -528,7 +549,15 @@ fn main() { } if let Some(subargs) = args.subcommand_matches("show") { - render(&mut wrench, &mut window, size, &mut events_loop, subargs); + let no_block = args.is_present("no_block"); + render( + &mut wrench, + &mut window, + size, + &mut events_loop, + subargs, + no_block, + ); } else if let Some(subargs) = args.subcommand_matches("png") { let surface = match subargs.value_of("surface") { Some("screen") | None => png::ReadSurface::Screen, @@ -571,6 +600,7 @@ fn render<'a>( size: DeviceIntSize, events_loop: &mut Option, subargs: &clap::ArgMatches<'a>, + no_block: bool, ) { let input_path = subargs.value_of("INPUT").map(PathBuf::from).unwrap(); @@ -835,7 +865,7 @@ fn render<'a>( // Block the thread until at least one event arrives // On Android, we are generally profiling when running // wrench, and don't want to block on UI events. - if cfg!(not(target_os = "android")) { + if !no_block && cfg!(not(target_os = "android")) { events_loop.run_forever(|event| { pending_events.push(event); winit::ControlFlow::Break From a5d2f2eb1aface5bee5575c0d936bf8c7e2f4f2f Mon Sep 17 00:00:00 2001 From: Andreea Pavel Date: Wed, 3 Jul 2019 02:01:36 -0400 Subject: [PATCH 3/4] Backed out changeset 9c6775d713e8 (bug 1562788) for webrender lint tidy bustage on a CLOSED TREE [wrupdater] From https://hg.mozilla.org/mozilla-central/rev/58fa32c56ff0f0507e7ecf60aa41bfc8d87f8ee1 --- Cargo.lock | 8 ++--- wrench/script/wrench_with_renderer.py | 52 --------------------------- wrench/src/args.yaml | 8 ----- wrench/src/main.rs | 44 ++++------------------- 4 files changed, 11 insertions(+), 101 deletions(-) delete mode 100755 wrench/script/wrench_with_renderer.py diff --git a/Cargo.lock b/Cargo.lock index f953b3de9f..d7151de0d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -604,7 +604,7 @@ dependencies = [ "wayland-client 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "winit 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)", - "x11-dl 2.18.3 (registry+https://github.com/rust-lang/crates.io-index)", + "x11-dl 2.17.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1898,7 +1898,7 @@ dependencies = [ "smithay-client-toolkit 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "wayland-client 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "x11-dl 2.18.3 (registry+https://github.com/rust-lang/crates.io-index)", + "x11-dl 2.17.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1971,7 +1971,7 @@ dependencies = [ [[package]] name = "x11-dl" -version = "2.18.3" +version = "2.17.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2221,7 +2221,7 @@ dependencies = [ "checksum winit 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ec43db5991cc509f5b0c68cb0a0d3614f697c888999990a186a2e895c7f723c0" "checksum ws 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ec91ea61b83ce033c43c06c52ddc7532f465c0153281610d44c58b74083aee1a" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -"checksum x11-dl 2.18.3 (registry+https://github.com/rust-lang/crates.io-index)" = "940586acb859ea05c53971ac231685799a7ec1dee66ac0bccc0e6ad96e06b4e3" +"checksum x11-dl 2.17.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3235540540fde1ae074c8df49054166c0e070407f1c6e1ee17b8c87c2c7bcc7d" "checksum xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2" "checksum xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5" "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" diff --git a/wrench/script/wrench_with_renderer.py b/wrench/script/wrench_with_renderer.py deleted file mode 100755 index 3d296ebc53..0000000000 --- a/wrench/script/wrench_with_renderer.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/python - -# 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/. - -import os -import subprocess -import sys - - -def is_linux(): - return sys.platform.startswith('linux') - - -if is_linux(): - requested_renderer = sys.argv[1] - renderer = "default" - - if requested_renderer == 'hardware': - pass - elif requested_renderer == 'llvmpipe': - os.environ["LIBGL_ALWAYS_SOFTWARE"] = "1" - os.environ["GALLIUM_DRIVER"] = "llvmpipe" - elif requested_renderer == 'softpipe': - os.environ["LIBGL_ALWAYS_SOFTWARE"] = "1" - os.environ["GALLIUM_DRIVER"] = "softpipe" - elif requested_renderer == 'swiftshader': - # TODO: Set up LD_LIBRARY_PATH to SwiftShader libraries automatically. - renderer = 'es3' - else: - print('Unknown renderer ' + requested_renderer) - sys.exit(1) - - cmd = [ - 'cargo', - 'run', - '--release', - '--', - '--no-block', # Run as fast as possible, for benchmarking - '--no-picture-caching', # Disable picture caching, to test rasterization performance - '--no-subpixel-aa', # SwiftShader doesn't support dual source blending, disable subpixel AA for fairer comparisons - '--renderer', # Select GL3/ES3 renderer API - renderer, - 'load' - ] - - cmd += sys.argv[2:] - print('Running: ' + ' '.join(cmd)) - subprocess.check_call(cmd) -else: - print('This script is only supported on Linux') diff --git a/wrench/src/args.yaml b/wrench/src/args.yaml index 0024a891c4..da5733ffc9 100644 --- a/wrench/src/args.yaml +++ b/wrench/src/args.yaml @@ -79,14 +79,6 @@ args: help: Dump the source of the specified shader takes_value: true global: true - - renderer: - long: renderer - help: Select rendering API (gl3, es3) - takes_value: true - global: true - - no_block: - long: no-block - help: Don't block on UI events - run event loop as fast as possible. subcommands: - png: diff --git a/wrench/src/main.rs b/wrench/src/main.rs index ba1b1a33cb..952b79fbd4 100644 --- a/wrench/src/main.rs +++ b/wrench/src/main.rs @@ -246,12 +246,14 @@ fn make_window( vsync: bool, events_loop: &Option, angle: bool, - gl_request: glutin::GlRequest, ) -> WindowWrapper { let wrapper = match *events_loop { Some(ref events_loop) => { let context_builder = glutin::ContextBuilder::new() - .with_gl(gl_request) + .with_gl(glutin::GlRequest::GlThenGles { + opengl_version: (3, 2), + opengles_version: (3, 0), + }) .with_vsync(vsync); let window_builder = winit::WindowBuilder::new() .with_title("WRench") @@ -482,31 +484,8 @@ fn main() { Some(winit::EventsLoop::new()) }; - let gl_request = match args.value_of("renderer") { - Some("es3") => { - glutin::GlRequest::Specific(glutin::Api::OpenGlEs, (3, 0)) - } - Some("gl3") => { - glutin::GlRequest::Specific(glutin::Api::OpenGl, (3, 2)) - } - Some("default") | None => { - glutin::GlRequest::GlThenGles { - opengl_version: (3, 2), - opengles_version: (3, 0), - } - } - Some(api) => { - panic!("Unexpected renderer string {}", api); - } - }; - let mut window = make_window( - size, - dp_ratio, - args.is_present("vsync"), - &events_loop, - args.is_present("angle"), - gl_request, + size, dp_ratio, args.is_present("vsync"), &events_loop, args.is_present("angle"), ); let dp_ratio = dp_ratio.unwrap_or(window.hidpi_factor()); let dim = window.get_inner_size(); @@ -549,15 +528,7 @@ fn main() { } if let Some(subargs) = args.subcommand_matches("show") { - let no_block = args.is_present("no_block"); - render( - &mut wrench, - &mut window, - size, - &mut events_loop, - subargs, - no_block, - ); + render(&mut wrench, &mut window, size, &mut events_loop, subargs); } else if let Some(subargs) = args.subcommand_matches("png") { let surface = match subargs.value_of("surface") { Some("screen") | None => png::ReadSurface::Screen, @@ -600,7 +571,6 @@ fn render<'a>( size: DeviceIntSize, events_loop: &mut Option, subargs: &clap::ArgMatches<'a>, - no_block: bool, ) { let input_path = subargs.value_of("INPUT").map(PathBuf::from).unwrap(); @@ -865,7 +835,7 @@ fn render<'a>( // Block the thread until at least one event arrives // On Android, we are generally profiling when running // wrench, and don't want to block on UI events. - if !no_block && cfg!(not(target_os = "android")) { + if cfg!(not(target_os = "android")) { events_loop.run_forever(|event| { pending_events.push(event); winit::ControlFlow::Break From 607de6d00541f46ddc9757a70ff1c5b0bd5b9a86 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Wed, 3 Jul 2019 02:01:50 -0400 Subject: [PATCH 4/4] Bug 1562788 - Add support for benchmarking llvmpipe and swiftshader in wrench. r=nical * Add a script for running wrench under various software rasterizers. * Add support to wrench for non-blocking event loop. * Add support to wrench for selecting GL/ES rendering API. * Update x11 bindings for wrench, to fix a release only crash. Differential Revision: https://phabricator.services.mozilla.com/D36551 [wrupdater] From https://hg.mozilla.org/mozilla-central/rev/d066f9f4b7bcf5d3b692ca5a198406e1ff358076 --- Cargo.lock | 8 ++--- wrench/script/wrench_with_renderer.py | 52 +++++++++++++++++++++++++++ wrench/src/args.yaml | 8 +++++ wrench/src/main.rs | 44 +++++++++++++++++++---- 4 files changed, 101 insertions(+), 11 deletions(-) create mode 100755 wrench/script/wrench_with_renderer.py diff --git a/Cargo.lock b/Cargo.lock index d7151de0d1..f953b3de9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -604,7 +604,7 @@ dependencies = [ "wayland-client 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "winit 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)", - "x11-dl 2.17.5 (registry+https://github.com/rust-lang/crates.io-index)", + "x11-dl 2.18.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1898,7 +1898,7 @@ dependencies = [ "smithay-client-toolkit 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "wayland-client 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "x11-dl 2.17.5 (registry+https://github.com/rust-lang/crates.io-index)", + "x11-dl 2.18.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1971,7 +1971,7 @@ dependencies = [ [[package]] name = "x11-dl" -version = "2.17.5" +version = "2.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2221,7 +2221,7 @@ dependencies = [ "checksum winit 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ec43db5991cc509f5b0c68cb0a0d3614f697c888999990a186a2e895c7f723c0" "checksum ws 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ec91ea61b83ce033c43c06c52ddc7532f465c0153281610d44c58b74083aee1a" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -"checksum x11-dl 2.17.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3235540540fde1ae074c8df49054166c0e070407f1c6e1ee17b8c87c2c7bcc7d" +"checksum x11-dl 2.18.3 (registry+https://github.com/rust-lang/crates.io-index)" = "940586acb859ea05c53971ac231685799a7ec1dee66ac0bccc0e6ad96e06b4e3" "checksum xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2" "checksum xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5" "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" diff --git a/wrench/script/wrench_with_renderer.py b/wrench/script/wrench_with_renderer.py new file mode 100755 index 0000000000..e2685e8476 --- /dev/null +++ b/wrench/script/wrench_with_renderer.py @@ -0,0 +1,52 @@ +#!/usr/bin/python + +# 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/. + +import os +import subprocess +import sys + + +def is_linux(): + return sys.platform.startswith('linux') + + +if is_linux(): + requested_renderer = sys.argv[1] + renderer = "default" + + if requested_renderer == 'hardware': + pass + elif requested_renderer == 'llvmpipe': + os.environ["LIBGL_ALWAYS_SOFTWARE"] = "1" + os.environ["GALLIUM_DRIVER"] = "llvmpipe" + elif requested_renderer == 'softpipe': + os.environ["LIBGL_ALWAYS_SOFTWARE"] = "1" + os.environ["GALLIUM_DRIVER"] = "softpipe" + elif requested_renderer == 'swiftshader': + # TODO: Set up LD_LIBRARY_PATH to SwiftShader libraries automatically. + renderer = 'es3' + else: + print('Unknown renderer ' + requested_renderer) + sys.exit(1) + + cmd = [ + 'cargo', + 'run', + '--release', + '--', + '--no-block', # Run as fast as possible, for benchmarking + '--no-picture-caching', # Disable picture caching, to test rasterization performance + '--no-subpixel-aa', # SwiftShader doesn't support dual source blending + '--renderer', # Select GL3/ES3 renderer API + renderer, + 'load' + ] + + cmd += sys.argv[2:] + print('Running: ' + ' '.join(cmd)) + subprocess.check_call(cmd) +else: + print('This script is only supported on Linux') diff --git a/wrench/src/args.yaml b/wrench/src/args.yaml index da5733ffc9..0024a891c4 100644 --- a/wrench/src/args.yaml +++ b/wrench/src/args.yaml @@ -79,6 +79,14 @@ args: help: Dump the source of the specified shader takes_value: true global: true + - renderer: + long: renderer + help: Select rendering API (gl3, es3) + takes_value: true + global: true + - no_block: + long: no-block + help: Don't block on UI events - run event loop as fast as possible. subcommands: - png: diff --git a/wrench/src/main.rs b/wrench/src/main.rs index 952b79fbd4..ba1b1a33cb 100644 --- a/wrench/src/main.rs +++ b/wrench/src/main.rs @@ -246,14 +246,12 @@ fn make_window( vsync: bool, events_loop: &Option, angle: bool, + gl_request: glutin::GlRequest, ) -> WindowWrapper { let wrapper = match *events_loop { Some(ref events_loop) => { let context_builder = glutin::ContextBuilder::new() - .with_gl(glutin::GlRequest::GlThenGles { - opengl_version: (3, 2), - opengles_version: (3, 0), - }) + .with_gl(gl_request) .with_vsync(vsync); let window_builder = winit::WindowBuilder::new() .with_title("WRench") @@ -484,8 +482,31 @@ fn main() { Some(winit::EventsLoop::new()) }; + let gl_request = match args.value_of("renderer") { + Some("es3") => { + glutin::GlRequest::Specific(glutin::Api::OpenGlEs, (3, 0)) + } + Some("gl3") => { + glutin::GlRequest::Specific(glutin::Api::OpenGl, (3, 2)) + } + Some("default") | None => { + glutin::GlRequest::GlThenGles { + opengl_version: (3, 2), + opengles_version: (3, 0), + } + } + Some(api) => { + panic!("Unexpected renderer string {}", api); + } + }; + let mut window = make_window( - size, dp_ratio, args.is_present("vsync"), &events_loop, args.is_present("angle"), + size, + dp_ratio, + args.is_present("vsync"), + &events_loop, + args.is_present("angle"), + gl_request, ); let dp_ratio = dp_ratio.unwrap_or(window.hidpi_factor()); let dim = window.get_inner_size(); @@ -528,7 +549,15 @@ fn main() { } if let Some(subargs) = args.subcommand_matches("show") { - render(&mut wrench, &mut window, size, &mut events_loop, subargs); + let no_block = args.is_present("no_block"); + render( + &mut wrench, + &mut window, + size, + &mut events_loop, + subargs, + no_block, + ); } else if let Some(subargs) = args.subcommand_matches("png") { let surface = match subargs.value_of("surface") { Some("screen") | None => png::ReadSurface::Screen, @@ -571,6 +600,7 @@ fn render<'a>( size: DeviceIntSize, events_loop: &mut Option, subargs: &clap::ArgMatches<'a>, + no_block: bool, ) { let input_path = subargs.value_of("INPUT").map(PathBuf::from).unwrap(); @@ -835,7 +865,7 @@ fn render<'a>( // Block the thread until at least one event arrives // On Android, we are generally profiling when running // wrench, and don't want to block on UI events. - if cfg!(not(target_os = "android")) { + if !no_block && cfg!(not(target_os = "android")) { events_loop.run_forever(|event| { pending_events.push(event); winit::ControlFlow::Break