From 1fbc96b5295e03760e3863f78fd8b31e51e9284f Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Sun, 17 Sep 2017 15:13:52 -0400 Subject: [PATCH] Rustfmt pass --- rustfmt.toml | 6 + webrender/build.rs | 17 +- webrender/examples/animation.rs | 77 +- webrender/examples/basic.rs | 127 +- webrender/examples/blob.rs | 111 +- webrender/examples/common/boilerplate.rs | 162 +- webrender/examples/frame_output.rs | 148 +- webrender/examples/iframe.rs | 66 +- webrender/examples/image_resize.rs | 73 +- webrender/examples/nested_display_list.rs | 116 +- webrender/examples/scrolling.rs | 138 +- webrender/examples/texture_cache_stress.rs | 110 +- webrender/examples/yuv.rs | 89 +- webrender/src/border.rs | 487 ++--- webrender/src/clip.rs | 66 +- webrender/src/clip_scroll_node.rs | 176 +- webrender/src/clip_scroll_tree.rs | 158 +- webrender/src/debug_render.rs | 205 ++- webrender/src/debug_server.rs | 93 +- webrender/src/device.rs | 932 +++++----- webrender/src/ellipse.rs | 24 +- webrender/src/frame.rs | 1142 +++++++----- webrender/src/frame_builder.rs | 1771 ++++++++++-------- webrender/src/freelist.rs | 14 +- webrender/src/geometry.rs | 58 +- webrender/src/glyph_cache.rs | 12 +- webrender/src/glyph_rasterizer.rs | 180 +- webrender/src/gpu_cache.rs | 89 +- webrender/src/gpu_types.rs | 30 +- webrender/src/internal_types.rs | 42 +- webrender/src/lib.rs | 42 +- webrender/src/platform/macos/font.rs | 212 ++- webrender/src/platform/unix/font.rs | 161 +- webrender/src/platform/windows/font.rs | 197 +- webrender/src/prim_store.rs | 456 +++-- webrender/src/print_tree.rs | 4 +- webrender/src/profiler.rs | 338 ++-- webrender/src/record.rs | 24 +- webrender/src/render_backend.rs | 383 ++-- webrender/src/render_task.rs | 208 ++- webrender/src/renderer.rs | 1943 ++++++++++++-------- webrender/src/resource_cache.rs | 373 ++-- webrender/src/scene.rs | 64 +- webrender/src/spring.rs | 29 +- webrender/src/texture_allocator.rs | 85 +- webrender/src/texture_cache.rs | 338 ++-- webrender/src/tiling.rs | 1053 ++++++----- webrender/src/util.rs | 109 +- webrender/tests/angle_shader_validation.rs | 98 +- webrender_api/src/api.rs | 226 ++- webrender_api/src/channel.rs | 25 +- webrender_api/src/color.rs | 20 +- webrender_api/src/display_item.rs | 120 +- webrender_api/src/display_list.rs | 501 ++--- webrender_api/src/font.rs | 73 +- webrender_api/src/image.rs | 59 +- webrender_api/src/lib.rs | 5 +- webrender_api/src/units.rs | 2 +- wrench/build.rs | 9 +- wrench/src/binary_frame_reader.rs | 34 +- wrench/src/blob.rs | 43 +- wrench/src/json_frame_writer.rs | 214 ++- wrench/src/main.rs | 405 ++-- wrench/src/parse_function.rs | 17 +- wrench/src/perf.rs | 98 +- wrench/src/png.rs | 26 +- wrench/src/premultiply.rs | 12 +- wrench/src/rawtest.rs | 95 +- wrench/src/reftest.rs | 150 +- wrench/src/scene.rs | 26 +- wrench/src/wrench.rs | 281 +-- wrench/src/yaml_frame_reader.rs | 856 ++++++--- wrench/src/yaml_frame_writer.rs | 505 +++-- wrench/src/yaml_helper.rs | 253 +-- 74 files changed, 9703 insertions(+), 7188 deletions(-) create mode 100644 rustfmt.toml diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000000..d43a44fcbd --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,6 @@ +reorder_imports = false +reorder_imports_in_group = true +reorder_imported_names = true +error_on_line_overflow_comments = false +max_width = 100 +spaces_around_ranges = true diff --git a/webrender/build.rs b/webrender/build.rs index 5f31d5121a..53b7450e8f 100644 --- a/webrender/build.rs +++ b/webrender/build.rs @@ -3,9 +3,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use std::env; -use std::path::{Path, PathBuf}; -use std::io::prelude::*; use std::fs::{canonicalize, read_dir, File}; +use std::io::prelude::*; +use std::path::{Path, PathBuf}; fn write_shaders(glsl_files: Vec, shader_file_path: &Path) { let mut shader_file = File::create(shader_file_path).unwrap(); @@ -13,7 +13,10 @@ fn write_shaders(glsl_files: Vec, shader_file_path: &Path) { write!(shader_file, "/// AUTO GENERATED BY build.rs\n\n").unwrap(); write!(shader_file, "use std::collections::HashMap;\n").unwrap(); write!(shader_file, "lazy_static! {{\n").unwrap(); - write!(shader_file, " pub static ref SHADERS: HashMap<&'static str, &'static str> = {{\n").unwrap(); + write!( + shader_file, + " pub static ref SHADERS: HashMap<&'static str, &'static str> = {{\n" + ).unwrap(); write!(shader_file, " let mut h = HashMap::new();\n").unwrap(); for glsl in glsl_files { let shader_name = glsl.file_name().unwrap().to_str().unwrap(); @@ -24,8 +27,12 @@ fn write_shaders(glsl_files: Vec, shader_file_path: &Path) { // if someone is building on a network share, I'm sorry. let full_name = full_name.replace("\\\\?\\", ""); let full_name = full_name.replace("\\", "/"); - write!(shader_file, " h.insert(\"{}\", include_str!(\"{}\"));\n", - shader_name, full_name).unwrap(); + write!( + shader_file, + " h.insert(\"{}\", include_str!(\"{}\"));\n", + shader_name, + full_name + ).unwrap(); } write!(shader_file, " h\n").unwrap(); write!(shader_file, " }};\n").unwrap(); diff --git a/webrender/examples/animation.rs b/webrender/examples/animation.rs index df451a2726..23420b83d9 100644 --- a/webrender/examples/animation.rs +++ b/webrender/examples/animation.rs @@ -6,7 +6,7 @@ extern crate gleam; extern crate glutin; extern crate webrender; -#[path="common/boilerplate.rs"] +#[path = "common/boilerplate.rs"] mod boilerplate; use boilerplate::{Example, HandyDandyRectBuilder}; @@ -20,30 +20,34 @@ struct App { } impl Example for App { - fn render(&mut self, - _api: &RenderApi, - builder: &mut DisplayListBuilder, - _resources: &mut ResourceUpdates, - _layout_size: LayoutSize, - _pipeline_id: PipelineId, - _document_id: DocumentId) { + fn render( + &mut self, + _api: &RenderApi, + builder: &mut DisplayListBuilder, + _resources: &mut ResourceUpdates, + _layout_size: LayoutSize, + _pipeline_id: PipelineId, + _document_id: DocumentId, + ) { // Create a 100x100 stacking context with an animatable transform property. // Note the magic "42" we use as the animation key. That is used to update // the transform in the keyboard event handler code. - let bounds = (0,0).to(100, 100); + let bounds = (0, 0).to(100, 100); let info = LayoutPrimitiveInfo { rect: bounds, local_clip: None, is_backface_visible: true, }; - builder.push_stacking_context(&info, - ScrollPolicy::Scrollable, - Some(PropertyBinding::Binding(PropertyBindingKey::new(42))), - TransformStyle::Flat, - None, - MixBlendMode::Normal, - Vec::new()); + builder.push_stacking_context( + &info, + ScrollPolicy::Scrollable, + Some(PropertyBinding::Binding(PropertyBindingKey::new(42))), + TransformStyle::Flat, + None, + MixBlendMode::Normal, + Vec::new(), + ); // Fill it with a white rect builder.push_rect(&info, ColorF::new(1.0, 1.0, 1.0, 1.0)); @@ -51,35 +55,36 @@ impl Example for App { builder.pop_stacking_context(); } - fn on_event(&mut self, - event: glutin::Event, - api: &RenderApi, - document_id: DocumentId) -> bool { + fn on_event(&mut self, event: glutin::Event, api: &RenderApi, document_id: DocumentId) -> bool { match event { glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(key)) => { let offset = match key { - glutin::VirtualKeyCode::Down => (0.0, 10.0), - glutin::VirtualKeyCode::Up => (0.0, -10.0), - glutin::VirtualKeyCode::Right => (10.0, 0.0), - glutin::VirtualKeyCode::Left => (-10.0, 0.0), - _ => return false, + glutin::VirtualKeyCode::Down => (0.0, 10.0), + glutin::VirtualKeyCode::Up => (0.0, -10.0), + glutin::VirtualKeyCode::Right => (10.0, 0.0), + glutin::VirtualKeyCode::Left => (-10.0, 0.0), + _ => return false, }; // Update the transform based on the keyboard input and push it to // webrender using the generate_frame API. This will recomposite with // the updated transform. - let new_transform = self.transform.post_translate(LayoutVector3D::new(offset.0, offset.1, 0.0)); - api.generate_frame(document_id, Some(DynamicProperties { - transforms: vec![ - PropertyValue { - key: PropertyBindingKey::new(42), - value: new_transform, - }, - ], - floats: vec![], - })); + let new_transform = self.transform + .post_translate(LayoutVector3D::new(offset.0, offset.1, 0.0)); + api.generate_frame( + document_id, + Some(DynamicProperties { + transforms: vec![ + PropertyValue { + key: PropertyBindingKey::new(42), + value: new_transform, + }, + ], + floats: vec![], + }), + ); self.transform = new_transform; } - _ => () + _ => (), } false diff --git a/webrender/examples/basic.rs b/webrender/examples/basic.rs index beace7a5f1..b5b5304feb 100644 --- a/webrender/examples/basic.rs +++ b/webrender/examples/basic.rs @@ -8,7 +8,7 @@ extern crate gleam; extern crate glutin; extern crate webrender; -#[path="common/boilerplate.rs"] +#[path = "common/boilerplate.rs"] mod boilerplate; use app_units::Au; @@ -52,7 +52,12 @@ impl Touch { } fn current_distance_from_other(&self, other: &Touch) -> f32 { - dist(self.current_x, self.current_y, other.current_x, other.current_y) + dist( + self.current_x, + self.current_y, + other.current_x, + other.current_y, + ) } } @@ -87,13 +92,16 @@ impl TouchState { match touch.phase { TouchPhase::Started => { debug_assert!(!self.active_touches.contains_key(&touch.id)); - self.active_touches.insert(touch.id, Touch { - id: touch.id, - start_x: touch.location.0 as f32, - start_y: touch.location.1 as f32, - current_x: touch.location.0 as f32, - current_y: touch.location.1 as f32, - }); + self.active_touches.insert( + touch.id, + Touch { + id: touch.id, + start_x: touch.location.0 as f32, + start_y: touch.location.1 as f32, + current_x: touch.location.0 as f32, + current_y: touch.location.1 as f32, + }, + ); self.current_gesture = Gesture::None; } TouchPhase::Moved => { @@ -102,7 +110,7 @@ impl TouchState { active_touch.current_x = touch.location.0 as f32; active_touch.current_y = touch.location.1 as f32; } - None => panic!("move touch event with unknown touch id!") + None => panic!("move touch event with unknown touch id!"), } match self.current_gesture { @@ -177,33 +185,37 @@ struct App { } impl Example for App { - fn render(&mut self, - api: &RenderApi, - builder: &mut DisplayListBuilder, - resources: &mut ResourceUpdates, - layout_size: LayoutSize, - _pipeline_id: PipelineId, - _document_id: DocumentId) { + fn render( + &mut self, + api: &RenderApi, + builder: &mut DisplayListBuilder, + resources: &mut ResourceUpdates, + layout_size: LayoutSize, + _pipeline_id: PipelineId, + _document_id: DocumentId, + ) { let bounds = LayoutRect::new(LayoutPoint::zero(), layout_size); let info = LayoutPrimitiveInfo { rect: bounds, local_clip: None, is_backface_visible: true, }; - builder.push_stacking_context(&info, - ScrollPolicy::Scrollable, - None, - TransformStyle::Flat, - None, - MixBlendMode::Normal, - Vec::new()); + builder.push_stacking_context( + &info, + ScrollPolicy::Scrollable, + None, + TransformStyle::Flat, + None, + MixBlendMode::Normal, + Vec::new(), + ); let image_mask_key = api.generate_image_key(); resources.add_image( image_mask_key, ImageDescriptor::new(2, 2, ImageFormat::A8, true), ImageData::new(vec![0, 80, 180, 255]), - None + None, ); let mask = ImageMask { image: image_mask_key, @@ -253,7 +265,8 @@ impl Example for App { builder.push_border(&info, border_widths, border_details); - if false { // draw text? + if false { + // draw text? let font_key = api.generate_font_key(); let font_bytes = load_file("res/FreeSans.ttf"); resources.add_raw_font(font_key, font_bytes, 0); @@ -318,14 +331,17 @@ impl Example for App { is_backface_visible: true, }; - builder.push_text(&info, - &glyphs, - font_instance_key, - ColorF::new(1.0, 1.0, 0.0, 1.0), - None); + builder.push_text( + &info, + &glyphs, + font_instance_key, + ColorF::new(1.0, 1.0, 0.0, 1.0), + None, + ); } - if false { // draw box shadow? + if false { + // draw box shadow? let rect = LayoutRect::zero(); let simple_box_bounds = (20, 200).by(50, 50); let offset = vec2(10.0, 10.0); @@ -340,39 +356,36 @@ impl Example for App { is_backface_visible: true, }; - builder.push_box_shadow(&info, - simple_box_bounds, - offset, - color, - blur_radius, - spread_radius, - simple_border_radius, - box_shadow_type); + builder.push_box_shadow( + &info, + simple_box_bounds, + offset, + color, + blur_radius, + spread_radius, + simple_border_radius, + box_shadow_type, + ); } builder.pop_clip_id(); builder.pop_stacking_context(); } - fn on_event(&mut self, - event: glutin::Event, - api: &RenderApi, - document_id: DocumentId) -> bool { + fn on_event(&mut self, event: glutin::Event, api: &RenderApi, document_id: DocumentId) -> bool { match event { - glutin::Event::Touch(touch) => { - match self.touch_state.handle_event(touch) { - TouchResult::Pan(pan) => { - api.set_pan(document_id, pan); - api.generate_frame(document_id, None); - } - TouchResult::Zoom(zoom) => { - api.set_pinch_zoom(document_id, ZoomFactor::new(zoom)); - api.generate_frame(document_id, None); - } - TouchResult::None => {} + glutin::Event::Touch(touch) => match self.touch_state.handle_event(touch) { + TouchResult::Pan(pan) => { + api.set_pan(document_id, pan); + api.generate_frame(document_id, None); } - } - _ => () + TouchResult::Zoom(zoom) => { + api.set_pinch_zoom(document_id, ZoomFactor::new(zoom)); + api.generate_frame(document_id, None); + } + TouchResult::None => {} + }, + _ => (), } false diff --git a/webrender/examples/blob.rs b/webrender/examples/blob.rs index 3c02a6a67c..86a39ca343 100644 --- a/webrender/examples/blob.rs +++ b/webrender/examples/blob.rs @@ -4,20 +4,21 @@ extern crate gleam; extern crate glutin; -extern crate webrender; extern crate rayon; +extern crate webrender; -#[path="common/boilerplate.rs"] +#[path = "common/boilerplate.rs"] mod boilerplate; use boilerplate::{Example, HandyDandyRectBuilder}; -use rayon::ThreadPool; use rayon::Configuration as ThreadPoolConfig; +use rayon::ThreadPool; use std::collections::HashMap; use std::collections::hash_map::Entry; use std::sync::Arc; -use std::sync::mpsc::{channel, Sender, Receiver}; -use webrender::api::{self, RenderApi, DisplayListBuilder, ResourceUpdates, LayoutSize, PipelineId, DocumentId}; +use std::sync::mpsc::{channel, Receiver, Sender}; +use webrender::api::{self, DisplayListBuilder, DocumentId, LayoutSize, PipelineId, RenderApi, + ResourceUpdates}; // This example shows how to implement a very basic BlobImageRenderer that can only render // a checkerboard pattern. @@ -38,15 +39,15 @@ fn deserialize_blob(blob: &[u8]) -> Result { (Some(&r), Some(&g), Some(&b), Some(&a)) => Ok(api::ColorU::new(r, g, b, a)), (Some(&a), None, None, None) => Ok(api::ColorU::new(a, a, a, a)), _ => Err(()), - } + }; } // This is the function that applies the deserialized drawing commands and generates // actual image data. fn render_blob( commands: Arc, - descriptor: &api::BlobImageDescriptor, - tile: Option + descriptor: &api::BlobImageDescriptor, + tile: Option, ) -> api::BlobImageResult { let color = *commands; @@ -61,15 +62,19 @@ fn render_blob( None => true, }; - for y in 0..descriptor.height { - for x in 0..descriptor.width { + for y in 0 .. descriptor.height { + for x in 0 .. descriptor.width { // Apply the tile's offset. This is important: all drawing commands should be // translated by this offset to give correct results with tiled blob images. let x2 = x + descriptor.offset.x as u32; let y2 = y + descriptor.offset.y as u32; // Render a simple checkerboard pattern - let checker = if (x2 % 20 >= 10) != (y2 % 20 >= 10) { 1 } else { 0 }; + let checker = if (x2 % 20 >= 10) != (y2 % 20 >= 10) { + 1 + } else { + 0 + }; // ..nested in the per-tile cherkerboard pattern let tc = if tile_checker { 0 } else { (1 - checker) * 40 }; @@ -84,10 +89,9 @@ fn render_blob( texels.push(color.a * checker + tc); } _ => { - return Err(api::BlobImageError::Other(format!( - "Usupported image format {:?}", - descriptor.format - ))); + return Err(api::BlobImageError::Other( + format!("Usupported image format {:?}", descriptor.format), + )); } } } @@ -137,24 +141,28 @@ impl CheckerboardRenderer { impl api::BlobImageRenderer for CheckerboardRenderer { fn add(&mut self, key: api::ImageKey, cmds: api::BlobImageData, _: Option) { - self.image_cmds.insert(key, Arc::new(deserialize_blob(&cmds[..]).unwrap())); + self.image_cmds + .insert(key, Arc::new(deserialize_blob(&cmds[..]).unwrap())); } fn update(&mut self, key: api::ImageKey, cmds: api::BlobImageData) { // Here, updating is just replacing the current version of the commands with // the new one (no incremental updates). - self.image_cmds.insert(key, Arc::new(deserialize_blob(&cmds[..]).unwrap())); + self.image_cmds + .insert(key, Arc::new(deserialize_blob(&cmds[..]).unwrap())); } fn delete(&mut self, key: api::ImageKey) { self.image_cmds.remove(&key); } - fn request(&mut self, - _resources: &api::BlobImageResources, - request: api::BlobImageRequest, - descriptor: &api::BlobImageDescriptor, - _dirty_rect: Option) { + fn request( + &mut self, + _resources: &api::BlobImageResources, + request: api::BlobImageRequest, + descriptor: &api::BlobImageDescriptor, + _dirty_rect: Option, + ) { // This method is where we kick off our rendering jobs. // It should avoid doing work on the calling thread as much as possible. // In this example we will use the thread pool to render individual tiles. @@ -199,7 +207,7 @@ impl api::BlobImageRenderer for CheckerboardRenderer { while let Ok((req, result)) = self.rx.recv() { if req == request { // There it is! - return result + return result; } self.rendered_images.insert(req, Some(result)); } @@ -207,22 +215,22 @@ impl api::BlobImageRenderer for CheckerboardRenderer { // If we break out of the loop above it means the channel closed unexpectedly. Err(api::BlobImageError::Other("Channel closed".into())) } - fn delete_font(&mut self, _font: api::FontKey) { } - fn delete_font_instance(&mut self, _instance: api::FontInstanceKey) { } + fn delete_font(&mut self, _font: api::FontKey) {} + fn delete_font_instance(&mut self, _instance: api::FontInstanceKey) {} } -struct App { - -} +struct App {} impl Example for App { - fn render(&mut self, - api: &RenderApi, - builder: &mut DisplayListBuilder, - resources: &mut ResourceUpdates, - layout_size: LayoutSize, - _pipeline_id: PipelineId, - _document_id: DocumentId) { + fn render( + &mut self, + api: &RenderApi, + builder: &mut DisplayListBuilder, + resources: &mut ResourceUpdates, + layout_size: LayoutSize, + _pipeline_id: PipelineId, + _document_id: DocumentId, + ) { let blob_img1 = api.generate_image_key(); resources.add_image( blob_img1, @@ -245,13 +253,15 @@ impl Example for App { local_clip: None, is_backface_visible: true, }; - builder.push_stacking_context(&info, - api::ScrollPolicy::Scrollable, - None, - api::TransformStyle::Flat, - None, - api::MixBlendMode::Normal, - Vec::new()); + builder.push_stacking_context( + &info, + api::ScrollPolicy::Scrollable, + None, + api::TransformStyle::Flat, + None, + api::MixBlendMode::Normal, + Vec::new(), + ); let info = api::LayoutPrimitiveInfo { rect: (30, 30).by(500, 500), @@ -282,18 +292,19 @@ impl Example for App { builder.pop_stacking_context(); } - fn on_event(&mut self, - _event: glutin::Event, - _api: &RenderApi, - _document_id: DocumentId) -> bool { + fn on_event( + &mut self, + _event: glutin::Event, + _api: &RenderApi, + _document_id: DocumentId, + ) -> bool { false } } fn main() { - let worker_config = ThreadPoolConfig::new().thread_name(|idx|{ - format!("WebRender:Worker#{}", idx) - }); + let worker_config = + ThreadPoolConfig::new().thread_name(|idx| format!("WebRender:Worker#{}", idx)); let workers = Arc::new(ThreadPool::new(worker_config).unwrap()); @@ -302,7 +313,7 @@ fn main() { // Register our blob renderer, so that WebRender integrates it in the resource cache.. // Share the same pool of worker threads between WebRender and our blob renderer. blob_image_renderer: Some(Box::new(CheckerboardRenderer::new(Arc::clone(&workers)))), - .. Default::default() + ..Default::default() }; let mut app = App {}; diff --git a/webrender/examples/common/boilerplate.rs b/webrender/examples/common/boilerplate.rs index 1b92258272..52756b103d 100644 --- a/webrender/examples/common/boilerplate.rs +++ b/webrender/examples/common/boilerplate.rs @@ -15,9 +15,7 @@ struct Notifier { impl Notifier { fn new(window_proxy: glutin::WindowProxy) -> Notifier { - Notifier { - window_proxy, - } + Notifier { window_proxy } } } @@ -41,41 +39,44 @@ pub trait HandyDandyRectBuilder { // values to build a f32 LayoutRect impl HandyDandyRectBuilder for (i32, i32) { fn to(&self, x2: i32, y2: i32) -> LayoutRect { - LayoutRect::new(LayoutPoint::new(self.0 as f32, self.1 as f32), - LayoutSize::new((x2 - self.0) as f32, (y2 - self.1) as f32)) + LayoutRect::new( + LayoutPoint::new(self.0 as f32, self.1 as f32), + LayoutSize::new((x2 - self.0) as f32, (y2 - self.1) as f32), + ) } fn by(&self, w: i32, h: i32) -> LayoutRect { - LayoutRect::new(LayoutPoint::new(self.0 as f32, self.1 as f32), - LayoutSize::new(w as f32, h as f32)) + LayoutRect::new( + LayoutPoint::new(self.0 as f32, self.1 as f32), + LayoutSize::new(w as f32, h as f32), + ) } } pub trait Example { - fn render(&mut self, - api: &RenderApi, - builder: &mut DisplayListBuilder, - resources: &mut ResourceUpdates, - layout_size: LayoutSize, - pipeline_id: PipelineId, - document_id: DocumentId); - fn on_event(&mut self, - event: glutin::Event, - api: &RenderApi, - document_id: DocumentId) -> bool; + fn render( + &mut self, + api: &RenderApi, + builder: &mut DisplayListBuilder, + resources: &mut ResourceUpdates, + layout_size: LayoutSize, + pipeline_id: PipelineId, + document_id: DocumentId, + ); + fn on_event(&mut self, event: glutin::Event, api: &RenderApi, document_id: DocumentId) -> bool; fn get_external_image_handler(&self) -> Option> { None } - fn get_output_image_handler(&mut self, _gl: &gl::Gl) -> Option> { + fn get_output_image_handler( + &mut self, + _gl: &gl::Gl, + ) -> Option> { None } - fn draw_custom(&self, _gl: &gl::Gl) { - } + fn draw_custom(&self, _gl: &gl::Gl) {} } -pub fn main_wrapper(example: &mut Example, - options: Option) -{ +pub fn main_wrapper(example: &mut Example, options: Option) { let args: Vec = env::args().collect(); let res_path = if args.len() > 1 { Some(PathBuf::from(&args[1])) @@ -84,22 +85,26 @@ pub fn main_wrapper(example: &mut Example, }; let window = glutin::WindowBuilder::new() - .with_title("WebRender Sample App") - .with_multitouch() - .with_gl(glutin::GlRequest::GlThenGles { - opengl_version: (3, 2), - opengles_version: (3, 0) - }) - .build() - .unwrap(); + .with_title("WebRender Sample App") + .with_multitouch() + .with_gl(glutin::GlRequest::GlThenGles { + opengl_version: (3, 2), + opengles_version: (3, 0), + }) + .build() + .unwrap(); unsafe { window.make_current().ok(); } let gl = match gl::GlType::default() { - gl::GlType::Gl => unsafe { gl::GlFns::load_with(|symbol| window.get_proc_address(symbol) as *const _) }, - gl::GlType::Gles => unsafe { gl::GlesFns::load_with(|symbol| window.get_proc_address(symbol) as *const _) }, + gl::GlType::Gl => unsafe { + gl::GlFns::load_with(|symbol| window.get_proc_address(symbol) as *const _) + }, + gl::GlType::Gles => unsafe { + gl::GlesFns::load_with(|symbol| window.get_proc_address(symbol) as *const _) + }, }; println!("OpenGL version {}", gl.get_string(gl::VERSION)); @@ -112,7 +117,7 @@ pub fn main_wrapper(example: &mut Example, debug: true, precache_shaders: true, device_pixel_ratio: window.hidpi_factor(), - .. options.unwrap_or(webrender::RendererOptions::default()) + ..options.unwrap_or(webrender::RendererOptions::default()) }; let size = DeviceUintSize::new(width, height); @@ -138,7 +143,14 @@ pub fn main_wrapper(example: &mut Example, let mut builder = DisplayListBuilder::new(pipeline_id, layout_size); let mut resources = ResourceUpdates::new(); - example.render(&api, &mut builder, &mut resources, layout_size, pipeline_id, document_id); + example.render( + &api, + &mut builder, + &mut resources, + layout_size, + pipeline_id, + document_id, + ); api.set_display_list( document_id, epoch, @@ -146,7 +158,7 @@ pub fn main_wrapper(example: &mut Example, LayoutSize::new(width as f32, height as f32), builder.finalize(), true, - resources + resources, ); api.set_root_pipeline(document_id, pipeline_id); api.generate_frame(document_id, None); @@ -165,52 +177,72 @@ pub fn main_wrapper(example: &mut Example, glutin::Event::KeyboardInput(_, _, Some(glutin::VirtualKeyCode::Escape)) | glutin::Event::KeyboardInput(_, _, Some(glutin::VirtualKeyCode::Q)) => break 'outer, - glutin::Event::KeyboardInput(glutin::ElementState::Pressed, - _, Some(glutin::VirtualKeyCode::P)) => { + glutin::Event::KeyboardInput( + glutin::ElementState::Pressed, + _, + Some(glutin::VirtualKeyCode::P), + ) => { let mut flags = renderer.get_debug_flags(); flags.toggle(webrender::PROFILER_DBG); renderer.set_debug_flags(flags); } - glutin::Event::KeyboardInput(glutin::ElementState::Pressed, - _, Some(glutin::VirtualKeyCode::O)) => { + glutin::Event::KeyboardInput( + glutin::ElementState::Pressed, + _, + Some(glutin::VirtualKeyCode::O), + ) => { let mut flags = renderer.get_debug_flags(); flags.toggle(webrender::RENDER_TARGET_DBG); renderer.set_debug_flags(flags); } - glutin::Event::KeyboardInput(glutin::ElementState::Pressed, - _, Some(glutin::VirtualKeyCode::I)) => { + glutin::Event::KeyboardInput( + glutin::ElementState::Pressed, + _, + Some(glutin::VirtualKeyCode::I), + ) => { let mut flags = renderer.get_debug_flags(); flags.toggle(webrender::TEXTURE_CACHE_DBG); renderer.set_debug_flags(flags); } - glutin::Event::KeyboardInput(glutin::ElementState::Pressed, - _, Some(glutin::VirtualKeyCode::B)) => { + glutin::Event::KeyboardInput( + glutin::ElementState::Pressed, + _, + Some(glutin::VirtualKeyCode::B), + ) => { let mut flags = renderer.get_debug_flags(); flags.toggle(webrender::ALPHA_PRIM_DBG); renderer.set_debug_flags(flags); } - glutin::Event::KeyboardInput(glutin::ElementState::Pressed, - _, Some(glutin::VirtualKeyCode::M)) => { + glutin::Event::KeyboardInput( + glutin::ElementState::Pressed, + _, + Some(glutin::VirtualKeyCode::M), + ) => { api.notify_memory_pressure(); } - _ => { - if example.on_event(event, &api, document_id) { - let mut builder = DisplayListBuilder::new(pipeline_id, layout_size); - let mut resources = ResourceUpdates::new(); - - example.render(&api, &mut builder, &mut resources, layout_size, pipeline_id, document_id); - api.set_display_list( - document_id, - epoch, - Some(root_background_color), - LayoutSize::new(width as f32, height as f32), - builder.finalize(), - true, - resources - ); - api.generate_frame(document_id, None); - } - } + _ => if example.on_event(event, &api, document_id) { + let mut builder = DisplayListBuilder::new(pipeline_id, layout_size); + let mut resources = ResourceUpdates::new(); + + example.render( + &api, + &mut builder, + &mut resources, + layout_size, + pipeline_id, + document_id, + ); + api.set_display_list( + document_id, + epoch, + Some(root_background_color), + LayoutSize::new(width as f32, height as f32), + builder.finalize(), + true, + resources, + ); + api.generate_frame(document_id, None); + }, } } diff --git a/webrender/examples/frame_output.rs b/webrender/examples/frame_output.rs index 3137fc2159..0f78cd317d 100644 --- a/webrender/examples/frame_output.rs +++ b/webrender/examples/frame_output.rs @@ -6,7 +6,7 @@ extern crate gleam; extern crate glutin; extern crate webrender; -#[path="common/boilerplate.rs"] +#[path = "common/boilerplate.rs"] mod boilerplate; use boilerplate::{Example, HandyDandyRectBuilder}; @@ -16,8 +16,16 @@ use webrender::api::*; // This example demonstrates using the frame output feature to copy // the output of a WR framebuffer to a custom texture. -const VS: &str = "#version 130\nin vec2 aPos;out vec2 vUv;\nvoid main() { vUv = aPos; gl_Position = vec4(aPos, 0.0, 1.0); }\n"; -const FS: &str = "#version 130\nout vec4 oFragColor;\nin vec2 vUv;\nuniform sampler2D s;\nvoid main() { oFragColor = texture(s, vUv); }\n"; +const VS: &str = "#version 130 + in vec2 aPos;out vec2 vUv; + void main() { vUv = aPos; gl_Position = vec4(aPos, 0.0, 1.0); } +"; +const FS: &str = "#version 130 + out vec4 oFragColor; + in vec2 vUv; + uniform sampler2D s; + void main() { oFragColor = texture(s, vUv); } +"; struct App { iframe_pipeline_id: Option, @@ -30,9 +38,7 @@ struct OutputHandler { impl OutputHandler { fn new(texture_id: gl::GLuint) -> OutputHandler { - OutputHandler { - texture_id - } + OutputHandler { texture_id } } } @@ -41,18 +47,19 @@ impl webrender::OutputImageHandler for OutputHandler { Some((self.texture_id, DeviceIntSize::new(100, 100))) } - fn unlock(&mut self, _id: PipelineId) { - } + fn unlock(&mut self, _id: PipelineId) {} } impl Example for App { - fn render(&mut self, - api: &RenderApi, - builder: &mut DisplayListBuilder, - _resources: &mut ResourceUpdates, - _layout_size: LayoutSize, - _pipeline_id: PipelineId, - document_id: DocumentId) { + fn render( + &mut self, + api: &RenderApi, + builder: &mut DisplayListBuilder, + _resources: &mut ResourceUpdates, + _layout_size: LayoutSize, + _pipeline_id: PipelineId, + document_id: DocumentId, + ) { // Build the iframe display list on first render. if self.iframe_pipeline_id.is_none() { let epoch = Epoch(0); @@ -63,19 +70,21 @@ impl Example for App { let mut builder = DisplayListBuilder::new(iframe_pipeline_id, layout_size); let resources = ResourceUpdates::new(); - let bounds = (0,0).to(50, 50); + let bounds = (0, 0).to(50, 50); let info = LayoutPrimitiveInfo { rect: bounds, local_clip: None, is_backface_visible: true, }; - builder.push_stacking_context(&info, - ScrollPolicy::Scrollable, - None, - TransformStyle::Flat, - None, - MixBlendMode::Normal, - Vec::new()); + builder.push_stacking_context( + &info, + ScrollPolicy::Scrollable, + None, + TransformStyle::Flat, + None, + MixBlendMode::Normal, + Vec::new(), + ); builder.push_rect(&info, ColorF::new(1.0, 1.0, 0.0, 1.0)); builder.pop_stacking_context(); @@ -87,26 +96,28 @@ impl Example for App { layout_size, builder.finalize(), true, - resources + resources, ); self.iframe_pipeline_id = Some(iframe_pipeline_id); api.enable_frame_output(document_id, iframe_pipeline_id, true); } - let bounds = (100,100).to(200, 200); + let bounds = (100, 100).to(200, 200); let info = LayoutPrimitiveInfo { rect: bounds, local_clip: None, is_backface_visible: true, }; - builder.push_stacking_context(&info, - ScrollPolicy::Scrollable, - None, - TransformStyle::Flat, - None, - MixBlendMode::Normal, - Vec::new()); + builder.push_stacking_context( + &info, + ScrollPolicy::Scrollable, + None, + TransformStyle::Flat, + None, + MixBlendMode::Normal, + Vec::new(), + ); builder.push_iframe(&info, self.iframe_pipeline_id.unwrap()); @@ -119,14 +130,7 @@ impl Example for App { let pid = create_program(gl); - let vertices: [f32; 12] = [ - 0.0, 1.0, - 1.0, 0.0, - 0.0, 0.0, - 0.0, 1.0, - 1.0, 1.0, - 1.0, 0.0 - ]; + let vertices: [f32; 12] = [0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0]; gl.active_texture(gl::TEXTURE0); gl.bind_texture(gl::TEXTURE_2D, self.texture_id); @@ -150,30 +154,53 @@ impl Example for App { gl.delete_program(pid); } - fn on_event(&mut self, - _event: glutin::Event, - _api: &RenderApi, - _document_id: DocumentId) -> bool { + fn on_event( + &mut self, + _event: glutin::Event, + _api: &RenderApi, + _document_id: DocumentId, + ) -> bool { false } - fn get_output_image_handler(&mut self, gl: &gl::Gl) -> Option> { + fn get_output_image_handler( + &mut self, + gl: &gl::Gl, + ) -> Option> { let texture_id = gl.gen_textures(1)[0]; gl.bind_texture(gl::TEXTURE_2D, texture_id); - gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as gl::GLint); - gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR as gl::GLint); - gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as gl::GLint); - gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as gl::GLint); - gl.tex_image_2d(gl::TEXTURE_2D, - 0, - gl::RGBA as gl::GLint, - 100, - 100, - 0, - gl::BGRA, - gl::UNSIGNED_BYTE, - None); + gl.tex_parameter_i( + gl::TEXTURE_2D, + gl::TEXTURE_MAG_FILTER, + gl::LINEAR as gl::GLint, + ); + gl.tex_parameter_i( + gl::TEXTURE_2D, + gl::TEXTURE_MIN_FILTER, + gl::LINEAR as gl::GLint, + ); + gl.tex_parameter_i( + gl::TEXTURE_2D, + gl::TEXTURE_WRAP_S, + gl::CLAMP_TO_EDGE as gl::GLint, + ); + gl.tex_parameter_i( + gl::TEXTURE_2D, + gl::TEXTURE_WRAP_T, + gl::CLAMP_TO_EDGE as gl::GLint, + ); + gl.tex_image_2d( + gl::TEXTURE_2D, + 0, + gl::RGBA as gl::GLint, + 100, + 100, + 0, + gl::BGRA, + gl::UNSIGNED_BYTE, + None, + ); gl.bind_texture(gl::TEXTURE_2D, 0); self.texture_id = texture_id; @@ -189,10 +216,7 @@ fn main() { boilerplate::main_wrapper(&mut app, None); } -pub fn compile_shader(gl: &gl::Gl, - shader_type: gl::GLenum, - source: &str) - -> gl::GLuint { +pub fn compile_shader(gl: &gl::Gl, shader_type: gl::GLenum, source: &str) -> gl::GLuint { let id = gl.create_shader(shader_type); gl.shader_source(id, &[source.as_bytes()]); gl.compile_shader(id); diff --git a/webrender/examples/iframe.rs b/webrender/examples/iframe.rs index eadcf0aec2..25f0ca67d6 100644 --- a/webrender/examples/iframe.rs +++ b/webrender/examples/iframe.rs @@ -6,7 +6,7 @@ extern crate gleam; extern crate glutin; extern crate webrender; -#[path="common/boilerplate.rs"] +#[path = "common/boilerplate.rs"] mod boilerplate; use boilerplate::{Example, HandyDandyRectBuilder}; @@ -16,21 +16,21 @@ use webrender::api::*; // inside the root pipeline's display list. When it works, a green square is // shown. If it fails, a red square is shown. -struct App { - -} +struct App {} impl Example for App { - fn render(&mut self, - api: &RenderApi, - builder: &mut DisplayListBuilder, - _resources: &mut ResourceUpdates, - _layout_size: LayoutSize, - pipeline_id: PipelineId, - document_id: DocumentId) { + fn render( + &mut self, + api: &RenderApi, + builder: &mut DisplayListBuilder, + _resources: &mut ResourceUpdates, + _layout_size: LayoutSize, + pipeline_id: PipelineId, + document_id: DocumentId, + ) { // All the sub_* things are for the nested pipeline let sub_size = DeviceUintSize::new(100, 100); - let sub_bounds = (0,0).to(sub_size.width as i32, sub_size.height as i32); + let sub_bounds = (0, 0).to(sub_size.width as i32, sub_size.height as i32); let sub_pipeline_id = PipelineId(pipeline_id.0, 42); let mut sub_builder = DisplayListBuilder::new(sub_pipeline_id, sub_bounds.size); @@ -40,13 +40,15 @@ impl Example for App { is_backface_visible: true, }; - sub_builder.push_stacking_context(&info, - ScrollPolicy::Scrollable, - None, - TransformStyle::Flat, - None, - MixBlendMode::Normal, - Vec::new()); + sub_builder.push_stacking_context( + &info, + ScrollPolicy::Scrollable, + None, + TransformStyle::Flat, + None, + MixBlendMode::Normal, + Vec::new(), + ); // green rect visible == success sub_builder.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0)); sub_builder.pop_stacking_context(); @@ -62,23 +64,27 @@ impl Example for App { ); // And this is for the root pipeline - builder.push_stacking_context(&info, - ScrollPolicy::Scrollable, - Some(PropertyBinding::Binding(PropertyBindingKey::new(42))), - TransformStyle::Flat, - None, - MixBlendMode::Normal, - Vec::new()); + builder.push_stacking_context( + &info, + ScrollPolicy::Scrollable, + Some(PropertyBinding::Binding(PropertyBindingKey::new(42))), + TransformStyle::Flat, + None, + MixBlendMode::Normal, + Vec::new(), + ); // red rect under the iframe: if this is visible, things have gone wrong builder.push_rect(&info, ColorF::new(1.0, 0.0, 0.0, 1.0)); builder.push_iframe(&info, sub_pipeline_id); builder.pop_stacking_context(); } - fn on_event(&mut self, - _event: glutin::Event, - _api: &RenderApi, - _document_id: DocumentId) -> bool { + fn on_event( + &mut self, + _event: glutin::Event, + _api: &RenderApi, + _document_id: DocumentId, + ) -> bool { false } } diff --git a/webrender/examples/image_resize.rs b/webrender/examples/image_resize.rs index 0a02ca58b9..5183bce606 100644 --- a/webrender/examples/image_resize.rs +++ b/webrender/examples/image_resize.rs @@ -6,7 +6,7 @@ extern crate gleam; extern crate glutin; extern crate webrender; -#[path="common/boilerplate.rs"] +#[path = "common/boilerplate.rs"] mod boilerplate; use boilerplate::{Example, HandyDandyRectBuilder}; @@ -17,16 +17,18 @@ struct App { } impl Example for App { - fn render(&mut self, - _api: &RenderApi, - builder: &mut DisplayListBuilder, - resources: &mut ResourceUpdates, - _layout_size: LayoutSize, - _pipeline_id: PipelineId, - _document_id: DocumentId) { + fn render( + &mut self, + _api: &RenderApi, + builder: &mut DisplayListBuilder, + resources: &mut ResourceUpdates, + _layout_size: LayoutSize, + _pipeline_id: PipelineId, + _document_id: DocumentId, + ) { let mut image_data = Vec::new(); - for y in 0..32 { - for x in 0..32 { + for y in 0 .. 32 { + for x in 0 .. 32 { let lum = 255 * (((x & 8) == 0) ^ ((y & 8) == 0)) as u8; image_data.extend_from_slice(&[lum, lum, lum, 0xff]); } @@ -45,13 +47,15 @@ impl Example for App { local_clip: None, is_backface_visible: true, }; - builder.push_stacking_context(&info, - ScrollPolicy::Scrollable, - None, - TransformStyle::Flat, - None, - MixBlendMode::Normal, - Vec::new()); + builder.push_stacking_context( + &info, + ScrollPolicy::Scrollable, + None, + TransformStyle::Flat, + None, + MixBlendMode::Normal, + Vec::new(), + ); let image_size = LayoutSize::new(100.0, 100.0); @@ -65,7 +69,7 @@ impl Example for App { image_size, LayoutSize::zero(), ImageRendering::Auto, - self.image_key + self.image_key, ); let info = LayoutPrimitiveInfo { @@ -78,23 +82,20 @@ impl Example for App { image_size, LayoutSize::zero(), ImageRendering::Pixelated, - self.image_key + self.image_key, ); builder.pop_stacking_context(); } - fn on_event(&mut self, - event: glutin::Event, - api: &RenderApi, - document_id: DocumentId) -> bool { + fn on_event(&mut self, event: glutin::Event, api: &RenderApi, document_id: DocumentId) -> bool { match event { glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(key)) => { match key { - glutin::VirtualKeyCode::Space => { + glutin::VirtualKeyCode::Space => { let mut image_data = Vec::new(); - for y in 0..64 { - for x in 0..64 { + for y in 0 .. 64 { + for x in 0 .. 64 { let r = 255 * ((y & 32) == 0) as u8; let g = 255 * ((x & 32) == 0) as u8; image_data.extend_from_slice(&[0, g, r, 0xff]); @@ -102,17 +103,19 @@ impl Example for App { } let mut updates = ResourceUpdates::new(); - updates.update_image(self.image_key, - ImageDescriptor::new(64, 64, ImageFormat::BGRA8, true), - ImageData::new(image_data), - None); + updates.update_image( + self.image_key, + ImageDescriptor::new(64, 64, ImageFormat::BGRA8, true), + ImageData::new(image_data), + None, + ); api.update_resources(updates); api.generate_frame(document_id, None); - } - _ => {} - } - } - _ => {} + } + _ => {} + } + } + _ => {} } false diff --git a/webrender/examples/nested_display_list.rs b/webrender/examples/nested_display_list.rs index a9b904c432..679385a9b2 100644 --- a/webrender/examples/nested_display_list.rs +++ b/webrender/examples/nested_display_list.rs @@ -6,7 +6,7 @@ extern crate gleam; extern crate glutin; extern crate webrender; -#[path="common/boilerplate.rs"] +#[path = "common/boilerplate.rs"] mod boilerplate; use boilerplate::{Example, HandyDandyRectBuilder}; @@ -17,26 +17,30 @@ struct App { } impl Example for App { - fn render(&mut self, - _api: &RenderApi, - builder: &mut DisplayListBuilder, - _resources: &mut ResourceUpdates, - layout_size: LayoutSize, - pipeline_id: PipelineId, - _document_id: DocumentId) { + fn render( + &mut self, + _api: &RenderApi, + builder: &mut DisplayListBuilder, + _resources: &mut ResourceUpdates, + layout_size: LayoutSize, + pipeline_id: PipelineId, + _document_id: DocumentId, + ) { let bounds = LayoutRect::new(LayoutPoint::zero(), layout_size); let info = LayoutPrimitiveInfo { rect: bounds, local_clip: None, is_backface_visible: true, }; - builder.push_stacking_context(&info, - ScrollPolicy::Scrollable, - None, - TransformStyle::Flat, - None, - MixBlendMode::Normal, - Vec::new()); + builder.push_stacking_context( + &info, + ScrollPolicy::Scrollable, + None, + TransformStyle::Flat, + None, + MixBlendMode::Normal, + Vec::new(), + ); let outer_scroll_frame_rect = (100, 100).to(600, 400); let info = LayoutPrimitiveInfo { @@ -46,12 +50,14 @@ impl Example for App { }; builder.push_rect(&info, ColorF::new(1.0, 1.0, 1.0, 1.0)); - let nested_clip_id = builder.define_scroll_frame(None, - (100, 100).to(1000, 1000), - outer_scroll_frame_rect, - vec![], - None, - ScrollSensitivity::ScriptAndInputEvents); + let nested_clip_id = builder.define_scroll_frame( + None, + (100, 100).to(1000, 1000), + outer_scroll_frame_rect, + vec![], + None, + ScrollSensitivity::ScriptAndInputEvents, + ); builder.push_clip_id(nested_clip_id); let mut builder2 = DisplayListBuilder::new(pipeline_id, layout_size); @@ -71,13 +77,15 @@ impl Example for App { local_clip: None, is_backface_visible: true, }; - builder3.push_stacking_context(&info, - ScrollPolicy::Fixed, - None, - TransformStyle::Flat, - None, - MixBlendMode::Normal, - Vec::new()); + builder3.push_stacking_context( + &info, + ScrollPolicy::Fixed, + None, + TransformStyle::Flat, + None, + MixBlendMode::Normal, + Vec::new(), + ); let info = LayoutPrimitiveInfo { rect: (0, 0).to(100, 100), local_clip: None, @@ -96,13 +104,14 @@ impl Example for App { is_backface_visible: true, }; builder3.push_rect(&info, ColorF::new(1.0, 0.0, 1.0, 0.5)); - let inner_nested_clip_id = - builder3.define_scroll_frame(None, - (330, 110).to(2000, 2000), - inner_scroll_frame_rect, - vec![], - None, - ScrollSensitivity::ScriptAndInputEvents); + let inner_nested_clip_id = builder3.define_scroll_frame( + None, + (330, 110).to(2000, 2000), + inner_scroll_frame_rect, + vec![], + None, + ScrollSensitivity::ScriptAndInputEvents, + ); builder3.push_clip_id(inner_nested_clip_id); let info = LayoutPrimitiveInfo { rect: (340, 120).to(440, 220), @@ -122,24 +131,23 @@ impl Example for App { builder.pop_stacking_context(); } - fn on_event(&mut self, - event: glutin::Event, - api: &RenderApi, - document_id: DocumentId) -> bool { + fn on_event(&mut self, event: glutin::Event, api: &RenderApi, document_id: DocumentId) -> bool { match event { glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(key)) => { let offset = match key { - glutin::VirtualKeyCode::Down => (0.0, -10.0), - glutin::VirtualKeyCode::Up => (0.0, 10.0), - glutin::VirtualKeyCode::Right => (-10.0, 0.0), - glutin::VirtualKeyCode::Left => (10.0, 0.0), - _ => return false, + glutin::VirtualKeyCode::Down => (0.0, -10.0), + glutin::VirtualKeyCode::Up => (0.0, 10.0), + glutin::VirtualKeyCode::Right => (-10.0, 0.0), + glutin::VirtualKeyCode::Left => (10.0, 0.0), + _ => return false, }; - api.scroll(document_id, - ScrollLocation::Delta(LayoutVector2D::new(offset.0, offset.1)), - self.cursor_position, - ScrollEventPhase::Start); + api.scroll( + document_id, + ScrollLocation::Delta(LayoutVector2D::new(offset.0, offset.1)), + self.cursor_position, + ScrollEventPhase::Start, + ); } glutin::Event::MouseMoved(x, y) => { self.cursor_position = WorldPoint::new(x as f32, y as f32); @@ -155,12 +163,14 @@ impl Example for App { glutin::MouseScrollDelta::PixelDelta(dx, dy) => (dx, dy), }; - api.scroll(document_id, - ScrollLocation::Delta(LayoutVector2D::new(dx, dy)), - self.cursor_position, - ScrollEventPhase::Start); + api.scroll( + document_id, + ScrollLocation::Delta(LayoutVector2D::new(dx, dy)), + self.cursor_position, + ScrollEventPhase::Start, + ); } - _ => () + _ => (), } false diff --git a/webrender/examples/scrolling.rs b/webrender/examples/scrolling.rs index 4b662d5b88..4d73f0e269 100644 --- a/webrender/examples/scrolling.rs +++ b/webrender/examples/scrolling.rs @@ -6,7 +6,7 @@ extern crate gleam; extern crate glutin; extern crate webrender; -#[path="common/boilerplate.rs"] +#[path = "common/boilerplate.rs"] mod boilerplate; use boilerplate::{Example, HandyDandyRectBuilder}; @@ -17,49 +17,57 @@ struct App { } impl Example for App { - fn render(&mut self, - _api: &RenderApi, - builder: &mut DisplayListBuilder, - _resources: &mut ResourceUpdates, - layout_size: LayoutSize, - _pipeline_id: PipelineId, - _document_id: DocumentId) { + fn render( + &mut self, + _api: &RenderApi, + builder: &mut DisplayListBuilder, + _resources: &mut ResourceUpdates, + layout_size: LayoutSize, + _pipeline_id: PipelineId, + _document_id: DocumentId, + ) { let info = LayoutPrimitiveInfo { rect: LayoutRect::new(LayoutPoint::zero(), layout_size), local_clip: None, is_backface_visible: true, }; - builder.push_stacking_context(&info, - ScrollPolicy::Scrollable, - None, - TransformStyle::Flat, - None, - MixBlendMode::Normal, - Vec::new()); - - if true { // scrolling and clips stuff + builder.push_stacking_context( + &info, + ScrollPolicy::Scrollable, + None, + TransformStyle::Flat, + None, + MixBlendMode::Normal, + Vec::new(), + ); + + if true { + // scrolling and clips stuff // let's make a scrollbox let scrollbox = (0, 0).to(300, 400); let info = LayoutPrimitiveInfo { - rect: LayoutRect::new(LayoutPoint::new(10.0, 10.0), - LayoutSize::zero()), + rect: LayoutRect::new(LayoutPoint::new(10.0, 10.0), LayoutSize::zero()), local_clip: None, is_backface_visible: true, }; - builder.push_stacking_context(&info, - ScrollPolicy::Scrollable, - None, - TransformStyle::Flat, - None, - MixBlendMode::Normal, - Vec::new()); + builder.push_stacking_context( + &info, + ScrollPolicy::Scrollable, + None, + TransformStyle::Flat, + None, + MixBlendMode::Normal, + Vec::new(), + ); // set the scrolling clip - let clip_id = builder.define_scroll_frame(None, - (0, 0).by(1000, 1000), - scrollbox, - vec![], - None, - ScrollSensitivity::ScriptAndInputEvents); + let clip_id = builder.define_scroll_frame( + None, + (0, 0).by(1000, 1000), + scrollbox, + vec![], + None, + ScrollSensitivity::ScriptAndInputEvents, + ); builder.push_clip_id(clip_id); // now put some content into it. @@ -86,18 +94,19 @@ impl Example for App { local_clip: Some(LocalClip::from((60, 10).to(110, 60))), is_backface_visible: true, }; - builder.push_rect(&info, - ColorF::new(0.0, 1.0, 0.0, 1.0)); + builder.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0)); // Below the above rectangles, set up a nested scrollbox. It's still in // the same stacking context, so note that the rects passed in need to // be relative to the stacking context. - let nested_clip_id = builder.define_scroll_frame(None, - (0, 100).to(300, 400), - (0, 100).to(200, 300), - vec![], - None, - ScrollSensitivity::ScriptAndInputEvents); + let nested_clip_id = builder.define_scroll_frame( + None, + (0, 100).to(300, 400), + (0, 100).to(200, 300), + vec![], + None, + ScrollSensitivity::ScriptAndInputEvents, + ); builder.push_clip_id(nested_clip_id); // give it a giant gray background just to distinguish it and to easily @@ -125,8 +134,16 @@ impl Example for App { let sticky_id = builder.define_sticky_frame( None, (50, 140).to(100, 190), - StickyFrameInfo::new(Some(StickySideConstraint{ margin: 10.0, max_offset: 60.0 }), - None, None, None)); + StickyFrameInfo::new( + Some(StickySideConstraint { + margin: 10.0, + max_offset: 60.0, + }), + None, + None, + None, + ), + ); builder.push_clip_id(sticky_id); let info = LayoutPrimitiveInfo { rect: (50, 140).to(100, 190), @@ -155,24 +172,23 @@ impl Example for App { builder.pop_stacking_context(); } - fn on_event(&mut self, - event: glutin::Event, - api: &RenderApi, - document_id: DocumentId) -> bool { + fn on_event(&mut self, event: glutin::Event, api: &RenderApi, document_id: DocumentId) -> bool { match event { glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(key)) => { let offset = match key { - glutin::VirtualKeyCode::Down => (0.0, -10.0), - glutin::VirtualKeyCode::Up => (0.0, 10.0), - glutin::VirtualKeyCode::Right => (-10.0, 0.0), - glutin::VirtualKeyCode::Left => (10.0, 0.0), - _ => return false, + glutin::VirtualKeyCode::Down => (0.0, -10.0), + glutin::VirtualKeyCode::Up => (0.0, 10.0), + glutin::VirtualKeyCode::Right => (-10.0, 0.0), + glutin::VirtualKeyCode::Left => (10.0, 0.0), + _ => return false, }; - api.scroll(document_id, - ScrollLocation::Delta(LayoutVector2D::new(offset.0, offset.1)), - self.cursor_position, - ScrollEventPhase::Start); + api.scroll( + document_id, + ScrollLocation::Delta(LayoutVector2D::new(offset.0, offset.1)), + self.cursor_position, + ScrollEventPhase::Start, + ); } glutin::Event::MouseMoved(x, y) => { self.cursor_position = WorldPoint::new(x as f32, y as f32); @@ -188,12 +204,14 @@ impl Example for App { glutin::MouseScrollDelta::PixelDelta(dx, dy) => (dx, dy), }; - api.scroll(document_id, - ScrollLocation::Delta(LayoutVector2D::new(dx, dy)), - self.cursor_position, - ScrollEventPhase::Start); + api.scroll( + document_id, + ScrollLocation::Delta(LayoutVector2D::new(dx, dy)), + self.cursor_position, + ScrollEventPhase::Start, + ); } - _ => () + _ => (), } false diff --git a/webrender/examples/texture_cache_stress.rs b/webrender/examples/texture_cache_stress.rs index 27b2f00eb4..a5d6033a12 100644 --- a/webrender/examples/texture_cache_stress.rs +++ b/webrender/examples/texture_cache_stress.rs @@ -6,7 +6,7 @@ extern crate gleam; extern crate glutin; extern crate webrender; -#[path="common/boilerplate.rs"] +#[path = "common/boilerplate.rs"] mod boilerplate; use boilerplate::{Example, HandyDandyRectBuilder}; @@ -38,13 +38,15 @@ impl ImageGenerator { fn generate_image(&mut self, size: u32) { let pattern = &self.patterns[self.next_pattern]; self.current_image.clear(); - for y in 0..size { - for x in 0..size { + for y in 0 .. size { + for x in 0 .. size { let lum = 255 * (1 - (((x & 8) == 0) ^ ((y & 8) == 0)) as u8); - self.current_image.extend_from_slice(&[lum * pattern[0], - lum * pattern[1], - lum * pattern[2], - 0xff]); + self.current_image.extend_from_slice(&[ + lum * pattern[0], + lum * pattern[1], + lum * pattern[2], + 0xff, + ]); } } @@ -64,11 +66,10 @@ impl webrender::ExternalImageHandler for ImageGenerator { v0: 0.0, u1: 1.0, v1: 1.0, - source: webrender::ExternalImageSource::RawData(&self.current_image) + source: webrender::ExternalImageSource::RawData(&self.current_image), } } - fn unlock(&mut self, _key: ExternalImageId, _channel_index: u8) { - } + fn unlock(&mut self, _key: ExternalImageId, _channel_index: u8) {} } struct App { @@ -80,26 +81,30 @@ struct App { } impl Example for App { - fn render(&mut self, - api: &RenderApi, - builder: &mut DisplayListBuilder, - resources: &mut ResourceUpdates, - _layout_size: LayoutSize, - _pipeline_id: PipelineId, - _document_id: DocumentId) { + fn render( + &mut self, + api: &RenderApi, + builder: &mut DisplayListBuilder, + resources: &mut ResourceUpdates, + _layout_size: LayoutSize, + _pipeline_id: PipelineId, + _document_id: DocumentId, + ) { let bounds = (0, 0).to(512, 512); let info = LayoutPrimitiveInfo { rect: bounds, local_clip: None, is_backface_visible: true, }; - builder.push_stacking_context(&info, - ScrollPolicy::Scrollable, - None, - TransformStyle::Flat, - None, - MixBlendMode::Normal, - Vec::new()); + builder.push_stacking_context( + &info, + ScrollPolicy::Scrollable, + None, + TransformStyle::Flat, + None, + MixBlendMode::Normal, + Vec::new(), + ); let x0 = 50.0; let y0 = 50.0; @@ -133,7 +138,10 @@ impl Example for App { let x = (i % 128) as f32; let y = (i / 128) as f32; let info = LayoutPrimitiveInfo { - rect: LayoutRect::new(LayoutPoint::new(x0 + image_size.width * x, y0 + image_size.height * y), image_size), + rect: LayoutRect::new( + LayoutPoint::new(x0 + image_size.width * x, y0 + image_size.height * y), + image_size, + ), local_clip: Some(LocalClip::from(bounds)), is_backface_visible: true, }; @@ -143,7 +151,7 @@ impl Example for App { image_size, LayoutSize::zero(), ImageRendering::Auto, - *key + *key, ); } @@ -160,7 +168,7 @@ impl Example for App { image_size, LayoutSize::zero(), ImageRendering::Auto, - image_key + image_key, ); } @@ -177,17 +185,19 @@ impl Example for App { image_size, LayoutSize::zero(), ImageRendering::Auto, - swap_key + swap_key, ); self.swap_index = 1 - self.swap_index; builder.pop_stacking_context(); } - fn on_event(&mut self, - event: glutin::Event, - api: &RenderApi, - _document_id: DocumentId) -> bool { + fn on_event( + &mut self, + event: glutin::Event, + api: &RenderApi, + _document_id: DocumentId, + ) -> bool { match event { glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(key)) => { let mut updates = ResourceUpdates::new(); @@ -196,8 +206,8 @@ impl Example for App { glutin::VirtualKeyCode::S => { self.stress_keys.clear(); - for _ in 0..16 { - for _ in 0..16 { + for _ in 0 .. 16 { + for _ in 0 .. 16 { let size = 4; let image_key = api.generate_image_key(); @@ -215,24 +225,20 @@ impl Example for App { } } } - glutin::VirtualKeyCode::D => { - if let Some(image_key) = self.image_key.take() { - updates.delete_image(image_key); - } - } - glutin::VirtualKeyCode::U => { - if let Some(image_key) = self.image_key { - let size = 128; - self.image_generator.generate_image(size); - - updates.update_image( - image_key, - ImageDescriptor::new(size, size, ImageFormat::BGRA8, true), - ImageData::new(self.image_generator.take()), - None, - ); - } - } + glutin::VirtualKeyCode::D => if let Some(image_key) = self.image_key.take() { + updates.delete_image(image_key); + }, + glutin::VirtualKeyCode::U => if let Some(image_key) = self.image_key { + let size = 128; + self.image_generator.generate_image(size); + + updates.update_image( + image_key, + ImageDescriptor::new(size, size, ImageFormat::BGRA8, true), + ImageData::new(self.image_generator.take()), + None, + ); + }, glutin::VirtualKeyCode::E => { if let Some(image_key) = self.image_key.take() { updates.delete_image(image_key); diff --git a/webrender/examples/yuv.rs b/webrender/examples/yuv.rs index 8074a34c54..a0e268d624 100644 --- a/webrender/examples/yuv.rs +++ b/webrender/examples/yuv.rs @@ -6,7 +6,7 @@ extern crate gleam; extern crate glutin; extern crate webrender; -#[path="common/boilerplate.rs"] +#[path = "common/boilerplate.rs"] mod boilerplate; use boilerplate::Example; @@ -46,7 +46,12 @@ impl Touch { } fn current_distance_from_other(&self, other: &Touch) -> f32 { - dist(self.current_x, self.current_y, other.current_x, other.current_y) + dist( + self.current_x, + self.current_y, + other.current_x, + other.current_y, + ) } } @@ -81,13 +86,16 @@ impl TouchState { match touch.phase { TouchPhase::Started => { debug_assert!(!self.active_touches.contains_key(&touch.id)); - self.active_touches.insert(touch.id, Touch { - id: touch.id, - start_x: touch.location.0 as f32, - start_y: touch.location.1 as f32, - current_x: touch.location.0 as f32, - current_y: touch.location.1 as f32, - }); + self.active_touches.insert( + touch.id, + Touch { + id: touch.id, + start_x: touch.location.0 as f32, + start_y: touch.location.1 as f32, + current_x: touch.location.0 as f32, + current_y: touch.location.1 as f32, + }, + ); self.current_gesture = Gesture::None; } TouchPhase::Moved => { @@ -96,7 +104,7 @@ impl TouchState { active_touch.current_x = touch.location.0 as f32; active_touch.current_y = touch.location.1 as f32; } - None => panic!("move touch event with unknown touch id!") + None => panic!("move touch event with unknown touch id!"), } match self.current_gesture { @@ -157,26 +165,30 @@ struct App { } impl Example for App { - fn render(&mut self, - api: &RenderApi, - builder: &mut DisplayListBuilder, - resources: &mut ResourceUpdates, - layout_size: LayoutSize, - _pipeline_id: PipelineId, - _document_id: DocumentId) { + fn render( + &mut self, + api: &RenderApi, + builder: &mut DisplayListBuilder, + resources: &mut ResourceUpdates, + layout_size: LayoutSize, + _pipeline_id: PipelineId, + _document_id: DocumentId, + ) { let bounds = LayoutRect::new(LayoutPoint::zero(), layout_size); let info = LayoutPrimitiveInfo { rect: bounds, local_clip: None, is_backface_visible: true, }; - builder.push_stacking_context(&info, - ScrollPolicy::Scrollable, - None, - TransformStyle::Flat, - None, - MixBlendMode::Normal, - Vec::new()); + builder.push_stacking_context( + &info, + ScrollPolicy::Scrollable, + None, + TransformStyle::Flat, + None, + MixBlendMode::Normal, + Vec::new(), + ); let yuv_chanel1 = api.generate_image_key(); let yuv_chanel2 = api.generate_image_key(); @@ -234,25 +246,20 @@ impl Example for App { builder.pop_stacking_context(); } - fn on_event(&mut self, - event: glutin::Event, - api: &RenderApi, - document_id: DocumentId) -> bool { + fn on_event(&mut self, event: glutin::Event, api: &RenderApi, document_id: DocumentId) -> bool { match event { - glutin::Event::Touch(touch) => { - match self.touch_state.handle_event(touch) { - TouchResult::Pan(pan) => { - api.set_pan(document_id, pan); - api.generate_frame(document_id, None); - } - TouchResult::Zoom(zoom) => { - api.set_pinch_zoom(document_id, ZoomFactor::new(zoom)); - api.generate_frame(document_id, None); - } - TouchResult::None => {} + glutin::Event::Touch(touch) => match self.touch_state.handle_event(touch) { + TouchResult::Pan(pan) => { + api.set_pan(document_id, pan); + api.generate_frame(document_id, None); } - } - _ => () + TouchResult::Zoom(zoom) => { + api.set_pinch_zoom(document_id, ZoomFactor::new(zoom)); + api.generate_frame(document_id, None); + } + TouchResult::None => {} + }, + _ => (), } false diff --git a/webrender/src/border.rs b/webrender/src/border.rs index cec2a51a65..58b0da174b 100644 --- a/webrender/src/border.rs +++ b/webrender/src/border.rs @@ -6,8 +6,8 @@ use api::{BorderSide, BorderStyle, BorderWidths, ClipAndScrollInfo, ColorF, Laye use api::{LayerPrimitiveInfo, LayerSize, NormalBorder}; use clip::ClipSource; use ellipse::Ellipse; -use gpu_cache::GpuDataRequest; use frame_builder::FrameBuilder; +use gpu_cache::GpuDataRequest; use prim_store::{BorderPrimitiveCpu, PrimitiveContainer}; use tiling::PrimitiveFlags; use util::{lerp, pack_as_float}; @@ -15,8 +15,8 @@ use util::{lerp, pack_as_float}; #[repr(u8)] #[derive(Debug, Copy, Clone, PartialEq)] pub enum BorderCornerInstance { - Single, // Single instance needed - corner styles are same or similar. - Double, // Different corner styles. Draw two instances, one per style. + Single, // Single instance needed - corner styles are same or similar. + Double, // Different corner styles. Draw two instances, one per style. } #[repr(C)] @@ -39,16 +39,23 @@ pub enum BorderCornerKind { None, Solid, Clip(BorderCornerInstance), - Mask(BorderCornerClipData, LayerSize, LayerSize, BorderCornerClipKind), + Mask( + BorderCornerClipData, + LayerSize, + LayerSize, + BorderCornerClipKind, + ), } impl BorderCornerKind { - fn new_mask(kind: BorderCornerClipKind, - width0: f32, - width1: f32, - corner: BorderCorner, - radius: LayerSize, - border_rect: LayerRect) -> BorderCornerKind { + fn new_mask( + kind: BorderCornerClipKind, + width0: f32, + width1: f32, + corner: BorderCorner, + radius: LayerSize, + border_rect: LayerRect, + ) -> BorderCornerKind { let size = LayerSize::new(width0.max(radius.width), width1.max(radius.height)); let (origin, clip_center) = match corner { BorderCorner::TopLeft => { @@ -57,10 +64,10 @@ impl BorderCornerKind { (origin, clip_center) } BorderCorner::TopRight => { - let origin = LayerPoint::new(border_rect.origin.x + - border_rect.size.width - - size.width, - border_rect.origin.y); + let origin = LayerPoint::new( + border_rect.origin.x + border_rect.size.width - size.width, + border_rect.origin.y, + ); let clip_center = origin + LayerSize::new(0.0, size.height); (origin, clip_center) } @@ -70,10 +77,10 @@ impl BorderCornerKind { (origin, clip_center) } BorderCorner::BottomLeft => { - let origin = LayerPoint::new(border_rect.origin.x, - border_rect.origin.y + - border_rect.size.height - - size.height); + let origin = LayerPoint::new( + border_rect.origin.x, + border_rect.origin.y + border_rect.size.height - size.height, + ); let clip_center = origin + LayerSize::new(size.width, 0.0); (origin, clip_center) } @@ -84,10 +91,7 @@ impl BorderCornerKind { corner: pack_as_float(corner as u32), kind: pack_as_float(kind as u32), }; - BorderCornerKind::Mask(clip_data, - radius, - LayerSize::new(width0, width1), - kind) + BorderCornerKind::Mask(clip_data, radius, LayerSize::new(width0, width1), kind) } } @@ -99,29 +103,31 @@ pub enum BorderEdgeKind { } trait NormalBorderHelpers { - fn get_corner(&self, - edge0: &BorderSide, - width0: f32, - edge1: &BorderSide, - width1: f32, - radius: &LayerSize, - corner: BorderCorner, - border_rect: &LayerRect) -> BorderCornerKind; - - fn get_edge(&self, - edge: &BorderSide, - width: f32) -> (BorderEdgeKind, f32); + fn get_corner( + &self, + edge0: &BorderSide, + width0: f32, + edge1: &BorderSide, + width1: f32, + radius: &LayerSize, + corner: BorderCorner, + border_rect: &LayerRect, + ) -> BorderCornerKind; + + fn get_edge(&self, edge: &BorderSide, width: f32) -> (BorderEdgeKind, f32); } impl NormalBorderHelpers for NormalBorder { - fn get_corner(&self, - edge0: &BorderSide, - width0: f32, - edge1: &BorderSide, - width1: f32, - radius: &LayerSize, - corner: BorderCorner, - border_rect: &LayerRect) -> BorderCornerKind { + fn get_corner( + &self, + edge0: &BorderSide, + width0: f32, + edge1: &BorderSide, + width1: f32, + radius: &LayerSize, + corner: BorderCorner, + border_rect: &LayerRect, + ) -> BorderCornerKind { // If either width is zero, a corner isn't formed. if width0 == 0.0 || width1 == 0.0 { return BorderCornerKind::None; @@ -158,22 +164,22 @@ impl NormalBorderHelpers for NormalBorder { } // Dashed and dotted border corners get drawn into a clip mask. - (BorderStyle::Dashed, BorderStyle::Dashed) => { - BorderCornerKind::new_mask(BorderCornerClipKind::Dash, - width0, - width1, - corner, - *radius, - *border_rect) - } - (BorderStyle::Dotted, BorderStyle::Dotted) => { - BorderCornerKind::new_mask(BorderCornerClipKind::Dot, - width0, - width1, - corner, - *radius, - *border_rect) - } + (BorderStyle::Dashed, BorderStyle::Dashed) => BorderCornerKind::new_mask( + BorderCornerClipKind::Dash, + width0, + width1, + corner, + *radius, + *border_rect, + ), + (BorderStyle::Dotted, BorderStyle::Dotted) => BorderCornerKind::new_mask( + BorderCornerClipKind::Dot, + width0, + width1, + corner, + *radius, + *border_rect, + ), // Draw border transitions with dots and/or dashes as // solid segments. The old border path didn't support @@ -183,9 +189,7 @@ impl NormalBorderHelpers for NormalBorder { (BorderStyle::Dotted, _) | (_, BorderStyle::Dotted) | (BorderStyle::Dashed, _) | - (_, BorderStyle::Dashed) => { - BorderCornerKind::Clip(BorderCornerInstance::Single) - } + (_, BorderStyle::Dashed) => BorderCornerKind::Clip(BorderCornerInstance::Single), // Everything else can be handled by drawing the corner twice, // where the shader outputs zero alpha for the side it's not @@ -196,20 +200,17 @@ impl NormalBorderHelpers for NormalBorder { } } - fn get_edge(&self, - edge: &BorderSide, - width: f32) -> (BorderEdgeKind, f32) { + fn get_edge(&self, edge: &BorderSide, width: f32) -> (BorderEdgeKind, f32) { if width == 0.0 { return (BorderEdgeKind::None, 0.0); } match edge.style { - BorderStyle::None | - BorderStyle::Hidden => (BorderEdgeKind::None, 0.0), + BorderStyle::None | BorderStyle::Hidden => (BorderEdgeKind::None, 0.0), - BorderStyle::Solid | - BorderStyle::Inset | - BorderStyle::Outset => (BorderEdgeKind::Solid, width), + BorderStyle::Solid | BorderStyle::Inset | BorderStyle::Outset => { + (BorderEdgeKind::Solid, width) + } BorderStyle::Double | BorderStyle::Groove | @@ -221,13 +222,15 @@ impl NormalBorderHelpers for NormalBorder { } impl FrameBuilder { - fn add_normal_border_primitive(&mut self, - info: &LayerPrimitiveInfo, - border: &NormalBorder, - widths: &BorderWidths, - clip_and_scroll: ClipAndScrollInfo, - corner_instances: [BorderCornerInstance; 4], - clip_sources: Vec) { + fn add_normal_border_primitive( + &mut self, + info: &LayerPrimitiveInfo, + border: &NormalBorder, + widths: &BorderWidths, + clip_and_scroll: ClipAndScrollInfo, + corner_instances: [BorderCornerInstance; 4], + clip_sources: Vec, + ) { let radius = &border.radius; let left = &border.left; let right = &border.right; @@ -235,10 +238,10 @@ impl FrameBuilder { let bottom = &border.bottom; // These colors are used during inset/outset scaling. - let left_color = left.border_color(1.0, 2.0/3.0, 0.3, 0.7); - let top_color = top.border_color(1.0, 2.0/3.0, 0.3, 0.7); - let right_color = right.border_color(2.0/3.0, 1.0, 0.7, 0.3); - let bottom_color = bottom.border_color(2.0/3.0, 1.0, 0.7, 0.3); + let left_color = left.border_color(1.0, 2.0 / 3.0, 0.3, 0.7); + let top_color = top.border_color(1.0, 2.0 / 3.0, 0.3, 0.7); + let right_color = right.border_color(2.0 / 3.0, 1.0, 0.7, 0.3); + let bottom_color = bottom.border_color(2.0 / 3.0, 1.0, 0.7, 0.3); let prim_cpu = BorderPrimitiveCpu { corner_instances, @@ -247,44 +250,51 @@ impl FrameBuilder { // from the deserialized display list, rather // than creating it immediately. gpu_blocks: [ - [ pack_as_float(left.style as u32), - pack_as_float(top.style as u32), - pack_as_float(right.style as u32), - pack_as_float(bottom.style as u32) ].into(), - [ widths.left, - widths.top, - widths.right, - widths.bottom ].into(), + [ + pack_as_float(left.style as u32), + pack_as_float(top.style as u32), + pack_as_float(right.style as u32), + pack_as_float(bottom.style as u32), + ].into(), + [widths.left, widths.top, widths.right, widths.bottom].into(), left_color.into(), top_color.into(), right_color.into(), bottom_color.into(), - [ radius.top_left.width, - radius.top_left.height, - radius.top_right.width, - radius.top_right.height ].into(), - [ radius.bottom_right.width, - radius.bottom_right.height, - radius.bottom_left.width, - radius.bottom_left.height ].into(), + [ + radius.top_left.width, + radius.top_left.height, + radius.top_right.width, + radius.top_right.height, + ].into(), + [ + radius.bottom_right.width, + radius.bottom_right.height, + radius.bottom_left.width, + radius.bottom_left.height, + ].into(), ], }; - self.add_primitive(clip_and_scroll, - info, - clip_sources, - PrimitiveContainer::Border(prim_cpu)); + self.add_primitive( + clip_and_scroll, + info, + clip_sources, + PrimitiveContainer::Border(prim_cpu), + ); } // TODO(gw): This allows us to move border types over to the // simplified shader model one at a time. Once all borders // are converted, this can be removed, along with the complex // border code path. - pub fn add_normal_border(&mut self, - info: &LayerPrimitiveInfo, - border: &NormalBorder, - widths: &BorderWidths, - clip_and_scroll: ClipAndScrollInfo) { + pub fn add_normal_border( + &mut self, + info: &LayerPrimitiveInfo, + border: &NormalBorder, + widths: &BorderWidths, + clip_and_scroll: ClipAndScrollInfo, + ) { // The border shader is quite expensive. For simple borders, we can just draw // the border with a few rectangles. This generally gives better batching, and // a GPU win in fragment shader time. @@ -301,34 +311,42 @@ impl FrameBuilder { let bottom = &border.bottom; let corners = [ - border.get_corner(left, - widths.left, - top, - widths.top, - &radius.top_left, - BorderCorner::TopLeft, - &info.rect), - border.get_corner(right, - widths.right, - top, - widths.top, - &radius.top_right, - BorderCorner::TopRight, - &info.rect), - border.get_corner(right, - widths.right, - bottom, - widths.bottom, - &radius.bottom_right, - BorderCorner::BottomRight, - &info.rect), - border.get_corner(left, - widths.left, - bottom, - widths.bottom, - &radius.bottom_left, - BorderCorner::BottomLeft, - &info.rect), + border.get_corner( + left, + widths.left, + top, + widths.top, + &radius.top_left, + BorderCorner::TopLeft, + &info.rect, + ), + border.get_corner( + right, + widths.right, + top, + widths.top, + &radius.top_right, + BorderCorner::TopRight, + &info.rect, + ), + border.get_corner( + right, + widths.right, + bottom, + widths.bottom, + &radius.bottom_right, + BorderCorner::BottomRight, + &info.rect, + ), + border.get_corner( + left, + widths.left, + bottom, + widths.bottom, + &radius.bottom_left, + BorderCorner::BottomLeft, + &info.rect, + ), ]; let (left_edge, left_len) = border.get_edge(left, widths.left); @@ -336,12 +354,7 @@ impl FrameBuilder { let (right_edge, right_len) = border.get_edge(right, widths.right); let (bottom_edge, bottom_len) = border.get_edge(bottom, widths.bottom); - let edges = [ - left_edge, - top_edge, - right_edge, - bottom_edge, - ]; + let edges = [left_edge, top_edge, right_edge, bottom_edge]; // Use a simple rectangle case when all edges and corners are either // solid or none. @@ -364,40 +377,51 @@ impl FrameBuilder { if top_edge == BorderEdgeKind::Solid { let mut info = info.clone(); info.rect = LayerRect::new(p0, LayerSize::new(rect_width, top_len)); - self.add_solid_rectangle(clip_and_scroll, - &info, - &border.top.color, - PrimitiveFlags::None); + self.add_solid_rectangle( + clip_and_scroll, + &info, + &border.top.color, + PrimitiveFlags::None, + ); } if left_edge == BorderEdgeKind::Solid { let mut info = info.clone(); - info.rect = LayerRect::new(LayerPoint::new(p0.x, p0.y + top_len), - LayerSize::new(left_len, - rect_height - top_len - bottom_len)); - self.add_solid_rectangle(clip_and_scroll, - &info, - &border.left.color, - PrimitiveFlags::None); + info.rect = LayerRect::new( + LayerPoint::new(p0.x, p0.y + top_len), + LayerSize::new(left_len, rect_height - top_len - bottom_len), + ); + self.add_solid_rectangle( + clip_and_scroll, + &info, + &border.left.color, + PrimitiveFlags::None, + ); } if right_edge == BorderEdgeKind::Solid { let mut info = info.clone(); - info.rect = LayerRect::new(LayerPoint::new(p1.x - right_len, - p0.y + top_len), - LayerSize::new(right_len, - rect_height - top_len - bottom_len)); - self.add_solid_rectangle(clip_and_scroll, - &info, - &border.right.color, - PrimitiveFlags::None); + info.rect = LayerRect::new( + LayerPoint::new(p1.x - right_len, p0.y + top_len), + LayerSize::new(right_len, rect_height - top_len - bottom_len), + ); + self.add_solid_rectangle( + clip_and_scroll, + &info, + &border.right.color, + PrimitiveFlags::None, + ); } if bottom_edge == BorderEdgeKind::Solid { let mut info = info.clone(); - info.rect = LayerRect::new(LayerPoint::new(p0.x, p1.y - bottom_len), - LayerSize::new(rect_width, bottom_len)); - self.add_solid_rectangle(clip_and_scroll, - &info, - &border.bottom.color, - PrimitiveFlags::None); + info.rect = LayerRect::new( + LayerPoint::new(p0.x, p1.y - bottom_len), + LayerSize::new(rect_width, bottom_len), + ); + self.add_solid_rectangle( + clip_and_scroll, + &info, + &border.bottom.color, + PrimitiveFlags::None, + ); } } else { // Create clip masks for border corners, if required. @@ -407,10 +431,8 @@ impl FrameBuilder { for (i, corner) in corners.iter().enumerate() { match corner { &BorderCornerKind::Mask(corner_data, corner_radius, widths, kind) => { - let clip_source = BorderCornerClipSource::new(corner_data, - corner_radius, - widths, - kind); + let clip_source = + BorderCornerClipSource::new(corner_data, corner_radius, widths, kind); extra_clips.push(ClipSource::BorderCorner(clip_source)); } &BorderCornerKind::Clip(instance_kind) => { @@ -420,30 +442,36 @@ impl FrameBuilder { } } - self.add_normal_border_primitive(info, - border, - widths, - clip_and_scroll, - corner_instances, - extra_clips); + self.add_normal_border_primitive( + info, + border, + widths, + clip_and_scroll, + corner_instances, + extra_clips, + ); } } } pub trait BorderSideHelpers { - fn border_color(&self, - scale_factor_0: f32, - scale_factor_1: f32, - black_color_0: f32, - black_color_1: f32) -> ColorF; + fn border_color( + &self, + scale_factor_0: f32, + scale_factor_1: f32, + black_color_0: f32, + black_color_1: f32, + ) -> ColorF; } impl BorderSideHelpers for BorderSide { - fn border_color(&self, - scale_factor_0: f32, - scale_factor_1: f32, - black_color_0: f32, - black_color_1: f32) -> ColorF { + fn border_color( + &self, + scale_factor_0: f32, + scale_factor_1: f32, + black_color_0: f32, + black_color_1: f32, + ) -> ColorF { match self.style { BorderStyle::Inset => { if self.color.r != 0.0 || self.color.g != 0.0 || self.color.b != 0.0 { @@ -484,10 +512,12 @@ pub struct BorderCornerClipSource { } impl BorderCornerClipSource { - pub fn new(corner_data: BorderCornerClipData, - corner_radius: LayerSize, - widths: LayerSize, - kind: BorderCornerClipKind) -> BorderCornerClipSource { + pub fn new( + corner_data: BorderCornerClipData, + corner_radius: LayerSize, + widths: LayerSize, + kind: BorderCornerClipKind, + ) -> BorderCornerClipSource { // Work out a dash length (and therefore dash count) // based on the width of the border edges. The "correct" // dash length is not mentioned in the CSS borders @@ -552,18 +582,18 @@ impl BorderCornerClipSource { BorderCornerClipKind::Dash => { // Get the correct dash arc length. self.actual_clip_count = self.max_clip_count; - let dash_arc_length = 0.5 * self.ellipse.total_arc_length / (self.actual_clip_count - 1) as f32; + let dash_arc_length = + 0.5 * self.ellipse.total_arc_length / (self.actual_clip_count - 1) as f32; let mut current_arc_length = -0.5 * dash_arc_length; - for _ in 0..self.actual_clip_count { + for _ in 0 .. self.actual_clip_count { let arc_length0 = current_arc_length; current_arc_length += dash_arc_length; let arc_length1 = current_arc_length; current_arc_length += dash_arc_length; - let dash_data = BorderCornerDashClipData::new(arc_length0, - arc_length1, - &self.ellipse); + let dash_data = + BorderCornerDashClipData::new(arc_length0, arc_length1, &self.ellipse); dash_data.write(&mut request); } @@ -578,9 +608,12 @@ impl BorderCornerClipSource { // ellipse arc. This ensures that we always end up with an exact // half dot at each end of the arc, to match up with the edges. forward_dots.push(DotInfo::new(0.0, self.widths.width)); - back_dots.push(DotInfo::new(self.ellipse.total_arc_length, self.widths.height)); + back_dots.push(DotInfo::new( + self.ellipse.total_arc_length, + self.widths.height, + )); - for dot_index in 0..self.max_clip_count { + for dot_index in 0 .. self.max_clip_count { let prev_forward_pos = *forward_dots.last().unwrap(); let prev_back_pos = *back_dots.last().unwrap(); @@ -591,7 +624,8 @@ impl BorderCornerClipSource { let going_forward = dot_index & 1 == 0; let (next_dot_pos, leftover) = if going_forward { - let next_dot_pos = prev_forward_pos.arc_pos + 2.0 * prev_forward_pos.diameter; + let next_dot_pos = + prev_forward_pos.arc_pos + 2.0 * prev_forward_pos.diameter; (next_dot_pos, prev_back_pos.arc_pos - next_dot_pos) } else { let next_dot_pos = prev_back_pos.arc_pos - 2.0 * prev_back_pos.diameter; @@ -629,17 +663,21 @@ impl BorderCornerClipSource { for (i, dot) in forward_dots.iter().enumerate() { let extra_dist = i as f32 * extra_space_per_dot; - let dot = BorderCornerDotClipData::new(dot.arc_pos + extra_dist, - 0.5 * dot.diameter, - &self.ellipse); + let dot = BorderCornerDotClipData::new( + dot.arc_pos + extra_dist, + 0.5 * dot.diameter, + &self.ellipse, + ); dot.write(&mut request); } for (i, dot) in back_dots.iter().enumerate() { let extra_dist = i as f32 * extra_space_per_dot; - let dot = BorderCornerDotClipData::new(dot.arc_pos - extra_dist, - 0.5 * dot.diameter, - &self.ellipse); + let dot = BorderCornerDotClipData::new( + dot.arc_pos - extra_dist, + 0.5 * dot.diameter, + &self.ellipse, + ); dot.write(&mut request); } @@ -662,14 +700,19 @@ pub struct BorderCornerClipData { /// The shader needs to know which corner, to /// be able to flip the dash tangents to the /// right orientation. - corner: f32, // Of type BorderCorner enum - kind: f32, // Of type BorderCornerClipKind enum + corner: f32, // Of type BorderCorner enum + kind: f32, // Of type BorderCornerClipKind enum } impl BorderCornerClipData { fn write(&self, request: &mut GpuDataRequest) { request.push(self.corner_rect); - request.push([self.clip_center.x, self.clip_center.y, self.corner, self.kind]); + request.push([ + self.clip_center.x, + self.clip_center.y, + self.corner, + self.kind, + ]); } } @@ -688,9 +731,7 @@ pub struct BorderCornerDashClipData { } impl BorderCornerDashClipData { - pub fn new(arc_length0: f32, - arc_length1: f32, - ellipse: &Ellipse) -> BorderCornerDashClipData { + pub fn new(arc_length0: f32, arc_length1: f32, ellipse: &Ellipse) -> BorderCornerDashClipData { let alpha = ellipse.find_angle_for_arc_length(arc_length0); let beta = ellipse.find_angle_for_arc_length(arc_length1); @@ -706,10 +747,18 @@ impl BorderCornerDashClipData { } fn write(&self, request: &mut GpuDataRequest) { - request.push([self.point0.x, self.point0.y, - self.tangent0.x, self.tangent0.y]); - request.push([self.point1.x, self.point1.y, - self.tangent1.x, self.tangent1.y]); + request.push([ + self.point0.x, + self.point0.y, + self.tangent0.x, + self.tangent0.y, + ]); + request.push([ + self.point1.x, + self.point1.y, + self.tangent1.x, + self.tangent1.y, + ]); } } @@ -723,16 +772,11 @@ pub struct BorderCornerDotClipData { } impl BorderCornerDotClipData { - pub fn new(arc_length: f32, - radius: f32, - ellipse: &Ellipse) -> BorderCornerDotClipData { + pub fn new(arc_length: f32, radius: f32, ellipse: &Ellipse) -> BorderCornerDotClipData { let theta = ellipse.find_angle_for_arc_length(arc_length); let (center, _) = ellipse.get_point_and_tangent(theta); - BorderCornerDotClipData { - center, - radius, - } + BorderCornerDotClipData { center, radius } } fn write(&self, request: &mut GpuDataRequest) { @@ -748,9 +792,6 @@ struct DotInfo { impl DotInfo { fn new(arc_pos: f32, diameter: f32) -> DotInfo { - DotInfo { - arc_pos, - diameter, - } + DotInfo { arc_pos, diameter } } } diff --git a/webrender/src/clip.rs b/webrender/src/clip.rs index 26142de207..0c48ef0412 100644 --- a/webrender/src/clip.rs +++ b/webrender/src/clip.rs @@ -27,10 +27,11 @@ pub struct ClipRegion { } impl ClipRegion { - pub fn create_for_clip_node(rect: LayerRect, - mut complex_clips: Vec, - mut image_mask: Option) - -> ClipRegion { + pub fn create_for_clip_node( + rect: LayerRect, + mut complex_clips: Vec, + mut image_mask: Option, + ) -> ClipRegion { // All the coordinates we receive are relative to the stacking context, but we want // to convert them to something relative to the origin of the clip. let negative_origin = -rect.origin.to_vector(); @@ -62,8 +63,8 @@ impl ClipRegion { #[repr(C)] #[derive(Copy, Clone, Debug, PartialEq)] pub enum ClipMode { - Clip, // Pixels inside the region are visible. - ClipOut, // Pixels outside the region are visible. + Clip, // Pixels inside the region are visible. + ClipOut, // Pixels outside the region are visible. } impl Not for ClipMode { @@ -72,7 +73,7 @@ impl Not for ClipMode { fn not(self) -> ClipMode { match self { ClipMode::Clip => ClipMode::ClipOut, - ClipMode::ClipOut => ClipMode::Clip + ClipMode::ClipOut => ClipMode::Clip, } } } @@ -100,7 +101,11 @@ impl From for ClipSources { clips.push(ClipSource::Rectangle(region.main)); for complex in region.complex_clips { - clips.push(ClipSource::RoundedRectangle(complex.rect, complex.radii, ClipMode::Clip)); + clips.push(ClipSource::RoundedRectangle( + complex.rect, + complex.radii, + ClipMode::Clip, + )); } ClipSources::new(clips) @@ -115,9 +120,10 @@ pub struct ClipSources { impl ClipSources { pub fn new(clips: Vec) -> ClipSources { - let clips = clips.into_iter() - .map(|clip| (clip, GpuCacheHandle::new())) - .collect(); + let clips = clips + .into_iter() + .map(|clip| (clip, GpuCacheHandle::new())) + .collect(); ClipSources { clips, @@ -132,19 +138,23 @@ impl ClipSources { &self.clips } - pub fn update(&mut self, - layer_transform: &LayerToWorldTransform, - gpu_cache: &mut GpuCache, - resource_cache: &mut ResourceCache, - device_pixel_ratio: f32) { + pub fn update( + &mut self, + layer_transform: &LayerToWorldTransform, + gpu_cache: &mut GpuCache, + resource_cache: &mut ResourceCache, + device_pixel_ratio: f32, + ) { if self.clips.is_empty() { return; } // compute the local bounds if self.bounds.inner.is_none() { - let mut local_rect = Some(LayerRect::new(LayerPoint::new(-MAX_CLIP, -MAX_CLIP), - LayerSize::new(2.0 * MAX_CLIP, 2.0 * MAX_CLIP))); + let mut local_rect = Some(LayerRect::new( + LayerPoint::new(-MAX_CLIP, -MAX_CLIP), + LayerSize::new(2.0 * MAX_CLIP, 2.0 * MAX_CLIP), + )); let mut local_inner = local_rect; let mut has_clip_out = false; let mut has_border_clip = false; @@ -171,9 +181,10 @@ impl ClipSources { local_rect = local_rect.and_then(|r| r.intersection(rect)); let inner_rect = extract_inner_rect_safe(rect, radius); - local_inner = local_inner.and_then(|r| inner_rect.and_then(|ref inner| r.intersection(inner))); + local_inner = local_inner + .and_then(|r| inner_rect.and_then(|ref inner| r.intersection(inner))); } - ClipSource::BorderCorner{..} => { + ClipSource::BorderCorner { .. } => { has_border_clip = true; } } @@ -224,10 +235,7 @@ impl ClipSources { for &(ref clip, _) in &self.clips { if let ClipSource::Image(ref mask) = *clip { - resource_cache.request_image(mask.image, - ImageRendering::Auto, - None, - gpu_cache); + resource_cache.request_image(mask.image, ImageRendering::Auto, None, gpu_cache); } } } @@ -269,15 +277,13 @@ pub struct MaskBounds { impl MaskBounds { pub fn update(&mut self, transform: &LayerToWorldTransform, device_pixel_ratio: f32) { if let Some(ref mut outer) = self.outer { - let transformed = TransformedRect::new(&outer.local_rect, - transform, - device_pixel_ratio); + let transformed = + TransformedRect::new(&outer.local_rect, transform, device_pixel_ratio); outer.device_rect = transformed.bounding_rect; } if let Some(ref mut inner) = self.inner { - let transformed = TransformedRect::new(&inner.local_rect, - transform, - device_pixel_ratio); + let transformed = + TransformedRect::new(&inner.local_rect, transform, device_pixel_ratio); inner.device_rect = transformed.inner_rect; } } diff --git a/webrender/src/clip_scroll_node.rs b/webrender/src/clip_scroll_node.rs index 1d3effa14c..38c116baf7 100644 --- a/webrender/src/clip_scroll_node.rs +++ b/webrender/src/clip_scroll_node.rs @@ -9,7 +9,7 @@ use api::WorldPoint; use clip::{ClipRegion, ClipSources, ClipSourcesHandle, ClipStore}; use clip_scroll_tree::TransformUpdateState; use geometry::ray_intersects_rect; -use spring::{DAMPING, STIFFNESS, Spring}; +use spring::{Spring, DAMPING, STIFFNESS}; use tiling::PackedLayerIndex; use util::{MatrixHelpers, TransformedRectKind}; @@ -39,9 +39,11 @@ pub struct ClipInfo { } impl ClipInfo { - pub fn new(clip_region: ClipRegion, - packed_layer_index: PackedLayerIndex, - clip_store: &mut ClipStore) -> ClipInfo { + pub fn new( + clip_region: ClipRegion, + packed_layer_index: PackedLayerIndex, + clip_store: &mut ClipStore, + ) -> ClipInfo { let clip_rect = LayerRect::new(clip_region.origin, clip_region.main.size); ClipInfo { clip_sources: clip_store.insert(ClipSources::from(clip_region)), @@ -118,12 +120,13 @@ pub struct ClipScrollNode { } impl ClipScrollNode { - pub fn new_scroll_frame(pipeline_id: PipelineId, - parent_id: ClipId, - frame_rect: &LayerRect, - content_size: &LayerSize, - scroll_sensitivity: ScrollSensitivity) - -> ClipScrollNode { + pub fn new_scroll_frame( + pipeline_id: PipelineId, + parent_id: ClipId, + frame_rect: &LayerRect, + content_size: &LayerSize, + scroll_sensitivity: ScrollSensitivity, + ) -> ClipScrollNode { ClipScrollNode { content_size: *content_size, local_viewport_rect: *frame_rect, @@ -155,13 +158,14 @@ impl ClipScrollNode { } } - pub fn new_reference_frame(parent_id: Option, - local_viewport_rect: &LayerRect, - content_size: LayerSize, - transform: &LayerToScrollTransform, - origin_in_parent_reference_frame: LayerVector2D, - pipeline_id: PipelineId) - -> ClipScrollNode { + pub fn new_reference_frame( + parent_id: Option, + local_viewport_rect: &LayerRect, + content_size: LayerSize, + transform: &LayerToScrollTransform, + origin_in_parent_reference_frame: LayerVector2D, + pipeline_id: PipelineId, + ) -> ClipScrollNode { let info = ReferenceFrameInfo { transform: *transform, origin_in_parent_reference_frame, @@ -182,11 +186,12 @@ impl ClipScrollNode { } } - pub fn new_sticky_frame(parent_id: ClipId, - frame_rect: LayerRect, - sticky_frame_info: StickyFrameInfo, - pipeline_id: PipelineId) - -> ClipScrollNode { + pub fn new_sticky_frame( + parent_id: ClipId, + frame_rect: LayerRect, + sticky_frame_info: StickyFrameInfo, + pipeline_id: PipelineId, + ) -> ClipScrollNode { ClipScrollNode { content_size: frame_rect.size, local_viewport_rect: frame_rect, @@ -214,8 +219,9 @@ impl ClipScrollNode { *scrolling = *new_scrolling; scrolling.scroll_sensitivity = scroll_sensitivity; } - _ if new_scrolling.offset != LayerVector2D::zero() => - warn!("Tried to scroll a non-scroll node."), + _ if new_scrolling.offset != LayerVector2D::zero() => { + warn!("Tried to scroll a non-scroll node.") + } _ => {} } } @@ -239,8 +245,10 @@ impl ClipScrollNode { } let origin = LayerPoint::new(origin.x.max(0.0), origin.y.max(0.0)); - LayerVector2D::new((-origin.x).max(-scrollable_width).min(0.0).round(), - (-origin.y).max(-scrollable_height).min(0.0).round()) + LayerVector2D::new( + (-origin.x).max(-scrollable_width).min(0.0).round(), + (-origin.y).max(-scrollable_height).min(0.0).round(), + ) } ScrollClamping::NoClamping => LayerPoint::zero() - *origin, }; @@ -256,41 +264,49 @@ impl ClipScrollNode { } pub fn update_transform(&mut self, state: &TransformUpdateState) { - let scrolled_parent_combined_clip = state.parent_combined_viewport_rect + let scrolled_parent_combined_clip = state + .parent_combined_viewport_rect .translate(&-state.parent_scroll_offset); let (local_transform, accumulated_scroll_offset) = match self.node_type { NodeType::ReferenceFrame(ref info) => { - self.combined_local_viewport_rect = - info.transform.with_destination::() - .inverse_rect_footprint(&scrolled_parent_combined_clip); + self.combined_local_viewport_rect = info.transform + .with_destination::() + .inverse_rect_footprint(&scrolled_parent_combined_clip); self.reference_frame_relative_scroll_offset = LayerVector2D::zero(); (info.transform, state.parent_accumulated_scroll_offset) } NodeType::Clip(_) | NodeType::ScrollFrame(_) => { // Move the parent's viewport into the local space (of the node origin) // and intersect with the local clip rectangle to get the local viewport. - self.combined_local_viewport_rect = - scrolled_parent_combined_clip.intersection(&self.local_clip_rect) - .unwrap_or(LayerRect::zero()); + self.combined_local_viewport_rect = scrolled_parent_combined_clip + .intersection(&self.local_clip_rect) + .unwrap_or(LayerRect::zero()); self.reference_frame_relative_scroll_offset = state.parent_accumulated_scroll_offset; - (LayerToScrollTransform::identity(), self.reference_frame_relative_scroll_offset) + ( + LayerToScrollTransform::identity(), + self.reference_frame_relative_scroll_offset, + ) } NodeType::StickyFrame(sticky_frame_info) => { - let sticky_offset = - self.calculate_sticky_offset(&self.local_viewport_rect, - &sticky_frame_info, - &state.nearest_scrolling_ancestor_offset, - &state.nearest_scrolling_ancestor_viewport); - - self.combined_local_viewport_rect = - scrolled_parent_combined_clip.translate(&-sticky_offset) - .intersection(&self.local_clip_rect) - .unwrap_or(LayerRect::zero()); + let sticky_offset = self.calculate_sticky_offset( + &self.local_viewport_rect, + &sticky_frame_info, + &state.nearest_scrolling_ancestor_offset, + &state.nearest_scrolling_ancestor_viewport, + ); + + self.combined_local_viewport_rect = scrolled_parent_combined_clip + .translate(&-sticky_offset) + .intersection(&self.local_clip_rect) + .unwrap_or(LayerRect::zero()); self.reference_frame_relative_scroll_offset = state.parent_accumulated_scroll_offset + sticky_offset; - (LayerToScrollTransform::identity(), self.reference_frame_relative_scroll_offset) + ( + LayerToScrollTransform::identity(), + self.reference_frame_relative_scroll_offset, + ) } }; @@ -299,24 +315,25 @@ impl ClipScrollNode { // between our reference frame and this node. For reference frames, we also include // whatever local transformation this reference frame provides. This can be combined // with the local_viewport_rect to get its position in world space. - self.world_viewport_transform = - state.parent_reference_frame_transform - .pre_translate(accumulated_scroll_offset.to_3d()) - .pre_mul(&local_transform.with_destination::()); + self.world_viewport_transform = state + .parent_reference_frame_transform + .pre_translate(accumulated_scroll_offset.to_3d()) + .pre_mul(&local_transform.with_destination::()); // The transformation for any content inside of us is the viewport transformation, plus // whatever scrolling offset we supply as well. let scroll_offset = self.scroll_offset(); - self.world_content_transform = - self.world_viewport_transform.pre_translate(scroll_offset.to_3d()); + self.world_content_transform = self.world_viewport_transform + .pre_translate(scroll_offset.to_3d()); } - fn calculate_sticky_offset(&self, - sticky_rect: &LayerRect, - sticky_frame_info: &StickyFrameInfo, - viewport_scroll_offset: &LayerVector2D, - viewport_rect: &LayerRect) - -> LayerVector2D { + fn calculate_sticky_offset( + &self, + sticky_rect: &LayerRect, + sticky_frame_info: &StickyFrameInfo, + viewport_scroll_offset: &LayerVector2D, + viewport_rect: &LayerRect, + ) -> LayerVector2D { let sticky_rect = sticky_rect.translate(viewport_scroll_offset); let mut sticky_offset = LayerVector2D::zero(); @@ -325,10 +342,10 @@ impl ClipScrollNode { sticky_offset.y = sticky_offset.y.max(0.0).min(info.max_offset); } - if sticky_offset.y == 0.0 { + if sticky_offset.y == 0.0 { if let Some(info) = sticky_frame_info.bottom { sticky_offset.y = (viewport_rect.max_y() - info.margin) - - (sticky_offset.y + sticky_rect.min_y() + sticky_rect.size.height); + (sticky_offset.y + sticky_rect.min_y() + sticky_rect.size.height); sticky_offset.y = sticky_offset.y.min(0.0).max(info.max_offset); } } @@ -338,10 +355,10 @@ impl ClipScrollNode { sticky_offset.x = sticky_offset.x.max(0.0).min(info.max_offset); } - if sticky_offset.x == 0.0 { + if sticky_offset.x == 0.0 { if let Some(info) = sticky_frame_info.right { sticky_offset.x = (viewport_rect.max_x() - info.margin) - - (sticky_offset.x + sticky_rect.min_x() + sticky_rect.size.width); + (sticky_offset.x + sticky_rect.min_x() + sticky_rect.size.width); sticky_offset.x = sticky_offset.x.min(0.0).max(info.max_offset); } } @@ -380,7 +397,7 @@ impl ClipScrollNode { scrolling.offset.y = 0.0; return true; - }, + } ScrollLocation::End => { let end_pos = self.local_viewport_rect.size.height - self.content_size.height; @@ -395,8 +412,8 @@ impl ClipScrollNode { }; let overscroll_amount = scrolling.overscroll_amount(scrollable_width, scrollable_height); - let overscrolling = CAN_OVERSCROLL && (overscroll_amount.x != 0.0 || - overscroll_amount.y != 0.0); + let overscrolling = + CAN_OVERSCROLL && (overscroll_amount.x != 0.0 || overscroll_amount.y != 0.0); if overscrolling { if overscroll_amount.x != 0.0 { delta.x /= overscroll_amount.x.abs() @@ -426,7 +443,8 @@ impl ClipScrollNode { if phase == ScrollEventPhase::Start || phase == ScrollEventPhase::Move(true) { scrolling.started_bouncing_back = false } else if overscrolling && - ((delta.x < 1.0 && delta.y < 1.0) || phase == ScrollEventPhase::End) { + ((delta.x < 1.0 && delta.y < 1.0) || phase == ScrollEventPhase::End) + { scrolling.started_bouncing_back = true; scrolling.bouncing_back = true } @@ -439,15 +457,15 @@ impl ClipScrollNode { } pub fn tick_scrolling_bounce_animation(&mut self) { - if let NodeType::ScrollFrame(ref mut scrolling) = self.node_type { - scrolling.tick_scrolling_bounce_animation(); + if let NodeType::ScrollFrame(ref mut scrolling) = self.node_type { + scrolling.tick_scrolling_bounce_animation(); } } pub fn ray_intersects_node(&self, cursor: &WorldPoint) -> bool { let inv = self.world_viewport_transform.inverse().unwrap(); let z0 = -10000.0; - let z1 = 10000.0; + let z1 = 10000.0; let p0 = inv.transform_point3d(&cursor.extend(z0)); let p1 = inv.transform_point3d(&cursor.extend(z1)); @@ -455,7 +473,11 @@ impl ClipScrollNode { if self.scrollable_width() <= 0. && self.scrollable_height() <= 0. { return false; } - ray_intersects_rect(p0.to_untyped(), p1.to_untyped(), self.local_viewport_rect.to_untyped()) + ray_intersects_rect( + p0.to_untyped(), + p1.to_untyped(), + self.local_viewport_rect.to_untyped(), + ) } pub fn scroll_offset(&self) -> LayerVector2D { @@ -468,8 +490,8 @@ impl ClipScrollNode { pub fn is_overscrolling(&self) -> bool { match self.node_type { NodeType::ScrollFrame(ref scrolling) => { - let overscroll_amount = scrolling.overscroll_amount(self.scrollable_width(), - self.scrollable_height()); + let overscroll_amount = + scrolling.overscroll_amount(self.scrollable_width(), self.scrollable_height()); overscroll_amount.x != 0.0 || overscroll_amount.y != 0.0 } _ => false, @@ -509,7 +531,8 @@ impl ScrollingState { pub fn stretch_overscroll_spring(&mut self, overscroll_amount: LayerVector2D) { let offset = self.offset.to_point(); - self.spring.coords(offset, offset, offset + overscroll_amount); + self.spring + .coords(offset, offset, offset + overscroll_amount); } pub fn tick_scrolling_bounce_animation(&mut self) { @@ -520,10 +543,11 @@ impl ScrollingState { } } - pub fn overscroll_amount(&self, - scrollable_width: f32, - scrollable_height: f32) - -> LayerVector2D { + pub fn overscroll_amount( + &self, + scrollable_width: f32, + scrollable_height: f32, + ) -> LayerVector2D { let overscroll_x = if self.offset.x > 0.0 { -self.offset.x } else if self.offset.x < -scrollable_width { diff --git a/webrender/src/clip_scroll_tree.rs b/webrender/src/clip_scroll_tree.rs index 1997f933fc..18fce3d2ab 100644 --- a/webrender/src/clip_scroll_tree.rs +++ b/webrender/src/clip_scroll_tree.rs @@ -2,13 +2,13 @@ * 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 clip::ClipStore; -use clip_scroll_node::{ClipScrollNode, NodeType, ScrollingState}; -use internal_types::{FastHashSet, FastHashMap}; -use print_tree::{PrintTree, PrintTreePrinter}; use api::{ClipId, LayerPoint, LayerRect, LayerToScrollTransform, LayerToWorldTransform}; use api::{LayerVector2D, PipelineId, ScrollClamping, ScrollEventPhase, ScrollLayerState}; use api::{ScrollLocation, StickyFrameInfo, WorldPoint}; +use clip::ClipStore; +use clip_scroll_node::{ClipScrollNode, NodeType, ScrollingState}; +use internal_types::{FastHashMap, FastHashSet}; +use print_tree::{PrintTree, PrintTreePrinter}; pub type ScrollStates = FastHashMap; @@ -75,8 +75,7 @@ impl ClipScrollTree { self.topmost_scrolling_node_id } - pub fn collect_nodes_bouncing_back(&self) - -> FastHashSet { + pub fn collect_nodes_bouncing_back(&self) -> FastHashSet { let mut nodes_bouncing_back = FastHashSet::default(); for (clip_id, node) in self.nodes.iter() { if let NodeType::ScrollFrame(ref scrolling) = node.node_type { @@ -88,20 +87,22 @@ impl ClipScrollTree { nodes_bouncing_back } - fn find_scrolling_node_at_point_in_node(&self, - cursor: &WorldPoint, - clip_id: ClipId) - -> Option { + fn find_scrolling_node_at_point_in_node( + &self, + cursor: &WorldPoint, + clip_id: ClipId, + ) -> Option { self.nodes.get(&clip_id).and_then(|node| { for child_layer_id in node.children.iter().rev() { if let Some(layer_id) = - self.find_scrolling_node_at_point_in_node(cursor, *child_layer_id) { + self.find_scrolling_node_at_point_in_node(cursor, *child_layer_id) + { return Some(layer_id); } } match node.node_type { - NodeType::ScrollFrame(state) if state.sensitive_to_input_events() => {}, + NodeType::ScrollFrame(state) if state.sensitive_to_input_events() => {} _ => return None, } @@ -122,7 +123,10 @@ impl ClipScrollTree { let mut result = vec![]; for (id, node) in self.nodes.iter() { if let NodeType::ScrollFrame(scrolling) = node.node_type { - result.push(ScrollLayerState { id: *id, scroll_offset: scrolling.offset }) + result.push(ScrollLayerState { + id: *id, + scroll_offset: scrolling.offset, + }) } } result @@ -160,11 +164,12 @@ impl ClipScrollTree { false } - pub fn scroll(&mut self, - scroll_location: ScrollLocation, - cursor: WorldPoint, - phase: ScrollEventPhase) - -> bool { + pub fn scroll( + &mut self, + scroll_location: ScrollLocation, + cursor: WorldPoint, + phase: ScrollEventPhase, + ) -> bool { if self.nodes.is_empty() { return false; } @@ -172,21 +177,22 @@ impl ClipScrollTree { let clip_id = match ( phase, self.find_scrolling_node_at_point(&cursor), - self.currently_scrolling_node_id) { + self.currently_scrolling_node_id, + ) { (ScrollEventPhase::Start, scroll_node_at_point_id, _) => { self.currently_scrolling_node_id = Some(scroll_node_at_point_id); scroll_node_at_point_id - }, + } (_, scroll_node_at_point_id, Some(cached_clip_id)) => { let clip_id = match self.nodes.get(&cached_clip_id) { Some(_) => cached_clip_id, None => { self.currently_scrolling_node_id = Some(scroll_node_at_point_id); scroll_node_at_point_id - }, + } }; clip_id - }, + } (_, _, None) => return false, }; @@ -206,12 +212,12 @@ impl ClipScrollTree { // however we do save the state of non_root_overscroll, // for use in the subsequent Move phase. scrolling.should_handoff_scroll = non_root_overscroll; - }, + } ScrollEventPhase::Move(_) => { // Switch node if movement originated in a new gesture, // from a non root node in overscroll. switch_node = scrolling.should_handoff_scroll && non_root_overscroll - }, + } ScrollEventPhase::End => { // clean-up when gesture ends. scrolling.should_handoff_scroll = false; @@ -226,7 +232,10 @@ impl ClipScrollTree { clip_id }; - self.nodes.get_mut(&clip_id).unwrap().scroll(scroll_location, phase) + self.nodes + .get_mut(&clip_id) + .unwrap() + .scroll(scroll_location, phase) } pub fn update_all_node_transforms(&mut self, pan: LayerPoint) { @@ -237,8 +246,11 @@ impl ClipScrollTree { let root_reference_frame_id = self.root_reference_frame_id(); let root_viewport = self.nodes[&root_reference_frame_id].local_clip_rect; let state = TransformUpdateState { - parent_reference_frame_transform: - LayerToWorldTransform::create_translation(pan.x, pan.y, 0.0), + parent_reference_frame_transform: LayerToWorldTransform::create_translation( + pan.x, + pan.y, + 0.0, + ), parent_combined_viewport_rect: root_viewport, parent_scroll_offset: LayerVector2D::zero(), parent_accumulated_scroll_offset: LayerVector2D::zero(), @@ -268,8 +280,9 @@ impl ClipScrollTree { parent_combined_viewport_rect: node.combined_local_viewport_rect, parent_scroll_offset: LayerVector2D::zero(), parent_accumulated_scroll_offset: LayerVector2D::zero(), - nearest_scrolling_ancestor_viewport: - state.nearest_scrolling_ancestor_viewport.translate(&info.origin_in_parent_reference_frame), + nearest_scrolling_ancestor_viewport: state + .nearest_scrolling_ancestor_viewport + .translate(&info.origin_in_parent_reference_frame), ..*state }, NodeType::Clip(..) | NodeType::StickyFrame(..) => TransformUpdateState { @@ -280,7 +293,8 @@ impl ClipScrollTree { NodeType::ScrollFrame(ref scrolling) => TransformUpdateState { parent_combined_viewport_rect: node.combined_local_viewport_rect, parent_scroll_offset: scrolling.offset, - parent_accumulated_scroll_offset: scrolling.offset + state.parent_accumulated_scroll_offset, + parent_accumulated_scroll_offset: scrolling.offset + + state.parent_accumulated_scroll_offset, nearest_scrolling_ancestor_offset: scrolling.offset, nearest_scrolling_ancestor_viewport: node.local_viewport_rect, ..*state @@ -321,33 +335,40 @@ impl ClipScrollTree { new_id } - pub fn add_reference_frame(&mut self, - rect: &LayerRect, - transform: &LayerToScrollTransform, - origin_in_parent_reference_frame: LayerVector2D, - pipeline_id: PipelineId, - parent_id: Option) - -> ClipId { + pub fn add_reference_frame( + &mut self, + rect: &LayerRect, + transform: &LayerToScrollTransform, + origin_in_parent_reference_frame: LayerVector2D, + pipeline_id: PipelineId, + parent_id: Option, + ) -> ClipId { let reference_frame_id = self.generate_new_clip_id(pipeline_id); - let node = ClipScrollNode::new_reference_frame(parent_id, - rect, - rect.size, - transform, - origin_in_parent_reference_frame, - pipeline_id); + let node = ClipScrollNode::new_reference_frame( + parent_id, + rect, + rect.size, + transform, + origin_in_parent_reference_frame, + pipeline_id, + ); self.add_node(node, reference_frame_id); reference_frame_id } - pub fn add_sticky_frame(&mut self, - id: ClipId, - parent_id: ClipId, - frame_rect: LayerRect, - sticky_frame_info: StickyFrameInfo) { - let node = ClipScrollNode::new_sticky_frame(parent_id, - frame_rect, - sticky_frame_info, - id.pipeline_id()); + pub fn add_sticky_frame( + &mut self, + id: ClipId, + parent_id: ClipId, + frame_rect: LayerRect, + sticky_frame_info: StickyFrameInfo, + ) { + let node = ClipScrollNode::new_sticky_frame( + parent_id, + frame_rect, + sticky_frame_info, + id.pipeline_id(), + ); self.add_node(node, id); } @@ -371,16 +392,16 @@ impl ClipScrollTree { } } - fn print_node(&self, - id: &ClipId, - pt: &mut T, - clip_store: &ClipStore) { + fn print_node(&self, id: &ClipId, pt: &mut T, clip_store: &ClipStore) { let node = self.nodes.get(id).unwrap(); match node.node_type { NodeType::Clip(ref info) => { pt.new_level("Clip".to_owned()); - pt.add_item(format!("screen_bounding_rect: {:?}", info.screen_bounding_rect)); + pt.add_item(format!( + "screen_bounding_rect: {:?}", + info.screen_bounding_rect + )); let clips = clip_store.get(&info.clip_sources).clips(); pt.new_level(format!("Clip Sources [{}]", clips.len())); @@ -403,11 +424,23 @@ impl ClipScrollTree { } pt.add_item(format!("content_size: {:?}", node.content_size)); - pt.add_item(format!("local_viewport_rect: {:?}", node.local_viewport_rect)); + pt.add_item(format!( + "local_viewport_rect: {:?}", + node.local_viewport_rect + )); pt.add_item(format!("local_clip_rect: {:?}", node.local_clip_rect)); - pt.add_item(format!("combined_local_viewport_rect: {:?}", node.combined_local_viewport_rect)); - pt.add_item(format!("world_viewport_transform: {:?}", node.world_viewport_transform)); - pt.add_item(format!("world_content_transform: {:?}", node.world_content_transform)); + pt.add_item(format!( + "combined_local_viewport_rect: {:?}", + node.combined_local_viewport_rect + )); + pt.add_item(format!( + "world_viewport_transform: {:?}", + node.world_viewport_transform + )); + pt.add_item(format!( + "world_content_transform: {:?}", + node.world_content_transform + )); for child_id in &node.children { self.print_node(child_id, pt, clip_store); @@ -420,7 +453,7 @@ impl ClipScrollTree { pub fn print(&self, clip_store: &ClipStore) { if !self.nodes.is_empty() { let mut pt = PrintTree::new("clip_scroll tree"); - self.print_with(clip_store, &mut pt,); + self.print_with(clip_store, &mut pt); } } @@ -430,4 +463,3 @@ impl ClipScrollTree { } } } - diff --git a/webrender/src/debug_render.rs b/webrender/src/debug_render.rs index 6e4699ed88..b409b91b53 100644 --- a/webrender/src/debug_render.rs +++ b/webrender/src/debug_render.rs @@ -2,14 +2,14 @@ * 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 api::{ColorU, DeviceIntRect, DeviceUintSize, ImageFormat}; use debug_font_data; -use device::{Device, GpuMarker, Program, VAO, Texture, TextureSlot, VertexDescriptor}; -use device::{TextureFilter, VertexAttribute, VertexUsageHint, VertexAttributeKind, TextureTarget}; -use euclid::{Transform3D, Point2D, Size2D, Rect}; -use internal_types::{ORTHO_NEAR_PLANE, ORTHO_FAR_PLANE}; +use device::{Device, GpuMarker, Program, Texture, TextureSlot, VertexDescriptor, VAO}; +use device::{TextureFilter, TextureTarget, VertexAttribute, VertexAttributeKind, VertexUsageHint}; +use euclid::{Point2D, Rect, Size2D, Transform3D}; +use internal_types::{ORTHO_FAR_PLANE, ORTHO_NEAR_PLANE}; use internal_types::RenderTargetMode; use std::f32; -use api::{ColorU, ImageFormat, DeviceUintSize, DeviceIntRect}; #[derive(Debug, Copy, Clone)] enum DebugSampler { @@ -26,19 +26,39 @@ impl Into for DebugSampler { const DESC_FONT: VertexDescriptor = VertexDescriptor { vertex_attributes: &[ - VertexAttribute { name: "aPosition", count: 2, kind: VertexAttributeKind::F32 }, - VertexAttribute { name: "aColor", count: 4, kind: VertexAttributeKind::U8Norm }, - VertexAttribute { name: "aColorTexCoord", count: 2, kind: VertexAttributeKind::F32 }, + VertexAttribute { + name: "aPosition", + count: 2, + kind: VertexAttributeKind::F32, + }, + VertexAttribute { + name: "aColor", + count: 4, + kind: VertexAttributeKind::U8Norm, + }, + VertexAttribute { + name: "aColorTexCoord", + count: 2, + kind: VertexAttributeKind::F32, + }, ], - instance_attributes: &[] + instance_attributes: &[], }; const DESC_COLOR: VertexDescriptor = VertexDescriptor { vertex_attributes: &[ - VertexAttribute { name: "aPosition", count: 2, kind: VertexAttributeKind::F32 }, - VertexAttribute { name: "aColor", count: 4, kind: VertexAttributeKind::U8Norm }, + VertexAttribute { + name: "aPosition", + count: 2, + kind: VertexAttributeKind::F32, + }, + VertexAttribute { + name: "aColor", + count: 4, + kind: VertexAttributeKind::U8Norm, + }, ], - instance_attributes: &[] + instance_attributes: &[], }; #[repr(C)] @@ -52,13 +72,7 @@ pub struct DebugFontVertex { impl DebugFontVertex { pub fn new(x: f32, y: f32, u: f32, v: f32, color: ColorU) -> DebugFontVertex { - DebugFontVertex { - x, - y, - color, - u, - v, - } + DebugFontVertex { x, y, color, u, v } } } @@ -71,11 +85,7 @@ pub struct DebugColorVertex { impl DebugColorVertex { pub fn new(x: f32, y: f32, color: ColorU) -> DebugColorVertex { - DebugColorVertex { - x, - y, - color, - } + DebugColorVertex { x, y, color } } } @@ -96,30 +106,28 @@ pub struct DebugRenderer { impl DebugRenderer { pub fn new(device: &mut Device) -> DebugRenderer { - let font_program = device.create_program("debug_font", - "", - &DESC_FONT).unwrap(); - device.bind_shader_samplers(&font_program, &[ - ("sColor0", DebugSampler::Font) - ]); + let font_program = device.create_program("debug_font", "", &DESC_FONT).unwrap(); + device.bind_shader_samplers(&font_program, &[("sColor0", DebugSampler::Font)]); - let color_program = device.create_program("debug_color", - "", - &DESC_COLOR).unwrap(); + let color_program = device + .create_program("debug_color", "", &DESC_COLOR) + .unwrap(); let font_vao = device.create_vao(&DESC_FONT); let line_vao = device.create_vao(&DESC_COLOR); let tri_vao = device.create_vao(&DESC_COLOR); let mut font_texture = device.create_texture(TextureTarget::Array); - device.init_texture(&mut font_texture, - debug_font_data::BMP_WIDTH, - debug_font_data::BMP_HEIGHT, - ImageFormat::A8, - TextureFilter::Linear, - RenderTargetMode::None, - 1, - Some(&debug_font_data::FONT_BITMAP)); + device.init_texture( + &mut font_texture, + debug_font_data::BMP_WIDTH, + debug_font_data::BMP_HEIGHT, + ImageFormat::A8, + TextureFilter::Linear, + RenderTargetMode::None, + 1, + Some(&debug_font_data::FONT_BITMAP), + ); DebugRenderer { font_vertices: Vec::new(), @@ -149,11 +157,7 @@ impl DebugRenderer { debug_font_data::FONT_SIZE as f32 * 1.1 } - pub fn add_text(&mut self, - x: f32, - y: f32, - text: &str, - color: ColorU) -> Rect { + pub fn add_text(&mut self, x: f32, y: f32, text: &str, color: ColorU) -> Rect { let mut x_start = x; let ipw = 1.0 / debug_font_data::BMP_WIDTH as f32; let iph = 1.0 / debug_font_data::BMP_HEIGHT as f32; @@ -183,10 +187,14 @@ impl DebugRenderer { let vertex_count = self.font_vertices.len() as u32; - self.font_vertices.push(DebugFontVertex::new(x0, y0, s0, t0, color)); - self.font_vertices.push(DebugFontVertex::new(x1, y0, s1, t0, color)); - self.font_vertices.push(DebugFontVertex::new(x0, y1, s0, t1, color)); - self.font_vertices.push(DebugFontVertex::new(x1, y1, s1, t1, color)); + self.font_vertices + .push(DebugFontVertex::new(x0, y0, s0, t0, color)); + self.font_vertices + .push(DebugFontVertex::new(x1, y0, s1, t0, color)); + self.font_vertices + .push(DebugFontVertex::new(x0, y1, s0, t1, color)); + self.font_vertices + .push(DebugFontVertex::new(x1, y1, s1, t1, color)); self.font_indices.push(vertex_count + 0); self.font_indices.push(vertex_count + 1); @@ -202,22 +210,31 @@ impl DebugRenderer { } } - Rect::new(Point2D::new(min_x, min_y), Size2D::new(max_x-min_x, max_y-min_y)) + Rect::new( + Point2D::new(min_x, min_y), + Size2D::new(max_x - min_x, max_y - min_y), + ) } - pub fn add_quad(&mut self, - x0: f32, - y0: f32, - x1: f32, - y1: f32, - color_top: ColorU, - color_bottom: ColorU) { + pub fn add_quad( + &mut self, + x0: f32, + y0: f32, + x1: f32, + y1: f32, + color_top: ColorU, + color_bottom: ColorU, + ) { let vertex_count = self.tri_vertices.len() as u32; - self.tri_vertices.push(DebugColorVertex::new(x0, y0, color_top)); - self.tri_vertices.push(DebugColorVertex::new(x1, y0, color_top)); - self.tri_vertices.push(DebugColorVertex::new(x0, y1, color_bottom)); - self.tri_vertices.push(DebugColorVertex::new(x1, y1, color_bottom)); + self.tri_vertices + .push(DebugColorVertex::new(x0, y0, color_top)); + self.tri_vertices + .push(DebugColorVertex::new(x1, y0, color_top)); + self.tri_vertices + .push(DebugColorVertex::new(x0, y1, color_bottom)); + self.tri_vertices + .push(DebugColorVertex::new(x1, y1, color_bottom)); self.tri_indices.push(vertex_count + 0); self.tri_indices.push(vertex_count + 1); @@ -228,15 +245,11 @@ impl DebugRenderer { } #[allow(dead_code)] - pub fn add_line(&mut self, - x0: i32, - y0: i32, - color0: ColorU, - x1: i32, - y1: i32, - color1: ColorU) { - self.line_vertices.push(DebugColorVertex::new(x0 as f32, y0 as f32, color0)); - self.line_vertices.push(DebugColorVertex::new(x1 as f32, y1 as f32, color1)); + pub fn add_line(&mut self, x0: i32, y0: i32, color0: ColorU, x1: i32, y1: i32, color1: ColorU) { + self.line_vertices + .push(DebugColorVertex::new(x0 as f32, y0 as f32, color0)); + self.line_vertices + .push(DebugColorVertex::new(x1 as f32, y1 as f32, color1)); } @@ -249,32 +262,32 @@ impl DebugRenderer { self.add_line(p0.x, p1.y, color, p0.x, p0.y, color); } - pub fn render(&mut self, - device: &mut Device, - viewport_size: &DeviceUintSize) { + pub fn render(&mut self, device: &mut Device, viewport_size: &DeviceUintSize) { let _gm = GpuMarker::new(device.rc_gl(), "debug"); device.disable_depth(); device.set_blend(true); device.set_blend_mode_alpha(); - let projection = Transform3D::ortho(0.0, - viewport_size.width as f32, - viewport_size.height as f32, - 0.0, - ORTHO_NEAR_PLANE, - ORTHO_FAR_PLANE); + let projection = Transform3D::ortho( + 0.0, + viewport_size.width as f32, + viewport_size.height as f32, + 0.0, + ORTHO_NEAR_PLANE, + ORTHO_FAR_PLANE, + ); // Triangles if !self.tri_vertices.is_empty() { device.bind_program(&self.color_program); device.set_uniforms(&self.color_program, &projection); device.bind_vao(&self.tri_vao); - device.update_vao_indices(&self.tri_vao, - &self.tri_indices, - VertexUsageHint::Dynamic); - device.update_vao_main_vertices(&self.tri_vao, - &self.tri_vertices, - VertexUsageHint::Dynamic); + device.update_vao_indices(&self.tri_vao, &self.tri_indices, VertexUsageHint::Dynamic); + device.update_vao_main_vertices( + &self.tri_vao, + &self.tri_vertices, + VertexUsageHint::Dynamic, + ); device.draw_triangles_u32(0, self.tri_indices.len() as i32); } @@ -283,9 +296,11 @@ impl DebugRenderer { device.bind_program(&self.color_program); device.set_uniforms(&self.color_program, &projection); device.bind_vao(&self.line_vao); - device.update_vao_main_vertices(&self.line_vao, - &self.line_vertices, - VertexUsageHint::Dynamic); + device.update_vao_main_vertices( + &self.line_vao, + &self.line_vertices, + VertexUsageHint::Dynamic, + ); device.draw_nonindexed_lines(0, self.line_vertices.len() as i32); } @@ -295,12 +310,12 @@ impl DebugRenderer { device.set_uniforms(&self.font_program, &projection); device.bind_texture(DebugSampler::Font, &self.font_texture); device.bind_vao(&self.font_vao); - device.update_vao_indices(&self.font_vao, - &self.font_indices, - VertexUsageHint::Dynamic); - device.update_vao_main_vertices(&self.font_vao, - &self.font_vertices, - VertexUsageHint::Dynamic); + device.update_vao_indices(&self.font_vao, &self.font_indices, VertexUsageHint::Dynamic); + device.update_vao_main_vertices( + &self.font_vao, + &self.font_vertices, + VertexUsageHint::Dynamic, + ); device.draw_triangles_u32(0, self.font_indices.len() as i32); } diff --git a/webrender/src/debug_server.rs b/webrender/src/debug_server.rs index 6f06ba0707..7924ff5e42 100644 --- a/webrender/src/debug_server.rs +++ b/webrender/src/debug_server.rs @@ -4,11 +4,10 @@ use api::{ApiMsg, DebugCommand}; use api::channel::MsgSender; +use print_tree::PrintTreePrinter; use std::sync::mpsc::{channel, Receiver}; -use std::thread; use std::sync::mpsc::Sender; - -use print_tree::PrintTreePrinter; +use std::thread; use ws; // Messages that are sent from the render backend to the renderer @@ -29,52 +28,34 @@ struct Server { impl ws::Handler for Server { fn on_open(&mut self, _: ws::Handshake) -> ws::Result<()> { - self.debug_tx.send(DebugMsg::AddSender(self.ws.clone())).ok(); + self.debug_tx + .send(DebugMsg::AddSender(self.ws.clone())) + .ok(); Ok(()) } fn on_close(&mut self, _: ws::CloseCode, _: &str) { - self.debug_tx.send(DebugMsg::RemoveSender(self.ws.token())).ok(); + self.debug_tx + .send(DebugMsg::RemoveSender(self.ws.token())) + .ok(); } fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> { match msg { ws::Message::Text(string) => { let cmd = match string.as_str() { - "enable_profiler" => { - DebugCommand::EnableProfiler(true) - } - "disable_profiler" => { - DebugCommand::EnableProfiler(false) - } - "enable_texture_cache_debug" => { - DebugCommand::EnableTextureCacheDebug(true) - } - "disable_texture_cache_debug" => { - DebugCommand::EnableTextureCacheDebug(false) - } - "enable_render_target_debug" => { - DebugCommand::EnableRenderTargetDebug(true) - } - "disable_render_target_debug" => { - DebugCommand::EnableRenderTargetDebug(false) - } - "enable_alpha_rects_debug" => { - DebugCommand::EnableAlphaRectsDebug(true) - } - "disable_alpha_rects_debug" => { - DebugCommand::EnableAlphaRectsDebug(false) - } - "fetch_passes" => { - DebugCommand::FetchPasses - } - "fetch_documents" => { - DebugCommand::FetchDocuments - } - "fetch_clipscrolltree" => { - DebugCommand::FetchClipScrollTree - } + "enable_profiler" => DebugCommand::EnableProfiler(true), + "disable_profiler" => DebugCommand::EnableProfiler(false), + "enable_texture_cache_debug" => DebugCommand::EnableTextureCacheDebug(true), + "disable_texture_cache_debug" => DebugCommand::EnableTextureCacheDebug(false), + "enable_render_target_debug" => DebugCommand::EnableRenderTargetDebug(true), + "disable_render_target_debug" => DebugCommand::EnableRenderTargetDebug(false), + "enable_alpha_rects_debug" => DebugCommand::EnableAlphaRectsDebug(true), + "disable_alpha_rects_debug" => DebugCommand::EnableAlphaRectsDebug(false), + "fetch_passes" => DebugCommand::FetchPasses, + "fetch_documents" => DebugCommand::FetchDocuments, + "fetch_clipscrolltree" => DebugCommand::FetchClipScrollTree, msg => { println!("unknown msg {}", msg); return Ok(()); @@ -104,13 +85,15 @@ impl DebugServer { pub fn new(api_tx: MsgSender) -> DebugServer { let (debug_tx, debug_rx) = channel(); - let socket = ws::Builder::new().build(move |out| { - Server { - ws: out, - debug_tx: debug_tx.clone(), - api_tx: api_tx.clone(), - } - }).unwrap(); + let socket = ws::Builder::new() + .build(move |out| { + Server { + ws: out, + debug_tx: debug_tx.clone(), + api_tx: api_tx.clone(), + } + }) + .unwrap(); let broadcaster = socket.broadcaster(); @@ -138,9 +121,7 @@ impl DebugServer { self.senders.push(sender); } DebugMsg::RemoveSender(token) => { - self.senders.retain(|sender| { - sender.token() != token - }); + self.senders.retain(|sender| sender.token() != token); } } } @@ -324,9 +305,7 @@ pub struct TreeNodeBuilder { impl TreeNodeBuilder { pub fn new(root: TreeNode) -> TreeNodeBuilder { - TreeNodeBuilder { - levels: vec![root] - } + TreeNodeBuilder { levels: vec![root] } } fn current_level_mut(&mut self) -> &mut TreeNode { @@ -342,17 +321,17 @@ impl TreeNodeBuilder { impl PrintTreePrinter for TreeNodeBuilder { fn new_level(&mut self, title: String) { - let level = TreeNode::new(&title); - self.levels.push(level); + let level = TreeNode::new(&title); + self.levels.push(level); } fn end_level(&mut self) { - assert!(!self.levels.is_empty()); - let last_level = self.levels.pop().unwrap(); - self.current_level_mut().add_child(last_level); + assert!(!self.levels.is_empty()); + let last_level = self.levels.pop().unwrap(); + self.current_level_mut().add_child(last_level); } fn add_item(&mut self, text: String) { - self.current_level_mut().add_item(&text); + self.current_level_mut().add_item(&text); } } diff --git a/webrender/src/device.rs b/webrender/src/device.rs index 2e3a008c03..37fd6dffb8 100644 --- a/webrender/src/device.rs +++ b/webrender/src/device.rs @@ -2,10 +2,12 @@ * 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 super::shader_source; +use api::{ColorF, ImageFormat}; +use api::{DeviceIntRect, DeviceUintSize}; use euclid::Transform3D; use gleam::gl; use internal_types::RenderTargetMode; -use super::shader_source; use std::fs::File; use std::io::Read; use std::iter::repeat; @@ -15,8 +17,6 @@ use std::path::PathBuf; use std::ptr; use std::rc::Rc; use std::thread; -use api::{ColorF, ImageFormat}; -use api::{DeviceIntRect, DeviceUintSize}; #[derive(Debug, Copy, Clone, PartialEq, Ord, Eq, PartialOrd)] pub struct FrameId(usize); @@ -117,23 +117,15 @@ enum FBOTarget { pub fn get_gl_format_bgra(gl: &gl::Gl) -> gl::GLuint { match gl.get_type() { - gl::GlType::Gl => { - GL_FORMAT_BGRA_GL - } - gl::GlType::Gles => { - GL_FORMAT_BGRA_GLES - } + gl::GlType::Gl => GL_FORMAT_BGRA_GL, + gl::GlType::Gles => GL_FORMAT_BGRA_GLES, } } fn get_shader_version(gl: &gl::Gl) -> &'static str { match gl.get_type() { - gl::GlType::Gl => { - SHADER_VERSION_GL - } - gl::GlType::Gles => { - SHADER_VERSION_GLES - } + gl::GlType::Gl => SHADER_VERSION_GL, + gl::GlType::Gles => SHADER_VERSION_GLES, } } @@ -144,12 +136,17 @@ fn get_shader_source(shader_name: &str, base_path: &Option) -> Option) -> Option, output: &mut String) { for line in source.lines() { if line.starts_with(SHADER_IMPORT) { - let imports = line[SHADER_IMPORT.len()..].split(","); + let imports = line[SHADER_IMPORT.len() ..].split(","); // For each import, get the source, and recurse. for import in imports { @@ -172,10 +169,12 @@ fn parse_shader_source(source: String, base_path: &Option, output: &mut } } -pub fn build_shader_strings(gl_version_string: &str, - features: &str, - base_filename: &str, - override_path: &Option) -> (String, String) { +pub fn build_shader_strings( + gl_version_string: &str, + features: &str, + base_filename: &str, + override_path: &Option, +) -> (String, String) { // Construct a list of strings to be passed to the shader compiler. let mut vs_source = String::new(); let mut fs_source = String::new(); @@ -196,9 +195,7 @@ pub fn build_shader_strings(gl_version_string: &str, // and append them to the list of sources. let mut shared_result = String::new(); if let Some(shared_source) = get_shader_source(base_filename, override_path) { - parse_shader_source(shared_source, - override_path, - &mut shared_result); + parse_shader_source(shared_source, override_path, &mut shared_result); } vs_source.push_str(SHADER_LINE_MARKER); @@ -224,7 +221,7 @@ pub fn build_shader_strings(gl_version_string: &str, (vs_source, fs_source) } -pub trait FileWatcherHandler : Send { +pub trait FileWatcherHandler: Send { fn file_changed(&self, path: PathBuf); } @@ -244,45 +241,55 @@ impl VertexAttribute { self.count * self.kind.size_in_bytes() } - fn bind_to_vao(&self, - attr_index: gl::GLuint, - divisor: gl::GLuint, - stride: gl::GLint, - offset: gl::GLuint, - gl: &gl::Gl) { + fn bind_to_vao( + &self, + attr_index: gl::GLuint, + divisor: gl::GLuint, + stride: gl::GLint, + offset: gl::GLuint, + gl: &gl::Gl, + ) { gl.enable_vertex_attrib_array(attr_index); gl.vertex_attrib_divisor(attr_index, divisor); match self.kind { VertexAttributeKind::F32 => { - gl.vertex_attrib_pointer(attr_index, - self.count as gl::GLint, - gl::FLOAT, - false, - stride, - offset); + gl.vertex_attrib_pointer( + attr_index, + self.count as gl::GLint, + gl::FLOAT, + false, + stride, + offset, + ); } VertexAttributeKind::U8Norm => { - gl.vertex_attrib_pointer(attr_index, - self.count as gl::GLint, - gl::UNSIGNED_BYTE, - true, - stride, - offset); + gl.vertex_attrib_pointer( + attr_index, + self.count as gl::GLint, + gl::UNSIGNED_BYTE, + true, + stride, + offset, + ); } VertexAttributeKind::I32 => { - gl.vertex_attrib_i_pointer(attr_index, - self.count as gl::GLint, - gl::INT, - stride, - offset); + gl.vertex_attrib_i_pointer( + attr_index, + self.count as gl::GLint, + gl::INT, + stride, + offset, + ); } VertexAttributeKind::U16 => { - gl.vertex_attrib_i_pointer(attr_index, - self.count as gl::GLint, - gl::UNSIGNED_SHORT, - stride, - offset); + gl.vertex_attrib_i_pointer( + attr_index, + self.count as gl::GLint, + gl::UNSIGNED_SHORT, + stride, + offset, + ); } } } @@ -292,27 +299,22 @@ impl VertexDescriptor { fn instance_stride(&self) -> u32 { self.instance_attributes .iter() - .map(|attr| attr.size_in_bytes()).sum() + .map(|attr| attr.size_in_bytes()) + .sum() } - fn bind(&self, - gl: &gl::Gl, - main: VBOId, - instance: VBOId) { + fn bind(&self, gl: &gl::Gl, main: VBOId, instance: VBOId) { main.bind(gl); let vertex_stride: u32 = self.vertex_attributes - .iter() - .map(|attr| attr.size_in_bytes()).sum(); + .iter() + .map(|attr| attr.size_in_bytes()) + .sum(); let mut vertex_offset = 0; for (i, attr) in self.vertex_attributes.iter().enumerate() { let attr_index = i as gl::GLuint; - attr.bind_to_vao(attr_index, - 0, - vertex_stride as gl::GLint, - vertex_offset, - gl); + attr.bind_to_vao(attr_index, 0, vertex_stride as gl::GLint, vertex_offset, gl); vertex_offset += attr.size_in_bytes(); } @@ -325,11 +327,13 @@ impl VertexDescriptor { for (i, attr) in self.instance_attributes.iter().enumerate() { let attr_index = base_attr + i as u32; - attr.bind_to_vao(attr_index, - 1, - instance_stride as gl::GLint, - instance_offset, - gl); + attr.bind_to_vao( + attr_index, + 1, + instance_stride as gl::GLint, + instance_offset, + gl, + ); instance_offset += attr.size_in_bytes(); } } @@ -425,7 +429,10 @@ pub struct Program { impl Drop for Program { fn drop(&mut self) { - debug_assert!(thread::panicking() || self.id == 0, "renderer::deinit not called"); + debug_assert!( + thread::panicking() || self.id == 0, + "renderer::deinit not called" + ); } } @@ -440,7 +447,10 @@ pub struct VAO { impl Drop for VAO { fn drop(&mut self) { - debug_assert!(thread::panicking() || self.id == 0, "renderer::deinit not called"); + debug_assert!( + thread::panicking() || self.id == 0, + "renderer::deinit not called" + ); } } @@ -450,7 +460,10 @@ pub struct PBO { impl Drop for PBO { fn drop(&mut self) { - debug_assert!(thread::panicking() || self.id == 0, "renderer::deinit not called"); + debug_assert!( + thread::panicking() || self.id == 0, + "renderer::deinit not called" + ); } } @@ -508,13 +521,11 @@ impl QuerySet { fn add(&mut self, value: T) -> Option { assert_eq!(self.pending, 0); - self.set.get(self.data.len()) - .cloned() - .map(|query_id| { - self.data.push(value); - self.pending = query_id; - query_id - }) + self.set.get(self.data.len()).cloned().map(|query_id| { + self.data.push(value); + self.pending = query_id; + query_id + }) } fn take(&mut self, fun: F) -> Vec { @@ -574,7 +585,10 @@ impl GpuFrameProfile { } } - fn add_marker(&mut self, tag: T) -> GpuMarker where T: NamedTag { + fn add_marker(&mut self, tag: T) -> GpuMarker + where + T: NamedTag, + { self.done_marker(); let marker = GpuMarker::new(&self.gl, tag.get_label()); @@ -596,7 +610,10 @@ impl GpuFrameProfile { */ } - fn add_sampler(&mut self, _tag: T) where T: NamedTag { + fn add_sampler(&mut self, _tag: T) + where + T: NamedTag, + { /* FIXME: samplers crash on MacOS self.done_sampler(); @@ -614,12 +631,13 @@ impl GpuFrameProfile { debug_assert!(!self.inside_frame); let gl = &self.gl; - (self.timers.take(|timer, query| { - timer.time_ns = gl.get_query_object_ui64v(query, gl::QUERY_RESULT) - }), - self.samplers.take(|sampler, query| { - sampler.count = gl.get_query_object_ui64v(query, gl::QUERY_RESULT) - }), + ( + self.timers.take(|timer, query| { + timer.time_ns = gl.get_query_object_ui64v(query, gl::QUERY_RESULT) + }), + self.samplers.take(|sampler, query| { + sampler.count = gl.get_query_object_ui64v(query, gl::QUERY_RESULT) + }), ) } } @@ -627,11 +645,11 @@ impl GpuFrameProfile { impl Drop for GpuFrameProfile { fn drop(&mut self) { match self.gl.get_type() { - gl::GlType::Gl => { + gl::GlType::Gl => { self.gl.delete_queries(&self.timers.set); self.gl.delete_queries(&self.samplers.set); } - gl::GlType::Gles => {}, + gl::GlType::Gles => {} } } } @@ -676,12 +694,16 @@ impl GpuProfiler { } pub fn add_marker(&mut self, tag: T) -> GpuMarker - where T: NamedTag { + where + T: NamedTag, + { self.frames[self.next_frame].add_marker(tag) } pub fn add_sampler(&mut self, tag: T) - where T: NamedTag { + where + T: NamedTag, + { self.frames[self.next_frame].add_sampler(tag) } @@ -691,45 +713,39 @@ impl GpuProfiler { } #[must_use] -pub struct GpuMarker{ +pub struct GpuMarker { gl: Rc, } impl GpuMarker { pub fn new(gl: &Rc, message: &str) -> GpuMarker { match gl.get_type() { - gl::GlType::Gl => { + gl::GlType::Gl => { gl.push_group_marker_ext(message); - GpuMarker{ - gl: Rc::clone(gl), - } - } - gl::GlType::Gles => { - GpuMarker{ - gl: Rc::clone(gl), - } + GpuMarker { gl: Rc::clone(gl) } } + gl::GlType::Gles => GpuMarker { gl: Rc::clone(gl) }, } } pub fn fire(gl: &gl::Gl, message: &str) { match gl.get_type() { - gl::GlType::Gl => { + gl::GlType::Gl => { gl.insert_event_marker_ext(message); } - gl::GlType::Gles => {}, + gl::GlType::Gles => {} } } } -#[cfg(not(any(target_arch="arm", target_arch="aarch64")))] +#[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))] impl Drop for GpuMarker { fn drop(&mut self) { match self.gl.get_type() { - gl::GlType::Gl => { + gl::GlType::Gl => { self.gl.pop_group_marker_ext(); } - gl::GlType::Gles => {}, + gl::GlType::Gles => {} } } } @@ -768,7 +784,7 @@ pub struct Capabilities { #[derive(Clone, Debug)] pub enum ShaderError { Compilation(String, String), // name, error mssage - Link(String, String), // name, error message + Link(String, String), // name, error message } pub struct Device { @@ -801,9 +817,11 @@ pub struct Device { } impl Device { - pub fn new(gl: Rc, - resource_override_path: Option, - _file_changed_handler: Box) -> Device { + pub fn new( + gl: Rc, + resource_override_path: Option, + _file_changed_handler: Box, + ) -> Device { let max_texture_size = gl.get_integer_v(gl::MAX_TEXTURE_SIZE) as u32; Device { @@ -856,11 +874,12 @@ impl Device { self.bound_draw_fbo = FBOId(0); } - pub fn compile_shader(gl: &gl::Gl, - name: &str, - shader_type: gl::GLenum, - source: String) - -> Result { + pub fn compile_shader( + gl: &gl::Gl, + name: &str, + shader_type: gl::GLenum, + source: String, + ) -> Result { debug!("compile {:?}", name); let id = gl.create_shader(shader_type); gl.shader_source(id, &[source.as_bytes()]); @@ -889,7 +908,7 @@ impl Device { self.default_draw_fbo = default_draw_fbo as gl::GLuint; // Texture state - for i in 0..self.bound_textures.len() { + for i in 0 .. self.bound_textures.len() { self.bound_textures[i] = 0; self.gl.active_texture(gl::TEXTURE0 + i as gl::GLuint); self.gl.bind_texture(gl::TEXTURE_2D, 0); @@ -918,30 +937,35 @@ impl Device { self.frame_id } - pub fn bind_texture(&mut self, - sampler: S, - texture: &Texture) where S: Into { + pub fn bind_texture(&mut self, sampler: S, texture: &Texture) + where + S: Into, + { debug_assert!(self.inside_frame); let sampler_index = sampler.into().0; if self.bound_textures[sampler_index] != texture.id { self.bound_textures[sampler_index] = texture.id; - self.gl.active_texture(gl::TEXTURE0 + sampler_index as gl::GLuint); + self.gl + .active_texture(gl::TEXTURE0 + sampler_index as gl::GLuint); self.gl.bind_texture(texture.target, texture.id); self.gl.active_texture(gl::TEXTURE0); } } - pub fn bind_external_texture(&mut self, - sampler: S, - external_texture: &ExternalTexture) where S: Into { + pub fn bind_external_texture(&mut self, sampler: S, external_texture: &ExternalTexture) + where + S: Into, + { debug_assert!(self.inside_frame); let sampler_index = sampler.into().0; if self.bound_textures[sampler_index] != external_texture.id { self.bound_textures[sampler_index] = external_texture.id; - self.gl.active_texture(gl::TEXTURE0 + sampler_index as gl::GLuint); - self.gl.bind_texture(external_texture.target, external_texture.id); + self.gl + .active_texture(gl::TEXTURE0 + sampler_index as gl::GLuint); + self.gl + .bind_texture(external_texture.target, external_texture.id); self.gl.active_texture(gl::TEXTURE0); } } @@ -959,9 +983,11 @@ impl Device { } } - pub fn bind_draw_target(&mut self, - texture_and_layer: Option<(&Texture, i32)>, - dimensions: Option) { + pub fn bind_draw_target( + &mut self, + texture_and_layer: Option<(&Texture, i32)>, + dimensions: Option, + ) { debug_assert!(self.inside_frame); let fbo_id = texture_and_layer.map_or(FBOId(self.default_draw_fbo), |texture_and_layer| { @@ -974,7 +1000,12 @@ impl Device { } if let Some(dimensions) = dimensions { - self.gl.viewport(0, 0, dimensions.width as gl::GLint, dimensions.height as gl::GLint); + self.gl.viewport( + 0, + 0, + dimensions.width as gl::GLint, + dimensions.height as gl::GLint, + ); } } @@ -982,11 +1013,13 @@ impl Device { let fbo = FBOId(self.gl.gen_framebuffers(1)[0]); self.bind_external_draw_target(fbo); self.gl.bind_framebuffer(gl::FRAMEBUFFER, fbo.0); - self.gl.framebuffer_texture_2d(gl::FRAMEBUFFER, - gl::COLOR_ATTACHMENT0, - gl::TEXTURE_2D, - texture_id, - 0); + self.gl.framebuffer_texture_2d( + gl::FRAMEBUFFER, + gl::COLOR_ATTACHMENT0, + gl::TEXTURE_2D, + texture_id, + 0, + ); fbo } @@ -1029,30 +1062,32 @@ impl Device { fn set_texture_parameters(&mut self, target: gl::GLuint, filter: TextureFilter) { let filter = match filter { - TextureFilter::Nearest => { - gl::NEAREST - } - TextureFilter::Linear => { - gl::LINEAR - } + TextureFilter::Nearest => gl::NEAREST, + TextureFilter::Linear => gl::LINEAR, }; - self.gl.tex_parameter_i(target, gl::TEXTURE_MAG_FILTER, filter as gl::GLint); - self.gl.tex_parameter_i(target, gl::TEXTURE_MIN_FILTER, filter as gl::GLint); - - self.gl.tex_parameter_i(target, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as gl::GLint); - self.gl.tex_parameter_i(target, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as gl::GLint); - } - - pub fn init_texture(&mut self, - texture: &mut Texture, - width: u32, - height: u32, - format: ImageFormat, - filter: TextureFilter, - mode: RenderTargetMode, - layer_count: i32, - pixels: Option<&[u8]>) { + self.gl + .tex_parameter_i(target, gl::TEXTURE_MAG_FILTER, filter as gl::GLint); + self.gl + .tex_parameter_i(target, gl::TEXTURE_MIN_FILTER, filter as gl::GLint); + + self.gl + .tex_parameter_i(target, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as gl::GLint); + self.gl + .tex_parameter_i(target, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as gl::GLint); + } + + pub fn init_texture( + &mut self, + texture: &mut Texture, + width: u32, + height: u32, + format: ImageFormat, + filter: TextureFilter, + mode: RenderTargetMode, + layer_count: i32, + pixels: Option<&[u8]>, + ) { debug_assert!(self.inside_frame); let resized = texture.width != width || texture.height != height; @@ -1077,10 +1112,14 @@ impl Device { self.bind_texture(DEFAULT_TEXTURE, texture); self.set_texture_parameters(texture.target, filter); let expanded_data: Vec; - let actual_pixels = if pixels.is_some() && - format == ImageFormat::A8 && - cfg!(any(target_arch="arm", target_arch="aarch64")) { - expanded_data = pixels.unwrap().iter().flat_map(|&byte| repeat(byte).take(4)).collect(); + let actual_pixels = if pixels.is_some() && format == ImageFormat::A8 && + cfg!(any(target_arch = "arm", target_arch = "aarch64")) + { + expanded_data = pixels + .unwrap() + .iter() + .flat_map(|&byte| repeat(byte).take(4)) + .collect(); Some(expanded_data.as_slice()) } else { pixels @@ -1088,28 +1127,31 @@ impl Device { match texture.target { gl::TEXTURE_2D_ARRAY => { - self.gl.tex_image_3d(gl::TEXTURE_2D_ARRAY, - 0, - internal_format as gl::GLint, - width as gl::GLint, - height as gl::GLint, - layer_count, - 0, - gl_format, - type_, - actual_pixels); + self.gl.tex_image_3d( + gl::TEXTURE_2D_ARRAY, + 0, + internal_format as gl::GLint, + width as gl::GLint, + height as gl::GLint, + layer_count, + 0, + gl_format, + type_, + actual_pixels, + ); } - gl::TEXTURE_2D | - gl::TEXTURE_RECTANGLE | - gl::TEXTURE_EXTERNAL_OES => { - self.gl.tex_image_2d(texture.target, - 0, - internal_format as gl::GLint, - width as gl::GLint, height as gl::GLint, - 0, - gl_format, - type_, - actual_pixels); + gl::TEXTURE_2D | gl::TEXTURE_RECTANGLE | gl::TEXTURE_EXTERNAL_OES => { + self.gl.tex_image_2d( + texture.target, + 0, + internal_format as gl::GLint, + width as gl::GLint, + height as gl::GLint, + 0, + gl_format, + type_, + actual_pixels, + ); } _ => panic!("BUG: Unexpected texture target!"), } @@ -1119,10 +1161,7 @@ impl Device { /// Updates the texture storage for the texture, creating /// FBOs as required. - fn update_texture_storage(&mut self, - texture: &mut Texture, - layer_count: i32, - resized: bool) { + fn update_texture_storage(&mut self, texture: &mut Texture, layer_count: i32, resized: bool) { assert!(layer_count > 0); assert_eq!(texture.target, gl::TEXTURE_2D_ARRAY); @@ -1132,25 +1171,30 @@ impl Device { return; } - let (internal_format, gl_format) = gl_texture_formats_for_image_format(&*self.gl, texture.format); + let (internal_format, gl_format) = + gl_texture_formats_for_image_format(&*self.gl, texture.format); let type_ = gl_type_for_texture_format(texture.format); - self.gl.tex_image_3d(texture.target, - 0, - internal_format as gl::GLint, - texture.width as gl::GLint, - texture.height as gl::GLint, - layer_count, - 0, - gl_format, - type_, - None); + self.gl.tex_image_3d( + texture.target, + 0, + internal_format as gl::GLint, + texture.width as gl::GLint, + texture.height as gl::GLint, + layer_count, + 0, + gl_format, + type_, + None, + ); let needed_layer_count = layer_count - current_layer_count; if needed_layer_count > 0 { // Create more framebuffers to fill the gap let new_fbos = self.gl.gen_framebuffers(needed_layer_count); - texture.fbo_ids.extend(new_fbos.into_iter().map(|id| FBOId(id))); + texture + .fbo_ids + .extend(new_fbos.into_iter().map(|id| FBOId(id))); } else if needed_layer_count < 0 { // Remove extra framebuffers for old in texture.fbo_ids.drain(layer_count as usize ..) { @@ -1167,44 +1211,52 @@ impl Device { depth_rb }; self.gl.bind_renderbuffer(gl::RENDERBUFFER, depth_rb); - self.gl.renderbuffer_storage(gl::RENDERBUFFER, - gl::DEPTH_COMPONENT24, - texture.width as gl::GLsizei, - texture.height as gl::GLsizei); + self.gl.renderbuffer_storage( + gl::RENDERBUFFER, + gl::DEPTH_COMPONENT24, + texture.width as gl::GLsizei, + texture.height as gl::GLsizei, + ); for (fbo_index, fbo_id) in texture.fbo_ids.iter().enumerate() { self.gl.bind_framebuffer(gl::FRAMEBUFFER, fbo_id.0); - self.gl.framebuffer_texture_layer(gl::FRAMEBUFFER, - gl::COLOR_ATTACHMENT0, - texture.id, - 0, - fbo_index as gl::GLint); - self.gl.framebuffer_renderbuffer(gl::FRAMEBUFFER, - gl::DEPTH_ATTACHMENT, - gl::RENDERBUFFER, - depth_rb); + self.gl.framebuffer_texture_layer( + gl::FRAMEBUFFER, + gl::COLOR_ATTACHMENT0, + texture.id, + 0, + fbo_index as gl::GLint, + ); + self.gl.framebuffer_renderbuffer( + gl::FRAMEBUFFER, + gl::DEPTH_ATTACHMENT, + gl::RENDERBUFFER, + depth_rb, + ); } // TODO(gw): Hack! Modify the code above to use the normal binding interfaces the device exposes. - self.gl.bind_framebuffer(gl::READ_FRAMEBUFFER, self.bound_read_fbo.0); - self.gl.bind_framebuffer(gl::DRAW_FRAMEBUFFER, self.bound_draw_fbo.0); + self.gl + .bind_framebuffer(gl::READ_FRAMEBUFFER, self.bound_read_fbo.0); + self.gl + .bind_framebuffer(gl::DRAW_FRAMEBUFFER, self.bound_draw_fbo.0); } - pub fn blit_render_target(&mut self, - src_rect: DeviceIntRect, - dest_rect: DeviceIntRect) { + pub fn blit_render_target(&mut self, src_rect: DeviceIntRect, dest_rect: DeviceIntRect) { debug_assert!(self.inside_frame); - self.gl.blit_framebuffer(src_rect.origin.x, - src_rect.origin.y, - src_rect.origin.x + src_rect.size.width, - src_rect.origin.y + src_rect.size.height, - dest_rect.origin.x, - dest_rect.origin.y, - dest_rect.origin.x + dest_rect.size.width, - dest_rect.origin.y + dest_rect.size.height, - gl::COLOR_BUFFER_BIT, - gl::LINEAR); + self.gl.blit_framebuffer( + src_rect.origin.x, + src_rect.origin.y, + src_rect.origin.x + src_rect.size.width, + src_rect.origin.y + src_rect.size.height, + dest_rect.origin.x, + dest_rect.origin.y, + dest_rect.origin.x + dest_rect.size.width, + dest_rect.origin.y + dest_rect.size.height, + gl::COLOR_BUFFER_BIT, + gl::LINEAR, + ); } pub fn free_texture_storage(&mut self, texture: &mut Texture) { @@ -1217,32 +1269,37 @@ impl Device { self.bind_texture(DEFAULT_TEXTURE, texture); - let (internal_format, gl_format) = gl_texture_formats_for_image_format(&*self.gl, texture.format); + let (internal_format, gl_format) = + gl_texture_formats_for_image_format(&*self.gl, texture.format); let type_ = gl_type_for_texture_format(texture.format); match texture.target { gl::TEXTURE_2D_ARRAY => { - self.gl.tex_image_3d(gl::TEXTURE_2D_ARRAY, - 0, - internal_format as gl::GLint, - 0, - 0, - 0, - 0, - gl_format, - type_, - None); + self.gl.tex_image_3d( + gl::TEXTURE_2D_ARRAY, + 0, + internal_format as gl::GLint, + 0, + 0, + 0, + 0, + gl_format, + type_, + None, + ); } _ => { - self.gl.tex_image_2d(texture.target, - 0, - internal_format, - 0, - 0, - 0, - gl_format, - type_, - None); + self.gl.tex_image_2d( + texture.target, + 0, + internal_format, + 0, + 0, + 0, + gl_format, + type_, + None, + ); } } @@ -1251,7 +1308,11 @@ impl Device { } if !texture.fbo_ids.is_empty() { - let fbo_ids: Vec<_> = texture.fbo_ids.drain(..).map(|FBOId(fbo_id)| fbo_id).collect(); + let fbo_ids: Vec<_> = texture + .fbo_ids + .drain(..) + .map(|FBOId(fbo_id)| fbo_id) + .collect(); self.gl.delete_framebuffers(&fbo_ids[..]); } @@ -1272,39 +1333,39 @@ impl Device { program.id = 0; } - pub fn create_program(&mut self, - base_filename: &str, - features: &str, - descriptor: &VertexDescriptor) -> Result { + pub fn create_program( + &mut self, + base_filename: &str, + features: &str, + descriptor: &VertexDescriptor, + ) -> Result { debug_assert!(self.inside_frame); let gl_version_string = get_shader_version(&*self.gl); - let (vs_source, fs_source) = build_shader_strings(gl_version_string, - features, - base_filename, - &self.resource_override_path); + let (vs_source, fs_source) = build_shader_strings( + gl_version_string, + features, + base_filename, + &self.resource_override_path, + ); // Compile the vertex shader - let vs_id = match Device::compile_shader(&*self.gl, - base_filename, - gl::VERTEX_SHADER, - vs_source) { - Ok(vs_id) => vs_id, - Err(err) => return Err(err), - }; + let vs_id = + match Device::compile_shader(&*self.gl, base_filename, gl::VERTEX_SHADER, vs_source) { + Ok(vs_id) => vs_id, + Err(err) => return Err(err), + }; // Compiler the fragment shader - let fs_id = match Device::compile_shader(&*self.gl, - base_filename, - gl::FRAGMENT_SHADER, - fs_source) { - Ok(fs_id) => fs_id, - Err(err) => { - self.gl.delete_shader(vs_id); - return Err(err); - } - }; + let fs_id = + match Device::compile_shader(&*self.gl, base_filename, gl::FRAGMENT_SHADER, fs_source) { + Ok(fs_id) => fs_id, + Err(err) => { + self.gl.delete_shader(vs_id); + return Err(err); + } + }; // Create program and attach shaders let pid = self.gl.create_program(); @@ -1312,13 +1373,14 @@ impl Device { self.gl.attach_shader(pid, fs_id); // Bind vertex attributes - for (i, attr) in descriptor.vertex_attributes - .iter() - .chain(descriptor.instance_attributes.iter()) - .enumerate() { - self.gl.bind_attrib_location(pid, - i as gl::GLuint, - attr.name); + for (i, attr) in descriptor + .vertex_attributes + .iter() + .chain(descriptor.instance_attributes.iter()) + .enumerate() + { + self.gl + .bind_attrib_location(pid, i as gl::GLuint, attr.name); } // Link! @@ -1334,7 +1396,11 @@ impl Device { if self.gl.get_program_iv(pid, gl::LINK_STATUS) == (0 as gl::GLint) { let error_log = self.gl.get_program_info_log(pid); - println!("Failed to link shader program: {:?}\n{}", base_filename, error_log); + println!( + "Failed to link shader program: {:?}\n{}", + base_filename, + error_log + ); self.gl.delete_program(pid); return Err(ShaderError::Link(base_filename.to_string(), error_log)); } @@ -1353,14 +1419,16 @@ impl Device { Ok(program) } - pub fn bind_shader_samplers(&mut self, - program: &Program, - bindings: &[(&'static str, S)]) where S: Into + Copy { + pub fn bind_shader_samplers(&mut self, program: &Program, bindings: &[(&'static str, S)]) + where + S: Into + Copy, + { for binding in bindings { let u_location = self.gl.get_uniform_location(program.id, binding.0); if u_location != -1 { self.bind_program(program); - self.gl.uniform_1i(u_location, binding.1.into().0 as gl::GLint); + self.gl + .uniform_1i(u_location, binding.1.into().0 as gl::GLint); } } } @@ -1375,21 +1443,17 @@ impl Device { self.gl.uniform_2f(location, x, y); } - pub fn set_uniforms(&self, - program: &Program, - transform: &Transform3D) { + pub fn set_uniforms(&self, program: &Program, transform: &Transform3D) { debug_assert!(self.inside_frame); - self.gl.uniform_matrix_4fv(program.u_transform, - false, - &transform.to_row_major_array()); - self.gl.uniform_1f(program.u_device_pixel_ratio, self.device_pixel_ratio); + self.gl + .uniform_matrix_4fv(program.u_transform, false, &transform.to_row_major_array()); + self.gl + .uniform_1f(program.u_device_pixel_ratio, self.device_pixel_ratio); } pub fn create_pbo(&mut self) -> PBO { let id = self.gl.gen_buffers(1)[0]; - PBO { - id - } + PBO { id } } pub fn delete_pbo(&mut self, mut pbo: PBO) { @@ -1412,31 +1476,32 @@ impl Device { debug_assert!(self.inside_frame); debug_assert_ne!(self.bound_pbo, 0); - gl::buffer_data(&*self.gl, - gl::PIXEL_UNPACK_BUFFER, - data, - gl::STREAM_DRAW); + gl::buffer_data(&*self.gl, gl::PIXEL_UNPACK_BUFFER, data, gl::STREAM_DRAW); } pub fn orphan_pbo(&mut self, new_size: usize) { debug_assert!(self.inside_frame); debug_assert_ne!(self.bound_pbo, 0); - self.gl.buffer_data_untyped(gl::PIXEL_UNPACK_BUFFER, - new_size as isize, - ptr::null(), - gl::STREAM_DRAW); - } - - pub fn update_texture_from_pbo(&mut self, - texture: &Texture, - x0: u32, - y0: u32, - width: u32, - height: u32, - layer_index: i32, - stride: Option, - offset: usize) { + self.gl.buffer_data_untyped( + gl::PIXEL_UNPACK_BUFFER, + new_size as isize, + ptr::null(), + gl::STREAM_DRAW, + ); + } + + pub fn update_texture_from_pbo( + &mut self, + texture: &Texture, + x0: u32, + y0: u32, + width: u32, + height: u32, + layer_index: i32, + stride: Option, + offset: usize, + ) { debug_assert!(self.inside_frame); let (gl_format, bpp, data_type) = match texture.format { @@ -1454,37 +1519,40 @@ impl Device { }; if let Some(..) = stride { - self.gl.pixel_store_i(gl::UNPACK_ROW_LENGTH, row_length as gl::GLint); + self.gl + .pixel_store_i(gl::UNPACK_ROW_LENGTH, row_length as gl::GLint); } self.bind_texture(DEFAULT_TEXTURE, texture); match texture.target { gl::TEXTURE_2D_ARRAY => { - self.gl.tex_sub_image_3d_pbo(texture.target, - 0, - x0 as gl::GLint, - y0 as gl::GLint, - layer_index, - width as gl::GLint, - height as gl::GLint, - 1, - gl_format, - data_type, - offset); + self.gl.tex_sub_image_3d_pbo( + texture.target, + 0, + x0 as gl::GLint, + y0 as gl::GLint, + layer_index, + width as gl::GLint, + height as gl::GLint, + 1, + gl_format, + data_type, + offset, + ); } - gl::TEXTURE_2D | - gl::TEXTURE_RECTANGLE | - gl::TEXTURE_EXTERNAL_OES => { - self.gl.tex_sub_image_2d_pbo(texture.target, - 0, - x0 as gl::GLint, - y0 as gl::GLint, - width as gl::GLint, - height as gl::GLint, - gl_format, - data_type, - offset); + gl::TEXTURE_2D | gl::TEXTURE_RECTANGLE | gl::TEXTURE_EXTERNAL_OES => { + self.gl.tex_sub_image_2d_pbo( + texture.target, + 0, + x0 as gl::GLint, + y0 as gl::GLint, + width as gl::GLint, + height as gl::GLint, + gl_format, + data_type, + offset, + ); } _ => panic!("BUG: Unexpected texture target!"), } @@ -1504,13 +1572,14 @@ impl Device { } } - fn create_vao_with_vbos(&mut self, - descriptor: &VertexDescriptor, - main_vbo_id: VBOId, - instance_vbo_id: VBOId, - ibo_id: IBOId, - owns_vertices_and_indices: bool) - -> VAO { + fn create_vao_with_vbos( + &mut self, + descriptor: &VertexDescriptor, + main_vbo_id: VBOId, + instance_vbo_id: VBOId, + ibo_id: IBOId, + owns_vertices_and_indices: bool, + ) -> VAO { debug_assert!(self.inside_frame); let instance_stride = descriptor.instance_stride(); @@ -1535,8 +1604,7 @@ impl Device { vao } - pub fn create_vao(&mut self, - descriptor: &VertexDescriptor) -> VAO { + pub fn create_vao(&mut self, descriptor: &VertexDescriptor) -> VAO { debug_assert!(self.inside_frame); let buffer_ids = self.gl.gen_buffers(3); @@ -1544,11 +1612,7 @@ impl Device { let main_vbo_id = VBOId(buffer_ids[1]); let intance_vbo_id = VBOId(buffer_ids[2]); - self.create_vao_with_vbos(descriptor, - main_vbo_id, - intance_vbo_id, - ibo_id, - true) + self.create_vao_with_vbos(descriptor, main_vbo_id, intance_vbo_id, ibo_id, true) } pub fn delete_vao(&mut self, mut vao: VAO) { @@ -1563,25 +1627,31 @@ impl Device { self.gl.delete_buffers(&[vao.instance_vbo_id.0]) } - pub fn create_vao_with_new_instances(&mut self, - descriptor: &VertexDescriptor, - base_vao: &VAO) -> VAO { + pub fn create_vao_with_new_instances( + &mut self, + descriptor: &VertexDescriptor, + base_vao: &VAO, + ) -> VAO { debug_assert!(self.inside_frame); let buffer_ids = self.gl.gen_buffers(1); let intance_vbo_id = VBOId(buffer_ids[0]); - self.create_vao_with_vbos(descriptor, - base_vao.main_vbo_id, - intance_vbo_id, - base_vao.ibo_id, - false) + self.create_vao_with_vbos( + descriptor, + base_vao.main_vbo_id, + intance_vbo_id, + base_vao.ibo_id, + false, + ) } - pub fn update_vao_main_vertices(&mut self, - vao: &VAO, - vertices: &[V], - usage_hint: VertexUsageHint) { + pub fn update_vao_main_vertices( + &mut self, + vao: &VAO, + vertices: &[V], + usage_hint: VertexUsageHint, + ) { debug_assert!(self.inside_frame); debug_assert_eq!(self.bound_vao, vao.id); @@ -1589,10 +1659,12 @@ impl Device { gl::buffer_data(self.gl(), gl::ARRAY_BUFFER, vertices, usage_hint.to_gl()); } - pub fn update_vao_instances(&mut self, - vao: &VAO, - instances: &[V], - usage_hint: VertexUsageHint) { + pub fn update_vao_instances( + &mut self, + vao: &VAO, + instances: &[V], + usage_hint: VertexUsageHint, + ) { debug_assert!(self.inside_frame); debug_assert_eq!(self.bound_vao, vao.id); debug_assert_eq!(vao.instance_stride as usize, mem::size_of::()); @@ -1601,45 +1673,53 @@ impl Device { gl::buffer_data(self.gl(), gl::ARRAY_BUFFER, instances, usage_hint.to_gl()); } - pub fn update_vao_indices(&mut self, - vao: &VAO, - indices: &[I], - usage_hint: VertexUsageHint) { + pub fn update_vao_indices(&mut self, vao: &VAO, indices: &[I], usage_hint: VertexUsageHint) { debug_assert!(self.inside_frame); debug_assert_eq!(self.bound_vao, vao.id); vao.ibo_id.bind(self.gl()); - gl::buffer_data(self.gl(), gl::ELEMENT_ARRAY_BUFFER, indices, usage_hint.to_gl()); + gl::buffer_data( + self.gl(), + gl::ELEMENT_ARRAY_BUFFER, + indices, + usage_hint.to_gl(), + ); } pub fn draw_triangles_u16(&mut self, first_vertex: i32, index_count: i32) { debug_assert!(self.inside_frame); - self.gl.draw_elements(gl::TRIANGLES, - index_count, - gl::UNSIGNED_SHORT, - first_vertex as u32 * 2); + self.gl.draw_elements( + gl::TRIANGLES, + index_count, + gl::UNSIGNED_SHORT, + first_vertex as u32 * 2, + ); } pub fn draw_triangles_u32(&mut self, first_vertex: i32, index_count: i32) { debug_assert!(self.inside_frame); - self.gl.draw_elements(gl::TRIANGLES, - index_count, - gl::UNSIGNED_INT, - first_vertex as u32 * 4); + self.gl.draw_elements( + gl::TRIANGLES, + index_count, + gl::UNSIGNED_INT, + first_vertex as u32 * 4, + ); } pub fn draw_nonindexed_lines(&mut self, first_vertex: i32, vertex_count: i32) { debug_assert!(self.inside_frame); - self.gl.draw_arrays(gl::LINES, - first_vertex, - vertex_count); + self.gl.draw_arrays(gl::LINES, first_vertex, vertex_count); } - pub fn draw_indexed_triangles_instanced_u16(&mut self, - index_count: i32, - instance_count: i32) { + pub fn draw_indexed_triangles_instanced_u16(&mut self, index_count: i32, instance_count: i32) { debug_assert!(self.inside_frame); - self.gl.draw_elements_instanced(gl::TRIANGLES, index_count, gl::UNSIGNED_SHORT, 0, instance_count); + self.gl.draw_elements_instanced( + gl::TRIANGLES, + index_count, + gl::UNSIGNED_SHORT, + 0, + instance_count, + ); } pub fn end_frame(&mut self) { @@ -1652,7 +1732,7 @@ impl Device { self.gl.bind_texture(gl::TEXTURE_2D, 0); self.gl.use_program(0); - for i in 0..self.bound_textures.len() { + for i in 0 .. self.bound_textures.len() { self.gl.active_texture(gl::TEXTURE0 + i as gl::GLuint); self.gl.bind_texture(gl::TEXTURE_2D, 0); } @@ -1662,9 +1742,7 @@ impl Device { self.frame_id.0 += 1; } - pub fn clear_target(&self, - color: Option<[f32; 4]>, - depth: Option) { + pub fn clear_target(&self, color: Option<[f32; 4]>, depth: Option) { let mut clear_bits = 0; if let Some(color) = color { @@ -1682,10 +1760,12 @@ impl Device { } } - pub fn clear_target_rect(&self, - color: Option<[f32; 4]>, - depth: Option, - rect: DeviceIntRect) { + pub fn clear_target_rect( + &self, + color: Option<[f32; 4]>, + depth: Option, + rect: DeviceIntRect, + ) { let mut clear_bits = 0; if let Some(color) = color { @@ -1700,7 +1780,12 @@ impl Device { if clear_bits != 0 { self.gl.enable(gl::SCISSOR_TEST); - self.gl.scissor(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); + self.gl.scissor( + rect.origin.x, + rect.origin.y, + rect.size.width, + rect.size.height, + ); self.gl.clear(clear_bits); self.gl.disable(gl::SCISSOR_TEST); } @@ -1748,54 +1833,54 @@ impl Device { } pub fn set_blend_mode_alpha(&self) { - self.gl.blend_func_separate(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA, - gl::ONE, gl::ONE_MINUS_SRC_ALPHA); + self.gl.blend_func_separate( + gl::SRC_ALPHA, + gl::ONE_MINUS_SRC_ALPHA, + gl::ONE, + gl::ONE_MINUS_SRC_ALPHA, + ); self.gl.blend_equation(gl::FUNC_ADD); } pub fn set_blend_mode_subpixel(&self, color: ColorF) { self.gl.blend_color(color.r, color.g, color.b, color.a); - self.gl.blend_func(gl::CONSTANT_COLOR, gl::ONE_MINUS_SRC_COLOR); + self.gl + .blend_func(gl::CONSTANT_COLOR, gl::ONE_MINUS_SRC_COLOR); } pub fn set_blend_mode_multiply(&self) { - self.gl.blend_func_separate(gl::ZERO, gl::SRC_COLOR, - gl::ZERO, gl::SRC_ALPHA); + self.gl + .blend_func_separate(gl::ZERO, gl::SRC_COLOR, gl::ZERO, gl::SRC_ALPHA); self.gl.blend_equation(gl::FUNC_ADD); } pub fn set_blend_mode_max(&self) { - self.gl.blend_func_separate(gl::ONE, gl::ONE, - gl::ONE, gl::ONE); + self.gl + .blend_func_separate(gl::ONE, gl::ONE, gl::ONE, gl::ONE); self.gl.blend_equation_separate(gl::MAX, gl::FUNC_ADD); } pub fn set_blend_mode_min(&self) { - self.gl.blend_func_separate(gl::ONE, gl::ONE, - gl::ONE, gl::ONE); + self.gl + .blend_func_separate(gl::ONE, gl::ONE, gl::ONE, gl::ONE); self.gl.blend_equation_separate(gl::MIN, gl::FUNC_ADD); } } /// return (gl_internal_format, gl_format) -fn gl_texture_formats_for_image_format(gl: &gl::Gl, format: ImageFormat) -> (gl::GLint, gl::GLuint) { +fn gl_texture_formats_for_image_format( + gl: &gl::Gl, + format: ImageFormat, +) -> (gl::GLint, gl::GLuint) { match format { - ImageFormat::A8 => { - if cfg!(any(target_arch="arm", target_arch="aarch64")) { - (get_gl_format_bgra(gl) as gl::GLint, get_gl_format_bgra(gl)) - } else { - (GL_FORMAT_A as gl::GLint, GL_FORMAT_A) - } + ImageFormat::A8 => if cfg!(any(target_arch = "arm", target_arch = "aarch64")) { + (get_gl_format_bgra(gl) as gl::GLint, get_gl_format_bgra(gl)) + } else { + (GL_FORMAT_A as gl::GLint, GL_FORMAT_A) }, ImageFormat::RGB8 => (gl::RGB as gl::GLint, gl::RGB), - ImageFormat::BGRA8 => { - match gl.get_type() { - gl::GlType::Gl => { - (gl::RGBA as gl::GLint, get_gl_format_bgra(gl)) - } - gl::GlType::Gles => { - (get_gl_format_bgra(gl) as gl::GLint, get_gl_format_bgra(gl)) - } - } - } + ImageFormat::BGRA8 => match gl.get_type() { + gl::GlType::Gl => (gl::RGBA as gl::GLint, get_gl_format_bgra(gl)), + gl::GlType::Gles => (get_gl_format_bgra(gl) as gl::GLint, get_gl_format_bgra(gl)), + }, ImageFormat::RGBAF32 => (gl::RGBA32F as gl::GLint, gl::RGBA), ImageFormat::RG8 => (gl::RG8 as gl::GLint, gl::RG), ImageFormat::Invalid => unreachable!(), @@ -1808,4 +1893,3 @@ fn gl_type_for_texture_format(format: ImageFormat) -> gl::GLuint { _ => gl::UNSIGNED_BYTE, } } - diff --git a/webrender/src/ellipse.rs b/webrender/src/ellipse.rs index 26e09bccf7..a021eb0cf5 100644 --- a/webrender/src/ellipse.rs +++ b/webrender/src/ellipse.rs @@ -18,9 +18,7 @@ pub struct Ellipse { impl Ellipse { pub fn new(radius: LayerSize) -> Ellipse { // Approximate the total length of the first quadrant of this ellipse. - let total_arc_length = get_simpson_length(FRAC_PI_2, - radius.width, - radius.height); + let total_arc_length = get_simpson_length(FRAC_PI_2, radius.width, radius.height); Ellipse { radius, @@ -42,9 +40,7 @@ impl Ellipse { while low <= high { theta = 0.5 * (low + high); - let length = get_simpson_length(theta, - self.radius.width, - self.radius.height); + let length = get_simpson_length(theta, self.radius.width, self.radius.height); if (length - arc_length).abs() < epsilon { break; @@ -62,10 +58,14 @@ impl Ellipse { /// This only works for the first quadrant of the ellipse. pub fn get_point_and_tangent(&self, theta: f32) -> (LayerPoint, LayerPoint) { let (sin_theta, cos_theta) = theta.sin_cos(); - let point = LayerPoint::new(self.radius.width * cos_theta, - self.radius.height * sin_theta); - let tangent = LayerPoint::new(-self.radius.width * sin_theta, - self.radius.height * cos_theta); + let point = LayerPoint::new( + self.radius.width * cos_theta, + self.radius.height * sin_theta, + ); + let tangent = LayerPoint::new( + -self.radius.width * sin_theta, + self.radius.height * cos_theta, + ); (point, tangent) } } @@ -80,11 +80,11 @@ fn get_simpson_length(theta: f32, rx: f32, ry: f32) -> f32 { let df = theta / STEP_COUNT as f32; let mut sum = 0.0; - for i in 0..(STEP_COUNT+1) { + for i in 0 .. (STEP_COUNT + 1) { let (sin_theta, cos_theta) = (i as f32 * df).sin_cos(); let a = rx * sin_theta; let b = ry * cos_theta; - let y = (a*a + b*b).sqrt(); + let y = (a * a + b * b).sqrt(); let q = if i == 0 || i == STEP_COUNT { 1.0 } else if i % 2 == 0 { diff --git a/webrender/src/frame.rs b/webrender/src/frame.rs index ebe46e6038..a9aaac2c2a 100644 --- a/webrender/src/frame.rs +++ b/webrender/src/frame.rs @@ -4,7 +4,8 @@ use api::{BuiltDisplayList, BuiltDisplayListIter, ClipAndScrollInfo, ClipId, ColorF}; use api::{ComplexClipRegion, DeviceUintRect, DeviceUintSize, DisplayItemRef, Epoch, FilterOp}; -use api::{ImageDisplayItem, ItemRange, LayerPoint, LayerPrimitiveInfo, LayerRect, LayerSize, LayerToScrollTransform}; +use api::{ImageDisplayItem, ItemRange, LayerPoint, LayerPrimitiveInfo, LayerRect, LayerSize, + LayerToScrollTransform}; use api::{LayerVector2D, LayoutSize, LayoutTransform, LocalClip, MixBlendMode, PipelineId}; use api::{PropertyBinding, ScrollClamping, ScrollEventPhase, ScrollLayerState, ScrollLocation}; use api::{ScrollPolicy, ScrollSensitivity, SpecificDisplayItem, StackingContext, TileOffset}; @@ -12,19 +13,24 @@ use api::{TransformStyle, WorldPoint}; use clip::ClipRegion; use clip_scroll_tree::{ClipScrollTree, ScrollStates}; use euclid::rect; +use frame_builder::{FrameBuilder, FrameBuilderConfig}; use gpu_cache::GpuCache; use internal_types::{FastHashMap, FastHashSet, RendererFrame}; -use frame_builder::{FrameBuilder, FrameBuilderConfig}; use profiler::{GpuCacheProfileCounters, TextureCacheProfileCounters}; use resource_cache::{ResourceCache, TiledImageMap}; use scene::{Scene, SceneProperties}; use tiling::{CompositeOps, DisplayListMap, PrimitiveFlags}; -use util::{ComplexClipRegionHelpers, subtract_rect}; +use util::{subtract_rect, ComplexClipRegionHelpers}; #[derive(Copy, Clone, PartialEq, PartialOrd, Debug, Eq, Ord)] pub struct FrameId(pub u32); -static DEFAULT_SCROLLBAR_COLOR: ColorF = ColorF { r: 0.3, g: 0.3, b: 0.3, a: 0.6 }; +static DEFAULT_SCROLLBAR_COLOR: ColorF = ColorF { + r: 0.3, + g: 0.3, + b: 0.3, + a: 0.6, +}; /// Nested display lists cause two types of replacements to ClipIds inside the nesting: /// 1. References to the root scroll frame are replaced by the ClipIds that @@ -103,10 +109,11 @@ struct FlattenContext<'a> { } impl<'a> FlattenContext<'a> { - fn new(scene: &'a Scene, - builder: &'a mut FrameBuilder, - resource_cache: &'a ResourceCache) - -> FlattenContext<'a> { + fn new( + scene: &'a Scene, + builder: &'a mut FrameBuilder, + resource_cache: &'a ResourceCache, + ) -> FlattenContext<'a> { FlattenContext { scene, builder, @@ -142,16 +149,18 @@ impl<'a> FlattenContext<'a> { fn convert_clip_scroll_info_to_nested(&self, info: &mut ClipAndScrollInfo) { if let Some(nested_info) = self.nested_display_list_info.last() { info.scroll_node_id = nested_info.convert_scroll_id_to_nested(&info.scroll_node_id); - info.clip_node_id = - info.clip_node_id.map(|ref id| nested_info.convert_clip_id_to_nested(id)); + info.clip_node_id = info.clip_node_id + .map(|ref id| nested_info.convert_clip_id_to_nested(id)); } // We only want to produce nested ClipIds if we are in a nested display // list situation. - debug_assert!(!info.scroll_node_id.is_nested() || - !self.nested_display_list_info.is_empty()); - debug_assert!(!info.clip_node_id().is_nested() || - !self.nested_display_list_info.is_empty()); + debug_assert!( + !info.scroll_node_id.is_nested() || !self.nested_display_list_info.is_empty() + ); + debug_assert!( + !info.clip_node_id().is_nested() || !self.nested_display_list_info.is_empty() + ); } /// Since WebRender still handles fixed position and reference frame content internally @@ -165,18 +174,21 @@ impl<'a> FlattenContext<'a> { } } - fn get_complex_clips(&self, - pipeline_id: PipelineId, - complex_clips: ItemRange) - -> Vec { + fn get_complex_clips( + &self, + pipeline_id: PipelineId, + complex_clips: ItemRange, + ) -> Vec { if complex_clips.is_empty() { return vec![]; } - self.scene.display_lists.get(&pipeline_id) - .expect("No display list?") - .get(complex_clips) - .collect() + self.scene + .display_lists + .get(&pipeline_id) + .expect("No display list?") + .get(complex_clips) + .collect() } } @@ -201,7 +213,7 @@ impl FilterOpHelpers for FilterOp { let amount = properties.resolve_float(value, 1.0); FilterOp::Opacity(PropertyBinding::Value(amount)) } - _ => self + _ => self, } } @@ -213,16 +225,12 @@ impl FilterOpHelpers for FilterOp { FilterOp::Grayscale(amount) => amount == 0.0, FilterOp::HueRotate(amount) => amount == 0.0, FilterOp::Invert(amount) => amount == 0.0, - FilterOp::Opacity(value) => { - match value { - PropertyBinding::Value(amount) => { - amount == 1.0 - } - PropertyBinding::Binding(..) => { - panic!("bug: binding value should be resolved"); - } + FilterOp::Opacity(value) => match value { + PropertyBinding::Value(amount) => amount == 1.0, + PropertyBinding::Binding(..) => { + panic!("bug: binding value should be resolved"); } - } + }, FilterOp::Saturate(amount) => amount == 1.0, FilterOp::Sepia(amount) => amount == 0.0, } @@ -231,10 +239,12 @@ impl FilterOpHelpers for FilterOp { trait StackingContextHelpers { fn mix_blend_mode_for_compositing(&self) -> Option; - fn filter_ops_for_compositing(&self, - display_list: &BuiltDisplayList, - input_filters: ItemRange, - properties: &SceneProperties) -> Vec; + fn filter_ops_for_compositing( + &self, + display_list: &BuiltDisplayList, + input_filters: ItemRange, + properties: &SceneProperties, + ) -> Vec; } impl StackingContextHelpers for StackingContext { @@ -245,10 +255,12 @@ impl StackingContextHelpers for StackingContext { } } - fn filter_ops_for_compositing(&self, - display_list: &BuiltDisplayList, - input_filters: ItemRange, - properties: &SceneProperties) -> Vec { + fn filter_ops_for_compositing( + &self, + display_list: &BuiltDisplayList, + input_filters: ItemRange, + properties: &SceneProperties, + ) -> Vec { let mut filters = vec![]; for filter in display_list.get(input_filters) { let filter = filter.resolve(properties); @@ -291,12 +303,13 @@ impl Frame { } /// Returns true if any nodes actually changed position or false otherwise. - pub fn scroll(&mut self, - scroll_location: ScrollLocation, - cursor: WorldPoint, - phase: ScrollEventPhase) - -> bool { - self.clip_scroll_tree.scroll(scroll_location, cursor, phase,) + pub fn scroll( + &mut self, + scroll_location: ScrollLocation, + cursor: WorldPoint, + phase: ScrollEventPhase, + ) -> bool { + self.clip_scroll_tree.scroll(scroll_location, cursor, phase) } pub fn tick_scrolling_bounce_animations(&mut self) { @@ -304,15 +317,18 @@ impl Frame { } pub fn discard_frame_state_for_pipeline(&mut self, pipeline_id: PipelineId) { - self.clip_scroll_tree.discard_frame_state_for_pipeline(pipeline_id); + self.clip_scroll_tree + .discard_frame_state_for_pipeline(pipeline_id); } - pub fn create(&mut self, - scene: &Scene, - resource_cache: &mut ResourceCache, - window_size: DeviceUintSize, - inner_rect: DeviceUintRect, - device_pixel_ratio: f32) { + pub fn create( + &mut self, + scene: &Scene, + resource_cache: &mut ResourceCache, + window_size: DeviceUintSize, + inner_rect: DeviceUintRect, + device_pixel_ratio: f32, + ) { let root_pipeline_id = match scene.root_pipeline_id { Some(root_pipeline_id) => root_pipeline_id, None => return, @@ -334,94 +350,112 @@ impl Frame { let old_scrolling_states = self.reset(); - self.pipeline_epoch_map.insert(root_pipeline_id, root_pipeline.epoch); + self.pipeline_epoch_map + .insert(root_pipeline_id, root_pipeline.epoch); - let background_color = root_pipeline.background_color.and_then(|color| { - if color.a > 0.0 { - Some(color) - } else { - None - } - }); + let background_color = root_pipeline + .background_color + .and_then(|color| if color.a > 0.0 { Some(color) } else { None }); - let mut frame_builder = FrameBuilder::new(self.frame_builder.take(), - window_size, - background_color, - self.frame_builder_config); + let mut frame_builder = FrameBuilder::new( + self.frame_builder.take(), + window_size, + background_color, + self.frame_builder_config, + ); { let mut context = FlattenContext::new(scene, &mut frame_builder, resource_cache); - context.builder.push_root(root_pipeline_id, - &root_pipeline.viewport_size, - &root_pipeline.content_size, - &mut self.clip_scroll_tree); - - context.builder.setup_viewport_offset(window_size, - inner_rect, - device_pixel_ratio, - &mut self.clip_scroll_tree); - - self.flatten_root(&mut display_list.iter(), - root_pipeline_id, - &mut context, - &root_pipeline.content_size); + context.builder.push_root( + root_pipeline_id, + &root_pipeline.viewport_size, + &root_pipeline.content_size, + &mut self.clip_scroll_tree, + ); + + context.builder.setup_viewport_offset( + window_size, + inner_rect, + device_pixel_ratio, + &mut self.clip_scroll_tree, + ); + + self.flatten_root( + &mut display_list.iter(), + root_pipeline_id, + &mut context, + &root_pipeline.content_size, + ); } self.frame_builder = Some(frame_builder); - self.clip_scroll_tree.finalize_and_apply_pending_scroll_offsets(old_scrolling_states); + self.clip_scroll_tree + .finalize_and_apply_pending_scroll_offsets(old_scrolling_states); } - fn flatten_clip<'a>(&mut self, - context: &mut FlattenContext, - pipeline_id: PipelineId, - parent_id: &ClipId, - new_clip_id: &ClipId, - clip_region: ClipRegion) { + fn flatten_clip<'a>( + &mut self, + context: &mut FlattenContext, + pipeline_id: PipelineId, + parent_id: &ClipId, + new_clip_id: &ClipId, + clip_region: ClipRegion, + ) { let new_clip_id = context.convert_new_id_to_nested(new_clip_id); - context.builder.add_clip_node(new_clip_id, - *parent_id, - pipeline_id, - clip_region, - &mut self.clip_scroll_tree); + context.builder.add_clip_node( + new_clip_id, + *parent_id, + pipeline_id, + clip_region, + &mut self.clip_scroll_tree, + ); } - fn flatten_scroll_frame<'a>(&mut self, - context: &mut FlattenContext, - pipeline_id: PipelineId, - parent_id: &ClipId, - new_scroll_frame_id: &ClipId, - frame_rect: &LayerRect, - content_rect: &LayerRect, - clip_region: ClipRegion, - scroll_sensitivity: ScrollSensitivity) { + fn flatten_scroll_frame<'a>( + &mut self, + context: &mut FlattenContext, + pipeline_id: PipelineId, + parent_id: &ClipId, + new_scroll_frame_id: &ClipId, + frame_rect: &LayerRect, + content_rect: &LayerRect, + clip_region: ClipRegion, + scroll_sensitivity: ScrollSensitivity, + ) { let clip_id = self.clip_scroll_tree.generate_new_clip_id(pipeline_id); - context.builder.add_clip_node(clip_id, - *parent_id, - pipeline_id, - clip_region, - &mut self.clip_scroll_tree); + context.builder.add_clip_node( + clip_id, + *parent_id, + pipeline_id, + clip_region, + &mut self.clip_scroll_tree, + ); let new_scroll_frame_id = context.convert_new_id_to_nested(new_scroll_frame_id); - context.builder.add_scroll_frame(new_scroll_frame_id, - clip_id, - pipeline_id, - &frame_rect, - &content_rect.size, - scroll_sensitivity, - &mut self.clip_scroll_tree); + context.builder.add_scroll_frame( + new_scroll_frame_id, + clip_id, + pipeline_id, + &frame_rect, + &content_rect.size, + scroll_sensitivity, + &mut self.clip_scroll_tree, + ); } - fn flatten_stacking_context<'a>(&mut self, - traversal: &mut BuiltDisplayListIter<'a>, - pipeline_id: PipelineId, - context: &mut FlattenContext, - context_scroll_node_id: ClipId, - mut reference_frame_relative_offset: LayerVector2D, - bounds: &LayerRect, - stacking_context: &StackingContext, - filters: ItemRange, - is_backface_visible: bool) { + fn flatten_stacking_context<'a>( + &mut self, + traversal: &mut BuiltDisplayListIter<'a>, + pipeline_id: PipelineId, + context: &mut FlattenContext, + context_scroll_node_id: ClipId, + mut reference_frame_relative_offset: LayerVector2D, + bounds: &LayerRect, + stacking_context: &StackingContext, + filters: ItemRange, + is_backface_visible: bool, + ) { // Avoid doing unnecessary work for empty stacking contexts. if traversal.current_stacking_context_empty() { traversal.skip_current_stacking_context(); @@ -430,61 +464,77 @@ impl Frame { let composition_operations = { // TODO(optimization?): self.traversal.display_list() - let display_list = context.scene.display_lists - .get(&pipeline_id) - .expect("No display list?!"); + let display_list = context + .scene + .display_lists + .get(&pipeline_id) + .expect("No display list?!"); CompositeOps::new( - stacking_context.filter_ops_for_compositing(display_list, filters, &context.scene.properties), - stacking_context.mix_blend_mode_for_compositing()) + stacking_context.filter_ops_for_compositing( + display_list, + filters, + &context.scene.properties, + ), + stacking_context.mix_blend_mode_for_compositing(), + ) }; if stacking_context.scroll_policy == ScrollPolicy::Fixed { - context.replacements.push((context_scroll_node_id, - context.builder.current_reference_frame_id())); + context.replacements.push(( + context_scroll_node_id, + context.builder.current_reference_frame_id(), + )); } // If we have a transformation, we establish a new reference frame. This means // that fixed position stacking contexts are positioned relative to us. - let is_reference_frame = stacking_context.transform.is_some() || - stacking_context.perspective.is_some(); + let is_reference_frame = + stacking_context.transform.is_some() || stacking_context.perspective.is_some(); if is_reference_frame { let transform = stacking_context.transform.as_ref(); let transform = context.scene.properties.resolve_layout_transform(transform); - let perspective = - stacking_context.perspective.unwrap_or_else(LayoutTransform::identity); + let perspective = stacking_context + .perspective + .unwrap_or_else(LayoutTransform::identity); let origin = reference_frame_relative_offset + bounds.origin.to_vector(); - let transform = - LayerToScrollTransform::create_translation(origin.x, origin.y, 0.0) - .pre_mul(&transform) - .pre_mul(&perspective); + let transform = LayerToScrollTransform::create_translation(origin.x, origin.y, 0.0) + .pre_mul(&transform) + .pre_mul(&perspective); let reference_frame_bounds = LayerRect::new(LayerPoint::zero(), bounds.size); let mut clip_id = context.apply_scroll_frame_id_replacement(context_scroll_node_id); - clip_id = context.builder.push_reference_frame(Some(clip_id), - pipeline_id, - &reference_frame_bounds, - &transform, - origin, - &mut self.clip_scroll_tree); + clip_id = context.builder.push_reference_frame( + Some(clip_id), + pipeline_id, + &reference_frame_bounds, + &transform, + origin, + &mut self.clip_scroll_tree, + ); context.replacements.push((context_scroll_node_id, clip_id)); reference_frame_relative_offset = LayerVector2D::zero(); } else { reference_frame_relative_offset = LayerVector2D::new( reference_frame_relative_offset.x + bounds.origin.x, - reference_frame_relative_offset.y + bounds.origin.y); + reference_frame_relative_offset.y + bounds.origin.y, + ); } - context.builder.push_stacking_context(&reference_frame_relative_offset, - pipeline_id, - composition_operations, - stacking_context.transform_style, - is_backface_visible, - false); + context.builder.push_stacking_context( + &reference_frame_relative_offset, + pipeline_id, + composition_operations, + stacking_context.transform_style, + is_backface_visible, + false, + ); - self.flatten_items(traversal, - pipeline_id, - context, - reference_frame_relative_offset); + self.flatten_items( + traversal, + pipeline_id, + context, + reference_frame_relative_offset, + ); if stacking_context.scroll_policy == ScrollPolicy::Fixed { context.replacements.pop(); @@ -498,13 +548,15 @@ impl Frame { context.builder.pop_stacking_context(); } - fn flatten_iframe<'a>(&mut self, - pipeline_id: PipelineId, - parent_id: ClipId, - bounds: &LayerRect, - local_clip: &LocalClip, - context: &mut FlattenContext, - reference_frame_relative_offset: LayerVector2D) { + fn flatten_iframe<'a>( + &mut self, + pipeline_id: PipelineId, + parent_id: ClipId, + bounds: &LayerRect, + local_clip: &LocalClip, + context: &mut FlattenContext, + reference_frame_relative_offset: LayerVector2D, + ) { let pipeline = match context.scene.pipeline_map.get(&pipeline_id) { Some(pipeline) => pipeline, None => return, @@ -518,25 +570,29 @@ impl Frame { let mut clip_region = ClipRegion::create_for_clip_node_with_local_clip(local_clip); clip_region.origin += reference_frame_relative_offset; let parent_pipeline_id = parent_id.pipeline_id(); - let clip_id = self.clip_scroll_tree.generate_new_clip_id(parent_pipeline_id); - context.builder.add_clip_node(clip_id, - parent_id, - parent_pipeline_id, - clip_region, - &mut self.clip_scroll_tree); + let clip_id = self.clip_scroll_tree + .generate_new_clip_id(parent_pipeline_id); + context.builder.add_clip_node( + clip_id, + parent_id, + parent_pipeline_id, + clip_region, + &mut self.clip_scroll_tree, + ); self.pipeline_epoch_map.insert(pipeline_id, pipeline.epoch); let iframe_rect = LayerRect::new(LayerPoint::zero(), bounds.size); let origin = reference_frame_relative_offset + bounds.origin.to_vector(); let transform = LayerToScrollTransform::create_translation(origin.x, origin.y, 0.0); - let iframe_reference_frame_id = - context.builder.push_reference_frame(Some(clip_id), - pipeline_id, - &iframe_rect, - &transform, - origin, - &mut self.clip_scroll_tree); + let iframe_reference_frame_id = context.builder.push_reference_frame( + Some(clip_id), + pipeline_id, + &iframe_rect, + &transform, + origin, + &mut self.clip_scroll_tree, + ); context.builder.add_scroll_frame( ClipId::root_scroll_node(pipeline_id), @@ -545,19 +601,26 @@ impl Frame { &iframe_rect, &pipeline.content_size, ScrollSensitivity::ScriptAndInputEvents, - &mut self.clip_scroll_tree); + &mut self.clip_scroll_tree, + ); - self.flatten_root(&mut display_list.iter(), pipeline_id, context, &pipeline.content_size); + self.flatten_root( + &mut display_list.iter(), + pipeline_id, + context, + &pipeline.content_size, + ); context.builder.pop_reference_frame(); } - fn flatten_item<'a, 'b>(&mut self, - item: DisplayItemRef<'a, 'b>, - pipeline_id: PipelineId, - context: &mut FlattenContext, - reference_frame_relative_offset: LayerVector2D) - -> Option> { + fn flatten_item<'a, 'b>( + &mut self, + item: DisplayItemRef<'a, 'b>, + pipeline_id: PipelineId, + context: &mut FlattenContext, + reference_frame_relative_offset: LayerVector2D, + ) -> Option> { let mut clip_and_scroll = item.clip_and_scroll(); context.convert_clip_scroll_info_to_nested(&mut clip_and_scroll); @@ -571,41 +634,49 @@ impl Frame { if let Some(tiling) = context.tiled_image_map.get(&info.image_key) { // The image resource is tiled. We have to generate an image primitive // for each tile. - self.decompose_image(clip_and_scroll, - &mut context.builder, - &prim_info, - info, - tiling.image_size, - tiling.tile_size as u32); + self.decompose_image( + clip_and_scroll, + &mut context.builder, + &prim_info, + info, + tiling.image_size, + tiling.tile_size as u32, + ); } else { - context.builder.add_image(clip_and_scroll, - &prim_info, - &info.stretch_size, - &info.tile_spacing, - None, - info.image_key, - info.image_rendering, - None); + context.builder.add_image( + clip_and_scroll, + &prim_info, + &info.stretch_size, + &info.tile_spacing, + None, + info.image_key, + info.image_rendering, + None, + ); } } SpecificDisplayItem::YuvImage(ref info) => { - context.builder.add_yuv_image(clip_and_scroll, - &prim_info, - info.yuv_data, - info.color_space, - info.image_rendering); + context.builder.add_yuv_image( + clip_and_scroll, + &prim_info, + info.yuv_data, + info.color_space, + info.image_rendering, + ); } SpecificDisplayItem::Text(ref text_info) => { match context.resource_cache.get_font_instance(text_info.font_key) { Some(instance) => { - context.builder.add_text(clip_and_scroll, - reference_frame_relative_offset, - &prim_info, - instance, - &text_info.color, - item.glyphs(), - item.display_list().get(item.glyphs()).count(), - text_info.glyph_options); + context.builder.add_text( + clip_and_scroll, + reference_frame_relative_offset, + &prim_info, + instance, + &text_info.color, + item.glyphs(), + item.display_list().get(item.glyphs()).count(), + text_info.glyph_options, + ); } None => { warn!("Unknown font instance key: {:?}", text_info.font_key); @@ -613,15 +684,18 @@ impl Frame { } } SpecificDisplayItem::Rectangle(ref info) => { - if !self.try_to_add_rectangle_splitting_on_clip(context, - &prim_info, - &info.color, - &clip_and_scroll) { - context.builder.add_solid_rectangle(clip_and_scroll, - &prim_info, - &info.color, - PrimitiveFlags::None); - + if !self.try_to_add_rectangle_splitting_on_clip( + context, + &prim_info, + &info.color, + &clip_and_scroll, + ) { + context.builder.add_solid_rectangle( + clip_and_scroll, + &prim_info, + &info.color, + PrimitiveFlags::None, + ); } } SpecificDisplayItem::Line(ref info) => { @@ -631,103 +705,121 @@ impl Frame { is_backface_visible: prim_info.is_backface_visible, }; - context.builder.add_line(clip_and_scroll, - &prim_info, - info.baseline, - info.start, - info.end, - info.orientation, - info.width, - &info.color, - info.style); + context.builder.add_line( + clip_and_scroll, + &prim_info, + info.baseline, + info.start, + info.end, + info.orientation, + info.width, + &info.color, + info.style, + ); } SpecificDisplayItem::Gradient(ref info) => { - context.builder.add_gradient(clip_and_scroll, - &prim_info, - info.gradient.start_point, - info.gradient.end_point, - item.gradient_stops(), - item.display_list() - .get(item.gradient_stops()).count(), - info.gradient.extend_mode, - info.tile_size, - info.tile_spacing); + context.builder.add_gradient( + clip_and_scroll, + &prim_info, + info.gradient.start_point, + info.gradient.end_point, + item.gradient_stops(), + item.display_list().get(item.gradient_stops()).count(), + info.gradient.extend_mode, + info.tile_size, + info.tile_spacing, + ); } SpecificDisplayItem::RadialGradient(ref info) => { - context.builder.add_radial_gradient(clip_and_scroll, - &prim_info, - info.gradient.start_center, - info.gradient.start_radius, - info.gradient.end_center, - info.gradient.end_radius, - info.gradient.ratio_xy, - item.gradient_stops(), - info.gradient.extend_mode, - info.tile_size, - info.tile_spacing); + context.builder.add_radial_gradient( + clip_and_scroll, + &prim_info, + info.gradient.start_center, + info.gradient.start_radius, + info.gradient.end_center, + info.gradient.end_radius, + info.gradient.ratio_xy, + item.gradient_stops(), + info.gradient.extend_mode, + info.tile_size, + info.tile_spacing, + ); } SpecificDisplayItem::BoxShadow(ref box_shadow_info) => { - let bounds = box_shadow_info.box_bounds.translate(&reference_frame_relative_offset); + let bounds = box_shadow_info + .box_bounds + .translate(&reference_frame_relative_offset); let mut prim_info = prim_info.clone(); prim_info.rect = bounds; - context.builder.add_box_shadow(clip_and_scroll, - &prim_info, - &box_shadow_info.offset, - &box_shadow_info.color, - box_shadow_info.blur_radius, - box_shadow_info.spread_radius, - box_shadow_info.border_radius, - box_shadow_info.clip_mode); + context.builder.add_box_shadow( + clip_and_scroll, + &prim_info, + &box_shadow_info.offset, + &box_shadow_info.color, + box_shadow_info.blur_radius, + box_shadow_info.spread_radius, + box_shadow_info.border_radius, + box_shadow_info.clip_mode, + ); } SpecificDisplayItem::Border(ref info) => { - context.builder.add_border(clip_and_scroll, - &prim_info, - info, - item.gradient_stops(), - item.display_list() - .get(item.gradient_stops()).count()); + context.builder.add_border( + clip_and_scroll, + &prim_info, + info, + item.gradient_stops(), + item.display_list().get(item.gradient_stops()).count(), + ); } SpecificDisplayItem::PushStackingContext(ref info) => { let mut subtraversal = item.sub_iter(); - self.flatten_stacking_context(&mut subtraversal, - pipeline_id, - context, - unreplaced_scroll_id, - reference_frame_relative_offset, - &item.rect(), - &info.stacking_context, - item.filters(), - prim_info.is_backface_visible); + self.flatten_stacking_context( + &mut subtraversal, + pipeline_id, + context, + unreplaced_scroll_id, + reference_frame_relative_offset, + &item.rect(), + &info.stacking_context, + item.filters(), + prim_info.is_backface_visible, + ); return Some(subtraversal); } SpecificDisplayItem::Iframe(ref info) => { - self.flatten_iframe(info.pipeline_id, - clip_and_scroll.scroll_node_id, - &item.rect(), - &item.local_clip(), - context, - reference_frame_relative_offset); + self.flatten_iframe( + info.pipeline_id, + clip_and_scroll.scroll_node_id, + &item.rect(), + &item.local_clip(), + context, + reference_frame_relative_offset, + ); } SpecificDisplayItem::Clip(ref info) => { let complex_clips = context.get_complex_clips(pipeline_id, item.complex_clip().0); - let mut clip_region = - ClipRegion::create_for_clip_node(*item.local_clip().clip_rect(), - complex_clips, - info.image_mask); + let mut clip_region = ClipRegion::create_for_clip_node( + *item.local_clip().clip_rect(), + complex_clips, + info.image_mask, + ); clip_region.origin += reference_frame_relative_offset; - self.flatten_clip(context, - pipeline_id, - &clip_and_scroll.scroll_node_id, - &info.id, - clip_region); + self.flatten_clip( + context, + pipeline_id, + &clip_and_scroll.scroll_node_id, + &info.id, + clip_region, + ); } SpecificDisplayItem::ScrollFrame(ref info) => { let complex_clips = context.get_complex_clips(pipeline_id, item.complex_clip().0); - let mut clip_region = - ClipRegion::create_for_clip_node(*item.local_clip().clip_rect(), - complex_clips, - info.image_mask); + let mut clip_region = ClipRegion::create_for_clip_node( + *item.local_clip().clip_rect(), + complex_clips, + info.image_mask, + ); clip_region.origin += reference_frame_relative_offset; // Just use clip rectangle as the frame rect for this scroll frame. @@ -735,17 +827,19 @@ impl Frame { // ClipScrollNode::scroll(..) API as well as for properly setting sticky // positioning offsets. let frame_rect = item.local_clip() - .clip_rect() - .translate(&reference_frame_relative_offset); + .clip_rect() + .translate(&reference_frame_relative_offset); let content_rect = item.rect().translate(&reference_frame_relative_offset); - self.flatten_scroll_frame(context, - pipeline_id, - &clip_and_scroll.scroll_node_id, - &info.id, - &frame_rect, - &content_rect, - clip_region, - info.scroll_sensitivity); + self.flatten_scroll_frame( + context, + pipeline_id, + &clip_and_scroll.scroll_node_id, + &info.id, + &frame_rect, + &content_rect, + clip_region, + info.scroll_sensitivity, + ); } SpecificDisplayItem::StickyFrame(ref info) => { let frame_rect = item.rect().translate(&reference_frame_relative_offset); @@ -754,8 +848,8 @@ impl Frame { new_clip_id, clip_and_scroll.scroll_node_id, /* parent id */ frame_rect, - info.sticky_frame_info); - + info.sticky_frame_info, + ); } SpecificDisplayItem::PushNestedDisplayList => { // Using the clip and scroll already processed for nesting here @@ -767,16 +861,17 @@ impl Frame { SpecificDisplayItem::PopNestedDisplayList => context.pop_nested_display_list_ids(), // Do nothing; these are dummy items for the display list parser - SpecificDisplayItem::SetGradientStops => { } + SpecificDisplayItem::SetGradientStops => {} - SpecificDisplayItem::PopStackingContext => - unreachable!("Should have returned in parent method."), + SpecificDisplayItem::PopStackingContext => { + unreachable!("Should have returned in parent method.") + } SpecificDisplayItem::PushTextShadow(shadow) => { let mut prim_info = prim_info.clone(); prim_info.rect = LayerRect::zero(); - context.builder.push_text_shadow(shadow, - clip_and_scroll, - &prim_info); + context + .builder + .push_text_shadow(shadow, clip_and_scroll, &prim_info); } SpecificDisplayItem::PopTextShadow => { context.builder.pop_text_shadow(); @@ -789,12 +884,13 @@ impl Frame { /// rounded rectangle, by only masking the parts of the rectangle that intersect /// the rounded parts of the clip. This is pretty simple now, so has a lot of /// potential for further optimizations. - fn try_to_add_rectangle_splitting_on_clip(&mut self, - context: &mut FlattenContext, - info: &LayerPrimitiveInfo, - color: &ColorF, - clip_and_scroll: &ClipAndScrollInfo) - -> bool { + fn try_to_add_rectangle_splitting_on_clip( + &mut self, + context: &mut FlattenContext, + info: &LayerPrimitiveInfo, + color: &ColorF, + clip_and_scroll: &ClipAndScrollInfo, + ) -> bool { // If this rectangle is not opaque, splitting the rectangle up // into an inner opaque region just ends up hurting batching and // doing more work than necessary. @@ -824,33 +920,41 @@ impl Frame { is_backface_visible: info.is_backface_visible, }; - context.builder.add_solid_rectangle(*clip_and_scroll, - &prim_info, - color, - PrimitiveFlags::None); + context.builder.add_solid_rectangle( + *clip_and_scroll, + &prim_info, + color, + PrimitiveFlags::None, + ); for clipped_rect in &clipped_rects { let mut info = info.clone(); info.rect = *clipped_rect; - context.builder.add_solid_rectangle(*clip_and_scroll, - &info, - color, - PrimitiveFlags::None); + context.builder.add_solid_rectangle( + *clip_and_scroll, + &info, + color, + PrimitiveFlags::None, + ); } true } - fn flatten_root<'a>(&mut self, - traversal: &mut BuiltDisplayListIter<'a>, - pipeline_id: PipelineId, - context: &mut FlattenContext, - content_size: &LayoutSize) { - context.builder.push_stacking_context(&LayerVector2D::zero(), - pipeline_id, - CompositeOps::default(), - TransformStyle::Flat, - true, - true); + fn flatten_root<'a>( + &mut self, + traversal: &mut BuiltDisplayListIter<'a>, + pipeline_id: PipelineId, + context: &mut FlattenContext, + content_size: &LayoutSize, + ) { + context.builder.push_stacking_context( + &LayerVector2D::zero(), + pipeline_id, + CompositeOps::default(), + TransformStyle::Flat, + true, + true, + ); // We do this here, rather than above because we want any of the top-level // stacking contexts in the display list to be treated like root stacking contexts. @@ -866,10 +970,12 @@ impl Frame { if let Some(bg_color) = pipeline.background_color { let root_bounds = LayerRect::new(LayerPoint::zero(), *content_size); let info = LayerPrimitiveInfo::new(root_bounds); - context.builder.add_solid_rectangle(ClipAndScrollInfo::simple(clip_id), - &info, - &bg_color, - PrimitiveFlags::None); + context.builder.add_solid_rectangle( + ClipAndScrollInfo::simple(clip_id), + &info, + &bg_color, + PrimitiveFlags::None, + ); } } } @@ -885,17 +991,20 @@ impl Frame { ClipAndScrollInfo::simple(clip_id), &info, &DEFAULT_SCROLLBAR_COLOR, - PrimitiveFlags::Scrollbar(self.clip_scroll_tree.topmost_scrolling_node_id(), 4.0)); + PrimitiveFlags::Scrollbar(self.clip_scroll_tree.topmost_scrolling_node_id(), 4.0), + ); } context.builder.pop_stacking_context(); } - fn flatten_items<'a>(&mut self, - traversal: &mut BuiltDisplayListIter<'a>, - pipeline_id: PipelineId, - context: &mut FlattenContext, - reference_frame_relative_offset: LayerVector2D) { + fn flatten_items<'a>( + &mut self, + traversal: &mut BuiltDisplayListIter<'a>, + pipeline_id: PipelineId, + context: &mut FlattenContext, + reference_frame_relative_offset: LayerVector2D, + ) { loop { let subtraversal = { let item = match traversal.next() { @@ -929,64 +1038,75 @@ impl Frame { /// /// decompose_image and decompose_image_row handle image repetitions while decompose_tiled_image /// takes care of the decomposition required by the internal tiling of the image. - fn decompose_image(&mut self, - clip_and_scroll: ClipAndScrollInfo, - builder: &mut FrameBuilder, - prim_info: &LayerPrimitiveInfo, - info: &ImageDisplayItem, - image_size: DeviceUintSize, - tile_size: u32) { + fn decompose_image( + &mut self, + clip_and_scroll: ClipAndScrollInfo, + builder: &mut FrameBuilder, + prim_info: &LayerPrimitiveInfo, + info: &ImageDisplayItem, + image_size: DeviceUintSize, + tile_size: u32, + ) { let no_vertical_tiling = image_size.height <= tile_size; let no_vertical_spacing = info.tile_spacing.height == 0.0; let item_rect = prim_info.rect; if no_vertical_tiling && no_vertical_spacing { - self.decompose_image_row(clip_and_scroll, - builder, - prim_info, - info, - image_size, - tile_size); + self.decompose_image_row( + clip_and_scroll, + builder, + prim_info, + info, + image_size, + tile_size, + ); return; } // Decompose each vertical repetition into rows. let layout_stride = info.stretch_size.height + info.tile_spacing.height; let num_repetitions = (item_rect.size.height / layout_stride).ceil() as u32; - for i in 0..num_repetitions { + for i in 0 .. num_repetitions { if let Some(row_rect) = rect( item_rect.origin.x, item_rect.origin.y + (i as f32) * layout_stride, item_rect.size.width, - info.stretch_size.height - ).intersection(&item_rect) { + info.stretch_size.height, + ).intersection(&item_rect) + { let mut prim_info = prim_info.clone(); prim_info.rect = row_rect; - self.decompose_image_row(clip_and_scroll, - builder, - &prim_info, - info, - image_size, - tile_size); + self.decompose_image_row( + clip_and_scroll, + builder, + &prim_info, + info, + image_size, + tile_size, + ); } } } - fn decompose_image_row(&mut self, - clip_and_scroll: ClipAndScrollInfo, - builder: &mut FrameBuilder, - prim_info: &LayerPrimitiveInfo, - info: &ImageDisplayItem, - image_size: DeviceUintSize, - tile_size: u32) { + fn decompose_image_row( + &mut self, + clip_and_scroll: ClipAndScrollInfo, + builder: &mut FrameBuilder, + prim_info: &LayerPrimitiveInfo, + info: &ImageDisplayItem, + image_size: DeviceUintSize, + tile_size: u32, + ) { let no_horizontal_tiling = image_size.width <= tile_size; let no_horizontal_spacing = info.tile_spacing.width == 0.0; if no_horizontal_tiling && no_horizontal_spacing { - self.decompose_tiled_image(clip_and_scroll, - builder, - prim_info, - info, - image_size, - tile_size); + self.decompose_tiled_image( + clip_and_scroll, + builder, + prim_info, + info, + image_size, + tile_size, + ); return; } @@ -994,32 +1114,37 @@ impl Frame { let item_rect = prim_info.rect; let layout_stride = info.stretch_size.width + info.tile_spacing.width; let num_repetitions = (item_rect.size.width / layout_stride).ceil() as u32; - for i in 0..num_repetitions { + for i in 0 .. num_repetitions { if let Some(decomposed_rect) = rect( item_rect.origin.x + (i as f32) * layout_stride, item_rect.origin.y, info.stretch_size.width, item_rect.size.height, - ).intersection(&item_rect) { + ).intersection(&item_rect) + { let mut prim_info = prim_info.clone(); prim_info.rect = decomposed_rect; - self.decompose_tiled_image(clip_and_scroll, - builder, - &prim_info, - info, - image_size, - tile_size); + self.decompose_tiled_image( + clip_and_scroll, + builder, + &prim_info, + info, + image_size, + tile_size, + ); } } } - fn decompose_tiled_image(&mut self, - clip_and_scroll: ClipAndScrollInfo, - builder: &mut FrameBuilder, - prim_info: &LayerPrimitiveInfo, - info: &ImageDisplayItem, - image_size: DeviceUintSize, - tile_size: u32) { + fn decompose_tiled_image( + &mut self, + clip_and_scroll: ClipAndScrollInfo, + builder: &mut FrameBuilder, + prim_info: &LayerPrimitiveInfo, + info: &ImageDisplayItem, + image_size: DeviceUintSize, + tile_size: u32, + ) { // The image resource is tiled. We have to generate an image primitive // for each tile. // We need to do this because the image is broken up into smaller tiles in the texture @@ -1076,81 +1201,95 @@ impl Frame { // Strected size of the tile in layout space. let stretched_tile_size = LayerSize::new( img_dw * info.stretch_size.width, - img_dh * info.stretch_size.height + img_dh * info.stretch_size.height, ); // The size in pixels of the tiles on the right and bottom edges, smaller // than the regular tile size if the image is not a multiple of the tile size. // Zero means the image size is a multiple of the tile size. - let leftover = DeviceUintSize::new(image_size.width % tile_size, image_size.height % tile_size); - - for ty in 0..num_tiles_y { - for tx in 0..num_tiles_x { - self.add_tile_primitive(clip_and_scroll, - builder, - prim_info, - info, - TileOffset::new(tx, ty), - stretched_tile_size, - 1.0, 1.0, - shader_repeat_x, shader_repeat_y); + let leftover = + DeviceUintSize::new(image_size.width % tile_size, image_size.height % tile_size); + + for ty in 0 .. num_tiles_y { + for tx in 0 .. num_tiles_x { + self.add_tile_primitive( + clip_and_scroll, + builder, + prim_info, + info, + TileOffset::new(tx, ty), + stretched_tile_size, + 1.0, + 1.0, + shader_repeat_x, + shader_repeat_y, + ); } if leftover.width != 0 { // Tiles on the right edge that are smaller than the tile size. - self.add_tile_primitive(clip_and_scroll, - builder, - prim_info, - info, - TileOffset::new(num_tiles_x, ty), - stretched_tile_size, - (leftover.width as f32) / tile_size_f32, - 1.0, - shader_repeat_x, shader_repeat_y); + self.add_tile_primitive( + clip_and_scroll, + builder, + prim_info, + info, + TileOffset::new(num_tiles_x, ty), + stretched_tile_size, + (leftover.width as f32) / tile_size_f32, + 1.0, + shader_repeat_x, + shader_repeat_y, + ); } } if leftover.height != 0 { - for tx in 0..num_tiles_x { + for tx in 0 .. num_tiles_x { // Tiles on the bottom edge that are smaller than the tile size. - self.add_tile_primitive(clip_and_scroll, - builder, - prim_info, - info, - TileOffset::new(tx, num_tiles_y), - stretched_tile_size, - 1.0, - (leftover.height as f32) / tile_size_f32, - shader_repeat_x, - shader_repeat_y); + self.add_tile_primitive( + clip_and_scroll, + builder, + prim_info, + info, + TileOffset::new(tx, num_tiles_y), + stretched_tile_size, + 1.0, + (leftover.height as f32) / tile_size_f32, + shader_repeat_x, + shader_repeat_y, + ); } if leftover.width != 0 { // Finally, the bottom-right tile with a "leftover" size. - self.add_tile_primitive(clip_and_scroll, - builder, - prim_info, - info, - TileOffset::new(num_tiles_x, num_tiles_y), - stretched_tile_size, - (leftover.width as f32) / tile_size_f32, - (leftover.height as f32) / tile_size_f32, - shader_repeat_x, - shader_repeat_y); + self.add_tile_primitive( + clip_and_scroll, + builder, + prim_info, + info, + TileOffset::new(num_tiles_x, num_tiles_y), + stretched_tile_size, + (leftover.width as f32) / tile_size_f32, + (leftover.height as f32) / tile_size_f32, + shader_repeat_x, + shader_repeat_y, + ); } } } - fn add_tile_primitive(&mut self, - clip_and_scroll: ClipAndScrollInfo, - builder: &mut FrameBuilder, - prim_info: &LayerPrimitiveInfo, - info: &ImageDisplayItem, - tile_offset: TileOffset, - stretched_tile_size: LayerSize, - tile_ratio_width: f32, - tile_ratio_height: f32, - shader_repeat_x: bool, - shader_repeat_y: bool) { + fn add_tile_primitive( + &mut self, + clip_and_scroll: ClipAndScrollInfo, + builder: &mut FrameBuilder, + prim_info: &LayerPrimitiveInfo, + info: &ImageDisplayItem, + tile_offset: TileOffset, + stretched_tile_size: LayerSize, + tile_ratio_width: f32, + tile_ratio_height: f32, + shader_repeat_x: bool, + shader_repeat_y: bool, + ) { // If the the image is tiled along a given axis, we can't have the shader compute // the image repetition pattern. In this case we base the primitive's rectangle size // on the stretched tile size which effectively cancels the repetion (and repetition @@ -1166,10 +1305,11 @@ impl Frame { ); let mut prim_rect = LayerRect::new( - prim_info.rect.origin + LayerVector2D::new( - tile_offset.x as f32 * stretched_tile_size.width, - tile_offset.y as f32 * stretched_tile_size.height, - ), + prim_info.rect.origin + + LayerVector2D::new( + tile_offset.x as f32 * stretched_tile_size.width, + tile_offset.y as f32 * stretched_tile_size.height, + ), stretched_size, ); @@ -1187,59 +1327,67 @@ impl Frame { if let Some(prim_rect) = prim_rect.intersection(&prim_info.rect) { let mut prim_info = prim_info.clone(); prim_info.rect = prim_rect; - builder.add_image(clip_and_scroll, - &prim_info, - &stretched_size, - &info.tile_spacing, - None, - info.image_key, - info.image_rendering, - Some(tile_offset)); + builder.add_image( + clip_and_scroll, + &prim_info, + &stretched_size, + &info.tile_spacing, + None, + info.image_key, + info.image_rendering, + Some(tile_offset), + ); } } - pub fn build(&mut self, - resource_cache: &mut ResourceCache, - gpu_cache: &mut GpuCache, - display_lists: &DisplayListMap, - device_pixel_ratio: f32, - pan: LayerPoint, - output_pipelines: &FastHashSet, - texture_cache_profile: &mut TextureCacheProfileCounters, - gpu_cache_profile: &mut GpuCacheProfileCounters) - -> RendererFrame { + pub fn build( + &mut self, + resource_cache: &mut ResourceCache, + gpu_cache: &mut GpuCache, + display_lists: &DisplayListMap, + device_pixel_ratio: f32, + pan: LayerPoint, + output_pipelines: &FastHashSet, + texture_cache_profile: &mut TextureCacheProfileCounters, + gpu_cache_profile: &mut GpuCacheProfileCounters, + ) -> RendererFrame { self.clip_scroll_tree.update_all_node_transforms(pan); - let frame = self.build_frame(resource_cache, - gpu_cache, - display_lists, - device_pixel_ratio, - output_pipelines, - texture_cache_profile, - gpu_cache_profile); + let frame = self.build_frame( + resource_cache, + gpu_cache, + display_lists, + device_pixel_ratio, + output_pipelines, + texture_cache_profile, + gpu_cache_profile, + ); frame } - fn build_frame(&mut self, - resource_cache: &mut ResourceCache, - gpu_cache: &mut GpuCache, - display_lists: &DisplayListMap, - device_pixel_ratio: f32, - output_pipelines: &FastHashSet, - texture_cache_profile: &mut TextureCacheProfileCounters, - gpu_cache_profile: &mut GpuCacheProfileCounters) - -> RendererFrame { + fn build_frame( + &mut self, + resource_cache: &mut ResourceCache, + gpu_cache: &mut GpuCache, + display_lists: &DisplayListMap, + device_pixel_ratio: f32, + output_pipelines: &FastHashSet, + texture_cache_profile: &mut TextureCacheProfileCounters, + gpu_cache_profile: &mut GpuCacheProfileCounters, + ) -> RendererFrame { let mut frame_builder = self.frame_builder.take(); - let frame = frame_builder.as_mut().map(|builder| - builder.build(resource_cache, - gpu_cache, - self.id, - &mut self.clip_scroll_tree, - display_lists, - device_pixel_ratio, - output_pipelines, - texture_cache_profile, - gpu_cache_profile) - ); + let frame = frame_builder.as_mut().map(|builder| { + builder.build( + resource_cache, + gpu_cache, + self.id, + &mut self.clip_scroll_tree, + display_lists, + device_pixel_ratio, + output_pipelines, + texture_cache_profile, + gpu_cache_profile, + ) + }); self.frame_builder = frame_builder; let nodes_bouncing_back = self.clip_scroll_tree.collect_nodes_bouncing_back(); diff --git a/webrender/src/frame_builder.rs b/webrender/src/frame_builder.rs index 74bb6174e9..67205dd40a 100644 --- a/webrender/src/frame_builder.rs +++ b/webrender/src/frame_builder.rs @@ -2,38 +2,40 @@ * 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 api::{BorderDetails, BorderDisplayItem, BorderRadius, BoxShadowClipMode, ClipAndScrollInfo, ClipId, ColorF}; +use api::{BorderDetails, BorderDisplayItem, BorderRadius, BoxShadowClipMode, ClipAndScrollInfo, + ClipId, ColorF}; use api::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DeviceUintRect, DeviceUintSize}; use api::{device_length, ExtendMode, FilterOp, FontInstance, FontRenderMode}; use api::{GlyphInstance, GlyphOptions, GradientStop}; -use api::{ImageKey, ImageRendering, ItemRange, LayerPoint, LayerPrimitiveInfo, LayerRect, LayerSize}; +use api::{ImageKey, ImageRendering, ItemRange, LayerPoint, LayerPrimitiveInfo, LayerRect, + LayerSize}; use api::{LayerToScrollTransform, LayerVector2D, LayoutVector2D, LineOrientation, LineStyle}; use api::{LocalClip, PipelineId, RepeatMode, ScrollSensitivity, SubpixelDirection, TextShadow}; use api::{TileOffset, TransformStyle, WorldPixel, YuvColorSpace, YuvData}; use app_units::Au; use clip::{ClipMode, ClipRegion, ClipSource, ClipSources, ClipStore}; +use clip_scroll_node::{ClipInfo, ClipScrollNode, NodeType}; +use clip_scroll_tree::ClipScrollTree; +use euclid::{SideOffsets2D, vec2, vec3}; use frame::FrameId; use gpu_cache::GpuCache; use internal_types::{FastHashMap, FastHashSet, HardwareCompositeOp}; use plane_split::{BspSplitter, Polygon, Splitter}; +use prim_store::{BoxShadowPrimitiveCpu, TexelRect, YuvImagePrimitiveCpu}; use prim_store::{GradientPrimitiveCpu, ImagePrimitiveCpu, LinePrimitive, PrimitiveKind}; use prim_store::{PrimitiveContainer, PrimitiveIndex}; use prim_store::{PrimitiveStore, RadialGradientPrimitiveCpu, TextRunMode}; use prim_store::{RectanglePrimitive, TextRunPrimitiveCpu, TextShadowPrimitiveCpu}; -use prim_store::{BoxShadowPrimitiveCpu, TexelRect, YuvImagePrimitiveCpu}; use profiler::{FrameProfileCounters, GpuCacheProfileCounters, TextureCacheProfileCounters}; use render_task::{AlphaRenderItem, ClipWorkItem, RenderTask}; -use render_task::{RenderTaskTree, RenderTaskId, RenderTaskLocation}; +use render_task::{RenderTaskId, RenderTaskLocation, RenderTaskTree}; use resource_cache::ResourceCache; -use clip_scroll_node::{ClipInfo, ClipScrollNode, NodeType}; -use clip_scroll_tree::ClipScrollTree; -use std::{f32, i32, mem, usize}; -use euclid::{SideOffsets2D, vec2, vec3}; -use tiling::{ContextIsolation, StackingContextIndex}; +use std::{mem, usize, f32, i32}; use tiling::{ClipScrollGroup, ClipScrollGroupIndex, CompositeOps, DisplayListMap, Frame}; +use tiling::{ContextIsolation, StackingContextIndex}; use tiling::{PackedLayer, PackedLayerIndex, PrimitiveFlags, PrimitiveRunCmd, RenderPass}; use tiling::{RenderTargetContext, ScrollbarPrimitive, StackingContext}; -use util::{self, pack_as_float, subtract_rect, recycle_vec}; +use util::{self, pack_as_float, recycle_vec, subtract_rect}; use util::{MatrixHelpers, RectHelpers}; #[derive(Debug, Clone)] @@ -45,17 +47,21 @@ struct ImageBorderSegment { } impl ImageBorderSegment { - fn new(rect: LayerRect, - sub_rect: TexelRect, - repeat_horizontal: RepeatMode, - repeat_vertical: RepeatMode) -> ImageBorderSegment { + fn new( + rect: LayerRect, + sub_rect: TexelRect, + repeat_horizontal: RepeatMode, + repeat_vertical: RepeatMode, + ) -> ImageBorderSegment { let tile_spacing = LayerSize::zero(); debug_assert!(sub_rect.uv1.x >= sub_rect.uv0.x); debug_assert!(sub_rect.uv1.y >= sub_rect.uv0.y); - let image_size = LayerSize::new(sub_rect.uv1.x - sub_rect.uv0.x, - sub_rect.uv1.y - sub_rect.uv0.y); + let image_size = LayerSize::new( + sub_rect.uv1.x - sub_rect.uv0.x, + sub_rect.uv1.y - sub_rect.uv0.y, + ); let stretch_size_x = match repeat_horizontal { RepeatMode::Stretch => rect.size.width, @@ -87,8 +93,11 @@ impl ImageBorderSegment { /// Construct a polygon from stacking context boundaries. /// `anchor` here is an index that's going to be preserved in all the /// splits of the polygon. -fn make_polygon(stacking_context: &StackingContext, node: &ClipScrollNode, - anchor: usize) -> Polygon { +fn make_polygon( + stacking_context: &StackingContext, + node: &ClipScrollNode, + anchor: usize, +) -> Polygon { //TODO: only work with `isolated_items_bounds.size` worth of space // This can be achieved by moving the `origin` shift // from the primitive local coordinates into the layer transformation. @@ -116,8 +125,7 @@ pub struct FrameBuilder { stacking_context_store: Vec, clip_scroll_group_store: Vec, - clip_scroll_group_indices: FastHashMap, + clip_scroll_group_indices: FastHashMap, packed_layers: Vec, // A stack of the current text-shadow primitives. @@ -138,49 +146,47 @@ pub struct FrameBuilder { } impl FrameBuilder { - pub fn new(previous: Option, - screen_size: DeviceUintSize, - background_color: Option, - config: FrameBuilderConfig) -> FrameBuilder { + pub fn new( + previous: Option, + screen_size: DeviceUintSize, + background_color: Option, + config: FrameBuilderConfig, + ) -> FrameBuilder { match previous { - Some(prev) => { - FrameBuilder { - stacking_context_store: recycle_vec(prev.stacking_context_store), - clip_scroll_group_store: recycle_vec(prev.clip_scroll_group_store), - clip_scroll_group_indices: FastHashMap::default(), - cmds: recycle_vec(prev.cmds), - packed_layers: recycle_vec(prev.packed_layers), - shadow_prim_stack: recycle_vec(prev.shadow_prim_stack), - scrollbar_prims: recycle_vec(prev.scrollbar_prims), - reference_frame_stack: recycle_vec(prev.reference_frame_stack), - stacking_context_stack: recycle_vec(prev.stacking_context_stack), - prim_store: prev.prim_store.recycle(), - clip_store: prev.clip_store.recycle(), - screen_size, - background_color, - config, - has_root_stacking_context: false, - } - } - None => { - FrameBuilder { - stacking_context_store: Vec::new(), - clip_scroll_group_store: Vec::new(), - clip_scroll_group_indices: FastHashMap::default(), - cmds: Vec::new(), - packed_layers: Vec::new(), - shadow_prim_stack: Vec::new(), - scrollbar_prims: Vec::new(), - reference_frame_stack: Vec::new(), - stacking_context_stack: Vec::new(), - prim_store: PrimitiveStore::new(), - clip_store: ClipStore::new(), - screen_size, - background_color, - config, - has_root_stacking_context: false, - } - } + Some(prev) => FrameBuilder { + stacking_context_store: recycle_vec(prev.stacking_context_store), + clip_scroll_group_store: recycle_vec(prev.clip_scroll_group_store), + clip_scroll_group_indices: FastHashMap::default(), + cmds: recycle_vec(prev.cmds), + packed_layers: recycle_vec(prev.packed_layers), + shadow_prim_stack: recycle_vec(prev.shadow_prim_stack), + scrollbar_prims: recycle_vec(prev.scrollbar_prims), + reference_frame_stack: recycle_vec(prev.reference_frame_stack), + stacking_context_stack: recycle_vec(prev.stacking_context_stack), + prim_store: prev.prim_store.recycle(), + clip_store: prev.clip_store.recycle(), + screen_size, + background_color, + config, + has_root_stacking_context: false, + }, + None => FrameBuilder { + stacking_context_store: Vec::new(), + clip_scroll_group_store: Vec::new(), + clip_scroll_group_indices: FastHashMap::default(), + cmds: Vec::new(), + packed_layers: Vec::new(), + shadow_prim_stack: Vec::new(), + scrollbar_prims: Vec::new(), + reference_frame_stack: Vec::new(), + stacking_context_stack: Vec::new(), + prim_store: PrimitiveStore::new(), + clip_store: ClipStore::new(), + screen_size, + background_color, + config, + has_root_stacking_context: false, + }, } } @@ -196,60 +202,76 @@ impl FrameBuilder { /// Create a primitive and add it to the prim store. This method doesn't /// add the primitive to the draw list, so can be used for creating /// sub-primitives. - fn create_primitive(&mut self, - clip_and_scroll: ClipAndScrollInfo, - info: &LayerPrimitiveInfo, - mut clip_sources: Vec, - container: PrimitiveContainer) -> PrimitiveIndex { + fn create_primitive( + &mut self, + clip_and_scroll: ClipAndScrollInfo, + info: &LayerPrimitiveInfo, + mut clip_sources: Vec, + container: PrimitiveContainer, + ) -> PrimitiveIndex { self.create_clip_scroll_group_if_necessary(clip_and_scroll); let local_clip = info.local_clip.unwrap(); if let &LocalClip::RoundedRect(main, region) = &local_clip { clip_sources.push(ClipSource::Rectangle(main)); - clip_sources.push(ClipSource::RoundedRectangle(region.rect, region.radii, ClipMode::Clip)); + clip_sources.push(ClipSource::RoundedRectangle( + region.rect, + region.radii, + ClipMode::Clip, + )); } let clip_sources = self.clip_store.insert(ClipSources::new(clip_sources)); - let prim_index = self.prim_store.add_primitive(&info.rect, - &local_clip.clip_rect(), - info.is_backface_visible, - clip_sources, - container); + let prim_index = self.prim_store.add_primitive( + &info.rect, + &local_clip.clip_rect(), + info.is_backface_visible, + clip_sources, + container, + ); prim_index } /// Add an already created primitive to the draw lists. - pub fn add_primitive_to_draw_list(&mut self, - prim_index: PrimitiveIndex, - clip_and_scroll: ClipAndScrollInfo) { + pub fn add_primitive_to_draw_list( + &mut self, + prim_index: PrimitiveIndex, + clip_and_scroll: ClipAndScrollInfo, + ) { match self.cmds.last_mut().unwrap() { - &mut PrimitiveRunCmd::PrimitiveRun(run_prim_index, ref mut count, run_clip_and_scroll) => { - if run_clip_and_scroll == clip_and_scroll && - run_prim_index.0 + *count == prim_index.0 { - *count += 1; - return; - } - } + &mut PrimitiveRunCmd::PrimitiveRun( + run_prim_index, + ref mut count, + run_clip_and_scroll, + ) => if run_clip_and_scroll == clip_and_scroll && + run_prim_index.0 + *count == prim_index.0 + { + *count += 1; + return; + }, &mut PrimitiveRunCmd::PushStackingContext(..) | &mut PrimitiveRunCmd::PopStackingContext => {} } - self.cmds.push(PrimitiveRunCmd::PrimitiveRun(prim_index, 1, clip_and_scroll)); + self.cmds.push(PrimitiveRunCmd::PrimitiveRun( + prim_index, + 1, + clip_and_scroll, + )); } /// Convenience interface that creates a primitive entry and adds it /// to the draw list. - pub fn add_primitive(&mut self, - clip_and_scroll: ClipAndScrollInfo, - info: &LayerPrimitiveInfo, - clip_sources: Vec, - container: PrimitiveContainer) -> PrimitiveIndex { - let prim_index = self.create_primitive(clip_and_scroll, - info, - clip_sources, - container); + pub fn add_primitive( + &mut self, + clip_and_scroll: ClipAndScrollInfo, + info: &LayerPrimitiveInfo, + clip_sources: Vec, + container: PrimitiveContainer, + ) -> PrimitiveIndex { + let prim_index = self.create_primitive(clip_and_scroll, info, clip_sources, container); self.add_primitive_to_draw_list(prim_index, clip_and_scroll); @@ -265,7 +287,7 @@ impl FrameBuilder { clip_node_id: info.clip_node_id(), packed_layer_index, screen_bounding_rect: None, - }); + }); ClipScrollGroupIndex(self.clip_scroll_group_store.len() - 1, info) } @@ -274,13 +296,15 @@ impl FrameBuilder { self.has_root_stacking_context = false; } - pub fn push_stacking_context(&mut self, - reference_frame_offset: &LayerVector2D, - pipeline_id: PipelineId, - composite_ops: CompositeOps, - transform_style: TransformStyle, - is_backface_visible: bool, - is_pipeline_root: bool) { + pub fn push_stacking_context( + &mut self, + reference_frame_offset: &LayerVector2D, + pipeline_id: PipelineId, + composite_ops: CompositeOps, + transform_style: TransformStyle, + is_backface_visible: bool, + is_pipeline_root: bool, + ) { if let Some(parent_index) = self.stacking_context_stack.last() { let parent_is_root = self.stacking_context_store[parent_index.0].is_page_root; @@ -290,7 +314,11 @@ impl FrameBuilder { // is the root of the page let isolation = &mut self.stacking_context_store[parent_index.0].isolation; if *isolation != ContextIsolation::None { - error!("Isolation conflict detected on {:?}: {:?}", parent_index, *isolation); + error!( + "Isolation conflict detected on {:?}: {:?}", + parent_index, + *isolation + ); } *isolation = ContextIsolation::Full; } @@ -298,39 +326,47 @@ impl FrameBuilder { let stacking_context_index = StackingContextIndex(self.stacking_context_store.len()); let reference_frame_id = self.current_reference_frame_id(); - self.stacking_context_store.push(StackingContext::new(pipeline_id, - *reference_frame_offset, - !self.has_root_stacking_context, - is_pipeline_root, - reference_frame_id, - transform_style, - composite_ops, - is_backface_visible)); + self.stacking_context_store.push(StackingContext::new( + pipeline_id, + *reference_frame_offset, + !self.has_root_stacking_context, + is_pipeline_root, + reference_frame_id, + transform_style, + composite_ops, + is_backface_visible, + )); self.has_root_stacking_context = true; - self.cmds.push(PrimitiveRunCmd::PushStackingContext(stacking_context_index)); + self.cmds + .push(PrimitiveRunCmd::PushStackingContext(stacking_context_index)); self.stacking_context_stack.push(stacking_context_index); } pub fn pop_stacking_context(&mut self) { self.cmds.push(PrimitiveRunCmd::PopStackingContext); self.stacking_context_stack.pop(); - assert!(self.shadow_prim_stack.is_empty(), - "Found unpopped text shadows when popping stacking context!"); + assert!( + self.shadow_prim_stack.is_empty(), + "Found unpopped text shadows when popping stacking context!" + ); } - pub fn push_reference_frame(&mut self, - parent_id: Option, - pipeline_id: PipelineId, - rect: &LayerRect, - transform: &LayerToScrollTransform, - origin_in_parent_reference_frame: LayerVector2D, - clip_scroll_tree: &mut ClipScrollTree) - -> ClipId { - let new_id = clip_scroll_tree.add_reference_frame(rect, - transform, - origin_in_parent_reference_frame, - pipeline_id, - parent_id); + pub fn push_reference_frame( + &mut self, + parent_id: Option, + pipeline_id: PipelineId, + rect: &LayerRect, + transform: &LayerToScrollTransform, + origin_in_parent_reference_frame: LayerVector2D, + clip_scroll_tree: &mut ClipScrollTree, + ) -> ClipId { + let new_id = clip_scroll_tree.add_reference_frame( + rect, + transform, + origin_in_parent_reference_frame, + pipeline_id, + parent_id, + ); self.reference_frame_stack.push(new_id); new_id } @@ -339,29 +375,41 @@ impl FrameBuilder { *self.reference_frame_stack.last().unwrap() } - pub fn setup_viewport_offset(&mut self, - window_size: DeviceUintSize, - inner_rect: DeviceUintRect, - device_pixel_ratio: f32, - clip_scroll_tree: &mut ClipScrollTree) { + pub fn setup_viewport_offset( + &mut self, + window_size: DeviceUintSize, + inner_rect: DeviceUintRect, + device_pixel_ratio: f32, + clip_scroll_tree: &mut ClipScrollTree, + ) { let inner_origin = inner_rect.origin.to_f32(); - let viewport_offset = LayerPoint::new((inner_origin.x / device_pixel_ratio).round(), - (inner_origin.y / device_pixel_ratio).round()); + let viewport_offset = LayerPoint::new( + (inner_origin.x / device_pixel_ratio).round(), + (inner_origin.y / device_pixel_ratio).round(), + ); let outer_size = window_size.to_f32(); - let outer_size = LayerSize::new((outer_size.width / device_pixel_ratio).round(), - (outer_size.height / device_pixel_ratio).round()); - let clip_size = LayerSize::new(outer_size.width + 2.0 * viewport_offset.x, - outer_size.height + 2.0 * viewport_offset.y); - - let viewport_clip = LayerRect::new(LayerPoint::new(-viewport_offset.x, -viewport_offset.y), - LayerSize::new(clip_size.width, clip_size.height)); + let outer_size = LayerSize::new( + (outer_size.width / device_pixel_ratio).round(), + (outer_size.height / device_pixel_ratio).round(), + ); + let clip_size = LayerSize::new( + outer_size.width + 2.0 * viewport_offset.x, + outer_size.height + 2.0 * viewport_offset.y, + ); + + let viewport_clip = LayerRect::new( + LayerPoint::new(-viewport_offset.x, -viewport_offset.y), + LayerSize::new(clip_size.width, clip_size.height), + ); let root_id = clip_scroll_tree.root_reference_frame_id(); if let Some(root_node) = clip_scroll_tree.nodes.get_mut(&root_id) { if let NodeType::ReferenceFrame(ref mut info) = root_node.node_type { - info.transform = LayerToScrollTransform::create_translation(viewport_offset.x, - viewport_offset.y, - 0.0); + info.transform = LayerToScrollTransform::create_translation( + viewport_offset.x, + viewport_offset.y, + 0.0, + ); } root_node.local_clip_rect = viewport_clip; } @@ -372,62 +420,75 @@ impl FrameBuilder { } } - pub fn push_root(&mut self, - pipeline_id: PipelineId, - viewport_size: &LayerSize, - content_size: &LayerSize, - clip_scroll_tree: &mut ClipScrollTree) - -> ClipId { + pub fn push_root( + &mut self, + pipeline_id: PipelineId, + viewport_size: &LayerSize, + content_size: &LayerSize, + clip_scroll_tree: &mut ClipScrollTree, + ) -> ClipId { let viewport_rect = LayerRect::new(LayerPoint::zero(), *viewport_size); let identity = &LayerToScrollTransform::identity(); - self.push_reference_frame(None, - pipeline_id, - &viewport_rect, - identity, - LayerVector2D::zero(), - clip_scroll_tree); + self.push_reference_frame( + None, + pipeline_id, + &viewport_rect, + identity, + LayerVector2D::zero(), + clip_scroll_tree, + ); let topmost_scrolling_node_id = ClipId::root_scroll_node(pipeline_id); clip_scroll_tree.topmost_scrolling_node_id = topmost_scrolling_node_id; - self.add_scroll_frame(topmost_scrolling_node_id, - clip_scroll_tree.root_reference_frame_id, - pipeline_id, - &viewport_rect, - content_size, - ScrollSensitivity::ScriptAndInputEvents, - clip_scroll_tree); + self.add_scroll_frame( + topmost_scrolling_node_id, + clip_scroll_tree.root_reference_frame_id, + pipeline_id, + &viewport_rect, + content_size, + ScrollSensitivity::ScriptAndInputEvents, + clip_scroll_tree, + ); topmost_scrolling_node_id } - pub fn add_clip_node(&mut self, - new_node_id: ClipId, - parent_id: ClipId, - pipeline_id: PipelineId, - clip_region: ClipRegion, - clip_scroll_tree: &mut ClipScrollTree) { - let clip_info = ClipInfo::new(clip_region, - PackedLayerIndex(self.packed_layers.len()), - &mut self.clip_store); + pub fn add_clip_node( + &mut self, + new_node_id: ClipId, + parent_id: ClipId, + pipeline_id: PipelineId, + clip_region: ClipRegion, + clip_scroll_tree: &mut ClipScrollTree, + ) { + let clip_info = ClipInfo::new( + clip_region, + PackedLayerIndex(self.packed_layers.len()), + &mut self.clip_store, + ); let node = ClipScrollNode::new(pipeline_id, parent_id, clip_info); clip_scroll_tree.add_node(node, new_node_id); self.packed_layers.push(PackedLayer::empty()); } - pub fn add_scroll_frame(&mut self, - new_node_id: ClipId, - parent_id: ClipId, - pipeline_id: PipelineId, - frame_rect: &LayerRect, - content_size: &LayerSize, - scroll_sensitivity: ScrollSensitivity, - clip_scroll_tree: &mut ClipScrollTree) { - let node = ClipScrollNode::new_scroll_frame(pipeline_id, - parent_id, - frame_rect, - content_size, - scroll_sensitivity); + pub fn add_scroll_frame( + &mut self, + new_node_id: ClipId, + parent_id: ClipId, + pipeline_id: PipelineId, + frame_rect: &LayerRect, + content_size: &LayerSize, + scroll_sensitivity: ScrollSensitivity, + clip_scroll_tree: &mut ClipScrollTree, + ) { + let node = ClipScrollNode::new_scroll_frame( + pipeline_id, + parent_id, + frame_rect, + content_size, + scroll_sensitivity, + ); clip_scroll_tree.add_node(node, new_node_id); } @@ -436,10 +497,12 @@ impl FrameBuilder { self.reference_frame_stack.pop(); } - pub fn push_text_shadow(&mut self, - shadow: TextShadow, - clip_and_scroll: ClipAndScrollInfo, - info: &LayerPrimitiveInfo) { + pub fn push_text_shadow( + &mut self, + shadow: TextShadow, + clip_and_scroll: ClipAndScrollInfo, + info: &LayerPrimitiveInfo, + ) { let prim = TextShadowPrimitiveCpu { shadow, primitives: Vec::new(), @@ -450,18 +513,20 @@ impl FrameBuilder { // the draw lists immediately so that it will be drawn // before any visual text elements that are added as // part of this text-shadow context. - let prim_index = self.add_primitive(clip_and_scroll, - info, - Vec::new(), - PrimitiveContainer::TextShadow(prim)); + let prim_index = self.add_primitive( + clip_and_scroll, + info, + Vec::new(), + PrimitiveContainer::TextShadow(prim), + ); self.shadow_prim_stack.push(prim_index); } pub fn pop_text_shadow(&mut self) { let prim_index = self.shadow_prim_stack - .pop() - .expect("invalid shadow push/pop count"); + .pop() + .expect("invalid shadow push/pop count"); // By now, the local rect of the text shadow has been calculated. It // is calculated as the items in the shadow are added. It's now @@ -473,19 +538,21 @@ impl FrameBuilder { metadata.local_rect = metadata.local_rect.translate(&prim.shadow.offset); } - pub fn add_solid_rectangle(&mut self, - clip_and_scroll: ClipAndScrollInfo, - info: &LayerPrimitiveInfo, - color: &ColorF, - flags: PrimitiveFlags) { - let prim = RectanglePrimitive { - color: *color, - }; - - let prim_index = self.add_primitive(clip_and_scroll, - info, - Vec::new(), - PrimitiveContainer::Rectangle(prim)); + pub fn add_solid_rectangle( + &mut self, + clip_and_scroll: ClipAndScrollInfo, + info: &LayerPrimitiveInfo, + color: &ColorF, + flags: PrimitiveFlags, + ) { + let prim = RectanglePrimitive { color: *color }; + + let prim_index = self.add_primitive( + clip_and_scroll, + info, + Vec::new(), + PrimitiveContainer::Rectangle(prim), + ); match flags { PrimitiveFlags::None => {} @@ -499,25 +566,27 @@ impl FrameBuilder { } } - pub fn add_line(&mut self, - clip_and_scroll: ClipAndScrollInfo, - info: &LayerPrimitiveInfo, - baseline: f32, - start: f32, - end: f32, - orientation: LineOrientation, - width: f32, - color: &ColorF, - style: LineStyle) { + pub fn add_line( + &mut self, + clip_and_scroll: ClipAndScrollInfo, + info: &LayerPrimitiveInfo, + baseline: f32, + start: f32, + end: f32, + orientation: LineOrientation, + width: f32, + color: &ColorF, + style: LineStyle, + ) { let new_rect = match orientation { - LineOrientation::Horizontal => { - LayerRect::new(LayerPoint::new(start, baseline), - LayerSize::new(end - start, width)) - } - LineOrientation::Vertical => { - LayerRect::new(LayerPoint::new(baseline, start), - LayerSize::new(width, end - start)) - } + LineOrientation::Horizontal => LayerRect::new( + LayerPoint::new(start, baseline), + LayerSize::new(end - start, width), + ), + LineOrientation::Vertical => LayerRect::new( + LayerPoint::new(baseline, start), + LayerSize::new(width, end - start), + ), }; let line = LinePrimitive { @@ -539,18 +608,22 @@ impl FrameBuilder { line.color = shadow.color; let mut info = info.clone(); info.rect = new_rect.translate(&shadow.offset); - self.add_primitive(clip_and_scroll, - &info, - Vec::new(), - PrimitiveContainer::Line(line)); + self.add_primitive( + clip_and_scroll, + &info, + Vec::new(), + PrimitiveContainer::Line(line), + ); } let mut info = info.clone(); info.rect = new_rect; - let prim_index = self.create_primitive(clip_and_scroll, - &info, - Vec::new(), - PrimitiveContainer::Line(line)); + let prim_index = self.create_primitive( + clip_and_scroll, + &info, + Vec::new(), + PrimitiveContainer::Line(line), + ); if color.a > 0.0 { self.add_primitive_to_draw_list(prim_index, clip_and_scroll); @@ -559,31 +632,37 @@ impl FrameBuilder { for shadow_prim_index in &self.shadow_prim_stack { let shadow_metadata = &mut self.prim_store.cpu_metadata[shadow_prim_index.0]; debug_assert_eq!(shadow_metadata.prim_kind, PrimitiveKind::TextShadow); - let shadow_prim = &mut self.prim_store.cpu_text_shadows[shadow_metadata.cpu_prim_index.0]; + let shadow_prim = + &mut self.prim_store.cpu_text_shadows[shadow_metadata.cpu_prim_index.0]; // Only run real blurs here (fast path zero blurs are handled above). if shadow_prim.shadow.blur_radius > 0.0 { - let shadow_rect = new_rect.inflate(shadow_prim.shadow.blur_radius, - shadow_prim.shadow.blur_radius); + let shadow_rect = new_rect.inflate( + shadow_prim.shadow.blur_radius, + shadow_prim.shadow.blur_radius, + ); shadow_metadata.local_rect = shadow_metadata.local_rect.union(&shadow_rect); shadow_prim.primitives.push(prim_index); } } } - pub fn add_border(&mut self, - clip_and_scroll: ClipAndScrollInfo, - info: &LayerPrimitiveInfo, - border_item: &BorderDisplayItem, - gradient_stops: ItemRange, - gradient_stops_count: usize) { + pub fn add_border( + &mut self, + clip_and_scroll: ClipAndScrollInfo, + info: &LayerPrimitiveInfo, + border_item: &BorderDisplayItem, + gradient_stops: ItemRange, + gradient_stops_count: usize, + ) { let rect = info.rect; let create_segments = |outset: SideOffsets2D| { // Calculate the modified rect as specific by border-image-outset - let origin = LayerPoint::new(rect.origin.x - outset.left, - rect.origin.y - outset.top); - let size = LayerSize::new(rect.size.width + outset.left + outset.right, - rect.size.height + outset.top + outset.bottom); + let origin = LayerPoint::new(rect.origin.x - outset.left, rect.origin.y - outset.top); + let size = LayerSize::new( + rect.size.width + outset.left + outset.right, + rect.size.height + outset.top + outset.bottom, + ); let rect = LayerRect::new(origin, size); let tl_outer = LayerPoint::new(rect.origin.x, rect.origin.y); @@ -595,8 +674,10 @@ impl FrameBuilder { let bl_outer = LayerPoint::new(rect.origin.x, rect.origin.y + rect.size.height); let bl_inner = bl_outer + vec2(border_item.widths.left, -border_item.widths.bottom); - let br_outer = LayerPoint::new(rect.origin.x + rect.size.width, - rect.origin.y + rect.size.height); + let br_outer = LayerPoint::new( + rect.origin.x + rect.size.width, + rect.origin.y + rect.size.height, + ); let br_inner = br_outer - vec2(border_item.widths.right, border_item.widths.bottom); // Build the list of gradient segments @@ -623,10 +704,14 @@ impl FrameBuilder { match border_item.details { BorderDetails::Image(ref border) => { // Calculate the modified rect as specific by border-image-outset - let origin = LayerPoint::new(rect.origin.x - border.outset.left, - rect.origin.y - border.outset.top); - let size = LayerSize::new(rect.size.width + border.outset.left + border.outset.right, - rect.size.height + border.outset.top + border.outset.bottom); + let origin = LayerPoint::new( + rect.origin.x - border.outset.left, + rect.origin.y - border.outset.top, + ); + let size = LayerSize::new( + rect.size.width + border.outset.left + border.outset.right, + rect.size.height + border.outset.top + border.outset.bottom, + ); let rect = LayerRect::new(origin, size); // Calculate the local texel coords of the slices. @@ -649,35 +734,42 @@ impl FrameBuilder { let bl_outer = LayerPoint::new(rect.origin.x, rect.origin.y + rect.size.height); let bl_inner = bl_outer + vec2(border_item.widths.left, -border_item.widths.bottom); - let br_outer = LayerPoint::new(rect.origin.x + rect.size.width, - rect.origin.y + rect.size.height); + let br_outer = LayerPoint::new( + rect.origin.x + rect.size.width, + rect.origin.y + rect.size.height, + ); let br_inner = br_outer - vec2(border_item.widths.right, border_item.widths.bottom); // Build the list of image segments let mut segments = vec![ // Top left - ImageBorderSegment::new(LayerRect::from_floats(tl_outer.x, tl_outer.y, tl_inner.x, tl_inner.y), - TexelRect::new(px0, py0, px1, py1), - RepeatMode::Stretch, - RepeatMode::Stretch), - + ImageBorderSegment::new( + LayerRect::from_floats(tl_outer.x, tl_outer.y, tl_inner.x, tl_inner.y), + TexelRect::new(px0, py0, px1, py1), + RepeatMode::Stretch, + RepeatMode::Stretch, + ), // Top right - ImageBorderSegment::new(LayerRect::from_floats(tr_inner.x, tr_outer.y, tr_outer.x, tr_inner.y), - TexelRect::new(px2, py0, px3, py1), - RepeatMode::Stretch, - RepeatMode::Stretch), - + ImageBorderSegment::new( + LayerRect::from_floats(tr_inner.x, tr_outer.y, tr_outer.x, tr_inner.y), + TexelRect::new(px2, py0, px3, py1), + RepeatMode::Stretch, + RepeatMode::Stretch, + ), // Bottom right - ImageBorderSegment::new(LayerRect::from_floats(br_inner.x, br_inner.y, br_outer.x, br_outer.y), - TexelRect::new(px2, py2, px3, py3), - RepeatMode::Stretch, - RepeatMode::Stretch), - + ImageBorderSegment::new( + LayerRect::from_floats(br_inner.x, br_inner.y, br_outer.x, br_outer.y), + TexelRect::new(px2, py2, px3, py3), + RepeatMode::Stretch, + RepeatMode::Stretch, + ), // Bottom left - ImageBorderSegment::new(LayerRect::from_floats(bl_outer.x, bl_inner.y, bl_inner.x, bl_outer.y), - TexelRect::new(px0, py2, px1, py3), - RepeatMode::Stretch, - RepeatMode::Stretch), + ImageBorderSegment::new( + LayerRect::from_floats(bl_outer.x, bl_inner.y, bl_inner.x, bl_outer.y), + TexelRect::new(px0, py2, px1, py3), + RepeatMode::Stretch, + RepeatMode::Stretch, + ), ]; // Center @@ -686,116 +778,124 @@ impl FrameBuilder { LayerRect::from_floats(tl_inner.x, tl_inner.y, tr_inner.x, bl_inner.y), TexelRect::new(px1, py1, px2, py2), border.repeat_horizontal, - border.repeat_vertical)) + border.repeat_vertical, + )) } // Add edge segments if valid size. if px1 < px2 && py1 < py2 { segments.extend_from_slice(&[ // Top - ImageBorderSegment::new(LayerRect::from_floats(tl_inner.x, tl_outer.y, tr_inner.x, tl_inner.y), - TexelRect::new(px1, py0, px2, py1), - border.repeat_horizontal, - RepeatMode::Stretch), - + ImageBorderSegment::new( + LayerRect::from_floats(tl_inner.x, tl_outer.y, tr_inner.x, tl_inner.y), + TexelRect::new(px1, py0, px2, py1), + border.repeat_horizontal, + RepeatMode::Stretch, + ), // Bottom - ImageBorderSegment::new(LayerRect::from_floats(bl_inner.x, bl_inner.y, br_inner.x, bl_outer.y), - TexelRect::new(px1, py2, px2, py3), - border.repeat_horizontal, - RepeatMode::Stretch), - + ImageBorderSegment::new( + LayerRect::from_floats(bl_inner.x, bl_inner.y, br_inner.x, bl_outer.y), + TexelRect::new(px1, py2, px2, py3), + border.repeat_horizontal, + RepeatMode::Stretch, + ), // Left - ImageBorderSegment::new(LayerRect::from_floats(tl_outer.x, tl_inner.y, tl_inner.x, bl_inner.y), - TexelRect::new(px0, py1, px1, py2), - RepeatMode::Stretch, - border.repeat_vertical), - + ImageBorderSegment::new( + LayerRect::from_floats(tl_outer.x, tl_inner.y, tl_inner.x, bl_inner.y), + TexelRect::new(px0, py1, px1, py2), + RepeatMode::Stretch, + border.repeat_vertical, + ), // Right - ImageBorderSegment::new(LayerRect::from_floats(tr_inner.x, tr_inner.y, br_outer.x, br_inner.y), - TexelRect::new(px2, py1, px3, py2), - RepeatMode::Stretch, - border.repeat_vertical), + ImageBorderSegment::new( + LayerRect::from_floats(tr_inner.x, tr_inner.y, br_outer.x, br_inner.y), + TexelRect::new(px2, py1, px3, py2), + RepeatMode::Stretch, + border.repeat_vertical, + ), ]); } for segment in segments { let mut info = info.clone(); info.rect = segment.geom_rect; - self.add_image(clip_and_scroll, - &info, - &segment.stretch_size, - &segment.tile_spacing, - Some(segment.sub_rect), - border.image_key, - ImageRendering::Auto, - None); + self.add_image( + clip_and_scroll, + &info, + &segment.stretch_size, + &segment.tile_spacing, + Some(segment.sub_rect), + border.image_key, + ImageRendering::Auto, + None, + ); } } BorderDetails::Normal(ref border) => { - self.add_normal_border(info, - border, - &border_item.widths, - clip_and_scroll); - } - BorderDetails::Gradient(ref border) => { - for segment in create_segments(border.outset) { - let segment_rel = segment.origin - rect.origin; - let mut info = info.clone(); - info.rect = segment; - - self.add_gradient(clip_and_scroll, - &info, - border.gradient.start_point - segment_rel, - border.gradient.end_point - segment_rel, - gradient_stops, - gradient_stops_count, - border.gradient.extend_mode, - segment.size, - LayerSize::zero()); - } + self.add_normal_border(info, border, &border_item.widths, clip_and_scroll); } + BorderDetails::Gradient(ref border) => for segment in create_segments(border.outset) { + let segment_rel = segment.origin - rect.origin; + let mut info = info.clone(); + info.rect = segment; + + self.add_gradient( + clip_and_scroll, + &info, + border.gradient.start_point - segment_rel, + border.gradient.end_point - segment_rel, + gradient_stops, + gradient_stops_count, + border.gradient.extend_mode, + segment.size, + LayerSize::zero(), + ); + }, BorderDetails::RadialGradient(ref border) => { for segment in create_segments(border.outset) { let segment_rel = segment.origin - rect.origin; let mut info = info.clone(); info.rect = segment; - self.add_radial_gradient(clip_and_scroll, - &info, - border.gradient.start_center - segment_rel, - border.gradient.start_radius, - border.gradient.end_center - segment_rel, - border.gradient.end_radius, - border.gradient.ratio_xy, - gradient_stops, - border.gradient.extend_mode, - segment.size, - LayerSize::zero()); + self.add_radial_gradient( + clip_and_scroll, + &info, + border.gradient.start_center - segment_rel, + border.gradient.start_radius, + border.gradient.end_center - segment_rel, + border.gradient.end_radius, + border.gradient.ratio_xy, + gradient_stops, + border.gradient.extend_mode, + segment.size, + LayerSize::zero(), + ); } } } } - pub fn add_gradient(&mut self, - clip_and_scroll: ClipAndScrollInfo, - info: &LayerPrimitiveInfo, - start_point: LayerPoint, - end_point: LayerPoint, - stops: ItemRange, - stops_count: usize, - extend_mode: ExtendMode, - tile_size: LayerSize, - tile_spacing: LayerSize) { + pub fn add_gradient( + &mut self, + clip_and_scroll: ClipAndScrollInfo, + info: &LayerPrimitiveInfo, + start_point: LayerPoint, + end_point: LayerPoint, + stops: ItemRange, + stops_count: usize, + extend_mode: ExtendMode, + tile_size: LayerSize, + tile_spacing: LayerSize, + ) { let tile_repeat = tile_size + tile_spacing; let is_not_tiled = tile_repeat.width >= info.rect.size.width && - tile_repeat.height >= info.rect.size.height; + tile_repeat.height >= info.rect.size.height; let aligned_and_fills_rect = (start_point.x == end_point.x && - start_point.y.min(end_point.y) <= 0.0 && - start_point.y.max(end_point.y) >= info.rect.size.height) || - (start_point.y == end_point.y && - start_point.x.min(end_point.x) <= 0.0 && - start_point.x.max(end_point.x) >= info.rect.size.width); + start_point.y.min(end_point.y) <= 0.0 && + start_point.y.max(end_point.y) >= info.rect.size.height) || + (start_point.y == end_point.y && start_point.x.min(end_point.x) <= 0.0 && + start_point.x.max(end_point.x) >= info.rect.size.width); // Fast path for clamped, axis-aligned gradients, with gradient lines intersecting all of rect: let aligned = extend_mode == ExtendMode::Clamp && is_not_tiled && aligned_and_fills_rect; @@ -807,9 +907,8 @@ impl FrameBuilder { // manages to produce the same result regardless of orientation, so don't worry about // reversing in that case. let reverse_stops = !aligned && - (start_point.x > end_point.x || - (start_point.x == end_point.x && - start_point.y > end_point.y)); + (start_point.x > end_point.x || + (start_point.x == end_point.x && start_point.y > end_point.y)); // To get reftests exactly matching with reverse start/end // points, it's necessary to reverse the gradient @@ -827,7 +926,12 @@ impl FrameBuilder { reverse_stops, gpu_blocks: [ [sp.x, sp.y, ep.x, ep.y].into(), - [tile_size.width, tile_size.height, tile_repeat.width, tile_repeat.height].into(), + [ + tile_size.width, + tile_size.height, + tile_repeat.width, + tile_repeat.height, + ].into(), [pack_as_float(extend_mode as u32), 0.0, 0.0, 0.0].into(), ], }; @@ -841,18 +945,20 @@ impl FrameBuilder { self.add_primitive(clip_and_scroll, info, Vec::new(), prim); } - pub fn add_radial_gradient(&mut self, - clip_and_scroll: ClipAndScrollInfo, - info: &LayerPrimitiveInfo, - start_center: LayerPoint, - start_radius: f32, - end_center: LayerPoint, - end_radius: f32, - ratio_xy: f32, - stops: ItemRange, - extend_mode: ExtendMode, - tile_size: LayerSize, - tile_spacing: LayerSize) { + pub fn add_radial_gradient( + &mut self, + clip_and_scroll: ClipAndScrollInfo, + info: &LayerPrimitiveInfo, + start_center: LayerPoint, + start_radius: f32, + end_center: LayerPoint, + end_radius: f32, + ratio_xy: f32, + stops: ItemRange, + extend_mode: ExtendMode, + tile_size: LayerSize, + tile_spacing: LayerSize, + ) { let tile_repeat = tile_size + tile_spacing; let radial_gradient_cpu = RadialGradientPrimitiveCpu { @@ -861,30 +967,44 @@ impl FrameBuilder { gpu_data_count: 0, gpu_blocks: [ [start_center.x, start_center.y, end_center.x, end_center.y].into(), - [start_radius, end_radius, ratio_xy, pack_as_float(extend_mode as u32)].into(), - [tile_size.width, tile_size.height, tile_repeat.width, tile_repeat.height].into(), + [ + start_radius, + end_radius, + ratio_xy, + pack_as_float(extend_mode as u32), + ].into(), + [ + tile_size.width, + tile_size.height, + tile_repeat.width, + tile_repeat.height, + ].into(), ], }; - self.add_primitive(clip_and_scroll, - info, - Vec::new(), - PrimitiveContainer::RadialGradient(radial_gradient_cpu)); + self.add_primitive( + clip_and_scroll, + info, + Vec::new(), + PrimitiveContainer::RadialGradient(radial_gradient_cpu), + ); } - pub fn add_text(&mut self, - clip_and_scroll: ClipAndScrollInfo, - run_offset: LayoutVector2D, - info: &LayerPrimitiveInfo, - font: &FontInstance, - color: &ColorF, - glyph_range: ItemRange, - glyph_count: usize, - glyph_options: Option) { + pub fn add_text( + &mut self, + clip_and_scroll: ClipAndScrollInfo, + run_offset: LayoutVector2D, + info: &LayerPrimitiveInfo, + font: &FontInstance, + color: &ColorF, + glyph_range: ItemRange, + glyph_count: usize, + glyph_options: Option, + ) { let rect = info.rect; // Trivial early out checks if font.size.0 <= 0 { - return + return; } // Sanity check - anything with glyphs bigger than this @@ -894,13 +1014,15 @@ impl FrameBuilder { // font as a crash test - the rendering is also ignored // by the azure renderer. if font.size >= Au::from_px(4096) { - return + return; } // TODO(gw): Use a proper algorithm to select // whether this item should be rendered with // subpixel AA! - let mut default_render_mode = self.config.default_font_render_mode.limit_by(font.render_mode); + let mut default_render_mode = self.config + .default_font_render_mode + .limit_by(font.render_mode); if let Some(options) = glyph_options { default_render_mode = default_render_mode.limit_by(options.render_mode); } @@ -934,17 +1056,17 @@ impl FrameBuilder { // vertical text runs. (FontRenderMode::Alpha, font.subpx_dir) } - FontRenderMode::Mono => { - (FontRenderMode::Mono, SubpixelDirection::None) - } + FontRenderMode::Mono => (FontRenderMode::Mono, SubpixelDirection::None), }; - let prim_font = FontInstance::new(font.font_key, - font.size, - *color, - normal_render_mode, - subpx_dir, - font.platform_options); + let prim_font = FontInstance::new( + font.font_key, + font.size, + *color, + normal_render_mode, + subpx_dir, + font.platform_options, + ); let prim = TextRunPrimitiveCpu { font: prim_font, glyph_range, @@ -980,18 +1102,22 @@ impl FrameBuilder { let rect = info.rect; let mut info = info.clone(); info.rect = rect.translate(&text_prim.offset); - self.add_primitive(clip_and_scroll, - &info, - Vec::new(), - PrimitiveContainer::TextRun(text_prim)); + self.add_primitive( + clip_and_scroll, + &info, + Vec::new(), + PrimitiveContainer::TextRun(text_prim), + ); } // Create (and add to primitive store) the primitive that will be // used for both the visual element and also the shadow(s). - let prim_index = self.create_primitive(clip_and_scroll, - info, - Vec::new(), - PrimitiveContainer::TextRun(prim)); + let prim_index = self.create_primitive( + clip_and_scroll, + info, + Vec::new(), + PrimitiveContainer::TextRun(prim), + ); // Only add a visual element if it can contribute to the scene. if color.a > 0.0 { @@ -1008,29 +1134,33 @@ impl FrameBuilder { for shadow_prim_index in &self.shadow_prim_stack { let shadow_metadata = &mut self.prim_store.cpu_metadata[shadow_prim_index.0]; debug_assert_eq!(shadow_metadata.prim_kind, PrimitiveKind::TextShadow); - let shadow_prim = &mut self.prim_store.cpu_text_shadows[shadow_metadata.cpu_prim_index.0]; + let shadow_prim = + &mut self.prim_store.cpu_text_shadows[shadow_metadata.cpu_prim_index.0]; // Only run real blurs here (fast path zero blurs are handled above). if shadow_prim.shadow.blur_radius > 0.0 { - let shadow_rect = rect.inflate(shadow_prim.shadow.blur_radius, - shadow_prim.shadow.blur_radius); + let shadow_rect = rect.inflate( + shadow_prim.shadow.blur_radius, + shadow_prim.shadow.blur_radius, + ); shadow_metadata.local_rect = shadow_metadata.local_rect.union(&shadow_rect); shadow_prim.primitives.push(prim_index); } } } - pub fn fill_box_shadow_rect(&mut self, - clip_and_scroll: ClipAndScrollInfo, - info: &LayerPrimitiveInfo, - bs_rect: LayerRect, - color: &ColorF, - border_radius: f32, - clip_mode: BoxShadowClipMode) { + pub fn fill_box_shadow_rect( + &mut self, + clip_and_scroll: ClipAndScrollInfo, + info: &LayerPrimitiveInfo, + bs_rect: LayerRect, + color: &ColorF, + border_radius: f32, + clip_mode: BoxShadowClipMode, + ) { // We can draw a rectangle instead with the proper border radius clipping. let (bs_clip_mode, rect_to_draw) = match clip_mode { - BoxShadowClipMode::Outset | - BoxShadowClipMode::None => (ClipMode::Clip, bs_rect), + BoxShadowClipMode::Outset | BoxShadowClipMode::None => (ClipMode::Clip, bs_rect), BoxShadowClipMode::Inset => (ClipMode::ClipOut, info.rect), }; @@ -1038,33 +1168,37 @@ impl FrameBuilder { // Clip the inside and then the outside of the box. let border_radius = BorderRadius::uniform(border_radius); - let extra_clips = vec![ClipSource::RoundedRectangle(bs_rect, border_radius, bs_clip_mode), - ClipSource::RoundedRectangle(info.rect, border_radius, box_clip_mode)]; + let extra_clips = vec![ + ClipSource::RoundedRectangle(bs_rect, border_radius, bs_clip_mode), + ClipSource::RoundedRectangle(info.rect, border_radius, box_clip_mode), + ]; - let prim = RectanglePrimitive { - color: *color, - }; + let prim = RectanglePrimitive { color: *color }; let mut info = info.clone(); info.rect = rect_to_draw; - self.add_primitive(clip_and_scroll, - &info, - extra_clips, - PrimitiveContainer::Rectangle(prim)); + self.add_primitive( + clip_and_scroll, + &info, + extra_clips, + PrimitiveContainer::Rectangle(prim), + ); } - pub fn add_box_shadow(&mut self, - clip_and_scroll: ClipAndScrollInfo, - info: &LayerPrimitiveInfo, - box_offset: &LayerVector2D, - color: &ColorF, - blur_radius: f32, - spread_radius: f32, - border_radius: f32, - clip_mode: BoxShadowClipMode) { + pub fn add_box_shadow( + &mut self, + clip_and_scroll: ClipAndScrollInfo, + info: &LayerPrimitiveInfo, + box_offset: &LayerVector2D, + color: &ColorF, + blur_radius: f32, + spread_radius: f32, + border_radius: f32, + clip_mode: BoxShadowClipMode, + ) { if color.a == 0.0 { - return + return; } // The local space box shadow rect. It is the element rect @@ -1075,29 +1209,30 @@ impl FrameBuilder { BoxShadowClipMode::Inset => -spread_radius, }; - let bs_rect = info.rect.translate(box_offset) - .inflate(inflate_amount, inflate_amount); + let bs_rect = info.rect + .translate(box_offset) + .inflate(inflate_amount, inflate_amount); // If we have negative inflate amounts. // Have to explicitly check this since euclid::TypedRect relies on negative rects let bs_rect_empty = bs_rect.size.width <= 0.0 || bs_rect.size.height <= 0.0; // Just draw a rectangle - if (blur_radius == 0.0 && spread_radius == 0.0 && clip_mode == BoxShadowClipMode::None) - || bs_rect_empty { - self.add_solid_rectangle(clip_and_scroll, - info, - color, - PrimitiveFlags::None); + if (blur_radius == 0.0 && spread_radius == 0.0 && clip_mode == BoxShadowClipMode::None) || + bs_rect_empty + { + self.add_solid_rectangle(clip_and_scroll, info, color, PrimitiveFlags::None); return; } if blur_radius == 0.0 && border_radius != 0.0 { - self.fill_box_shadow_rect(clip_and_scroll, - info, - bs_rect, - color, - border_radius, - clip_mode); + self.fill_box_shadow_rect( + clip_and_scroll, + info, + bs_rect, + color, + border_radius, + clip_mode, + ); return; } @@ -1112,8 +1247,8 @@ impl FrameBuilder { // solid rectangle shader wherever possible, to avoid invoking the // expensive box-shadow shader. enum BoxShadowKind { - Simple(Vec), // Can be drawn via simple rectangles only - Shadow(Vec), // Requires the full box-shadow code path + Simple(Vec), // Can be drawn via simple rectangles only + Shadow(Vec), // Requires the full box-shadow code path } let shadow_kind = match clip_mode { @@ -1122,8 +1257,7 @@ impl FrameBuilder { // the original box in order to draw where the border // corners are. A clip-out mask applied below will // ensure that we don't draw on the box itself. - let inner_box_bounds = info.rect.inflate(-border_radius, - -border_radius); + let inner_box_bounds = info.rect.inflate(-border_radius, -border_radius); // For outset shadows, subtracting the element rectangle // from the outer rectangle gives the rectangles we need // to draw. In the simple case (no blur radius), we can @@ -1163,25 +1297,22 @@ impl FrameBuilder { }; match shadow_kind { - BoxShadowKind::Simple(rects) => { - for rect in &rects { - let mut info = info.clone(); - info.rect = *rect; - self.add_solid_rectangle(clip_and_scroll, - &info, - color, - PrimitiveFlags::None) - } - } + BoxShadowKind::Simple(rects) => for rect in &rects { + let mut info = info.clone(); + info.rect = *rect; + self.add_solid_rectangle(clip_and_scroll, &info, color, PrimitiveFlags::None) + }, BoxShadowKind::Shadow(rects) => { assert!(blur_radius > 0.0); if clip_mode == BoxShadowClipMode::Inset { - self.fill_box_shadow_rect(clip_and_scroll, - info, - bs_rect, - color, - border_radius, - clip_mode); + self.fill_box_shadow_rect( + clip_and_scroll, + info, + bs_rect, + color, + border_radius, + clip_mode, + ); } let inverted = match clip_mode { @@ -1198,9 +1329,11 @@ impl FrameBuilder { let mut extra_clips = Vec::new(); if border_radius >= 0.0 { - extra_clips.push(ClipSource::RoundedRectangle(info.rect, - BorderRadius::uniform(border_radius), - extra_clip_mode)); + extra_clips.push(ClipSource::RoundedRectangle( + info.rect, + BorderRadius::uniform(border_radius), + extra_clip_mode, + )); } let prim_cpu = BoxShadowPrimitiveCpu { @@ -1217,23 +1350,27 @@ impl FrameBuilder { let mut info = info.clone(); info.rect = outer_rect; - self.add_primitive(clip_and_scroll, - &info, - extra_clips, - PrimitiveContainer::BoxShadow(prim_cpu)); + self.add_primitive( + clip_and_scroll, + &info, + extra_clips, + PrimitiveContainer::BoxShadow(prim_cpu), + ); } } } - pub fn add_image(&mut self, - clip_and_scroll: ClipAndScrollInfo, - info: &LayerPrimitiveInfo, - stretch_size: &LayerSize, - tile_spacing: &LayerSize, - sub_rect: Option, - image_key: ImageKey, - image_rendering: ImageRendering, - tile: Option) { + pub fn add_image( + &mut self, + clip_and_scroll: ClipAndScrollInfo, + info: &LayerPrimitiveInfo, + stretch_size: &LayerSize, + tile_spacing: &LayerSize, + sub_rect: Option, + image_key: ImageKey, + image_rendering: ImageRendering, + tile: Option, + ) { let sub_rect_block = sub_rect.unwrap_or(TexelRect::invalid()).into(); let prim_cpu = ImagePrimitiveCpu { @@ -1241,33 +1378,38 @@ impl FrameBuilder { image_rendering, tile_offset: tile, tile_spacing: *tile_spacing, - gpu_blocks: [ [ stretch_size.width, - stretch_size.height, - tile_spacing.width, - tile_spacing.height ].into(), - sub_rect_block, - ], + gpu_blocks: [ + [ + stretch_size.width, + stretch_size.height, + tile_spacing.width, + tile_spacing.height, + ].into(), + sub_rect_block, + ], }; - self.add_primitive(clip_and_scroll, - info, - Vec::new(), - PrimitiveContainer::Image(prim_cpu)); + self.add_primitive( + clip_and_scroll, + info, + Vec::new(), + PrimitiveContainer::Image(prim_cpu), + ); } - pub fn add_yuv_image(&mut self, - clip_and_scroll: ClipAndScrollInfo, - info: &LayerPrimitiveInfo, - yuv_data: YuvData, - color_space: YuvColorSpace, - image_rendering: ImageRendering) { + pub fn add_yuv_image( + &mut self, + clip_and_scroll: ClipAndScrollInfo, + info: &LayerPrimitiveInfo, + yuv_data: YuvData, + color_space: YuvColorSpace, + image_rendering: ImageRendering, + ) { let format = yuv_data.get_format(); let yuv_key = match yuv_data { YuvData::NV12(plane_0, plane_1) => [plane_0, plane_1, ImageKey::dummy()], - YuvData::PlanarYCbCr(plane_0, plane_1, plane_2) => - [plane_0, plane_1, plane_2], - YuvData::InterleavedYCbCr(plane_0) => - [plane_0, ImageKey::dummy(), ImageKey::dummy()], + YuvData::PlanarYCbCr(plane_0, plane_1, plane_2) => [plane_0, plane_1, plane_2], + YuvData::InterleavedYCbCr(plane_0) => [plane_0, ImageKey::dummy(), ImageKey::dummy()], }; let prim_cpu = YuvImagePrimitiveCpu { @@ -1278,38 +1420,42 @@ impl FrameBuilder { gpu_block: [info.rect.size.width, info.rect.size.height, 0.0, 0.0].into(), }; - self.add_primitive(clip_and_scroll, - info, - Vec::new(), - PrimitiveContainer::YuvImage(prim_cpu)); + self.add_primitive( + clip_and_scroll, + info, + Vec::new(), + PrimitiveContainer::YuvImage(prim_cpu), + ); } /// Compute the contribution (bounding rectangles, and resources) of layers and their /// primitives in screen space. - fn build_layer_screen_rects_and_cull_layers(&mut self, - screen_rect: &DeviceIntRect, - clip_scroll_tree: &mut ClipScrollTree, - display_lists: &DisplayListMap, - resource_cache: &mut ResourceCache, - gpu_cache: &mut GpuCache, - render_tasks: &mut RenderTaskTree, - profile_counters: &mut FrameProfileCounters, - device_pixel_ratio: f32) { + fn build_layer_screen_rects_and_cull_layers( + &mut self, + screen_rect: &DeviceIntRect, + clip_scroll_tree: &mut ClipScrollTree, + display_lists: &DisplayListMap, + resource_cache: &mut ResourceCache, + gpu_cache: &mut GpuCache, + render_tasks: &mut RenderTaskTree, + profile_counters: &mut FrameProfileCounters, + device_pixel_ratio: f32, + ) { profile_scope!("cull"); - LayerRectCalculationAndCullingPass::create_and_run(self, - screen_rect, - clip_scroll_tree, - display_lists, - resource_cache, - gpu_cache, - render_tasks, - profile_counters, - device_pixel_ratio); + LayerRectCalculationAndCullingPass::create_and_run( + self, + screen_rect, + clip_scroll_tree, + display_lists, + resource_cache, + gpu_cache, + render_tasks, + profile_counters, + device_pixel_ratio, + ); } - fn update_scroll_bars(&mut self, - clip_scroll_tree: &ClipScrollTree, - gpu_cache: &mut GpuCache) { + fn update_scroll_bars(&mut self, clip_scroll_tree: &ClipScrollTree, gpu_cache: &mut GpuCache) { let distance_from_edge = 8.0; for scrollbar_prim in &self.scrollbar_prims { @@ -1329,20 +1475,18 @@ impl FrameBuilder { let scroll_offset = clip_scroll_node.scroll_offset(); let f = -scroll_offset.y / scrollable_distance; - let min_y = clip_scroll_node.local_viewport_rect.origin.y - - scroll_offset.y + - distance_from_edge; + let min_y = clip_scroll_node.local_viewport_rect.origin.y - scroll_offset.y + + distance_from_edge; let max_y = clip_scroll_node.local_viewport_rect.origin.y + - clip_scroll_node.local_viewport_rect.size.height - - scroll_offset.y - - metadata.local_rect.size.height - - distance_from_edge; + clip_scroll_node.local_viewport_rect.size.height - + scroll_offset.y - metadata.local_rect.size.height - + distance_from_edge; metadata.local_rect.origin.x = clip_scroll_node.local_viewport_rect.origin.x + - clip_scroll_node.local_viewport_rect.size.width - - metadata.local_rect.size.width - - distance_from_edge; + clip_scroll_node.local_viewport_rect.size.width - + metadata.local_rect.size.width - + distance_from_edge; metadata.local_rect.origin.y = util::lerp(min_y, max_y, f); metadata.local_clip_rect = metadata.local_rect; @@ -1354,20 +1498,20 @@ impl FrameBuilder { } } - fn build_render_task(&mut self, - clip_scroll_tree: &ClipScrollTree, - gpu_cache: &mut GpuCache, - render_tasks: &mut RenderTaskTree, - output_pipelines: &FastHashSet, - device_pixel_ratio: f32) - -> RenderTaskId { + fn build_render_task( + &mut self, + clip_scroll_tree: &ClipScrollTree, + gpu_cache: &mut GpuCache, + render_tasks: &mut RenderTaskTree, + output_pipelines: &FastHashSet, + device_pixel_ratio: f32, + ) -> RenderTaskId { profile_scope!("build_render_task"); let mut next_z = 0; let mut sc_stack: Vec = Vec::new(); - let mut current_task = RenderTask::new_alpha_batch(DeviceIntPoint::zero(), - RenderTaskLocation::Fixed, - None); + let mut current_task = + RenderTask::new_alpha_batch(DeviceIntPoint::zero(), RenderTaskLocation::Fixed, None); // A stack of the alpha batcher tasks. We create them on the way down, // and then actually populate with items and dependencies on the way up. let mut alpha_task_stack = Vec::new(); @@ -1376,7 +1520,8 @@ impl FrameBuilder { // The stacking contexts that fall into this category are // - ones with `ContextIsolation::Items`, for their actual items to be backed // - immediate children of `ContextIsolation::Items` - let mut preserve_3d_map_stack: Vec> = Vec::new(); + let mut preserve_3d_map_stack: Vec> = + Vec::new(); // The plane splitter stack, using a simple BSP tree. let mut splitter_stack = Vec::new(); @@ -1385,8 +1530,9 @@ impl FrameBuilder { for cmd in &self.cmds { match *cmd { PrimitiveRunCmd::PushStackingContext(stacking_context_index) => { - let parent_isolation = sc_stack.last() - .map(|index| self.stacking_context_store[index.0].isolation); + let parent_isolation = sc_stack + .last() + .map(|index| self.stacking_context_store[index.0].isolation); let stacking_context = &self.stacking_context_store[stacking_context_index.0]; sc_stack.push(stacking_context_index); @@ -1394,47 +1540,69 @@ impl FrameBuilder { continue; } - debug!("\tpush {:?} {:?}", stacking_context_index, stacking_context.isolation); + debug!( + "\tpush {:?} {:?}", + stacking_context_index, + stacking_context.isolation + ); let stacking_context_rect = &stacking_context.screen_bounds; let composite_count = stacking_context.composite_ops.count(); // If this stacking context if the root of a pipeline, and the caller // has requested it as an output frame, create a render task to isolate it. - if stacking_context.is_pipeline_root && output_pipelines.contains(&stacking_context.pipeline_id) { + if stacking_context.is_pipeline_root && + output_pipelines.contains(&stacking_context.pipeline_id) + { alpha_task_stack.push(current_task); - current_task = RenderTask::new_dynamic_alpha_batch(stacking_context_rect, - Some(stacking_context.pipeline_id)); + current_task = RenderTask::new_dynamic_alpha_batch( + stacking_context_rect, + Some(stacking_context.pipeline_id), + ); } - if stacking_context.isolation == ContextIsolation::Full && composite_count == 0 { + if stacking_context.isolation == ContextIsolation::Full && composite_count == 0 + { alpha_task_stack.push(current_task); - current_task = RenderTask::new_dynamic_alpha_batch(stacking_context_rect, None); + current_task = + RenderTask::new_dynamic_alpha_batch(stacking_context_rect, None); } if parent_isolation == Some(ContextIsolation::Items) || - stacking_context.isolation == ContextIsolation::Items { + stacking_context.isolation == ContextIsolation::Items + { if parent_isolation != Some(ContextIsolation::Items) { splitter_stack.push(BspSplitter::new()); preserve_3d_map_stack.push(FastHashMap::default()); } alpha_task_stack.push(current_task); - current_task = RenderTask::new_dynamic_alpha_batch(stacking_context_rect, None); + current_task = + RenderTask::new_dynamic_alpha_batch(stacking_context_rect, None); //Note: technically, we shouldn't make a new alpha task for "preserve-3d" contexts // that have no child items (only other stacking contexts). However, we don't know if // there are any items at this time (in `PushStackingContext`). //Note: the reason we add the polygon for splitting during `Push*` as opposed to `Pop*` // is because we need to preserve the order of drawing for planes that match together. - let frame_node = clip_scroll_tree.nodes.get(&stacking_context.reference_frame_id).unwrap(); - let sc_polygon = make_polygon(stacking_context, frame_node, stacking_context_index.0); - debug!("\tsplitter[{}]: add {:?} -> {:?} with bounds {:?}", splitter_stack.len(), - stacking_context_index, sc_polygon, stacking_context.isolated_items_bounds); + let frame_node = clip_scroll_tree + .nodes + .get(&stacking_context.reference_frame_id) + .unwrap(); + let sc_polygon = + make_polygon(stacking_context, frame_node, stacking_context_index.0); + debug!( + "\tsplitter[{}]: add {:?} -> {:?} with bounds {:?}", + splitter_stack.len(), + stacking_context_index, + sc_polygon, + stacking_context.isolated_items_bounds + ); splitter_stack.last_mut().unwrap().add(sc_polygon); } - for _ in 0..composite_count { + for _ in 0 .. composite_count { alpha_task_stack.push(current_task); - current_task = RenderTask::new_dynamic_alpha_batch(stacking_context_rect, None); + current_task = + RenderTask::new_dynamic_alpha_batch(stacking_context_rect, None); } } PrimitiveRunCmd::PopStackingContext => { @@ -1447,18 +1615,22 @@ impl FrameBuilder { } debug!("\tpop {:?}", stacking_context_index); - let parent_isolation = sc_stack.last() - .map(|index| self.stacking_context_store[index.0].isolation); + let parent_isolation = sc_stack + .last() + .map(|index| self.stacking_context_store[index.0].isolation); - if stacking_context.isolation == ContextIsolation::Full && composite_count == 0 { + if stacking_context.isolation == ContextIsolation::Full && composite_count == 0 + { let mut prev_task = alpha_task_stack.pop().unwrap(); let screen_origin = current_task.as_alpha_batch().screen_origin; let current_task_id = render_tasks.add(current_task); - let item = AlphaRenderItem::HardwareComposite(stacking_context_index, - current_task_id, - HardwareCompositeOp::PremultipliedAlpha, - screen_origin, - next_z); + let item = AlphaRenderItem::HardwareComposite( + stacking_context_index, + current_task_id, + HardwareCompositeOp::PremultipliedAlpha, + screen_origin, + next_z, + ); next_z += 1; prev_task.as_alpha_batch_mut().items.push(item); prev_task.children.push(current_task_id); @@ -1472,25 +1644,33 @@ impl FrameBuilder { match *filter { FilterOp::Blur(blur_radius) => { let blur_radius = device_length(blur_radius, device_pixel_ratio); - let blur_render_task = RenderTask::new_blur(blur_radius, - current_task_id, - render_tasks); + let blur_render_task = RenderTask::new_blur( + blur_radius, + current_task_id, + render_tasks, + ); let blur_render_task_id = render_tasks.add(blur_render_task); - let item = AlphaRenderItem::HardwareComposite(stacking_context_index, - blur_render_task_id, - HardwareCompositeOp::PremultipliedAlpha, - DeviceIntPoint::new(screen_origin.x - blur_radius.0, - screen_origin.y - blur_radius.0), - next_z); + let item = AlphaRenderItem::HardwareComposite( + stacking_context_index, + blur_render_task_id, + HardwareCompositeOp::PremultipliedAlpha, + DeviceIntPoint::new( + screen_origin.x - blur_radius.0, + screen_origin.y - blur_radius.0, + ), + next_z, + ); prev_task.as_alpha_batch_mut().items.push(item); prev_task.children.push(blur_render_task_id); current_task = prev_task; } _ => { - let item = AlphaRenderItem::Blend(stacking_context_index, - current_task_id, - *filter, - next_z); + let item = AlphaRenderItem::Blend( + stacking_context_index, + current_task_id, + *filter, + next_z, + ); prev_task.as_alpha_batch_mut().items.push(item); prev_task.children.push(current_task_id); current_task = prev_task; @@ -1506,11 +1686,13 @@ impl FrameBuilder { let backdrop_task_id = render_tasks.add(backdrop_task); let mut prev_task = alpha_task_stack.pop().unwrap(); - let item = AlphaRenderItem::Composite(stacking_context_index, - source_task_id, - backdrop_task_id, - mix_blend_mode, - next_z); + let item = AlphaRenderItem::Composite( + stacking_context_index, + source_task_id, + backdrop_task_id, + mix_blend_mode, + next_z, + ); next_z += 1; prev_task.as_alpha_batch_mut().items.push(item); prev_task.children.push(source_task_id); @@ -1519,22 +1701,29 @@ impl FrameBuilder { } if parent_isolation == Some(ContextIsolation::Items) || - stacking_context.isolation == ContextIsolation::Items { + stacking_context.isolation == ContextIsolation::Items + { //Note: we don't register the dependent tasks here. It's only done // when we are out of the `preserve-3d` branch (see the code below), // since this is only where the parent task is known. let current_task_id = render_tasks.add(current_task); - preserve_3d_map_stack.last_mut().unwrap().insert(stacking_context_index, current_task_id); + preserve_3d_map_stack + .last_mut() + .unwrap() + .insert(stacking_context_index, current_task_id); current_task = alpha_task_stack.pop().unwrap(); } if parent_isolation != Some(ContextIsolation::Items) && - stacking_context.isolation == ContextIsolation::Items { + stacking_context.isolation == ContextIsolation::Items + { debug!("\tsplitter[{}]: flush", splitter_stack.len()); let mut splitter = splitter_stack.pop().unwrap(); // Flush the accumulated plane splits onto the task tree. // Notice how this is done before splitting in order to avoid duplicate tasks. - current_task.children.extend(preserve_3d_map_stack.last().unwrap().values().cloned()); + current_task + .children + .extend(preserve_3d_map_stack.last().unwrap().values().cloned()); // Z axis is directed at the screen, `sort` is ascending, and we need back-to-front order. for poly in splitter.sort(vec3(0.0, 0.0, 1.0)) { let sc_index = StackingContextIndex(poly.anchor); @@ -1547,22 +1736,27 @@ impl FrameBuilder { [pp[2].z, pp[3].x, pp[3].y, pp[3].z].into(), ]; let handle = gpu_cache.push_per_frame_blocks(&gpu_blocks); - let item = AlphaRenderItem::SplitComposite(sc_index, task_id, handle, next_z); + let item = + AlphaRenderItem::SplitComposite(sc_index, task_id, handle, next_z); current_task.as_alpha_batch_mut().items.push(item); } preserve_3d_map_stack.pop(); next_z += 1; } - if stacking_context.is_pipeline_root && output_pipelines.contains(&stacking_context.pipeline_id) { + if stacking_context.is_pipeline_root && + output_pipelines.contains(&stacking_context.pipeline_id) + { let mut prev_task = alpha_task_stack.pop().unwrap(); let screen_origin = current_task.as_alpha_batch().screen_origin; let current_task_id = render_tasks.add(current_task); - let item = AlphaRenderItem::HardwareComposite(stacking_context_index, - current_task_id, - HardwareCompositeOp::PremultipliedAlpha, - screen_origin, - next_z); + let item = AlphaRenderItem::HardwareComposite( + stacking_context_index, + current_task_id, + HardwareCompositeOp::PremultipliedAlpha, + screen_origin, + next_z, + ); next_z += 1; prev_task.as_alpha_batch_mut().items.push(item); prev_task.children.push(current_task_id); @@ -1575,20 +1769,27 @@ impl FrameBuilder { continue; } - let group_index = *self.clip_scroll_group_indices.get(&clip_and_scroll).unwrap(); - if self.clip_scroll_group_store[group_index.0].screen_bounding_rect.is_none() { + let group_index = *self.clip_scroll_group_indices + .get(&clip_and_scroll) + .unwrap(); + if self.clip_scroll_group_store[group_index.0] + .screen_bounding_rect + .is_none() + { debug!("\tcs-group {:?} screen rect is None", group_index); - continue + continue; } debug!("\trun of {} items", prim_count); - for i in 0..prim_count { + for i in 0 .. prim_count { let prim_index = PrimitiveIndex(first_prim_index.0 + i); if self.prim_store.cpu_bounding_rects[prim_index.0].is_some() { - self.prim_store.add_render_tasks_for_prim(prim_index, &mut current_task); - let item = AlphaRenderItem::Primitive(Some(group_index), prim_index, next_z); + self.prim_store + .add_render_tasks_for_prim(prim_index, &mut current_task); + let item = + AlphaRenderItem::Primitive(Some(group_index), prim_index, next_z); current_task.as_alpha_batch_mut().items.push(item); next_z += 1; } @@ -1602,48 +1803,58 @@ impl FrameBuilder { render_tasks.add(current_task) } - pub fn build(&mut self, - resource_cache: &mut ResourceCache, - gpu_cache: &mut GpuCache, - frame_id: FrameId, - clip_scroll_tree: &mut ClipScrollTree, - display_lists: &DisplayListMap, - device_pixel_ratio: f32, - output_pipelines: &FastHashSet, - texture_cache_profile: &mut TextureCacheProfileCounters, - gpu_cache_profile: &mut GpuCacheProfileCounters) - -> Frame { + pub fn build( + &mut self, + resource_cache: &mut ResourceCache, + gpu_cache: &mut GpuCache, + frame_id: FrameId, + clip_scroll_tree: &mut ClipScrollTree, + display_lists: &DisplayListMap, + device_pixel_ratio: f32, + output_pipelines: &FastHashSet, + texture_cache_profile: &mut TextureCacheProfileCounters, + gpu_cache_profile: &mut GpuCacheProfileCounters, + ) -> Frame { profile_scope!("build"); let mut profile_counters = FrameProfileCounters::new(); - profile_counters.total_primitives.set(self.prim_store.prim_count()); + profile_counters + .total_primitives + .set(self.prim_store.prim_count()); resource_cache.begin_frame(frame_id); gpu_cache.begin_frame(); let screen_rect = DeviceIntRect::new( DeviceIntPoint::zero(), - DeviceIntSize::new(self.screen_size.width as i32, - self.screen_size.height as i32)); + DeviceIntSize::new( + self.screen_size.width as i32, + self.screen_size.height as i32, + ), + ); self.update_scroll_bars(clip_scroll_tree, gpu_cache); let mut render_tasks = RenderTaskTree::new(); - self.build_layer_screen_rects_and_cull_layers(&screen_rect, - clip_scroll_tree, - display_lists, - resource_cache, - gpu_cache, - &mut render_tasks, - &mut profile_counters, - device_pixel_ratio); - - let main_render_task_id = self.build_render_task(clip_scroll_tree, - gpu_cache, - &mut render_tasks, - output_pipelines, - device_pixel_ratio); + self.build_layer_screen_rects_and_cull_layers( + &screen_rect, + clip_scroll_tree, + display_lists, + resource_cache, + gpu_cache, + &mut render_tasks, + &mut profile_counters, + device_pixel_ratio, + ); + + let main_render_task_id = self.build_render_task( + clip_scroll_tree, + gpu_cache, + &mut render_tasks, + output_pipelines, + device_pixel_ratio, + ); let mut required_pass_count = 0; render_tasks.max_depth(main_render_task_id, 0, &mut required_pass_count); @@ -1656,8 +1867,8 @@ impl FrameBuilder { // Do the allocations now, assigning each tile's tasks to a render // pass and target as required. - for index in 0..required_pass_count { - passes.push(RenderPass::new(index == required_pass_count-1)); + for index in 0 .. required_pass_count { + passes.push(RenderPass::new(index == required_pass_count - 1)); } render_tasks.assign_to_passes(main_render_task_id, passes.len() - 1, &mut passes); @@ -1671,11 +1882,21 @@ impl FrameBuilder { resource_cache, }; - pass.build(&ctx, gpu_cache, &mut render_tasks, &mut deferred_resolves, &self.clip_store); + pass.build( + &ctx, + gpu_cache, + &mut render_tasks, + &mut deferred_resolves, + &self.clip_store, + ); profile_counters.passes.inc(); - profile_counters.color_targets.add(pass.color_targets.target_count()); - profile_counters.alpha_targets.add(pass.alpha_targets.target_count()); + profile_counters + .color_targets + .add(pass.color_targets.target_count()); + profile_counters + .alpha_targets + .add(pass.alpha_targets.target_count()); } let gpu_cache_updates = gpu_cache.end_frame(gpu_cache_profile); @@ -1696,7 +1917,6 @@ impl FrameBuilder { gpu_cache_updates: Some(gpu_cache_updates), } } - } #[derive(Debug, Clone, Copy)] @@ -1724,20 +1944,21 @@ struct LayerRectCalculationAndCullingPass<'a> { /// Information about the cached clip stack, which is used to avoid having /// to recalculate it for every primitive. - current_clip_info: Option<(ClipId, Option)> + current_clip_info: Option<(ClipId, Option)>, } impl<'a> LayerRectCalculationAndCullingPass<'a> { - fn create_and_run(frame_builder: &'a mut FrameBuilder, - screen_rect: &'a DeviceIntRect, - clip_scroll_tree: &'a mut ClipScrollTree, - display_lists: &'a DisplayListMap, - resource_cache: &'a mut ResourceCache, - gpu_cache: &'a mut GpuCache, - render_tasks: &'a mut RenderTaskTree, - profile_counters: &'a mut FrameProfileCounters, - device_pixel_ratio: f32) { - + fn create_and_run( + frame_builder: &'a mut FrameBuilder, + screen_rect: &'a DeviceIntRect, + clip_scroll_tree: &'a mut ClipScrollTree, + display_lists: &'a DisplayListMap, + resource_cache: &'a mut ResourceCache, + gpu_cache: &'a mut GpuCache, + render_tasks: &'a mut RenderTaskTree, + profile_counters: &'a mut FrameProfileCounters, + device_pixel_ratio: f32, + ) { let mut pass = LayerRectCalculationAndCullingPass { frame_builder, screen_rect, @@ -1763,10 +1984,12 @@ impl<'a> LayerRectCalculationAndCullingPass<'a> { let commands = mem::replace(&mut self.frame_builder.cmds, Vec::new()); for cmd in &commands { match *cmd { - PrimitiveRunCmd::PushStackingContext(stacking_context_index) => - self.handle_push_stacking_context(stacking_context_index), - PrimitiveRunCmd::PrimitiveRun(prim_index, prim_count, clip_and_scroll) => - self.handle_primitive_run(prim_index, prim_count, clip_and_scroll), + PrimitiveRunCmd::PushStackingContext(stacking_context_index) => { + self.handle_push_stacking_context(stacking_context_index) + } + PrimitiveRunCmd::PrimitiveRun(prim_index, prim_count, clip_and_scroll) => { + self.handle_primitive_run(prim_index, prim_count, clip_and_scroll) + } PrimitiveRunCmd::PopStackingContext => self.handle_pop_stacking_context(), } } @@ -1796,18 +2019,24 @@ impl<'a> LayerRectCalculationAndCullingPass<'a> { let local_viewport_rect = node.combined_local_viewport_rect .translate(&-node.local_viewport_rect.origin.to_vector()); - packed_layer.set_rect(&local_viewport_rect, - self.screen_rect, - self.device_pixel_ratio) + packed_layer.set_rect( + &local_viewport_rect, + self.screen_rect, + self.device_pixel_ratio, + ) } else { None }; - let clip_sources = self.frame_builder.clip_store.get_mut(&node_clip_info.clip_sources); - clip_sources.update(&transform, - self.gpu_cache, - self.resource_cache, - self.device_pixel_ratio); + let clip_sources = self.frame_builder + .clip_store + .get_mut(&node_clip_info.clip_sources); + clip_sources.update( + &transform, + self.gpu_cache, + self.resource_cache, + self.device_pixel_ratio, + ); } } @@ -1818,8 +2047,11 @@ impl<'a> LayerRectCalculationAndCullingPass<'a> { let clip_node = &self.clip_scroll_tree.nodes[&group.clip_node_id]; let packed_layer = &mut self.frame_builder.packed_layers[group.packed_layer_index.0]; - debug!("\tProcessing group scroll={:?}, clip={:?}", - group.scroll_node_id, group.clip_node_id); + debug!( + "\tProcessing group scroll={:?}, clip={:?}", + group.scroll_node_id, + group.clip_node_id + ); let transform = scroll_node.world_content_transform; if !packed_layer.set_transform(transform) { @@ -1829,35 +2061,44 @@ impl<'a> LayerRectCalculationAndCullingPass<'a> { // Here we move the viewport rectangle into the coordinate system // of the stacking context content. - let local_viewport_rect = clip_node.combined_local_viewport_rect + let local_viewport_rect = clip_node + .combined_local_viewport_rect .translate(&clip_node.reference_frame_relative_scroll_offset) .translate(&-scroll_node.reference_frame_relative_scroll_offset) .translate(&-scroll_node.scroll_offset()); - group.screen_bounding_rect = packed_layer.set_rect(&local_viewport_rect, - self.screen_rect, - self.device_pixel_ratio); - - debug!("\t\tlocal viewport {:?} screen bound {:?}", - local_viewport_rect, - group.screen_bounding_rect); + group.screen_bounding_rect = packed_layer.set_rect( + &local_viewport_rect, + self.screen_rect, + self.device_pixel_ratio, + ); + + debug!( + "\t\tlocal viewport {:?} screen bound {:?}", + local_viewport_rect, + group.screen_bounding_rect + ); } } fn handle_pop_stacking_context(&mut self) { let stacking_context_index = self.stacking_context_stack.pop().unwrap(); - let (bounding_rect, is_visible, is_preserve_3d, reference_frame_id, reference_frame_bounds) = { + let (bounding_rect, is_visible, is_preserve_3d, reference_id, reference_bounds) = { let stacking_context = &mut self.frame_builder.stacking_context_store[stacking_context_index.0]; - stacking_context.screen_bounds = stacking_context.screen_bounds - .intersection(self.screen_rect) - .unwrap_or(DeviceIntRect::zero()); - (stacking_context.screen_bounds.clone(), - stacking_context.is_visible, - stacking_context.isolation == ContextIsolation::Items, - stacking_context.reference_frame_id, - stacking_context.isolated_items_bounds.translate(&stacking_context.reference_frame_offset), + stacking_context.screen_bounds = stacking_context + .screen_bounds + .intersection(self.screen_rect) + .unwrap_or(DeviceIntRect::zero()); + ( + stacking_context.screen_bounds.clone(), + stacking_context.is_visible, + stacking_context.isolation == ContextIsolation::Items, + stacking_context.reference_frame_id, + stacking_context + .isolated_items_bounds + .translate(&stacking_context.reference_frame_offset), ) }; @@ -1865,8 +2106,8 @@ impl<'a> LayerRectCalculationAndCullingPass<'a> { let parent = &mut self.frame_builder.stacking_context_store[parent_index.0]; parent.screen_bounds = parent.screen_bounds.union(&bounding_rect); // add children local bounds only for non-item-isolated contexts - if !is_preserve_3d && parent.reference_frame_id == reference_frame_id { - let child_bounds = reference_frame_bounds.translate(&-parent.reference_frame_offset); + if !is_preserve_3d && parent.reference_frame_id == reference_id { + let child_bounds = reference_bounds.translate(&-parent.reference_frame_offset); parent.isolated_items_bounds = parent.isolated_items_bounds.union(&child_bounds); } // Per-primitive stacking context visibility checks do not take into account @@ -1883,8 +2124,8 @@ impl<'a> LayerRectCalculationAndCullingPass<'a> { // calculate the device bounding rect. In the future, we could cache this during // the initial adding of items for the common case (where there is only a single // scroll layer for items in a stacking context). - let stacking_context = &mut self.frame_builder - .stacking_context_store[stacking_context_index.0]; + let stacking_context = + &mut self.frame_builder.stacking_context_store[stacking_context_index.0]; stacking_context.screen_bounds = DeviceIntRect::zero(); stacking_context.isolated_items_bounds = LayerRect::zero(); } @@ -1914,11 +2155,9 @@ impl<'a> LayerRectCalculationAndCullingPass<'a> { NodeType::ReferenceFrame(ref info) => { // if the transform is non-aligned, bake the next LCCR into the clip mask next_node_needs_region_mask |= !info.transform.preserves_2d_axis_alignment(); - continue - }, - NodeType::Clip(ref clip) => { - clip + continue; } + NodeType::Clip(ref clip) => clip, NodeType::StickyFrame(..) | NodeType::ScrollFrame(..) => { continue; } @@ -1949,7 +2188,9 @@ impl<'a> LayerRectCalculationAndCullingPass<'a> { //TODO-LCCR: bake a single LCCR instead of all aligned rects? self.current_clip_stack.push(ClipWorkItem { layer_index: clip.packed_layer_index, - clip_sources: self.frame_builder.clip_store.create_weak_handle(&clip.clip_sources), + clip_sources: self.frame_builder + .clip_store + .create_weak_handle(&clip.clip_sources), apply_rectangles: next_node_needs_region_mask, }); next_node_needs_region_mask = false; @@ -1960,10 +2201,12 @@ impl<'a> LayerRectCalculationAndCullingPass<'a> { Some(bounding_rect) } - fn handle_primitive_run(&mut self, - base_prim_index: PrimitiveIndex, - prim_count: usize, - clip_and_scroll: ClipAndScrollInfo) { + fn handle_primitive_run( + &mut self, + base_prim_index: PrimitiveIndex, + prim_count: usize, + clip_and_scroll: ClipAndScrollInfo, + ) { let stacking_context_index = *self.stacking_context_stack.last().unwrap(); let (packed_layer_index, pipeline_id) = { let stacking_context = @@ -1972,11 +2215,17 @@ impl<'a> LayerRectCalculationAndCullingPass<'a> { return; } - let group_index = - self.frame_builder.clip_scroll_group_indices.get(&clip_and_scroll).unwrap(); + let group_index = self.frame_builder + .clip_scroll_group_indices + .get(&clip_and_scroll) + .unwrap(); let clip_scroll_group = &self.frame_builder.clip_scroll_group_store[group_index.0]; if !clip_scroll_group.is_visible() { - debug!("{:?} of invisible {:?}", base_prim_index, stacking_context_index); + debug!( + "{:?} of invisible {:?}", + base_prim_index, + stacking_context_index + ); return; } @@ -1984,101 +2233,125 @@ impl<'a> LayerRectCalculationAndCullingPass<'a> { // context is visible. stacking_context.is_visible = true; - (clip_scroll_group.packed_layer_index, stacking_context.pipeline_id) + ( + clip_scroll_group.packed_layer_index, + stacking_context.pipeline_id, + ) }; - debug!("\t{:?} of {:?} at {:?}", base_prim_index, stacking_context_index, packed_layer_index); - let clip_bounds = match self.rebuild_clip_info_stack_if_necessary(clip_and_scroll.clip_node_id()) { - Some(rect) => rect, - None => return, - }; + debug!( + "\t{:?} of {:?} at {:?}", + base_prim_index, + stacking_context_index, + packed_layer_index + ); + let clip_bounds = + match self.rebuild_clip_info_stack_if_necessary(clip_and_scroll.clip_node_id()) { + Some(rect) => rect, + None => return, + }; let stacking_context = &mut self.frame_builder.stacking_context_store[stacking_context_index.0]; let packed_layer = &self.frame_builder.packed_layers[packed_layer_index.0]; - let display_list = self.display_lists.get(&pipeline_id) - .expect("No display list?"); - debug!("\tclip_bounds {:?}, layer_local_clip {:?}", clip_bounds, packed_layer.local_clip_rect); + let display_list = self.display_lists + .get(&pipeline_id) + .expect("No display list?"); + debug!( + "\tclip_bounds {:?}, layer_local_clip {:?}", + clip_bounds, + packed_layer.local_clip_rect + ); if !stacking_context.is_backface_visible && packed_layer.transform.is_backface_visible() { return; } - for i in 0..prim_count { + for i in 0 .. prim_count { let prim_index = PrimitiveIndex(base_prim_index.0 + i); let prim_store = &mut self.frame_builder.prim_store; - let (prim_local_rect, prim_screen_rect) = match prim_store - .build_bounding_rect(prim_index, - &clip_bounds, - &packed_layer.transform, - &packed_layer.local_clip_rect, - self.device_pixel_ratio) { + let (prim_local_rect, prim_screen_rect) = match prim_store.build_bounding_rect( + prim_index, + &clip_bounds, + &packed_layer.transform, + &packed_layer.local_clip_rect, + self.device_pixel_ratio, + ) { Some(rects) => rects, None => continue, }; debug!("\t\t{:?} bound is {:?}", prim_index, prim_screen_rect); - let prim_metadata = prim_store.prepare_prim_for_render(prim_index, - self.resource_cache, - self.gpu_cache, - &packed_layer.transform, - self.device_pixel_ratio, - display_list, - TextRunMode::Normal, - &mut self.render_tasks, - &mut self.frame_builder.clip_store); - - stacking_context.screen_bounds = stacking_context.screen_bounds.union(&prim_screen_rect); - stacking_context.isolated_items_bounds = stacking_context.isolated_items_bounds.union(&prim_local_rect); + let prim_metadata = prim_store.prepare_prim_for_render( + prim_index, + self.resource_cache, + self.gpu_cache, + &packed_layer.transform, + self.device_pixel_ratio, + display_list, + TextRunMode::Normal, + &mut self.render_tasks, + &mut self.frame_builder.clip_store, + ); + + stacking_context.screen_bounds = + stacking_context.screen_bounds.union(&prim_screen_rect); + stacking_context.isolated_items_bounds = stacking_context + .isolated_items_bounds + .union(&prim_local_rect); // Try to create a mask if we may need to. - let prim_clips = self.frame_builder.clip_store.get(&prim_metadata.clip_sources); + let prim_clips = self.frame_builder + .clip_store + .get(&prim_metadata.clip_sources); let clip_task = if prim_clips.is_masking() { // Take into account the actual clip info of the primitive, and // mutate the current bounds accordingly. let mask_rect = match prim_clips.bounds.outer { - Some(ref outer) => { - match prim_screen_rect.intersection(&outer.device_rect) { - Some(rect) => rect, - None => continue, - } - } + Some(ref outer) => match prim_screen_rect.intersection(&outer.device_rect) { + Some(rect) => rect, + None => continue, + }, _ => prim_screen_rect, }; let extra = ClipWorkItem { layer_index: packed_layer_index, - clip_sources: self.frame_builder.clip_store.create_weak_handle(&prim_metadata.clip_sources), + clip_sources: self.frame_builder + .clip_store + .create_weak_handle(&prim_metadata.clip_sources), apply_rectangles: false, }; - RenderTask::new_mask(None, - mask_rect, - &self.current_clip_stack, - Some(extra), - prim_screen_rect, - &self.frame_builder.clip_store) + RenderTask::new_mask( + None, + mask_rect, + &self.current_clip_stack, + Some(extra), + prim_screen_rect, + &self.frame_builder.clip_store, + ) } else if !self.current_clip_stack.is_empty() { // If the primitive doesn't have a specific clip, key the task ID off the // stacking context. This means that two primitives which are only clipped // by the stacking context stack can share clip masks during render task // assignment to targets. - RenderTask::new_mask(Some(clip_and_scroll.clip_node_id()), - clip_bounds, - &self.current_clip_stack, - None, - prim_screen_rect, - &self.frame_builder.clip_store) + RenderTask::new_mask( + Some(clip_and_scroll.clip_node_id()), + clip_bounds, + &self.current_clip_stack, + None, + prim_screen_rect, + &self.frame_builder.clip_store, + ) } else { None }; let render_tasks = &mut self.render_tasks; - prim_metadata.clip_task_id = clip_task.map(|clip_task| { - render_tasks.add(clip_task) - }); + prim_metadata.clip_task_id = clip_task.map(|clip_task| render_tasks.add(clip_task)); self.profile_counters.visible_primitives.inc(); } diff --git a/webrender/src/freelist.rs b/webrender/src/freelist.rs index 79c4e3d2ee..9c6a23dfd5 100644 --- a/webrender/src/freelist.rs +++ b/webrender/src/freelist.rs @@ -68,18 +68,12 @@ impl FreeList { #[allow(dead_code)] pub fn get(&self, id: &FreeListHandle) -> &T { - self.slots[id.index as usize] - .value - .as_ref() - .unwrap() + self.slots[id.index as usize].value.as_ref().unwrap() } #[allow(dead_code)] pub fn get_mut(&mut self, id: &FreeListHandle) -> &mut T { - self.slots[id.index as usize] - .value - .as_mut() - .unwrap() + self.slots[id.index as usize].value.as_mut().unwrap() } pub fn get_opt(&self, id: &WeakFreeListHandle) -> Option<&T> { @@ -113,9 +107,7 @@ impl FreeList { // handle is a valid entry, update the value and return the // previous data. If the provided handle is invalid, then // insert the data into a new slot and return the new handle. - pub fn upsert(&mut self, - id: &WeakFreeListHandle, - data: T) -> UpsertResult { + pub fn upsert(&mut self, id: &WeakFreeListHandle, data: T) -> UpsertResult { if self.slots[id.index as usize].epoch == id.epoch { let slot = &mut self.slots[id.index as usize]; let result = UpsertResult::Updated(slot.value.take().unwrap()); diff --git a/webrender/src/geometry.rs b/webrender/src/geometry.rs index 6dae628b68..b8ca5b343f 100644 --- a/webrender/src/geometry.rs +++ b/webrender/src/geometry.rs @@ -2,7 +2,7 @@ * 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 euclid::{Rect, Point3D}; +use euclid::{Point3D, Rect}; /* A naive port of "An Efficient and Robust Ray–Box Intersection Algorithm" @@ -12,43 +12,30 @@ use euclid::{Rect, Point3D}; */ // Assumes rect is in the z=0 plane! -pub fn ray_intersects_rect(ray_origin: Point3D, - ray_end: Point3D, - rect: Rect) -> bool { +pub fn ray_intersects_rect( + ray_origin: Point3D, + ray_end: Point3D, + rect: Rect, +) -> bool { let mut dir = ray_end - ray_origin; - let len = ((dir.x*dir.x) + (dir.y*dir.y) + (dir.z*dir.z)).sqrt(); + let len = ((dir.x * dir.x) + (dir.y * dir.y) + (dir.z * dir.z)).sqrt(); dir.x = dir.x / len; dir.y = dir.y / len; dir.z = dir.z / len; - let inv_direction = Point3D::new(1.0/dir.x, 1.0/dir.y, 1.0/dir.z); + let inv_direction = Point3D::new(1.0 / dir.x, 1.0 / dir.y, 1.0 / dir.z); let sign = [ - if inv_direction.x < 0.0 { - 1 - } else { - 0 - }, - if inv_direction.y < 0.0 { - 1 - } else { - 0 - }, - if inv_direction.z < 0.0 { - 1 - } else { - 0 - }, + if inv_direction.x < 0.0 { 1 } else { 0 }, + if inv_direction.y < 0.0 { 1 } else { 0 }, + if inv_direction.z < 0.0 { 1 } else { 0 }, ]; - let parameters = [ - rect.origin.to_3d(), - rect.bottom_right().to_3d(), - ]; + let parameters = [rect.origin.to_3d(), rect.bottom_right().to_3d()]; let mut tmin = (parameters[sign[0]].x - ray_origin.x) * inv_direction.x; - let mut tmax = (parameters[1-sign[0]].x - ray_origin.x) * inv_direction.x; + let mut tmax = (parameters[1 - sign[0]].x - ray_origin.x) * inv_direction.x; let tymin = (parameters[sign[1]].y - ray_origin.y) * inv_direction.y; - let tymax = (parameters[1-sign[1]].y - ray_origin.y) * inv_direction.y; + let tymax = (parameters[1 - sign[1]].y - ray_origin.y) * inv_direction.y; if (tmin > tymax) || (tymin > tmax) { return false; } @@ -59,7 +46,7 @@ pub fn ray_intersects_rect(ray_origin: Point3D, tmax = tymax; } let tzmin = (parameters[sign[2]].z - ray_origin.z) * inv_direction.z; - let tzmax = (parameters[1-sign[2]].z - ray_origin.z) * inv_direction.z; + let tzmax = (parameters[1 - sign[2]].z - ray_origin.z) * inv_direction.z; if (tmin > tzmax) || (tzmin > tmax) { return false; } @@ -86,8 +73,12 @@ pub fn ray_intersects_rect(ray_origin: Point3D, pub fn circle_contains_rect(circle_center: &Point2D, radius: f32, rect: &Rect) -> bool { - let dx = (circle_center.x - rect.origin.x).max(rect.origin.x + rect.size.width - circle_center.x); - let dy = (circle_center.y - rect.origin.y).max(rect.origin.y + rect.size.height - circle_center.y); + let dx = (circle_center.x - rect.origin.x).max( + rect.origin.x + rect.size.width - circle_center.x + ); + let dy = (circle_center.y - rect.origin.y).max( + rect.origin.y + rect.size.height - circle_center.y + ); radius * radius >= dx * dx + dy * dy } @@ -111,8 +102,11 @@ pub fn rect_intersects_circle(circle_center: &Point2D, return true; } - let corner_distance_sq = (circle_distance_x - rect.size.width * 0.5) * (circle_distance_x - rect.size.width * 0.5) + - (circle_distance_y - rect.size.height * 0.5) * (circle_distance_y - rect.size.height * 0.5); + let corner_distance_sq = + (circle_distance_x - rect.size.width * 0.5) * + (circle_distance_x - rect.size.width * 0.5) + + (circle_distance_y - rect.size.height * 0.5) * + (circle_distance_y - rect.size.height * 0.5); corner_distance_sq <= radius * radius } diff --git a/webrender/src/glyph_cache.rs b/webrender/src/glyph_cache.rs index 59ea9bbe89..c06ea005cb 100644 --- a/webrender/src/glyph_cache.rs +++ b/webrender/src/glyph_cache.rs @@ -28,15 +28,13 @@ impl GlyphCache { } } - pub fn get_glyph_key_cache_for_font_mut(&mut self, - font: FontInstance) -> &mut GlyphKeyCache { + pub fn get_glyph_key_cache_for_font_mut(&mut self, font: FontInstance) -> &mut GlyphKeyCache { self.glyph_key_caches .entry(font) .or_insert(ResourceClassCache::new()) } - pub fn get_glyph_key_cache_for_font(&self, - font: &FontInstance) -> &GlyphKeyCache { + pub fn get_glyph_key_cache_for_font(&self, font: &FontInstance) -> &GlyphKeyCache { self.glyph_key_caches .get(font) .expect("BUG: Unable to find glyph key cache!") @@ -52,9 +50,11 @@ impl GlyphCache { } pub fn clear_fonts(&mut self, key_fun: F) - where for<'r> F: Fn(&'r &FontInstance) -> bool + where + for<'r> F: Fn(&'r &FontInstance) -> bool, { - let caches_to_destroy = self.glyph_key_caches.keys() + let caches_to_destroy = self.glyph_key_caches + .keys() .filter(&key_fun) .cloned() .collect::>(); diff --git a/webrender/src/glyph_rasterizer.rs b/webrender/src/glyph_rasterizer.rs index 0d04f3d846..a97753c587 100644 --- a/webrender/src/glyph_rasterizer.rs +++ b/webrender/src/glyph_rasterizer.rs @@ -2,6 +2,12 @@ * 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/. */ +#[cfg(test)] +use api::{ColorF, FontRenderMode, IdNamespace, LayoutPoint, SubpixelDirection}; +use api::{DevicePoint, DeviceUintSize, FontInstance}; +use api::{FontKey, FontTemplate}; +use api::{GlyphDimensions, GlyphKey}; +use api::{ImageData, ImageDescriptor, ImageFormat}; #[cfg(test)] use app_units::Au; use device::TextureFilter; @@ -12,17 +18,11 @@ use platform::font::{FontContext, RasterizedGlyph}; use profiler::TextureCacheProfileCounters; use rayon::ThreadPool; use rayon::prelude::*; -use std::sync::{Arc, Mutex, MutexGuard}; -use std::sync::mpsc::{channel, Receiver, Sender}; use std::collections::hash_map::Entry; use std::mem; +use std::sync::{Arc, Mutex, MutexGuard}; +use std::sync::mpsc::{channel, Receiver, Sender}; use texture_cache::{TextureCache, TextureCacheHandle}; -#[cfg(test)] -use api::{ColorF, LayoutPoint, FontRenderMode, IdNamespace, SubpixelDirection}; -use api::{DevicePoint, DeviceUintSize, FontInstance}; -use api::{FontKey, FontTemplate}; -use api::{ImageData, ImageDescriptor, ImageFormat}; -use api::{GlyphKey, GlyphDimensions}; pub struct FontContexts { // These worker are mostly accessed from their corresponding worker threads. @@ -101,18 +101,16 @@ impl GlyphRasterizer { let num_workers = workers.current_num_threads(); let mut contexts = Vec::with_capacity(num_workers); - for _ in 0..num_workers { + for _ in 0 .. num_workers { contexts.push(Mutex::new(FontContext::new())); } GlyphRasterizer { - font_contexts: Arc::new( - FontContexts { - worker_contexts: contexts, - shared_context: Mutex::new(FontContext::new()), - workers: Arc::clone(&workers), - } - ), + font_contexts: Arc::new(FontContexts { + worker_contexts: contexts, + shared_context: Mutex::new(FontContext::new()), + workers: Arc::clone(&workers), + }), pending_glyphs: FastHashSet::default(), glyph_rx, glyph_tx, @@ -125,7 +123,9 @@ impl GlyphRasterizer { let font_contexts = Arc::clone(&self.font_contexts); // It's important to synchronously add the font for the shared context because // we use it to check that fonts have been properly added when requesting glyphs. - font_contexts.lock_shared_context().add_font(&font_key, &template); + font_contexts + .lock_shared_context() + .add_font(&font_key, &template); // TODO: this locks each font context while adding the font data, probably not a big deal, // but if there is contention on this lock we could easily have a queue of per-context @@ -133,8 +133,10 @@ impl GlyphRasterizer { // before rendering a glyph. // We can also move this into a worker to free up some cycles in the calling (render backend) // thread. - for i in 0..font_contexts.num_worker_contexts() { - font_contexts.lock_context(Some(i)).add_font(&font_key, &template); + for i in 0 .. font_contexts.num_worker_contexts() { + font_contexts + .lock_context(Some(i)) + .add_font(&font_key, &template); } } @@ -148,8 +150,13 @@ impl GlyphRasterizer { font: FontInstance, glyph_keys: &[GlyphKey], texture_cache: &mut TextureCache, - gpu_cache: &mut GpuCache) { - assert!(self.font_contexts.lock_shared_context().has_font(&font.font_key)); + gpu_cache: &mut GpuCache, + ) { + assert!( + self.font_contexts + .lock_shared_context() + .has_font(&font.font_key) + ); let mut glyphs = Vec::new(); let glyph_key_cache = glyph_cache.get_glyph_key_cache_for_font_mut(font.clone()); @@ -164,20 +171,22 @@ impl GlyphRasterizer { // the glyph and stored it in CPU memory, the the glyph // has been evicted from the texture cache. In which case // we need to re-upload it to the GPU. - texture_cache.update(&mut glyph_info.texture_cache_handle, - ImageDescriptor { - width: glyph_info.size.width, - height: glyph_info.size.height, - stride: None, - format: ImageFormat::BGRA8, - is_opaque: false, - offset: 0, - }, - TextureFilter::Linear, - ImageData::Raw(glyph_info.glyph_bytes.clone()), - [glyph_info.offset.x, glyph_info.offset.y], - None, - gpu_cache); + texture_cache.update( + &mut glyph_info.texture_cache_handle, + ImageDescriptor { + width: glyph_info.size.width, + height: glyph_info.size.height, + stride: None, + format: ImageFormat::BGRA8, + is_opaque: false, + offset: 0, + }, + TextureFilter::Linear, + ImageData::Raw(glyph_info.glyph_bytes.clone()), + [glyph_info.offset.x, glyph_info.offset.y], + None, + gpu_cache, + ); } } } @@ -200,35 +209,47 @@ impl GlyphRasterizer { // possible and in that task use rayon's fork join dispatch to rasterize the // glyphs in the thread pool. self.workers.spawn(move || { - let jobs = glyphs.par_iter().map(|request: &GlyphRequest| { - profile_scope!("glyph-raster"); - let mut context = font_contexts.lock_current_context(); - let job = GlyphRasterJob { - request: request.clone(), - result: context.rasterize_glyph(&request.font, &request.key), - }; - - // Sanity check. - if let Some(ref glyph) = job.result { - let bpp = 4; // We always render glyphs in 32 bits RGBA format. - assert_eq!(glyph.bytes.len(), bpp * (glyph.width * glyph.height) as usize); - } + let jobs = glyphs + .par_iter() + .map(|request: &GlyphRequest| { + profile_scope!("glyph-raster"); + let mut context = font_contexts.lock_current_context(); + let job = GlyphRasterJob { + request: request.clone(), + result: context.rasterize_glyph(&request.font, &request.key), + }; + + // Sanity check. + if let Some(ref glyph) = job.result { + let bpp = 4; // We always render glyphs in 32 bits RGBA format. + assert_eq!( + glyph.bytes.len(), + bpp * (glyph.width * glyph.height) as usize + ); + } - job - }).collect(); + job + }) + .collect(); glyph_tx.send(jobs).unwrap(); }); } - pub fn get_glyph_dimensions(&mut self, - font: &FontInstance, - glyph_key: &GlyphKey) -> Option { - self.font_contexts.lock_shared_context().get_glyph_dimensions(font, glyph_key) + pub fn get_glyph_dimensions( + &mut self, + font: &FontInstance, + glyph_key: &GlyphKey, + ) -> Option { + self.font_contexts + .lock_shared_context() + .get_glyph_dimensions(font, glyph_key) } pub fn get_glyph_index(&mut self, font_key: FontKey, ch: char) -> Option { - self.font_contexts.lock_shared_context().get_glyph_index(font_key, ch) + self.font_contexts + .lock_shared_context() + .get_glyph_index(font_key, ch) } pub fn resolve_glyphs( @@ -247,7 +268,9 @@ impl GlyphRasterizer { // we could try_recv and steal work from the thread pool to take advantage // of the fact that this thread is alive and we avoid the added latency // of blocking it. - let raster_jobs = self.glyph_rx.recv().expect("BUG: Should be glyphs pending!"); + let raster_jobs = self.glyph_rx + .recv() + .expect("BUG: Should be glyphs pending!"); for job in raster_jobs { debug_assert!(self.pending_glyphs.contains(&job.request)); self.pending_glyphs.remove(&job.request); @@ -265,8 +288,8 @@ impl GlyphRasterizer { // Update the caches. for job in rasterized_glyphs { - let glyph_info = job.result.and_then( - |glyph| if glyph.width > 0 && glyph.height > 0 { + let glyph_info = job.result + .and_then(|glyph| if glyph.width > 0 && glyph.height > 0 { assert_eq!((glyph.left.fract(), glyph.top.fract()), (0.0, 0.0)); let glyph_bytes = Arc::new(glyph.bytes); let mut texture_cache_handle = TextureCacheHandle::new(); @@ -295,8 +318,7 @@ impl GlyphRasterizer { }) } else { None - } - ); + }); let glyph_key_cache = glyph_cache.get_glyph_key_cache_for_font_mut(job.request.font); @@ -312,7 +334,7 @@ impl GlyphRasterizer { for font_key in &fonts_to_remove { font_contexts.lock_shared_context().delete_font(font_key); } - for i in 0..font_contexts.num_worker_contexts() { + for i in 0 .. font_contexts.num_worker_contexts() { let mut context = font_contexts.lock_context(Some(i)); for font_key in &fonts_to_remove { context.delete_font(font_key); @@ -371,32 +393,42 @@ fn raterize_200_glyphs() { let mut gpu_cache = GpuCache::new(); let mut texture_cache = TextureCache::new(2048); - let mut font_file = File::open("../wrench/reftests/text/VeraBd.ttf").expect("Couldn't open font file"); + let mut font_file = + File::open("../wrench/reftests/text/VeraBd.ttf").expect("Couldn't open font file"); let mut font_data = vec![]; - font_file.read_to_end(&mut font_data).expect("failed to read font file"); + font_file + .read_to_end(&mut font_data) + .expect("failed to read font file"); let font_key = FontKey::new(IdNamespace(0), 0); glyph_rasterizer.add_font(font_key, FontTemplate::Raw(Arc::new(font_data), 0)); - let font = FontInstance::new(font_key, - Au::from_px(32), - ColorF::new(0.0, 0.0, 0.0, 1.0), - FontRenderMode::Subpixel, - SubpixelDirection::Horizontal, - None); + let font = FontInstance::new( + font_key, + Au::from_px(32), + ColorF::new(0.0, 0.0, 0.0, 1.0), + FontRenderMode::Subpixel, + SubpixelDirection::Horizontal, + None, + ); let mut glyph_keys = Vec::with_capacity(200); - for i in 0..200 { - glyph_keys.push(GlyphKey::new(i, LayoutPoint::zero(), font.render_mode, font.subpx_dir)); + for i in 0 .. 200 { + glyph_keys.push(GlyphKey::new( + i, + LayoutPoint::zero(), + font.render_mode, + font.subpx_dir, + )); } - for i in 0..4 { + for i in 0 .. 4 { glyph_rasterizer.request_glyphs( &mut glyph_cache, font.clone(), - &glyph_keys[(50 * i)..(50 * (i + 1))], + &glyph_keys[(50 * i) .. (50 * (i + 1))], &mut texture_cache, - &mut gpu_cache + &mut gpu_cache, ); } diff --git a/webrender/src/gpu_cache.rs b/webrender/src/gpu_cache.rs index 250eedae9c..d2e1abb72c 100644 --- a/webrender/src/gpu_cache.rs +++ b/webrender/src/gpu_cache.rs @@ -24,13 +24,13 @@ //! address in the GPU cache of a given resource slot //! for this frame. +use api::{ColorF, LayerRect}; use device::FrameId; use internal_types::UvRect; use profiler::GpuCacheProfileCounters; use renderer::MAX_VERTEX_TEXTURE_WIDTH; use std::{mem, u16, u32}; use std::ops::Add; -use api::{ColorF, LayerRect}; pub const GPU_CACHE_INITIAL_HEIGHT: u32 = 512; const FRAMES_BEFORE_EVICTION: usize = 10; @@ -59,9 +59,7 @@ pub struct GpuBlockData { impl GpuBlockData { pub fn empty() -> GpuBlockData { - GpuBlockData { - data: [0.0; 4], - } + GpuBlockData { data: [0.0; 4] } } } @@ -76,19 +74,19 @@ impl Into for ColorF { impl Into for [f32; 4] { fn into(self) -> GpuBlockData { - GpuBlockData { - data: self, - } + GpuBlockData { data: self } } } impl Into for LayerRect { fn into(self) -> GpuBlockData { GpuBlockData { - data: [ self.origin.x, - self.origin.y, - self.size.width, - self.size.height ], + data: [ + self.origin.x, + self.origin.y, + self.size.width, + self.size.height, + ], } } } @@ -96,10 +94,7 @@ impl Into for LayerRect { impl Into for UvRect { fn into(self) -> GpuBlockData { GpuBlockData { - data: [ self.uv0.x, - self.uv0.y, - self.uv1.x, - self.uv1.y ], + data: [self.uv0.x, self.uv0.y, self.uv1.x, self.uv1.y], } } } @@ -119,9 +114,7 @@ pub struct GpuCacheHandle { impl GpuCacheHandle { pub fn new() -> GpuCacheHandle { - GpuCacheHandle { - location: None, - } + GpuCacheHandle { location: None } } } @@ -177,9 +170,7 @@ struct Block { } impl Block { - fn new(address: GpuCacheAddress, - next: Option, - frame_id: FrameId) -> Block { + fn new(address: GpuCacheAddress, next: Option, frame_id: FrameId) -> Block { Block { address, next, @@ -218,7 +209,7 @@ pub enum GpuCacheUpdate { block_index: usize, block_count: usize, address: GpuCacheAddress, - } + }, } pub struct GpuCacheUpdateList { @@ -261,8 +252,10 @@ impl FreeBlockLists { } } - fn get_actual_block_count_and_free_list(&mut self, - block_count: usize) -> (usize, &mut Option) { + fn get_actual_block_count_and_free_list( + &mut self, + block_count: usize, + ) -> (usize, &mut Option) { // Find the appropriate free list to use // based on the block size. match block_count { @@ -323,13 +316,15 @@ impl Texture { // Push new data into the cache. The ```pending_block_index``` field represents // where the data was pushed into the texture ```pending_blocks``` array. // Return the allocated address for this data. - fn push_data(&mut self, - pending_block_index: Option, - block_count: usize, - frame_id: FrameId) -> CacheLocation { + fn push_data( + &mut self, + pending_block_index: Option, + block_count: usize, + frame_id: FrameId, + ) -> CacheLocation { // Find the appropriate free list to use based on the block size. let (alloc_size, free_list) = self.free_lists - .get_actual_block_count_and_free_list(block_count); + .get_actual_block_count_and_free_list(block_count); // See if we need a new row (if free-list has nothing available) if free_list.is_none() { @@ -346,7 +341,7 @@ impl Texture { // in this row, and link it in to the free-list for this // block size. let mut prev_block_index = None; - for i in 0..items_per_row { + for i in 0 .. items_per_row { let address = GpuCacheAddress::new(i * alloc_size, row_index); let block_index = BlockIndex(self.blocks.len()); let block = Block::new(address, prev_block_index, frame_id); @@ -414,7 +409,7 @@ impl Texture { // Use the row metadata to determine which free-list // this block belongs to. let (_, free_list) = self.free_lists - .get_actual_block_count_and_free_list(row.block_count_per_item); + .get_actual_block_count_and_free_list(row.block_count_per_item); block.epoch.next(); block.next = *free_list; @@ -459,7 +454,8 @@ pub struct GpuDataRequest<'a> { impl<'a> GpuDataRequest<'a> { pub fn push(&mut self, block: B) - where B: Into + where + B: Into, { self.texture.pending_blocks.push(block.into()); } @@ -482,9 +478,8 @@ impl<'a> Drop for GpuDataRequest<'a> { fn drop(&mut self) { // Push the data to the texture pending updates list. let block_count = self.texture.pending_blocks.len() - self.start_index; - let location = self.texture.push_data(Some(self.start_index), - block_count, - self.frame_id); + let location = self.texture + .push_data(Some(self.start_index), block_count, self.frame_id); self.handle.location = Some(location); } } @@ -532,7 +527,7 @@ impl GpuCache { if block.epoch == location.epoch { // Mark last access time to avoid evicting this block. block.last_access_time = self.frame_id; - return None + return None; } } @@ -553,9 +548,8 @@ impl GpuCache { pub fn push_per_frame_blocks(&mut self, blocks: &[GpuBlockData]) -> GpuCacheHandle { let start_index = self.texture.pending_blocks.len(); self.texture.pending_blocks.extend_from_slice(blocks); - let location = self.texture.push_data(Some(start_index), - blocks.len(), - self.frame_id); + let location = self.texture + .push_data(Some(start_index), blocks.len(), self.frame_id); GpuCacheHandle { location: Some(location), } @@ -565,9 +559,7 @@ impl GpuCache { // will be resolved by the render thread via the // external image callback. pub fn push_deferred_per_frame_blocks(&mut self, block_count: usize) -> GpuCacheHandle { - let location = self.texture.push_data(None, - block_count, - self.frame_id); + let location = self.texture.push_data(None, block_count, self.frame_id); GpuCacheHandle { location: Some(location), } @@ -575,10 +567,14 @@ impl GpuCache { /// End the frame. Return the list of updates to apply to the /// device specific cache texture. - pub fn end_frame(&mut self, - profile_counters: &mut GpuCacheProfileCounters) -> GpuCacheUpdateList { + pub fn end_frame( + &mut self, + profile_counters: &mut GpuCacheProfileCounters, + ) -> GpuCacheUpdateList { profile_counters.allocated_rows.set(self.texture.rows.len()); - profile_counters.allocated_blocks.set(self.texture.allocated_block_count); + profile_counters + .allocated_blocks + .set(self.texture.allocated_block_count); GpuCacheUpdateList { height: self.texture.height, @@ -592,8 +588,7 @@ impl GpuCache { /// and built for this frame. Attempting to get the address for a /// freed or pending slot will panic! pub fn get_address(&self, id: &GpuCacheHandle) -> GpuCacheAddress { - let location = id.location - .expect("handle not requested or allocated!"); + let location = id.location.expect("handle not requested or allocated!"); let block = &self.texture.blocks[location.block_index.0]; debug_assert_eq!(block.epoch, location.epoch); debug_assert_eq!(block.last_access_time, self.frame_id); diff --git a/webrender/src/gpu_types.rs b/webrender/src/gpu_types.rs index efd8b4a460..fae1a02478 100644 --- a/webrender/src/gpu_types.rs +++ b/webrender/src/gpu_types.rs @@ -68,11 +68,13 @@ pub struct SimplePrimitiveInstance { } impl SimplePrimitiveInstance { - pub fn new(specific_prim_address: GpuCacheAddress, - task_address: RenderTaskAddress, - clip_task_address: RenderTaskAddress, - layer_address: PackedLayerAddress, - z_sort_index: i32) -> SimplePrimitiveInstance { + pub fn new( + specific_prim_address: GpuCacheAddress, + task_address: RenderTaskAddress, + clip_task_address: RenderTaskAddress, + layer_address: PackedLayerAddress, + z_sort_index: i32, + ) -> SimplePrimitiveInstance { SimplePrimitiveInstance { specific_prim_address, task_address, @@ -93,7 +95,7 @@ impl SimplePrimitiveInstance { data0, data1, data2, - ] + ], } } } @@ -108,12 +110,14 @@ pub struct CompositePrimitiveInstance { } impl CompositePrimitiveInstance { - pub fn new(task_address: RenderTaskAddress, - src_task_address: RenderTaskAddress, - backdrop_task_address: RenderTaskAddress, - data0: i32, - data1: i32, - z: i32) -> CompositePrimitiveInstance { + pub fn new( + task_address: RenderTaskAddress, + src_task_address: RenderTaskAddress, + backdrop_task_address: RenderTaskAddress, + data0: i32, + data1: i32, + z: i32, + ) -> CompositePrimitiveInstance { CompositePrimitiveInstance { task_address, src_task_address, @@ -137,7 +141,7 @@ impl From for PrimitiveInstance { instance.data1, 0, 0, - ] + ], } } } diff --git a/webrender/src/internal_types.rs b/webrender/src/internal_types.rs index e942e74165..dfb7fa27de 100644 --- a/webrender/src/internal_types.rs +++ b/webrender/src/internal_types.rs @@ -2,21 +2,21 @@ * 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 api::{ClipId, DevicePoint, DeviceUintRect, DocumentId, Epoch}; +use api::{ExternalImageData, ExternalImageId}; +use api::{ImageFormat, PipelineId}; use api::DebugCommand; use device::TextureFilter; use fxhash::FxHasher; use profiler::BackendProfileCounters; +use renderer::BlendMode; +use std::{usize, i32}; use std::collections::{HashMap, HashSet}; use std::f32; use std::hash::BuildHasherDefault; -use std::{i32, usize}; use std::path::PathBuf; use std::sync::Arc; use tiling; -use renderer::BlendMode; -use api::{ClipId, DevicePoint, DeviceUintRect, DocumentId, Epoch}; -use api::{ExternalImageData, ExternalImageId}; -use api::{ImageFormat, PipelineId}; pub type FastHashMap = HashMap>; pub type FastHashSet = HashSet>; @@ -71,15 +71,13 @@ impl BatchTextures { SourceTexture::CacheRGBA8, SourceTexture::CacheA8, SourceTexture::Invalid, - ] + ], } } pub fn color(texture: SourceTexture) -> Self { BatchTextures { - colors: [ texture, - SourceTexture::Invalid, - SourceTexture::Invalid ] + colors: [texture, SourceTexture::Invalid, SourceTexture::Invalid], } } } @@ -92,7 +90,10 @@ pub enum RenderTargetMode { #[derive(Debug)] pub enum TextureUpdateSource { - External { id: ExternalImageId, channel_index: u8 }, + External { + id: ExternalImageId, + channel_index: u8, + }, Bytes { data: Arc> }, } @@ -152,10 +153,11 @@ pub struct RendererFrame { } impl RendererFrame { - pub fn new(pipeline_epoch_map: FastHashMap, - layers_bouncing_back: FastHashSet, - frame: Option) - -> RendererFrame { + pub fn new( + pipeline_epoch_map: FastHashMap, + layers_bouncing_back: FastHashSet, + frame: Option, + ) -> RendererFrame { RendererFrame { pipeline_epoch_map, layers_bouncing_back, @@ -173,8 +175,16 @@ pub enum ResultMsg { DebugCommand(DebugCommand), DebugOutput(DebugOutput), RefreshShader(PathBuf), - NewFrame(DocumentId, RendererFrame, TextureUpdateList, BackendProfileCounters), - UpdateResources { updates: TextureUpdateList, cancel_rendering: bool }, + NewFrame( + DocumentId, + RendererFrame, + TextureUpdateList, + BackendProfileCounters, + ), + UpdateResources { + updates: TextureUpdateList, + cancel_rendering: bool, + }, } #[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)] diff --git a/webrender/src/lib.rs b/webrender/src/lib.rs index a243192094..ed36a53dd7 100644 --- a/webrender/src/lib.rs +++ b/webrender/src/lib.rs @@ -40,13 +40,13 @@ they're nestable. [notifier]: renderer/struct.Renderer.html#method.set_render_notifier */ +#[macro_use] +extern crate bitflags; #[macro_use] extern crate lazy_static; #[macro_use] extern crate log; #[macro_use] -extern crate bitflags; -#[macro_use] extern crate thread_profiler; mod border; @@ -91,14 +91,14 @@ mod shader_source { pub use record::{ApiRecordingReceiver, BinaryRecorder, WEBRENDER_RECORDING_HEADER}; mod platform { - #[cfg(target_os="macos")] + #[cfg(target_os = "macos")] pub use platform::macos::font; #[cfg(any(target_os = "android", all(unix, not(target_os = "macos"))))] pub use platform::unix::font; #[cfg(target_os = "windows")] pub use platform::windows::font; - #[cfg(target_os="macos")] + #[cfg(target_os = "macos")] pub mod macos { pub mod font; } @@ -112,12 +112,12 @@ mod platform { } } -#[cfg(target_os="macos")] +#[cfg(target_os = "macos")] extern crate core_graphics; -#[cfg(target_os="macos")] +#[cfg(target_os = "macos")] extern crate core_text; -#[cfg(all(unix, not(target_os="macos")))] +#[cfg(all(unix, not(target_os = "macos")))] extern crate freetype; #[cfg(target_os = "windows")] @@ -125,33 +125,31 @@ extern crate dwrote; extern crate app_units; extern crate bincode; +extern crate byteorder; extern crate euclid; extern crate fxhash; extern crate gleam; extern crate num_traits; -extern crate time; -pub extern crate webrender_api; -extern crate byteorder; -extern crate rayon; extern crate plane_split; +extern crate rayon; #[cfg(feature = "debugger")] -extern crate ws; +#[macro_use] +extern crate serde_derive; #[cfg(feature = "debugger")] extern crate serde_json; +extern crate time; #[cfg(feature = "debugger")] -#[macro_use] -extern crate serde_derive; +extern crate ws; +pub extern crate webrender_api; -#[cfg(any(target_os="macos", target_os="windows"))] +#[cfg(any(target_os = "macos", target_os = "windows"))] extern crate gamma_lut; -pub use renderer::{ExternalImage, ExternalImageSource, ExternalImageHandler}; +#[doc(hidden)] +pub use device::build_shader_strings; +pub use renderer::{ALPHA_PRIM_DBG, PROFILER_DBG, RENDER_TARGET_DBG, TEXTURE_CACHE_DBG}; +pub use renderer::{CpuProfile, DebugFlags, GpuProfile, OutputImageHandler, RendererKind}; +pub use renderer::{ExternalImage, ExternalImageHandler, ExternalImageSource}; pub use renderer::{GraphicsApi, GraphicsApiInfo, ReadPixelsFormat, Renderer, RendererOptions}; -pub use renderer::{CpuProfile, GpuProfile, DebugFlags, OutputImageHandler, RendererKind}; -pub use renderer::{PROFILER_DBG, RENDER_TARGET_DBG, TEXTURE_CACHE_DBG, ALPHA_PRIM_DBG}; pub use renderer::MAX_VERTEX_TEXTURE_WIDTH; - pub use webrender_api as api; - -#[doc(hidden)] -pub use device::build_shader_strings; diff --git a/webrender/src/platform/macos/font.rs b/webrender/src/platform/macos/font.rs index 12155388e4..67af321723 100644 --- a/webrender/src/platform/macos/font.rs +++ b/webrender/src/platform/macos/font.rs @@ -2,6 +2,9 @@ * 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 api::{ColorU, FontKey, FontRenderMode, GlyphDimensions}; +use api::{FontInstance, NativeFontHandle}; +use api::GlyphKey; use app_units::Au; use core_graphics::base::{kCGImageAlphaNoneSkipFirst, kCGImageAlphaPremultipliedLast}; use core_graphics::base::kCGBitmapByteOrder32Little; @@ -9,16 +12,13 @@ use core_graphics::color_space::CGColorSpace; use core_graphics::context::{CGContext, CGTextDrawingMode}; use core_graphics::data_provider::CGDataProvider; use core_graphics::font::{CGFont, CGGlyph}; -use core_graphics::geometry::{CGPoint, CGSize, CGRect}; +use core_graphics::geometry::{CGPoint, CGRect, CGSize}; +use core_text; use core_text::font::CTFont; use core_text::font_descriptor::kCTFontDefaultOrientation; -use core_text; +use gamma_lut::{Color as ColorLut, GammaLut}; use internal_types::FastHashMap; use std::collections::hash_map::Entry; -use api::{ColorU, FontKey, FontRenderMode, GlyphDimensions}; -use api::{GlyphKey}; -use api::{FontInstance, NativeFontHandle}; -use gamma_lut::{GammaLut, Color as ColorLut}; use std::ptr; use std::sync::Arc; @@ -66,30 +66,38 @@ struct GlyphMetrics { // this function from Skia which is used to check if a glyph // can be rendered with subpixel AA. fn supports_subpixel_aa() -> bool { - let mut cg_context = CGContext::create_bitmap_context(None, 1, 1, 8, 4, - &CGColorSpace::create_device_rgb(), - kCGImageAlphaNoneSkipFirst | - kCGBitmapByteOrder32Little); + let mut cg_context = CGContext::create_bitmap_context( + None, + 1, + 1, + 8, + 4, + &CGColorSpace::create_device_rgb(), + kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little, + ); let ct_font = core_text::font::new_from_name("Helvetica", 16.).unwrap(); cg_context.set_should_smooth_fonts(true); cg_context.set_should_antialias(true); cg_context.set_allows_font_smoothing(true); cg_context.set_rgb_fill_color(1.0, 1.0, 1.0, 1.0); - let point = CGPoint {x: -1., y: 0.}; + let point = CGPoint { x: -1., y: 0. }; let glyph = '|' as CGGlyph; ct_font.draw_glyphs(&[glyph], &[point], cg_context.clone()); let data = cg_context.data(); data[0] != data[1] || data[1] != data[2] } -fn get_glyph_metrics(ct_font: &CTFont, - glyph: CGGlyph, - x_offset: f64, - y_offset: f64) -> GlyphMetrics { +fn get_glyph_metrics( + ct_font: &CTFont, + glyph: CGGlyph, + x_offset: f64, + y_offset: f64, +) -> GlyphMetrics { let bounds = ct_font.get_bounding_rects_for_glyphs(kCTFontDefaultOrientation, &[glyph]); - if bounds.origin.x.is_nan() || bounds.origin.y.is_nan() || - bounds.size.width.is_nan() || bounds.size.height.is_nan() { + if bounds.origin.x.is_nan() || bounds.origin.y.is_nan() || bounds.size.width.is_nan() || + bounds.size.height.is_nan() + { // If an unexpected glyph index is requested, core text will return NaN values // which causes us to do bad thing as the value is cast into an integer and // overflow when expanding the bounds a few lines below. @@ -109,12 +117,8 @@ fn get_glyph_metrics(ct_font: &CTFont, // CG Origin is bottom left let mut left = bounds.origin.x.floor() as i32; let mut bottom = bounds.origin.y.floor() as i32; - let mut right = (bounds.origin.x - + bounds.size.width - + x_offset).ceil() as i32; - let mut top = (bounds.origin.y - + bounds.size.height - + y_offset).ceil() as i32; + let mut right = (bounds.origin.x + bounds.size.width + x_offset).ceil() as i32; + let mut top = (bounds.origin.y + bounds.size.height + y_offset).ceil() as i32; // Expand the bounds by 1 pixel, to give CG room for anti-aliasing. // Note that this outset is to allow room for LCD smoothed glyphs. However, the correct outset @@ -128,10 +132,8 @@ fn get_glyph_metrics(ct_font: &CTFont, let width = right - left; let height = top - bottom; - let advance = ct_font.get_advances_for_glyphs(kCTFontDefaultOrientation, - &glyph, - ptr::null_mut(), - 1); + let advance = + ct_font.get_advances_for_glyphs(kCTFontDefaultOrientation, &glyph, ptr::null_mut(), 1); let metrics = GlyphMetrics { rasterized_left: left, @@ -166,7 +168,7 @@ impl FontContext { pub fn add_raw_font(&mut self, font_key: &FontKey, bytes: Arc>, index: u32) { if self.cg_fonts.contains_key(font_key) { - return + return; } assert_eq!(index, 0); @@ -180,29 +182,29 @@ impl FontContext { pub fn add_native_font(&mut self, font_key: &FontKey, native_font_handle: NativeFontHandle) { if self.cg_fonts.contains_key(font_key) { - return + return; } - self.cg_fonts.insert((*font_key).clone(), native_font_handle.0); + self.cg_fonts + .insert((*font_key).clone(), native_font_handle.0); } pub fn delete_font(&mut self, font_key: &FontKey) { if let Some(_) = self.cg_fonts.remove(font_key) { // Unstable Rust has a retain() method on HashMap that will // let us do this in-place. https://github.com/rust-lang/rust/issues/36648 - let ct_font_keys = self.ct_fonts.keys() - .filter(|k| k.0 == *font_key) - .cloned() - .collect::>(); + let ct_font_keys = self.ct_fonts + .keys() + .filter(|k| k.0 == *font_key) + .cloned() + .collect::>(); for ct_font_key in ct_font_keys { self.ct_fonts.remove(&ct_font_key); } } } - fn get_ct_font(&mut self, - font_key: FontKey, - size: Au) -> Option { + fn get_ct_font(&mut self, font_key: FontKey, size: Au) -> Option { match self.ct_fonts.entry(((font_key).clone(), size)) { Entry::Occupied(entry) => Some((*entry.get()).clone()), Entry::Vacant(entry) => { @@ -210,9 +212,7 @@ impl FontContext { None => return None, Some(cg_font) => cg_font, }; - let ct_font = core_text::font::new_from_CGFont( - cg_font, - size.to_f64_px()); + let ct_font = core_text::font::new_from_CGFont(cg_font, size.to_f64_px()); entry.insert(ct_font.clone()); Some(ct_font) } @@ -225,9 +225,7 @@ impl FontContext { self.get_ct_font(font_key, Au(16 * 60)) .and_then(|ref ct_font| { - let result = ct_font.get_glyphs_for_characters(&character, - &mut glyph, - 1); + let result = ct_font.get_glyphs_for_characters(&character, &mut glyph, 1); if result { Some(glyph as u32) @@ -237,44 +235,50 @@ impl FontContext { }) } - pub fn get_glyph_dimensions(&mut self, - font: &FontInstance, - key: &GlyphKey) -> Option { - self.get_ct_font(font.font_key, font.size).and_then(|ref ct_font| { - let glyph = key.index as CGGlyph; - let (x_offset, y_offset) = font.get_subpx_offset(key); - let metrics = get_glyph_metrics(ct_font, glyph, x_offset, y_offset); - if metrics.rasterized_width == 0 || metrics.rasterized_height == 0 { - None - } else { - Some(GlyphDimensions { - left: metrics.rasterized_left, - top: metrics.rasterized_ascent, - width: metrics.rasterized_width as u32, - height: metrics.rasterized_height as u32, - advance: metrics.advance, - }) - } - }) + pub fn get_glyph_dimensions( + &mut self, + font: &FontInstance, + key: &GlyphKey, + ) -> Option { + self.get_ct_font(font.font_key, font.size) + .and_then(|ref ct_font| { + let glyph = key.index as CGGlyph; + let (x_offset, y_offset) = font.get_subpx_offset(key); + let metrics = get_glyph_metrics(ct_font, glyph, x_offset, y_offset); + if metrics.rasterized_width == 0 || metrics.rasterized_height == 0 { + None + } else { + Some(GlyphDimensions { + left: metrics.rasterized_left, + top: metrics.rasterized_ascent, + width: metrics.rasterized_width as u32, + height: metrics.rasterized_height as u32, + advance: metrics.advance, + }) + } + }) } // Assumes the pixels here are linear values from CG - fn gamma_correct_pixels(&self, pixels: &mut Vec, width: usize, - height: usize, render_mode: FontRenderMode, - color: ColorU) { + fn gamma_correct_pixels( + &self, + pixels: &mut Vec, + width: usize, + height: usize, + render_mode: FontRenderMode, + color: ColorU, + ) { // Then convert back to gamma corrected values. - let color_lut = ColorLut::new(color.r, - color.g, - color.b, - color.a); + let color_lut = ColorLut::new(color.r, color.g, color.b, color.a); match render_mode { FontRenderMode::Alpha => { - self.gamma_lut.preblend_grayscale_bgra(pixels, width, - height, color_lut); - }, + self.gamma_lut + .preblend_grayscale_bgra(pixels, width, height, color_lut); + } FontRenderMode::Subpixel => { - self.gamma_lut.preblend_bgra(pixels, width, height, color_lut); - }, + self.gamma_lut + .preblend_bgra(pixels, width, height, color_lut); + } _ => {} // Again, give mono untouched since only the alpha matters. } } @@ -283,7 +287,7 @@ impl FontContext { fn print_glyph_data(&mut self, data: &[u8], width: usize, height: usize) { // Rust doesn't have step_by support on stable :( println!("Width is: {:?} height: {:?}", width, height); - for i in 0..height { + for i in 0 .. height { let current_height = i * width * 4; for pixel in data[current_height .. current_height + (width * 4)].chunks(4) { @@ -297,21 +301,21 @@ impl FontContext { } } - pub fn rasterize_glyph(&mut self, - font: &FontInstance, - key: &GlyphKey) - -> Option { - + pub fn rasterize_glyph( + &mut self, + font: &FontInstance, + key: &GlyphKey, + ) -> Option { let ct_font = match self.get_ct_font(font.font_key, font.size) { Some(font) => font, - None => return Some(RasterizedGlyph::blank()) + None => return Some(RasterizedGlyph::blank()), }; let glyph = key.index as CGGlyph; let (x_offset, y_offset) = font.get_subpx_offset(key); let metrics = get_glyph_metrics(&ct_font, glyph, x_offset, y_offset); if metrics.rasterized_width == 0 || metrics.rasterized_height == 0 { - return Some(RasterizedGlyph::blank()) + return Some(RasterizedGlyph::blank()); } let context_flags = match font.render_mode { @@ -319,12 +323,15 @@ impl FontContext { FontRenderMode::Alpha | FontRenderMode::Mono => kCGImageAlphaPremultipliedLast, }; - let mut cg_context = CGContext::create_bitmap_context(None, metrics.rasterized_width as usize, - metrics.rasterized_height as usize, - 8, - metrics.rasterized_width as usize * 4, - &CGColorSpace::create_device_rgb(), - context_flags); + let mut cg_context = CGContext::create_bitmap_context( + None, + metrics.rasterized_width as usize, + metrics.rasterized_height as usize, + 8, + metrics.rasterized_width as usize * 4, + &CGColorSpace::create_device_rgb(), + context_flags, + ); // Tested on mac OS Sierra, 10.12 @@ -377,14 +384,11 @@ impl FontContext { // Fill the background cg_context.set_rgb_fill_color(1.0, 1.0, 1.0, 1.0); let rect = CGRect { - origin: CGPoint { - x: 0.0, - y: 0.0, - }, + origin: CGPoint { x: 0.0, y: 0.0 }, size: CGSize { width: metrics.rasterized_width as f64, height: metrics.rasterized_height as f64, - } + }, }; cg_context.fill_rect(rect); @@ -398,14 +402,16 @@ impl FontContext { // Convert to linear space for subpixel AA. // We explicitly do not do this for grayscale AA if font.render_mode == FontRenderMode::Subpixel { - self.gamma_lut.coregraphics_convert_to_linear_bgra(&mut rasterized_pixels, - metrics.rasterized_width as usize, - metrics.rasterized_height as usize); + self.gamma_lut.coregraphics_convert_to_linear_bgra( + &mut rasterized_pixels, + metrics.rasterized_width as usize, + metrics.rasterized_height as usize, + ); } // We need to invert the pixels back since right now // transparent pixels are actually opaque white. - for i in 0..metrics.rasterized_height { + for i in 0 .. metrics.rasterized_height { let current_height = (i * metrics.rasterized_width * 4) as usize; let end_row = current_height + (metrics.rasterized_width as usize * 4); @@ -425,11 +431,13 @@ impl FontContext { } // end row } // end height - self.gamma_correct_pixels(&mut rasterized_pixels, - metrics.rasterized_width as usize, - metrics.rasterized_height as usize, - font.render_mode, - font.color); + self.gamma_correct_pixels( + &mut rasterized_pixels, + metrics.rasterized_width as usize, + metrics.rasterized_height as usize, + font.render_mode, + font.color, + ); Some(RasterizedGlyph { left: metrics.rasterized_left as f32, diff --git a/webrender/src/platform/unix/font.rs b/webrender/src/platform/unix/font.rs index 693c85f543..a033ae52f4 100644 --- a/webrender/src/platform/unix/font.rs +++ b/webrender/src/platform/unix/font.rs @@ -4,17 +4,15 @@ use api::{FontInstance, FontKey, FontRenderMode, GlyphDimensions}; use api::{NativeFontHandle, SubpixelDirection}; -use api::{GlyphKey}; -use internal_types::FastHashMap; - -use freetype::freetype::{FT_Render_Mode, FT_Pixel_Mode, FT_BBox, FT_Outline_Translate}; +use api::GlyphKey; +use freetype::freetype::{FT_BBox, FT_Outline_Translate, FT_Pixel_Mode, FT_Render_Mode}; +use freetype::freetype::{FT_Done_Face, FT_Error, FT_Get_Char_Index, FT_Int32}; use freetype::freetype::{FT_Done_FreeType, FT_Library_SetLcdFilter, FT_Pos}; -use freetype::freetype::{FT_Library, FT_Set_Char_Size, FT_Outline_Get_CBox}; -use freetype::freetype::{FT_Face, FT_Long, FT_UInt, FT_F26Dot6, FT_Glyph_Format}; +use freetype::freetype::{FT_F26Dot6, FT_Face, FT_Glyph_Format, FT_Long, FT_UInt}; +use freetype::freetype::{FT_GlyphSlot, FT_LcdFilter, FT_New_Memory_Face}; use freetype::freetype::{FT_Init_FreeType, FT_Load_Glyph, FT_Render_Glyph}; -use freetype::freetype::{FT_New_Memory_Face, FT_GlyphSlot, FT_LcdFilter}; -use freetype::freetype::{FT_Done_Face, FT_Error, FT_Int32, FT_Get_Char_Index}; - +use freetype::freetype::{FT_Library, FT_Outline_Get_CBox, FT_Set_Char_Size}; +use internal_types::FastHashMap; use std::{mem, ptr, slice}; use std::sync::Arc; @@ -66,13 +64,19 @@ impl FontContext { unsafe { let result = FT_Init_FreeType(&mut lib); - assert!(result.succeeded(), "Unable to initialize FreeType library {:?}", result); + assert!( + result.succeeded(), + "Unable to initialize FreeType library {:?}", + result + ); // TODO(gw): Check result of this to determine if freetype build supports subpixel. let result = FT_Library_SetLcdFilter(lib, FT_LcdFilter::FT_LCD_FILTER_DEFAULT); if !result.succeeded() { - println!("WARN: Initializing a FreeType library build without subpixel AA enabled!"); + println!( + "WARN: Initializing a FreeType library build without subpixel AA enabled!" + ); lcd_extra_pixels = 0; } } @@ -92,17 +96,22 @@ impl FontContext { if !self.faces.contains_key(&font_key) { let mut face: FT_Face = ptr::null_mut(); let result = unsafe { - FT_New_Memory_Face(self.lib, - bytes.as_ptr(), - bytes.len() as FT_Long, - index as FT_Long, - &mut face) + FT_New_Memory_Face( + self.lib, + bytes.as_ptr(), + bytes.len() as FT_Long, + index as FT_Long, + &mut face, + ) }; if result.succeeded() && !face.is_null() { - self.faces.insert(*font_key, Face { - face, - _bytes: bytes, - }); + self.faces.insert( + *font_key, + Face { + face, + _bytes: bytes, + }, + ); } else { println!("WARN: webrender failed to load font {:?}", font_key); } @@ -115,17 +124,12 @@ impl FontContext { pub fn delete_font(&mut self, font_key: &FontKey) { if let Some(face) = self.faces.remove(font_key) { - let result = unsafe { - FT_Done_Face(face.face) - }; + let result = unsafe { FT_Done_Face(face.face) }; assert!(result.succeeded()); } } - fn load_glyph(&self, - font: &FontInstance, - glyph: &GlyphKey) -> Option { - + fn load_glyph(&self, font: &FontInstance, glyph: &GlyphKey) -> Option { debug_assert!(self.faces.contains_key(&font.font_key)); let face = self.faces.get(&font.font_key).unwrap(); let char_size = font.size.to_f64_px() * 64.0 + 0.5; @@ -134,11 +138,7 @@ impl FontContext { FT_Set_Char_Size(face.face, char_size as FT_F26Dot6, 0, 0, 0) }); - let result = unsafe { - FT_Load_Glyph(face.face, - glyph.index as FT_UInt, - GLYPH_LOAD_FLAGS) - }; + let result = unsafe { FT_Load_Glyph(face.face, glyph.index as FT_UInt, GLYPH_LOAD_FLAGS) }; if result == SUCCESS { let slot = unsafe { (*face.face).glyph }; @@ -148,26 +148,31 @@ impl FontContext { // We will need a custom code path for bitmap fonts (which // are very rare). match unsafe { (*slot).format } { - FT_Glyph_Format::FT_GLYPH_FORMAT_OUTLINE => { - Some(slot) - } + FT_Glyph_Format::FT_GLYPH_FORMAT_OUTLINE => Some(slot), _ => { error!("TODO: Support bitmap fonts!"); None } } } else { - error!("Unable to load glyph for {} of size {:?} from font {:?}, {:?}", - glyph.index, font.size, font.font_key, result); + error!( + "Unable to load glyph for {} of size {:?} from font {:?}, {:?}", + glyph.index, + font.size, + font.font_key, + result + ); None } } // Get the bounding box for a glyph, accounting for sub-pixel positioning. - fn get_bounding_box(&self, - slot: FT_GlyphSlot, - font: &FontInstance, - glyph: &GlyphKey) -> FT_BBox { + fn get_bounding_box( + &self, + slot: FT_GlyphSlot, + font: &FontInstance, + glyph: &GlyphKey, + ) -> FT_BBox { let mut cbox: FT_BBox = unsafe { mem::uninitialized() }; // Get the estimated bounding box from FT (control points). @@ -211,10 +216,12 @@ impl FontContext { cbox } - fn get_glyph_dimensions_impl(&self, - slot: FT_GlyphSlot, - font: &FontInstance, - glyph: &GlyphKey) -> Option { + fn get_glyph_dimensions_impl( + &self, + slot: FT_GlyphSlot, + font: &FontInstance, + glyph: &GlyphKey, + ) -> Option { let metrics = unsafe { &(*slot).metrics }; // If there's no advance, no need to consider this glyph @@ -235,9 +242,7 @@ impl FontContext { } pub fn get_glyph_index(&mut self, font_key: FontKey, ch: char) -> Option { - let face = self.faces - .get(&font_key) - .expect("Unknown font key!"); + let face = self.faces.get(&font_key).expect("Unknown font key!"); unsafe { let idx = FT_Get_Char_Index(face.face, ch as _); if idx != 0 { @@ -248,20 +253,20 @@ impl FontContext { } } - pub fn get_glyph_dimensions(&mut self, - font: &FontInstance, - key: &GlyphKey) -> Option { + pub fn get_glyph_dimensions( + &mut self, + font: &FontInstance, + key: &GlyphKey, + ) -> Option { let slot = self.load_glyph(font, key); - slot.and_then(|slot| { - self.get_glyph_dimensions_impl(slot, font, key) - }) + slot.and_then(|slot| self.get_glyph_dimensions_impl(slot, font, key)) } - pub fn rasterize_glyph(&mut self, - font: &FontInstance, - key: &GlyphKey) - -> Option { - + pub fn rasterize_glyph( + &mut self, + font: &FontInstance, + key: &GlyphKey, + ) -> Option { let slot = match self.load_glyph(font, key) { Some(slot) => slot, None => return None, @@ -295,29 +300,39 @@ impl FontContext { let outline = &(*slot).outline; let mut cbox: FT_BBox = mem::uninitialized(); FT_Outline_Get_CBox(outline, &mut cbox); - FT_Outline_Translate(outline, dx - ((cbox.xMin + dx) & !63), - dy - ((cbox.yMin + dy) & !63)); + FT_Outline_Translate( + outline, + dx - ((cbox.xMin + dx) & !63), + dy - ((cbox.yMin + dy) & !63), + ); } let result = unsafe { FT_Render_Glyph(slot, render_mode) }; if result != SUCCESS { - error!("Unable to rasterize {:?} with {:?}, {:?}", key, render_mode, result); + error!( + "Unable to rasterize {:?} with {:?}, {:?}", + key, + render_mode, + result + ); return None; } let bitmap = unsafe { &(*slot).bitmap }; let pixel_mode = unsafe { mem::transmute(bitmap.pixel_mode as u32) }; - info!("Rasterizing {:?} as {:?} with dimensions {:?}", key, render_mode, dimensions); + info!( + "Rasterizing {:?} as {:?} with dimensions {:?}", + key, + render_mode, + dimensions + ); let actual_width = match pixel_mode { FT_Pixel_Mode::FT_PIXEL_MODE_LCD => { assert!(bitmap.width % 3 == 0); bitmap.width / 3 - }, - FT_Pixel_Mode::FT_PIXEL_MODE_MONO | - FT_Pixel_Mode::FT_PIXEL_MODE_GRAY => { - bitmap.width } + FT_Pixel_Mode::FT_PIXEL_MODE_MONO | FT_Pixel_Mode::FT_PIXEL_MODE_GRAY => bitmap.width, _ => { panic!("Unexpected pixel mode!"); } @@ -330,13 +345,11 @@ impl FontContext { // Extract the final glyph from FT format into RGBA8 format, which is // what WR expects. - for y in 0..actual_height { + for y in 0 .. actual_height { // Get pointer to the bytes for this row. - let mut src = unsafe { - bitmap.buffer.offset((y * bitmap.pitch) as isize) - }; + let mut src = unsafe { bitmap.buffer.offset((y * bitmap.pitch) as isize) }; - for x in 0..actual_width { + for x in 0 .. actual_width { let value = match pixel_mode { FT_Pixel_Mode::FT_PIXEL_MODE_MONO => { let mask = 0x80 >> (x & 0x7); @@ -354,10 +367,10 @@ impl FontContext { src = unsafe { src.offset(3) }; [t[2], t[1], t[0], 0xff] } - _ => panic!("Unsupported {:?}", pixel_mode) + _ => panic!("Unsupported {:?}", pixel_mode), }; let i = 4 * (y * actual_width + x) as usize; - let dest = &mut final_buffer[i..i+4]; + let dest = &mut final_buffer[i .. i + 4]; dest.clone_from_slice(&value); } } diff --git a/webrender/src/platform/windows/font.rs b/webrender/src/platform/windows/font.rs index 289aec4ab8..82d6e89aad 100644 --- a/webrender/src/platform/windows/font.rs +++ b/webrender/src/platform/windows/font.rs @@ -4,10 +4,9 @@ use api::{FontInstance, FontInstancePlatformOptions, FontKey, FontRenderMode}; use api::{GlyphDimensions, GlyphKey}; -use gamma_lut::{GammaLut, Color as ColorLut}; -use internal_types::FastHashMap; - use dwrote; +use gamma_lut::{Color as ColorLut, GammaLut}; +use internal_types::FastHashMap; use std::sync::Arc; lazy_static! { @@ -37,49 +36,54 @@ pub struct RasterizedGlyph { pub bytes: Vec, } -fn dwrite_texture_type(render_mode: FontRenderMode) -> - dwrote::DWRITE_TEXTURE_TYPE { +fn dwrite_texture_type(render_mode: FontRenderMode) -> dwrote::DWRITE_TEXTURE_TYPE { match render_mode { - FontRenderMode::Mono => dwrote::DWRITE_TEXTURE_ALIASED_1x1 , - FontRenderMode::Alpha | - FontRenderMode::Subpixel => dwrote::DWRITE_TEXTURE_CLEARTYPE_3x1, + FontRenderMode::Mono => dwrote::DWRITE_TEXTURE_ALIASED_1x1, + FontRenderMode::Alpha | FontRenderMode::Subpixel => dwrote::DWRITE_TEXTURE_CLEARTYPE_3x1, } } -fn dwrite_measure_mode(render_mode: FontRenderMode, options: Option) -> - dwrote::DWRITE_MEASURING_MODE { - if let Some(FontInstancePlatformOptions{ force_gdi_rendering: true, .. }) = options { +fn dwrite_measure_mode( + render_mode: FontRenderMode, + options: Option, +) -> dwrote::DWRITE_MEASURING_MODE { + if let Some(FontInstancePlatformOptions { + force_gdi_rendering: true, + .. + }) = options + { return dwrote::DWRITE_MEASURING_MODE_GDI_CLASSIC; } match render_mode { FontRenderMode::Mono => dwrote::DWRITE_MEASURING_MODE_GDI_NATURAL, - FontRenderMode::Alpha | - FontRenderMode::Subpixel => dwrote::DWRITE_MEASURING_MODE_NATURAL, + FontRenderMode::Alpha | FontRenderMode::Subpixel => dwrote::DWRITE_MEASURING_MODE_NATURAL, } } -fn dwrite_render_mode(font_face: &dwrote::FontFace, - render_mode: FontRenderMode, - em_size: f32, - measure_mode: dwrote::DWRITE_MEASURING_MODE, - options: Option) -> - dwrote::DWRITE_RENDERING_MODE { - if let Some(FontInstancePlatformOptions{ force_gdi_rendering: true, .. }) = options { +fn dwrite_render_mode( + font_face: &dwrote::FontFace, + render_mode: FontRenderMode, + em_size: f32, + measure_mode: dwrote::DWRITE_MEASURING_MODE, + options: Option, +) -> dwrote::DWRITE_RENDERING_MODE { + if let Some(FontInstancePlatformOptions { + force_gdi_rendering: true, + .. + }) = options + { return dwrote::DWRITE_RENDERING_MODE_GDI_CLASSIC; } let dwrite_render_mode = match render_mode { FontRenderMode::Mono => dwrote::DWRITE_RENDERING_MODE_ALIASED, - FontRenderMode::Alpha | - FontRenderMode::Subpixel => { - font_face.get_recommended_rendering_mode_default_params(em_size, - 1.0, - measure_mode) - }, + FontRenderMode::Alpha | FontRenderMode::Subpixel => { + font_face.get_recommended_rendering_mode_default_params(em_size, 1.0, measure_mode) + } }; - if dwrite_render_mode == dwrote::DWRITE_RENDERING_MODE_OUTLINE { + if dwrite_render_mode == dwrote::DWRITE_RENDERING_MODE_OUTLINE { // Outline mode is not supported return dwrote::DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC; } @@ -108,7 +112,7 @@ impl FontContext { pub fn add_raw_font(&mut self, font_key: &FontKey, data: Arc>, index: u32) { if self.fonts.contains_key(font_key) { - return + return; } if let Some(font_file) = dwrote::FontFile::new_from_data(&**data) { @@ -123,7 +127,7 @@ impl FontContext { pub fn add_native_font(&mut self, font_key: &FontKey, font_handle: dwrote::FontDescriptor) { if self.fonts.contains_key(font_key) { - return + return; } let system_fc = dwrote::FontCollection::system(); @@ -141,27 +145,31 @@ impl FontContext { #[allow(dead_code)] fn print_glyph_data(&self, data: &[u8], width: usize, height: usize) { // Rust doesn't have step_by support on stable :( - for i in 0..height { + for i in 0 .. height { let current_height = i * width * 3; for pixel in data[current_height .. current_height + (width * 3)].chunks(3) { let r = pixel[0]; let g = pixel[1]; let b = pixel[2]; - print!("({}, {}, {}) ", r, g, b, ); + print!("({}, {}, {}) ", r, g, b,); } println!(""); } } - fn create_glyph_analysis(&self, - font: &FontInstance, - key: &GlyphKey) -> - dwrote::GlyphRunAnalysis { + fn create_glyph_analysis( + &self, + font: &FontInstance, + key: &GlyphKey, + ) -> dwrote::GlyphRunAnalysis { let face = self.fonts.get(&font.font_key).unwrap(); let glyph = key.index as u16; let advance = 0.0f32; - let offset = dwrote::GlyphOffset { advanceOffset: 0.0, ascenderOffset: 0.0 }; + let offset = dwrote::GlyphOffset { + advanceOffset: 0.0, + ascenderOffset: 0.0, + }; let glyph_run = dwrote::DWRITE_GLYPH_RUN { fontFace: unsafe { face.as_ptr() }, @@ -174,24 +182,34 @@ impl FontContext { bidiLevel: 0, }; - let dwrite_measure_mode = dwrite_measure_mode(font.render_mode, - font.platform_options); - let dwrite_render_mode = dwrite_render_mode(face, - font.render_mode, - font.size.to_f32_px(), - dwrite_measure_mode, - font.platform_options); + let dwrite_measure_mode = dwrite_measure_mode(font.render_mode, font.platform_options); + let dwrite_render_mode = dwrite_render_mode( + face, + font.render_mode, + font.size.to_f32_px(), + dwrite_measure_mode, + font.platform_options, + ); let (x_offset, y_offset) = font.get_subpx_offset(key); - let transform = Some( - dwrote::DWRITE_MATRIX { m11: 1.0, m12: 0.0, m21: 0.0, m22: 1.0, - dx: x_offset as f32, dy: y_offset as f32 } - ); - - dwrote::GlyphRunAnalysis::create(&glyph_run, 1.0, transform, - dwrite_render_mode, - dwrite_measure_mode, - 0.0, 0.0) + let transform = Some(dwrote::DWRITE_MATRIX { + m11: 1.0, + m12: 0.0, + m21: 0.0, + m22: 1.0, + dx: x_offset as f32, + dy: y_offset as f32, + }); + + dwrote::GlyphRunAnalysis::create( + &glyph_run, + 1.0, + transform, + dwrite_render_mode, + dwrite_measure_mode, + 0.0, + 0.0, + ) } pub fn get_glyph_index(&mut self, font_key: FontKey, ch: char) -> Option { @@ -201,10 +219,11 @@ impl FontContext { } // TODO: Pipe GlyphOptions into glyph_dimensions too - pub fn get_glyph_dimensions(&self, - font: &FontInstance, - key: &GlyphKey) - -> Option { + pub fn get_glyph_dimensions( + &self, + font: &FontInstance, + key: &GlyphKey, + ) -> Option { // Probably have to default to something else here. let render_mode = FontRenderMode::Subpixel; let analysis = self.create_glyph_analysis(font, key); @@ -219,7 +238,7 @@ impl FontContext { // Alpha texture bounds can sometimes return an empty rect // Such as for spaces if width == 0 || height == 0 { - return None + return None; } let face = self.fonts.get(&font.font_key).unwrap(); @@ -247,45 +266,46 @@ impl FontContext { match render_mode { FontRenderMode::Mono => { let mut rgba_pixels: Vec = vec![0; pixels.len() * 4]; - for i in 0..pixels.len() { - rgba_pixels[i*4+0] = pixels[i]; - rgba_pixels[i*4+1] = pixels[i]; - rgba_pixels[i*4+2] = pixels[i]; - rgba_pixels[i*4+3] = pixels[i]; + for i in 0 .. pixels.len() { + rgba_pixels[i * 4 + 0] = pixels[i]; + rgba_pixels[i * 4 + 1] = pixels[i]; + rgba_pixels[i * 4 + 2] = pixels[i]; + rgba_pixels[i * 4 + 3] = pixels[i]; } rgba_pixels } FontRenderMode::Alpha => { let length = pixels.len() / 3; let mut rgba_pixels: Vec = vec![0; length * 4]; - for i in 0..length { + for i in 0 .. length { // Only take the G channel, as its closest to D2D - let alpha = pixels[i*3 + 1] as u8; - rgba_pixels[i*4+0] = alpha; - rgba_pixels[i*4+1] = alpha; - rgba_pixels[i*4+2] = alpha; - rgba_pixels[i*4+3] = alpha; + let alpha = pixels[i * 3 + 1] as u8; + rgba_pixels[i * 4 + 0] = alpha; + rgba_pixels[i * 4 + 1] = alpha; + rgba_pixels[i * 4 + 2] = alpha; + rgba_pixels[i * 4 + 3] = alpha; } rgba_pixels } FontRenderMode::Subpixel => { let length = pixels.len() / 3; let mut rgba_pixels: Vec = vec![0; length * 4]; - for i in 0..length { - rgba_pixels[i*4+0] = pixels[i*3+0]; - rgba_pixels[i*4+1] = pixels[i*3+1]; - rgba_pixels[i*4+2] = pixels[i*3+2]; - rgba_pixels[i*4+3] = 0xff; + for i in 0 .. length { + rgba_pixels[i * 4 + 0] = pixels[i * 3 + 0]; + rgba_pixels[i * 4 + 1] = pixels[i * 3 + 1]; + rgba_pixels[i * 4 + 2] = pixels[i * 3 + 2]; + rgba_pixels[i * 4 + 3] = 0xff; } rgba_pixels } } } - pub fn rasterize_glyph(&mut self, - font: &FontInstance, - key: &GlyphKey) - -> Option { + pub fn rasterize_glyph( + &mut self, + font: &FontInstance, + key: &GlyphKey, + ) -> Option { let analysis = self.create_glyph_analysis(font, key); let texture_type = dwrite_texture_type(font.render_mode); @@ -303,21 +323,20 @@ impl FontContext { if font.render_mode != FontRenderMode::Mono { let lut_correction = match font.platform_options { - Some(option) => { - if option.force_gdi_rendering { - &self.gdi_gamma_lut - } else { - &self.gamma_lut - } + Some(option) => if option.force_gdi_rendering { + &self.gdi_gamma_lut + } else { + &self.gamma_lut }, - None => &self.gamma_lut + None => &self.gamma_lut, }; - lut_correction.preblend_rgb(&mut pixels, width, height, - ColorLut::new(font.color.r, - font.color.g, - font.color.b, - font.color.a)); + lut_correction.preblend_rgb( + &mut pixels, + width, + height, + ColorLut::new(font.color.r, font.color.g, font.color.b, font.color.a), + ); } let rgba_pixels = self.convert_to_rgba(&mut pixels, font.render_mode); diff --git a/webrender/src/prim_store.rs b/webrender/src/prim_store.rs index d6f663ff20..e491e2d242 100644 --- a/webrender/src/prim_store.rs +++ b/webrender/src/prim_store.rs @@ -2,21 +2,22 @@ * 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 api::{BuiltDisplayList, ColorF, ComplexClipRegion, DeviceIntRect, DeviceIntSize, DevicePoint}; use api::{BorderRadius, ExtendMode, FontRenderMode, GlyphInstance, GradientStop}; -use api::{ImageKey, ImageRendering, ItemRange, LayerPoint, LayerRect, LayerSize, TextShadow}; -use api::{GlyphKey, LayerToWorldTransform, TileOffset, YuvColorSpace, YuvFormat}; +use api::{BuiltDisplayList, ColorF, ComplexClipRegion, DeviceIntRect, DeviceIntSize, DevicePoint}; use api::{device_length, FontInstance, LayerVector2D, LineOrientation, LineStyle}; +use api::{GlyphKey, LayerToWorldTransform, TileOffset, YuvColorSpace, YuvFormat}; +use api::{ImageKey, ImageRendering, ItemRange, LayerPoint, LayerRect, LayerSize, TextShadow}; use app_units::Au; use border::BorderCornerInstance; use clip::{ClipMode, ClipSourcesHandle, ClipStore}; -use euclid::{Size2D}; -use gpu_cache::{GpuCacheAddress, GpuBlockData, GpuCache, GpuCacheHandle, GpuDataRequest, ToGpuBlocks}; -use renderer::MAX_VERTEX_TEXTURE_WIDTH; +use euclid::Size2D; +use gpu_cache::{GpuBlockData, GpuCache, GpuCacheAddress, GpuCacheHandle, GpuDataRequest, + ToGpuBlocks}; use render_task::{RenderTask, RenderTaskId, RenderTaskTree}; +use renderer::MAX_VERTEX_TEXTURE_WIDTH; use resource_cache::{ImageProperties, ResourceCache}; use std::{mem, usize}; -use util::{pack_as_float, TransformedRect, recycle_vec}; +use util::{pack_as_float, recycle_vec, TransformedRect}; #[derive(Debug, Copy, Clone)] pub struct PrimitiveOpacity { @@ -25,15 +26,11 @@ pub struct PrimitiveOpacity { impl PrimitiveOpacity { pub fn opaque() -> PrimitiveOpacity { - PrimitiveOpacity { - is_opaque: true, - } + PrimitiveOpacity { is_opaque: true } } pub fn translucent() -> PrimitiveOpacity { - PrimitiveOpacity { - is_opaque: false, - } + PrimitiveOpacity { is_opaque: false } } pub fn from_alpha(alpha: f32) -> PrimitiveOpacity { @@ -172,10 +169,12 @@ pub struct LinePrimitive { impl ToGpuBlocks for LinePrimitive { fn write_gpu_blocks(&self, mut request: GpuDataRequest) { request.push(self.color); - request.push([pack_as_float(self.style as u32), - pack_as_float(self.orientation as u32), - 0.0, - 0.0]); + request.push([ + pack_as_float(self.style as u32), + pack_as_float(self.orientation as u32), + 0.0, + 0.0, + ]); } } @@ -253,10 +252,12 @@ impl ToGpuBlocks for BoxShadowPrimitiveCpu { request.push(self.src_rect); request.push(self.bs_rect); request.push(self.color); - request.push([self.border_radius, - self.edge_size, - self.blur_radius, - self.inverted]); + request.push([ + self.border_radius, + self.edge_size, + self.blur_radius, + self.inverted, + ]); for &rect in &self.rects { request.push(rect); } @@ -273,9 +274,11 @@ pub struct GradientPrimitiveCpu { } impl GradientPrimitiveCpu { - fn build_gpu_blocks_for_aligned(&self, - display_list: &BuiltDisplayList, - mut request: GpuDataRequest) -> PrimitiveOpacity { + fn build_gpu_blocks_for_aligned( + &self, + display_list: &BuiltDisplayList, + mut request: GpuDataRequest, + ) -> PrimitiveOpacity { let mut opacity = PrimitiveOpacity::opaque(); request.extend_from_slice(&self.gpu_blocks); let src_stops = display_list.get(self.stops_range); @@ -289,13 +292,14 @@ impl GradientPrimitiveCpu { opacity } - fn build_gpu_blocks_for_angle_radial(&self, - display_list: &BuiltDisplayList, - mut request: GpuDataRequest) { + fn build_gpu_blocks_for_angle_radial( + &self, + display_list: &BuiltDisplayList, + mut request: GpuDataRequest, + ) { request.extend_from_slice(&self.gpu_blocks); - let gradient_builder = GradientGpuBlockBuilder::new(self.stops_range, - display_list); + let gradient_builder = GradientGpuBlockBuilder::new(self.stops_range, display_list); gradient_builder.build(self.reverse_stops, &mut request); } } @@ -329,8 +333,10 @@ struct GradientGpuBlockBuilder<'a> { } impl<'a> GradientGpuBlockBuilder<'a> { - fn new(stops_range: ItemRange, - display_list: &'a BuiltDisplayList) -> GradientGpuBlockBuilder<'a> { + fn new( + stops_range: ItemRange, + display_list: &'a BuiltDisplayList, + ) -> GradientGpuBlockBuilder<'a> { GradientGpuBlockBuilder { stops_range, display_list, @@ -339,12 +345,14 @@ impl<'a> GradientGpuBlockBuilder<'a> { /// Generate a color ramp filling the indices in [start_idx, end_idx) and interpolating /// from start_color to end_color. - fn fill_colors(&self, - start_idx: usize, - end_idx: usize, - start_color: &ColorF, - end_color: &ColorF, - entries: &mut [GradientDataEntry; GRADIENT_DATA_SIZE]) { + fn fill_colors( + &self, + start_idx: usize, + end_idx: usize, + start_color: &ColorF, + end_color: &ColorF, + entries: &mut [GradientDataEntry; GRADIENT_DATA_SIZE], + ) { // Calculate the color difference for individual steps in the ramp. let inv_steps = 1.0 / (end_idx - start_idx) as f32; let step_r = (end_color.r - start_color.r) * inv_steps; @@ -355,7 +363,7 @@ impl<'a> GradientGpuBlockBuilder<'a> { let mut cur_color = *start_color; // Walk the ramp writing start and end colors for each entry. - for index in start_idx..end_idx { + for index in start_idx .. end_idx { let entry = &mut entries[index]; entry.start_color = cur_color; cur_color.r += step_r; @@ -370,9 +378,9 @@ impl<'a> GradientGpuBlockBuilder<'a> { /// function maps offsets from [0, 1] to indices in [GRADIENT_DATA_TABLE_BEGIN, GRADIENT_DATA_TABLE_END]. #[inline] fn get_index(offset: f32) -> usize { - (offset.max(0.0).min(1.0) - * GRADIENT_DATA_TABLE_SIZE as f32 - + GRADIENT_DATA_TABLE_BEGIN as f32).round() as usize + (offset.max(0.0).min(1.0) * GRADIENT_DATA_TABLE_SIZE as f32 + + GRADIENT_DATA_TABLE_BEGIN as f32) + .round() as usize } // Build the gradient data from the supplied stops, reversing them if necessary. @@ -402,7 +410,13 @@ impl<'a> GradientGpuBlockBuilder<'a> { if reverse_stops { // Fill in the first entry (for reversed stops) with the first color stop - self.fill_colors(GRADIENT_DATA_LAST_STOP, GRADIENT_DATA_LAST_STOP + 1, &cur_color, &cur_color, &mut entries); + self.fill_colors( + GRADIENT_DATA_LAST_STOP, + GRADIENT_DATA_LAST_STOP + 1, + &cur_color, + &cur_color, + &mut entries, + ); // Fill in the center of the gradient table, generating a color ramp between each consecutive pair // of gradient stops. Each iteration of a loop will fill the indices in [next_idx, cur_idx). The @@ -413,8 +427,7 @@ impl<'a> GradientGpuBlockBuilder<'a> { let next_idx = Self::get_index(1.0 - next.offset); if next_idx < cur_idx { - self.fill_colors(next_idx, cur_idx, - &next_color, &cur_color, &mut entries); + self.fill_colors(next_idx, cur_idx, &next_color, &cur_color, &mut entries); cur_idx = next_idx; } @@ -423,10 +436,22 @@ impl<'a> GradientGpuBlockBuilder<'a> { debug_assert_eq!(cur_idx, GRADIENT_DATA_TABLE_BEGIN); // Fill in the last entry (for reversed stops) with the last color stop - self.fill_colors(GRADIENT_DATA_FIRST_STOP, GRADIENT_DATA_FIRST_STOP + 1, &cur_color, &cur_color, &mut entries); + self.fill_colors( + GRADIENT_DATA_FIRST_STOP, + GRADIENT_DATA_FIRST_STOP + 1, + &cur_color, + &cur_color, + &mut entries, + ); } else { // Fill in the first entry with the first color stop - self.fill_colors(GRADIENT_DATA_FIRST_STOP, GRADIENT_DATA_FIRST_STOP + 1, &cur_color, &cur_color, &mut entries); + self.fill_colors( + GRADIENT_DATA_FIRST_STOP, + GRADIENT_DATA_FIRST_STOP + 1, + &cur_color, + &cur_color, + &mut entries, + ); // Fill in the center of the gradient table, generating a color ramp between each consecutive pair // of gradient stops. Each iteration of a loop will fill the indices in [cur_idx, next_idx). The @@ -437,8 +462,7 @@ impl<'a> GradientGpuBlockBuilder<'a> { let next_idx = Self::get_index(next.offset); if next_idx > cur_idx { - self.fill_colors(cur_idx, next_idx, - &cur_color, &next_color, &mut entries); + self.fill_colors(cur_idx, next_idx, &cur_color, &next_color, &mut entries); cur_idx = next_idx; } @@ -447,7 +471,13 @@ impl<'a> GradientGpuBlockBuilder<'a> { debug_assert_eq!(cur_idx, GRADIENT_DATA_TABLE_END); // Fill in the last entry with the last color stop - self.fill_colors(GRADIENT_DATA_LAST_STOP, GRADIENT_DATA_LAST_STOP + 1, &cur_color, &cur_color, &mut entries); + self.fill_colors( + GRADIENT_DATA_LAST_STOP, + GRADIENT_DATA_LAST_STOP + 1, + &cur_color, + &cur_color, + &mut entries, + ); } for entry in entries.iter() { @@ -466,13 +496,14 @@ pub struct RadialGradientPrimitiveCpu { } impl RadialGradientPrimitiveCpu { - fn build_gpu_blocks_for_angle_radial(&self, - display_list: &BuiltDisplayList, - mut request: GpuDataRequest) { + fn build_gpu_blocks_for_angle_radial( + &self, + display_list: &BuiltDisplayList, + mut request: GpuDataRequest, + ) { request.extend_from_slice(&self.gpu_blocks); - let gradient_builder = GradientGpuBlockBuilder::new(self.stops_range, - display_list); + let gradient_builder = GradientGpuBlockBuilder::new(self.stops_range, display_list); gradient_builder.build(false, &mut request); } } @@ -503,12 +534,14 @@ pub enum TextRunMode { } impl TextRunPrimitiveCpu { - fn prepare_for_render(&mut self, - resource_cache: &mut ResourceCache, - device_pixel_ratio: f32, - display_list: &BuiltDisplayList, - run_mode: TextRunMode, - gpu_cache: &mut GpuCache) { + fn prepare_for_render( + &mut self, + resource_cache: &mut ResourceCache, + device_pixel_ratio: f32, + display_list: &BuiltDisplayList, + run_mode: TextRunMode, + gpu_cache: &mut GpuCache, + ) { let mut font = self.font.clone(); font.size = font.size.scale_by(device_pixel_ratio); match run_mode { @@ -535,10 +568,7 @@ impl TextRunPrimitiveCpu { let mut gpu_block = GpuBlockData::empty(); for (i, src) in src_glyphs.enumerate() { - let key = GlyphKey::new(src.index, - src.point, - font.render_mode, - font.subpx_dir); + let key = GlyphKey::new(src.index, src.point, font.render_mode, font.subpx_dir); self.glyph_keys.push(key); // Two glyphs are packed per GPU block. @@ -563,13 +593,14 @@ impl TextRunPrimitiveCpu { resource_cache.request_glyphs(font, &self.glyph_keys, gpu_cache); } - fn write_gpu_blocks(&self, - request: &mut GpuDataRequest) { + fn write_gpu_blocks(&self, request: &mut GpuDataRequest) { request.push(self.color); - request.push([self.offset.x, - self.offset.y, - self.font.subpx_dir as u32 as f32, - 0.0]); + request.push([ + self.offset.x, + self.offset.y, + self.font.subpx_dir as u32 as f32, + 0.0, + ]); request.extend_from_slice(&self.glyph_gpu_blocks); assert!(request.current_used_block_num() <= MAX_VERTEX_TEXTURE_WIDTH); @@ -602,9 +633,12 @@ impl ToGpuBlocks for ClipCorner { impl ClipCorner { fn write(&self, request: &mut GpuDataRequest) { request.push(self.rect); - request.push([self.outer_radius_x, self.outer_radius_y, - self.inner_radius_x, self.inner_radius_y, - ]); + request.push([ + self.outer_radius_x, + self.outer_radius_y, + self.inner_radius_x, + self.inner_radius_y, + ]); } fn uniform(rect: LayerRect, outer_radius: f32, inner_radius: f32) -> ClipCorner { @@ -649,7 +683,8 @@ impl ClipData { top_left: ClipCorner { rect: LayerRect::new( LayerPoint::new(rect.origin.x, rect.origin.y), - LayerSize::new(radii.top_left.width, radii.top_left.height)), + LayerSize::new(radii.top_left.width, radii.top_left.height), + ), outer_radius_x: radii.top_left.width, outer_radius_y: radii.top_left.height, inner_radius_x: 0.0, @@ -657,8 +692,12 @@ impl ClipData { }, top_right: ClipCorner { rect: LayerRect::new( - LayerPoint::new(rect.origin.x + rect.size.width - radii.top_right.width, rect.origin.y), - LayerSize::new(radii.top_right.width, radii.top_right.height)), + LayerPoint::new( + rect.origin.x + rect.size.width - radii.top_right.width, + rect.origin.y, + ), + LayerSize::new(radii.top_right.width, radii.top_right.height), + ), outer_radius_x: radii.top_right.width, outer_radius_y: radii.top_right.height, inner_radius_x: 0.0, @@ -666,8 +705,12 @@ impl ClipData { }, bottom_left: ClipCorner { rect: LayerRect::new( - LayerPoint::new(rect.origin.x, rect.origin.y + rect.size.height - radii.bottom_left.height), - LayerSize::new(radii.bottom_left.width, radii.bottom_left.height)), + LayerPoint::new( + rect.origin.x, + rect.origin.y + rect.size.height - radii.bottom_left.height, + ), + LayerSize::new(radii.bottom_left.width, radii.bottom_left.height), + ), outer_radius_x: radii.bottom_left.width, outer_radius_y: radii.bottom_left.height, inner_radius_x: 0.0, @@ -675,9 +718,12 @@ impl ClipData { }, bottom_right: ClipCorner { rect: LayerRect::new( - LayerPoint::new(rect.origin.x + rect.size.width - radii.bottom_right.width, - rect.origin.y + rect.size.height - radii.bottom_right.height), - LayerSize::new(radii.bottom_right.width, radii.bottom_right.height)), + LayerPoint::new( + rect.origin.x + rect.size.width - radii.bottom_right.width, + rect.origin.y + rect.size.height - radii.bottom_right.height, + ), + LayerSize::new(radii.bottom_right.width, radii.bottom_right.height), + ), outer_radius_x: radii.bottom_right.width, outer_radius_y: radii.bottom_right.height, inner_radius_x: 0.0, @@ -695,30 +741,50 @@ impl ClipData { top_left: ClipCorner::uniform( LayerRect::new( LayerPoint::new(rect.origin.x, rect.origin.y), - LayerSize::new(radius, radius)), - radius, 0.0), + LayerSize::new(radius, radius), + ), + radius, + 0.0, + ), top_right: ClipCorner::uniform( LayerRect::new( LayerPoint::new(rect.origin.x + rect.size.width - radius, rect.origin.y), - LayerSize::new(radius, radius)), - radius, 0.0), + LayerSize::new(radius, radius), + ), + radius, + 0.0, + ), bottom_left: ClipCorner::uniform( LayerRect::new( LayerPoint::new(rect.origin.x, rect.origin.y + rect.size.height - radius), - LayerSize::new(radius, radius)), - radius, 0.0), + LayerSize::new(radius, radius), + ), + radius, + 0.0, + ), bottom_right: ClipCorner::uniform( LayerRect::new( - LayerPoint::new(rect.origin.x + rect.size.width - radius, rect.origin.y + rect.size.height - radius), - LayerSize::new(radius, radius)), - radius, 0.0), + LayerPoint::new( + rect.origin.x + rect.size.width - radius, + rect.origin.y + rect.size.height - radius, + ), + LayerSize::new(radius, radius), + ), + radius, + 0.0, + ), } } pub fn write(&self, request: &mut GpuDataRequest) { request.push(self.rect.rect); request.push([self.rect.mode, 0.0, 0.0, 0.0]); - for corner in &[&self.top_left, &self.top_right, &self.bottom_left, &self.bottom_right] { + for corner in &[ + &self.top_left, + &self.top_right, + &self.bottom_left, + &self.bottom_right, + ] { corner.write(request); } } @@ -790,12 +856,14 @@ impl PrimitiveStore { } } - pub fn add_primitive(&mut self, - local_rect: &LayerRect, - local_clip_rect: &LayerRect, - is_backface_visible: bool, - clip_sources: ClipSourcesHandle, - container: PrimitiveContainer) -> PrimitiveIndex { + pub fn add_primitive( + &mut self, + local_rect: &LayerRect, + local_clip_rect: &LayerRect, + is_backface_visible: bool, + clip_sources: ClipSourcesHandle, + container: PrimitiveContainer, + ) -> PrimitiveIndex { let prim_index = self.cpu_metadata.len(); self.cpu_bounding_rects.push(None); @@ -994,26 +1062,27 @@ impl PrimitiveStore { self.cpu_metadata.len() } - pub fn build_bounding_rect(&mut self, - prim_index: PrimitiveIndex, - screen_rect: &DeviceIntRect, - layer_transform: &LayerToWorldTransform, - layer_combined_local_clip_rect: &LayerRect, - device_pixel_ratio: f32) -> Option<(LayerRect, DeviceIntRect)> { + pub fn build_bounding_rect( + &mut self, + prim_index: PrimitiveIndex, + screen_rect: &DeviceIntRect, + layer_transform: &LayerToWorldTransform, + layer_combined_local_clip_rect: &LayerRect, + device_pixel_ratio: f32, + ) -> Option<(LayerRect, DeviceIntRect)> { let metadata = &self.cpu_metadata[prim_index.0]; if !metadata.is_backface_visible && layer_transform.is_backface_visible() { return None; } - let local_rect = metadata.local_rect - .intersection(&metadata.local_clip_rect) - .and_then(|rect| rect.intersection(layer_combined_local_clip_rect)); + let local_rect = metadata + .local_rect + .intersection(&metadata.local_clip_rect) + .and_then(|rect| rect.intersection(layer_combined_local_clip_rect)); let bounding_rect = local_rect.and_then(|local_rect| { - let xf_rect = TransformedRect::new(&local_rect, - layer_transform, - device_pixel_ratio); + let xf_rect = TransformedRect::new(&local_rect, layer_transform, device_pixel_ratio); xf_rect.bounding_rect.intersection(screen_rect) }); @@ -1022,9 +1091,7 @@ impl PrimitiveStore { } /// Add any task dependencies for this primitive to the provided task. - pub fn add_render_tasks_for_prim(&self, - prim_index: PrimitiveIndex, - task: &mut RenderTask) { + pub fn add_render_tasks_for_prim(&self, prim_index: PrimitiveIndex, task: &mut RenderTask) { // Add any dynamic render tasks needed to render this primitive let metadata = &self.cpu_metadata[prim_index.0]; @@ -1045,9 +1112,7 @@ impl PrimitiveStore { PrimitiveKind::Border | PrimitiveKind::AngleGradient | PrimitiveKind::RadialGradient | - PrimitiveKind::Line => { - None - } + PrimitiveKind::Line => None, }; if let Some(render_task_id) = render_task_id { @@ -1060,17 +1125,18 @@ impl PrimitiveStore { } /// Returns true if the bounding box needs to be updated. - pub fn prepare_prim_for_render(&mut self, - prim_index: PrimitiveIndex, - resource_cache: &mut ResourceCache, - gpu_cache: &mut GpuCache, - layer_transform: &LayerToWorldTransform, - device_pixel_ratio: f32, - display_list: &BuiltDisplayList, - text_run_mode: TextRunMode, - render_tasks: &mut RenderTaskTree, - clip_store: &mut ClipStore) - -> &mut PrimitiveMetadata { + pub fn prepare_prim_for_render( + &mut self, + prim_index: PrimitiveIndex, + resource_cache: &mut ResourceCache, + gpu_cache: &mut GpuCache, + layer_transform: &LayerToWorldTransform, + device_pixel_ratio: f32, + display_list: &BuiltDisplayList, + text_run_mode: TextRunMode, + render_tasks: &mut RenderTaskTree, + clip_store: &mut ClipStore, + ) -> &mut PrimitiveMetadata { let (prim_kind, cpu_prim_index) = { let metadata = &self.cpu_metadata[prim_index.0]; (metadata.prim_kind, metadata.cpu_prim_index) @@ -1083,28 +1149,30 @@ impl PrimitiveStore { // avoid borrow checker issues. if prim_kind == PrimitiveKind::TextShadow { for sub_prim_index in self.cpu_text_shadows[cpu_prim_index.0].primitives.clone() { - self.prepare_prim_for_render(sub_prim_index, - resource_cache, - gpu_cache, - layer_transform, - device_pixel_ratio, - display_list, - TextRunMode::Shadow, - render_tasks, - clip_store); + self.prepare_prim_for_render( + sub_prim_index, + resource_cache, + gpu_cache, + layer_transform, + device_pixel_ratio, + display_list, + TextRunMode::Shadow, + render_tasks, + clip_store, + ); } } let metadata = &mut self.cpu_metadata[prim_index.0]; - clip_store.get_mut(&metadata.clip_sources).update(layer_transform, - gpu_cache, - resource_cache, - device_pixel_ratio); + clip_store.get_mut(&metadata.clip_sources).update( + layer_transform, + gpu_cache, + resource_cache, + device_pixel_ratio, + ); match metadata.prim_kind { - PrimitiveKind::Rectangle | - PrimitiveKind::Border | - PrimitiveKind::Line => {} + PrimitiveKind::Rectangle | PrimitiveKind::Border | PrimitiveKind::Line => {} PrimitiveKind::BoxShadow => { // TODO(gw): Account for zoom factor! // Here, we calculate the size of the patch required in order @@ -1115,15 +1183,17 @@ impl PrimitiveStore { // the patch is clamped / mirrored across the box shadow rect. let box_shadow = &mut self.cpu_box_shadows[cpu_prim_index.0]; let edge_size = box_shadow.edge_size.ceil() * device_pixel_ratio; - let edge_size = edge_size as i32 + 2; // Account for bilinear filtering + let edge_size = edge_size as i32 + 2; // Account for bilinear filtering let cache_size = DeviceIntSize::new(edge_size, edge_size); let cache_key = BoxShadowPrimitiveCacheKey { blur_radius: Au::from_f32_px(box_shadow.blur_radius), border_radius: Au::from_f32_px(box_shadow.border_radius), inverted: box_shadow.inverted != 0.0, - shadow_rect_size: Size2D::new(Au::from_f32_px(box_shadow.bs_rect.size.width), - Au::from_f32_px(box_shadow.bs_rect.size.height)), + shadow_rect_size: Size2D::new( + Au::from_f32_px(box_shadow.bs_rect.size.width), + Au::from_f32_px(box_shadow.bs_rect.size.height), + ), }; // Create a render task for this box shadow primitive. This renders a small @@ -1145,42 +1215,48 @@ impl PrimitiveStore { // render the text run to a target, and then apply a gaussian // blur to that text run in order to build the actual primitive // which will be blitted to the framebuffer. - let cache_width = (metadata.local_rect.size.width * device_pixel_ratio).ceil() as i32; - let cache_height = (metadata.local_rect.size.height * device_pixel_ratio).ceil() as i32; + let cache_width = + (metadata.local_rect.size.width * device_pixel_ratio).ceil() as i32; + let cache_height = + (metadata.local_rect.size.height * device_pixel_ratio).ceil() as i32; let cache_size = DeviceIntSize::new(cache_width, cache_height); - let blur_radius = device_length(shadow.shadow.blur_radius, - device_pixel_ratio); + let blur_radius = device_length(shadow.shadow.blur_radius, device_pixel_ratio); let prim_cache_task = RenderTask::new_prim_cache(cache_size, prim_index); let prim_cache_task_id = render_tasks.add(prim_cache_task); - let render_task = RenderTask::new_blur(blur_radius, - prim_cache_task_id, - render_tasks); + let render_task = + RenderTask::new_blur(blur_radius, prim_cache_task_id, render_tasks); shadow.render_task_id = Some(render_tasks.add(render_task)); } PrimitiveKind::TextRun => { let text = &mut self.cpu_text_runs[cpu_prim_index.0]; - text.prepare_for_render(resource_cache, - device_pixel_ratio, - display_list, - text_run_mode, - gpu_cache); + text.prepare_for_render( + resource_cache, + device_pixel_ratio, + display_list, + text_run_mode, + gpu_cache, + ); } PrimitiveKind::Image => { let image_cpu = &mut self.cpu_images[cpu_prim_index.0]; - resource_cache.request_image(image_cpu.image_key, - image_cpu.image_rendering, - image_cpu.tile_offset, - gpu_cache); + resource_cache.request_image( + image_cpu.image_key, + image_cpu.image_rendering, + image_cpu.tile_offset, + gpu_cache, + ); // TODO(gw): This doesn't actually need to be calculated each frame. // It's cheap enough that it's not worth introducing a cache for images // right now, but if we introduce a cache for images for some other // reason then we might as well cache this with it. - if let Some(image_properties) = resource_cache.get_image_properties(image_cpu.image_key) { + if let Some(image_properties) = + resource_cache.get_image_properties(image_cpu.image_key) + { metadata.opacity.is_opaque = image_properties.descriptor.is_opaque && - image_cpu.tile_spacing.width == 0.0 && - image_cpu.tile_spacing.height == 0.0; + image_cpu.tile_spacing.width == 0.0 && + image_cpu.tile_spacing.height == 0.0; } } PrimitiveKind::YuvImage => { @@ -1188,11 +1264,13 @@ impl PrimitiveStore { let channel_num = image_cpu.format.get_plane_num(); debug_assert!(channel_num <= 3); - for channel in 0..channel_num { - resource_cache.request_image(image_cpu.yuv_key[channel], - image_cpu.image_rendering, - None, - gpu_cache); + for channel in 0 .. channel_num { + resource_cache.request_image( + image_cpu.yuv_key[channel], + image_cpu.image_rendering, + None, + gpu_cache, + ); } } PrimitiveKind::AlignedGradient | @@ -1232,18 +1310,15 @@ impl PrimitiveStore { } PrimitiveKind::AlignedGradient => { let gradient = &self.cpu_gradients[cpu_prim_index.0]; - metadata.opacity = gradient.build_gpu_blocks_for_aligned(display_list, - request); + metadata.opacity = gradient.build_gpu_blocks_for_aligned(display_list, request); } PrimitiveKind::AngleGradient => { let gradient = &self.cpu_gradients[cpu_prim_index.0]; - gradient.build_gpu_blocks_for_angle_radial(display_list, - request); + gradient.build_gpu_blocks_for_angle_radial(display_list, request); } PrimitiveKind::RadialGradient => { let gradient = &self.cpu_radial_gradients[cpu_prim_index.0]; - gradient.build_gpu_blocks_for_angle_radial(display_list, - request); + gradient.build_gpu_blocks_for_angle_radial(display_list, request); } PrimitiveKind::TextRun => { let text = &self.cpu_text_runs[cpu_prim_index.0]; @@ -1252,10 +1327,12 @@ impl PrimitiveStore { PrimitiveKind::TextShadow => { let prim = &self.cpu_text_shadows[cpu_prim_index.0]; request.push(prim.shadow.color); - request.push([prim.shadow.offset.x, - prim.shadow.offset.y, - prim.shadow.blur_radius, - 0.0]); + request.push([ + prim.shadow.offset.x, + prim.shadow.offset.y, + prim.shadow.blur_radius, + 0.0, + ]); } } } @@ -1278,17 +1355,14 @@ impl InsideTest for ComplexClipRegion { let delta_right = self.rect.max_x() - clip.rect.max_x(); let delta_bottom = self.rect.max_y() - clip.rect.max_y(); - delta_left >= 0f32 && - delta_top >= 0f32 && - delta_right >= 0f32 && - delta_bottom >= 0f32 && - clip.radii.top_left.width >= self.radii.top_left.width - delta_left && - clip.radii.top_left.height >= self.radii.top_left.height - delta_top && - clip.radii.top_right.width >= self.radii.top_right.width - delta_right && - clip.radii.top_right.height >= self.radii.top_right.height - delta_top && - clip.radii.bottom_left.width >= self.radii.bottom_left.width - delta_left && - clip.radii.bottom_left.height >= self.radii.bottom_left.height - delta_bottom && - clip.radii.bottom_right.width >= self.radii.bottom_right.width - delta_right && - clip.radii.bottom_right.height >= self.radii.bottom_right.height - delta_bottom + delta_left >= 0f32 && delta_top >= 0f32 && delta_right >= 0f32 && delta_bottom >= 0f32 && + clip.radii.top_left.width >= self.radii.top_left.width - delta_left && + clip.radii.top_left.height >= self.radii.top_left.height - delta_top && + clip.radii.top_right.width >= self.radii.top_right.width - delta_right && + clip.radii.top_right.height >= self.radii.top_right.height - delta_top && + clip.radii.bottom_left.width >= self.radii.bottom_left.width - delta_left && + clip.radii.bottom_left.height >= self.radii.bottom_left.height - delta_bottom && + clip.radii.bottom_right.width >= self.radii.bottom_right.width - delta_right && + clip.radii.bottom_right.height >= self.radii.bottom_right.height - delta_bottom } } diff --git a/webrender/src/print_tree.rs b/webrender/src/print_tree.rs index 6ee12cbdc1..0948d19abb 100644 --- a/webrender/src/print_tree.rs +++ b/webrender/src/print_tree.rs @@ -32,7 +32,7 @@ impl PrintTree { } fn print_level_prefix(&self) { - for _ in 0..self.level { + for _ in 0 .. self.level { print!("\u{2502} "); } } @@ -67,7 +67,7 @@ impl PrintTreePrinter for PrintTree { fn add_item(&mut self, text: String) { self.flush_queued_item("\u{251C}\u{2500}"); self.queued_item = Some(text); - } + } } impl Drop for PrintTree { diff --git a/webrender/src/profiler.rs b/webrender/src/profiler.rs index 6d9a687688..0a1e6d96b6 100644 --- a/webrender/src/profiler.rs +++ b/webrender/src/profiler.rs @@ -2,13 +2,13 @@ * 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 api::{ColorF, ColorU}; use debug_render::DebugRenderer; -use device::{Device, GpuMarker, GpuTimer, GpuSampler, NamedTag}; -use euclid::{Point2D, Size2D, Rect, vec2}; +use device::{Device, GpuMarker, GpuSampler, GpuTimer, NamedTag}; +use euclid::{Point2D, Rect, Size2D, vec2}; use std::collections::vec_deque::VecDeque; use std::f32; use std::mem; -use api::{ColorF, ColorU}; use time::precise_time_ns; const GRAPH_WIDTH: f32 = 1024.0; @@ -37,8 +37,12 @@ trait ProfileCounter { } impl<'a, T: ProfileCounter> ProfileCounter for &'a T { - fn description(&self) -> &'static str { (*self).description() } - fn value(&self) -> String { (*self).value() } + fn description(&self) -> &'static str { + (*self).description() + } + fn value(&self) -> String { + (*self).value() + } } #[derive(Clone)] @@ -186,7 +190,10 @@ impl TimeProfileCounter { self.nanoseconds = ns; } - pub fn profile(&mut self, callback: F) -> T where F: FnOnce() -> T { + pub fn profile(&mut self, callback: F) -> T + where + F: FnOnce() -> T, + { let t0 = precise_time_ns(); let val = callback(); let t1 = precise_time_ns(); @@ -259,8 +266,7 @@ impl AverageTimeProfileCounter { pub fn set(&mut self, ns: u64) { let now = precise_time_ns(); - if (now - self.start_ns) > self.average_over_ns && - self.num_samples > 0 { + if (now - self.start_ns) > self.average_over_ns && self.num_samples > 0 { self.nanoseconds = self.sum_ns / self.num_samples; self.start_ns = now; self.sum_ns = 0; @@ -271,7 +277,10 @@ impl AverageTimeProfileCounter { } #[allow(dead_code)] - pub fn profile(&mut self, callback: F) -> T where F: FnOnce() -> T { + pub fn profile(&mut self, callback: F) -> T + where + F: FnOnce() -> T, + { let t0 = precise_time_ns(); let val = callback(); let t1 = precise_time_ns(); @@ -374,7 +383,8 @@ pub struct IpcProfileCounters { } impl IpcProfileCounters { - pub fn set(&mut self, + pub fn set( + &mut self, build_start: u64, build_end: u64, send_start: u64, @@ -511,13 +521,13 @@ impl ProfileGraph { stats } - fn draw_graph(&self, + fn draw_graph( + &self, x: f32, y: f32, description: &'static str, debug_renderer: &mut DebugRenderer, - ) -> Rect - { + ) -> Rect { let size = Size2D::new(600.0, 120.0); let line_height = debug_renderer.line_height(); let mut rect = Rect::new(Point2D::new(x, y), size); @@ -525,30 +535,40 @@ impl ProfileGraph { let text_color = ColorU::new(255, 255, 0, 255); let text_origin = rect.origin + vec2(rect.size.width, 20.0); - debug_renderer.add_text(text_origin.x, - text_origin.y, - description, - ColorU::new(0, 255, 0, 255)); - debug_renderer.add_text(text_origin.x, - text_origin.y + line_height, - &format!("Min: {:.2} ms", stats.min_value), - text_color); - debug_renderer.add_text(text_origin.x, - text_origin.y + line_height * 2.0, - &format!("Mean: {:.2} ms", stats.mean_value), - text_color); - debug_renderer.add_text(text_origin.x, - text_origin.y + line_height * 3.0, - &format!("Max: {:.2} ms", stats.max_value), - text_color); + debug_renderer.add_text( + text_origin.x, + text_origin.y, + description, + ColorU::new(0, 255, 0, 255), + ); + debug_renderer.add_text( + text_origin.x, + text_origin.y + line_height, + &format!("Min: {:.2} ms", stats.min_value), + text_color, + ); + debug_renderer.add_text( + text_origin.x, + text_origin.y + line_height * 2.0, + &format!("Mean: {:.2} ms", stats.mean_value), + text_color, + ); + debug_renderer.add_text( + text_origin.x, + text_origin.y + line_height * 3.0, + &format!("Max: {:.2} ms", stats.max_value), + text_color, + ); rect.size.width += 140.0; - debug_renderer.add_quad(rect.origin.x, - rect.origin.y, - rect.origin.x + rect.size.width + 10.0, - rect.origin.y + rect.size.height, - ColorF::new(0.1, 0.1, 0.1, 0.8).into(), - ColorF::new(0.2, 0.2, 0.2, 0.8).into()); + debug_renderer.add_quad( + rect.origin.x, + rect.origin.y, + rect.origin.x + rect.size.width + 10.0, + rect.origin.y + rect.size.height, + ColorF::new(0.1, 0.1, 0.1, 0.8).into(), + ColorF::new(0.2, 0.2, 0.2, 0.8).into(), + ); let bx0 = x + 10.0; let by0 = y + 10.0; @@ -618,32 +638,33 @@ impl GpuFrameCollection { } impl GpuFrameCollection { - fn draw(&self, - x: f32, - y: f32, - debug_renderer: &mut DebugRenderer, - ) -> Rect - { - let bounding_rect = Rect::new(Point2D::new(x, y), - Size2D::new(GRAPH_WIDTH + 2.0 * GRAPH_PADDING, - GRAPH_HEIGHT + 2.0 * GRAPH_PADDING)); + fn draw(&self, x: f32, y: f32, debug_renderer: &mut DebugRenderer) -> Rect { + let bounding_rect = Rect::new( + Point2D::new(x, y), + Size2D::new( + GRAPH_WIDTH + 2.0 * GRAPH_PADDING, + GRAPH_HEIGHT + 2.0 * GRAPH_PADDING, + ), + ); let graph_rect = bounding_rect.inflate(-GRAPH_PADDING, -GRAPH_PADDING); - debug_renderer.add_quad(bounding_rect.origin.x, - bounding_rect.origin.y, - bounding_rect.origin.x + bounding_rect.size.width, - bounding_rect.origin.y + bounding_rect.size.height, - ColorF::new(0.1, 0.1, 0.1, 0.8).into(), - ColorF::new(0.2, 0.2, 0.2, 0.8).into()); + debug_renderer.add_quad( + bounding_rect.origin.x, + bounding_rect.origin.y, + bounding_rect.origin.x + bounding_rect.size.width, + bounding_rect.origin.y + bounding_rect.size.height, + ColorF::new(0.1, 0.1, 0.1, 0.8).into(), + ColorF::new(0.2, 0.2, 0.2, 0.8).into(), + ); let w = graph_rect.size.width; let mut y0 = graph_rect.origin.y; let max_time = self.frames - .iter() - .max_by_key(|f| f.total_time) - .unwrap() - .total_time as f32; + .iter() + .max_by_key(|f| f.total_time) + .unwrap() + .total_time as f32; for frame in &self.frames { let y1 = y0 + GRAPH_FRAME_HEIGHT; @@ -657,12 +678,14 @@ impl GpuFrameCollection { let mut bottom_color = sample.tag.color; bottom_color.a *= 0.5; - debug_renderer.add_quad(x0, - y0, - x1, - y1, - sample.tag.color.into(), - bottom_color.into()); + debug_renderer.add_quad( + x0, + y0, + x1, + y1, + sample.tag.color.into(), + bottom_color.into(), + ); } y0 = y1; @@ -699,7 +722,8 @@ impl Profiler { } } - fn draw_counters(&mut self, + fn draw_counters( + &mut self, counters: &[T], debug_renderer: &mut DebugRenderer, left: bool, @@ -720,11 +744,13 @@ impl Profiler { ]; for counter in counters { - let rect = debug_renderer.add_text(current_x, - current_y, - counter.description(), - colors[color_index]); - color_index = (color_index+1) % colors.len(); + let rect = debug_renderer.add_text( + current_x, + current_y, + counter.description(), + colors[color_index], + ); + color_index = (color_index + 1) % colors.len(); label_rect = label_rect.union(&rect); current_y += line_height; @@ -732,30 +758,30 @@ impl Profiler { color_index = 0; current_x = label_rect.origin.x + label_rect.size.width + 60.0; - current_y = if left { - self.y_left - } else { - self.y_right - }; + current_y = if left { self.y_left } else { self.y_right }; for counter in counters { - let rect = debug_renderer.add_text(current_x, - current_y, - &counter.value(), - colors[color_index]); - color_index = (color_index+1) % colors.len(); + let rect = debug_renderer.add_text( + current_x, + current_y, + &counter.value(), + colors[color_index], + ); + color_index = (color_index + 1) % colors.len(); value_rect = value_rect.union(&rect); current_y += line_height; } let total_rect = label_rect.union(&value_rect).inflate(10.0, 10.0); - debug_renderer.add_quad(total_rect.origin.x, - total_rect.origin.y, - total_rect.origin.x + total_rect.size.width, - total_rect.origin.y + total_rect.size.height, - ColorF::new(0.1, 0.1, 0.1, 0.8).into(), - ColorF::new(0.2, 0.2, 0.2, 0.8).into()); + debug_renderer.add_quad( + total_rect.origin.x, + total_rect.origin.y, + total_rect.origin.x + total_rect.size.width, + total_rect.origin.y + total_rect.size.height, + ColorF::new(0.1, 0.1, 0.1, 0.8).into(), + ColorF::new(0.2, 0.2, 0.2, 0.8).into(), + ); let new_y = total_rect.origin.y + total_rect.size.height + 30.0; if left { self.y_left = new_y; @@ -764,7 +790,8 @@ impl Profiler { } } - pub fn draw_profile(&mut self, + pub fn draw_profile( + &mut self, device: &mut Device, frame_profile: &FrameProfileCounters, backend_profile: &BackendProfileCounters, @@ -787,58 +814,79 @@ impl Profiler { } renderer_timers.gpu_time.set(gpu_time); - self.draw_counters(&[ - &renderer_profile.frame_time - ], debug_renderer, true); - - self.draw_counters(&[ - &renderer_profile.frame_counter, - &frame_profile.total_primitives, - &frame_profile.visible_primitives, - &frame_profile.passes, - &frame_profile.color_targets, - &frame_profile.alpha_targets, - &backend_profile.resources.gpu_cache.allocated_rows, - &backend_profile.resources.gpu_cache.allocated_blocks, - ], debug_renderer, true); - - self.draw_counters(&[ - &backend_profile.resources.font_templates, - &backend_profile.resources.image_templates, - ], debug_renderer, true); - - self.draw_counters(&[ - &backend_profile.resources.texture_cache.pages_a8, - &backend_profile.resources.texture_cache.pages_rgb8, - &backend_profile.resources.texture_cache.pages_rgba8, - &backend_profile.resources.texture_cache.pages_rg8, - &backend_profile.ipc.display_lists, - ], debug_renderer, true); - - self.draw_counters(&[ - &backend_profile.ipc.build_time, - &backend_profile.ipc.send_time, - &backend_profile.ipc.consume_time, - &backend_profile.ipc.total_time, - ], debug_renderer, true); - - self.draw_counters(&[ - &renderer_profile.draw_calls, - &renderer_profile.vertices, - ], debug_renderer, true); - - self.draw_counters(&[ - &backend_profile.total_time, - &renderer_timers.cpu_time, - &renderer_timers.gpu_time, - ], debug_renderer, false); + self.draw_counters(&[&renderer_profile.frame_time], debug_renderer, true); + + self.draw_counters( + &[ + &renderer_profile.frame_counter, + &frame_profile.total_primitives, + &frame_profile.visible_primitives, + &frame_profile.passes, + &frame_profile.color_targets, + &frame_profile.alpha_targets, + &backend_profile.resources.gpu_cache.allocated_rows, + &backend_profile.resources.gpu_cache.allocated_blocks, + ], + debug_renderer, + true, + ); + + self.draw_counters( + &[ + &backend_profile.resources.font_templates, + &backend_profile.resources.image_templates, + ], + debug_renderer, + true, + ); + + self.draw_counters( + &[ + &backend_profile.resources.texture_cache.pages_a8, + &backend_profile.resources.texture_cache.pages_rgb8, + &backend_profile.resources.texture_cache.pages_rgba8, + &backend_profile.resources.texture_cache.pages_rg8, + &backend_profile.ipc.display_lists, + ], + debug_renderer, + true, + ); + + self.draw_counters( + &[ + &backend_profile.ipc.build_time, + &backend_profile.ipc.send_time, + &backend_profile.ipc.consume_time, + &backend_profile.ipc.total_time, + ], + debug_renderer, + true, + ); + + self.draw_counters( + &[&renderer_profile.draw_calls, &renderer_profile.vertices], + debug_renderer, + true, + ); + + self.draw_counters( + &[ + &backend_profile.total_time, + &renderer_timers.cpu_time, + &renderer_timers.gpu_time, + ], + debug_renderer, + false, + ); let mut samplers = Vec::::new(); // Gathering unique GPU samplers. This has O(N^2) complexity, // but we only have a few samplers per target. for sampler in gpu_samplers { let value = sampler.count as f32 * screen_fraction; - match samplers.iter().position(|s| s.description as *const _ == sampler.tag.label as *const _) { + match samplers.iter().position(|s| { + s.description as *const _ == sampler.tag.label as *const _ + }) { Some(pos) => samplers[pos].value += value, None => samplers.push(FloatProfileCounter { description: sampler.tag.label, @@ -848,24 +896,36 @@ impl Profiler { } self.draw_counters(&samplers, debug_renderer, false); - self.backend_time.push(backend_profile.total_time.nanoseconds); - self.compositor_time.push(renderer_timers.cpu_time.nanoseconds); - self.ipc_time.push(backend_profile.ipc.total_time.nanoseconds); + self.backend_time + .push(backend_profile.total_time.nanoseconds); + self.compositor_time + .push(renderer_timers.cpu_time.nanoseconds); + self.ipc_time + .push(backend_profile.ipc.total_time.nanoseconds); self.gpu_time.push(gpu_time); self.gpu_frames.push(gpu_time, gpu_samples); - let rect = self.backend_time.draw_graph(self.x_left, self.y_left, "CPU (backend)", debug_renderer); + let rect = + self.backend_time + .draw_graph(self.x_left, self.y_left, "CPU (backend)", debug_renderer); self.y_left += rect.size.height + PROFILE_PADDING; - let rect = self.compositor_time.draw_graph(self.x_left, self.y_left, "CPU (compositor)", debug_renderer); + let rect = self.compositor_time.draw_graph( + self.x_left, + self.y_left, + "CPU (compositor)", + debug_renderer, + ); self.y_left += rect.size.height + PROFILE_PADDING; - let rect = self.ipc_time.draw_graph(self.x_left, self.y_left, "DisplayList IPC", debug_renderer); + let rect = + self.ipc_time + .draw_graph(self.x_left, self.y_left, "DisplayList IPC", debug_renderer); self.y_left += rect.size.height + PROFILE_PADDING; - let rect = self.gpu_time.draw_graph(self.x_left, self.y_left, "GPU", debug_renderer); + let rect = self.gpu_time + .draw_graph(self.x_left, self.y_left, "GPU", debug_renderer); self.y_left += rect.size.height + PROFILE_PADDING; - let rect = self.gpu_frames.draw(self.x_left, - self.y_left, - debug_renderer); + let rect = self.gpu_frames + .draw(self.x_left, self.y_left, debug_renderer); self.y_left += rect.size.height + PROFILE_PADDING; } } diff --git a/webrender/src/record.rs b/webrender/src/record.rs index fe03d823ca..cbc78c97a5 100644 --- a/webrender/src/record.rs +++ b/webrender/src/record.rs @@ -2,15 +2,15 @@ * 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 bincode::{Infinite, serialize}; -use std::fmt::Debug; -use std::mem; +use api::ApiMsg; +use bincode::{serialize, Infinite}; +use byteorder::{LittleEndian, WriteBytesExt}; use std::any::TypeId; +use std::fmt::Debug; use std::fs::File; use std::io::Write; +use std::mem; use std::path::PathBuf; -use api::ApiMsg; -use byteorder::{LittleEndian, WriteBytesExt}; pub static WEBRENDER_RECORDING_HEADER: u64 = 0xbeefbeefbeefbe01u64; @@ -33,12 +33,11 @@ impl BinaryRecorder { assert!(mem::size_of::() == mem::size_of::()); mem::transmute::(TypeId::of::()) }; - file.write_u64::(WEBRENDER_RECORDING_HEADER).ok(); + file.write_u64::(WEBRENDER_RECORDING_HEADER) + .ok(); file.write_u64::(apimsg_type_id).ok(); - BinaryRecorder { - file, - } + BinaryRecorder { file } } fn write_length_and_data(&mut self, data: &[u8]) { @@ -65,10 +64,9 @@ impl ApiRecordingReceiver for BinaryRecorder { pub fn should_record_msg(msg: &ApiMsg) -> bool { match *msg { ApiMsg::UpdateResources(..) | - ApiMsg::AddDocument{..} | + ApiMsg::AddDocument { .. } | ApiMsg::UpdateDocument(..) | - ApiMsg::DeleteDocument(..) => - true, - _ => false + ApiMsg::DeleteDocument(..) => true, + _ => false, } } diff --git a/webrender/src/render_backend.rs b/webrender/src/render_backend.rs index 29a176929a..fedcfc23a1 100644 --- a/webrender/src/render_backend.rs +++ b/webrender/src/render_backend.rs @@ -2,13 +2,21 @@ * 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 api::{ApiMsg, BlobImageRenderer, BuiltDisplayList, DebugCommand, DeviceIntPoint}; +#[cfg(feature = "debugger")] +use api::{BuiltDisplayListIter, SpecificDisplayItem}; +use api::{DeviceUintPoint, DeviceUintRect, DeviceUintSize, DocumentId, DocumentMsg}; +use api::{IdNamespace, LayerPoint, PipelineId, RenderNotifier}; +use api::channel::{MsgReceiver, PayloadReceiver, PayloadReceiverHelperMethods}; +use api::channel::{PayloadSender, PayloadSenderHelperMethods}; #[cfg(feature = "debugger")] use debug_server; use frame::Frame; use frame_builder::FrameBuilderConfig; use gpu_cache::GpuCache; -use internal_types::{DebugOutput, FastHashMap, FastHashSet, ResultMsg, RendererFrame}; +use internal_types::{DebugOutput, FastHashMap, FastHashSet, RendererFrame, ResultMsg}; use profiler::{BackendProfileCounters, ResourceProfileCounters}; +use rayon::ThreadPool; use record::ApiRecordingReceiver; use resource_cache::ResourceCache; use scene::Scene; @@ -18,16 +26,8 @@ use std::sync::{Arc, Mutex}; use std::sync::mpsc::Sender; use std::u32; use texture_cache::TextureCache; -use time::precise_time_ns; use thread_profiler::register_thread_with_profiler; -use rayon::ThreadPool; -use api::channel::{MsgReceiver, PayloadReceiver, PayloadReceiverHelperMethods}; -use api::channel::{PayloadSender, PayloadSenderHelperMethods}; -use api::{ApiMsg, DebugCommand, BlobImageRenderer, BuiltDisplayList, DeviceIntPoint}; -use api::{DeviceUintPoint, DeviceUintRect, DeviceUintSize, DocumentId, DocumentMsg}; -use api::{IdNamespace, LayerPoint, PipelineId, RenderNotifier}; -#[cfg(feature = "debugger")] -use api::{BuiltDisplayListIter, SpecificDisplayItem}; +use time::precise_time_ns; struct Document { scene: Scene, @@ -78,30 +78,37 @@ impl Document { fn build_scene(&mut self, resource_cache: &mut ResourceCache, hidpi_factor: f32) { let accumulated_scale_factor = self.accumulated_scale_factor(hidpi_factor); - self.frame.create(&self.scene, - resource_cache, - self.window_size, - self.inner_rect, - accumulated_scale_factor); + self.frame.create( + &self.scene, + resource_cache, + self.window_size, + self.inner_rect, + accumulated_scale_factor, + ); } - fn render(&mut self, + fn render( + &mut self, resource_cache: &mut ResourceCache, gpu_cache: &mut GpuCache, resource_profile: &mut ResourceProfileCounters, hidpi_factor: f32, - )-> RendererFrame { + ) -> RendererFrame { let accumulated_scale_factor = self.accumulated_scale_factor(hidpi_factor); - let pan = LayerPoint::new(self.pan.x as f32 / accumulated_scale_factor, - self.pan.y as f32 / accumulated_scale_factor); - self.frame.build(resource_cache, - gpu_cache, - &self.scene.display_lists, - accumulated_scale_factor, - pan, - &self.output_pipelines, - &mut resource_profile.texture_cache, - &mut resource_profile.gpu_cache) + let pan = LayerPoint::new( + self.pan.x as f32 / accumulated_scale_factor, + self.pan.y as f32 / accumulated_scale_factor, + ); + self.frame.build( + resource_cache, + gpu_cache, + &self.scene.display_lists, + accumulated_scale_factor, + pan, + &self.output_pipelines, + &mut resource_profile.texture_cache, + &mut resource_profile.gpu_cache, + ) } } @@ -154,10 +161,7 @@ impl RenderBackend { blob_image_renderer: Option>, enable_render_on_scroll: bool, ) -> RenderBackend { - - let resource_cache = ResourceCache::new(texture_cache, - workers, - blob_image_renderer); + let resource_cache = ResourceCache::new(texture_cache, workers, blob_image_renderer); register_thread_with_profiler("Backend".to_string()); @@ -180,10 +184,13 @@ impl RenderBackend { } } - fn process_document(&mut self, document_id: DocumentId, message: DocumentMsg, - frame_counter: u32, profile_counters: &mut BackendProfileCounters) - -> DocumentOp - { + fn process_document( + &mut self, + document_id: DocumentId, + message: DocumentMsg, + frame_counter: u32, + profile_counters: &mut BackendProfileCounters, + ) -> DocumentOp { let doc = self.documents.get_mut(&document_id).expect("No document?"); match message { @@ -207,7 +214,10 @@ impl RenderBackend { doc.pan = pan; DocumentOp::Nop } - DocumentMsg::SetWindowParameters{ window_size, inner_rect } => { + DocumentMsg::SetWindowParameters { + window_size, + inner_rect, + } => { doc.window_size = window_size; doc.inner_rect = inner_rect; DocumentOp::Nop @@ -224,13 +234,14 @@ impl RenderBackend { } => { profile_scope!("SetDisplayList"); - self.resource_cache.update_resources(resources, &mut profile_counters.resources); + self.resource_cache + .update_resources(resources, &mut profile_counters.resources); let mut data; while { data = self.payload_rx.recv_payload().unwrap(); data.epoch != epoch || data.pipeline_id != pipeline_id - }{ + } { self.payload_tx.send_payload(data).unwrap() } @@ -238,17 +249,16 @@ impl RenderBackend { r.write_payload(frame_counter, &data.to_data()); } - let built_display_list = BuiltDisplayList::from_data( - data.display_list_data, - list_descriptor - ); + let built_display_list = + BuiltDisplayList::from_data(data.display_list_data, list_descriptor); if !preserve_frame_state { doc.frame.discard_frame_state_for_pipeline(pipeline_id); } let display_list_len = built_display_list.data().len(); - let (builder_start_time, builder_finish_time, send_start_time) = built_display_list.times(); + let (builder_start_time, builder_finish_time, send_start_time) = + built_display_list.times(); let display_list_received_time = precise_time_ns(); { @@ -259,7 +269,7 @@ impl RenderBackend { built_display_list, background, viewport_size, - content_size + content_size, ); doc.build_scene(&mut self.resource_cache, self.hidpi_factor); } @@ -273,12 +283,14 @@ impl RenderBackend { // really simple and cheap to access, so it's not a big deal. let display_list_consumed_time = precise_time_ns(); - profile_counters.ipc.set(builder_start_time, - builder_finish_time, - send_start_time, - display_list_received_time, - display_list_consumed_time, - display_list_len); + profile_counters.ipc.set( + builder_start_time, + builder_finish_time, + send_start_time, + display_list_received_time, + display_list_consumed_time, + display_list_len, + ); DocumentOp::Built } @@ -304,11 +316,14 @@ impl RenderBackend { profile_scope!("Scroll"); let _timer = profile_counters.total_time.timer(); - if doc.frame.scroll(delta, cursor, move_phase) && doc.render_on_scroll == Some(true) { - let frame = doc.render(&mut self.resource_cache, - &mut self.gpu_cache, - &mut profile_counters.resources, - self.hidpi_factor); + if doc.frame.scroll(delta, cursor, move_phase) && doc.render_on_scroll == Some(true) + { + let frame = doc.render( + &mut self.resource_cache, + &mut self.gpu_cache, + &mut profile_counters.resources, + self.hidpi_factor, + ); DocumentOp::Scrolled(frame) } else { DocumentOp::ScrolledNop @@ -319,10 +334,12 @@ impl RenderBackend { let _timer = profile_counters.total_time.timer(); if doc.frame.scroll_node(origin, id, clamp) && doc.render_on_scroll == Some(true) { - let frame = doc.render(&mut self.resource_cache, - &mut self.gpu_cache, - &mut profile_counters.resources, - self.hidpi_factor); + let frame = doc.render( + &mut self.resource_cache, + &mut self.gpu_cache, + &mut profile_counters.resources, + self.hidpi_factor, + ); DocumentOp::Scrolled(frame) } else { DocumentOp::ScrolledNop @@ -334,10 +351,12 @@ impl RenderBackend { doc.frame.tick_scrolling_bounce_animations(); if doc.render_on_scroll == Some(true) { - let frame = doc.render(&mut self.resource_cache, - &mut self.gpu_cache, - &mut profile_counters.resources, - self.hidpi_factor); + let frame = doc.render( + &mut self.resource_cache, + &mut self.gpu_cache, + &mut profile_counters.resources, + self.hidpi_factor, + ); DocumentOp::Scrolled(frame) } else { DocumentOp::ScrolledNop @@ -372,10 +391,12 @@ impl RenderBackend { } if doc.scene.root_pipeline_id.is_some() { - let frame = doc.render(&mut self.resource_cache, - &mut self.gpu_cache, - &mut profile_counters.resources, - self.hidpi_factor); + let frame = doc.render( + &mut self.resource_cache, + &mut self.gpu_cache, + &mut profile_counters.resources, + self.hidpi_factor, + ); DocumentOp::Rendered(frame) } else { DocumentOp::ScrolledNop @@ -399,24 +420,22 @@ impl RenderBackend { } Err(..) => { let notifier = self.notifier.lock(); - notifier.unwrap() - .as_mut() - .unwrap() - .shut_down(); + notifier.unwrap().as_mut().unwrap().shut_down(); break; } }; match msg { ApiMsg::UpdateResources(updates) => { - self.resource_cache.update_resources(updates, &mut profile_counters.resources); + self.resource_cache + .update_resources(updates, &mut profile_counters.resources); } ApiMsg::GetGlyphDimensions(font, glyph_keys, tx) => { let mut glyph_dimensions = Vec::with_capacity(glyph_keys.len()); for glyph_key in &glyph_keys { let glyph_dim = self.resource_cache.get_glyph_dimensions(&font, glyph_key); glyph_dimensions.push(glyph_dim); - }; + } tx.send(glyph_dimensions).unwrap(); } ApiMsg::GetGlyphIndices(font_key, text, tx) => { @@ -424,7 +443,7 @@ impl RenderBackend { for ch in text.chars() { let index = self.resource_cache.get_glyph_index(font_key, ch); glyph_indices.push(index); - }; + } tx.send(glyph_indices).unwrap(); } ApiMsg::CloneApi(sender) => { @@ -433,44 +452,51 @@ impl RenderBackend { sender.send(namespace).unwrap(); } ApiMsg::AddDocument(document_id, initial_size) => { - let document = Document::new(self.frame_config.clone(), - initial_size, - self.enable_render_on_scroll); + let document = Document::new( + self.frame_config.clone(), + initial_size, + self.enable_render_on_scroll, + ); self.documents.insert(document_id, document); } - ApiMsg::UpdateDocument(document_id, doc_msg) => { - match self.process_document(document_id, doc_msg, frame_counter, &mut profile_counters) { - DocumentOp::Nop => {} - DocumentOp::Built => {} - DocumentOp::ScrolledNop => { - self.notify_compositor_of_new_scroll_frame(false); - } - DocumentOp::Scrolled(frame) => { - self.publish_frame(document_id, frame, &mut profile_counters); - self.notify_compositor_of_new_scroll_frame(true); - } - DocumentOp::Rendered(frame) => { - frame_counter += 1; - self.publish_frame_and_notify_compositor(document_id, frame, &mut profile_counters); - } + ApiMsg::UpdateDocument(document_id, doc_msg) => match self.process_document( + document_id, + doc_msg, + frame_counter, + &mut profile_counters, + ) { + DocumentOp::Nop => {} + DocumentOp::Built => {} + DocumentOp::ScrolledNop => { + self.notify_compositor_of_new_scroll_frame(false); } - } + DocumentOp::Scrolled(frame) => { + self.publish_frame(document_id, frame, &mut profile_counters); + self.notify_compositor_of_new_scroll_frame(true); + } + DocumentOp::Rendered(frame) => { + frame_counter += 1; + self.publish_frame_and_notify_compositor( + document_id, + frame, + &mut profile_counters, + ); + } + }, ApiMsg::DeleteDocument(document_id) => { self.documents.remove(&document_id); } ApiMsg::ExternalEvent(evt) => { let notifier = self.notifier.lock(); - notifier.unwrap() - .as_mut() - .unwrap() - .external_event(evt); + notifier.unwrap().as_mut().unwrap().external_event(evt); } ApiMsg::ClearNamespace(namespace_id) => { self.resource_cache.clear_namespace(namespace_id); - let document_ids = self.documents.keys() - .filter(|did| did.0 == namespace_id) - .cloned() - .collect::>(); + let document_ids = self.documents + .keys() + .filter(|did| did.0 == namespace_id) + .cloned() + .collect::>(); for document in document_ids { self.documents.remove(&document); } @@ -479,12 +505,20 @@ impl RenderBackend { self.resource_cache.on_memory_pressure(); let pending_update = self.resource_cache.pending_updates(); - let msg = ResultMsg::UpdateResources { updates: pending_update, cancel_rendering: true }; + let msg = ResultMsg::UpdateResources { + updates: pending_update, + cancel_rendering: true, + }; self.result_tx.send(msg).unwrap(); // We use new_frame_ready to wake up the renderer and get the // resource updates processed, but the UpdateResources message // will cancel rendering the frame. - self.notifier.lock().unwrap().as_mut().unwrap().new_frame_ready(); + self.notifier + .lock() + .unwrap() + .as_mut() + .unwrap() + .new_frame_ready(); } ApiMsg::DebugCommand(option) => { let msg = match option { @@ -496,43 +530,39 @@ impl RenderBackend { let json = self.get_clip_scroll_tree_for_debugger(); ResultMsg::DebugOutput(DebugOutput::FetchClipScrollTree(json)) } - _ => { - ResultMsg::DebugCommand(option) - } + _ => ResultMsg::DebugCommand(option), }; self.result_tx.send(msg).unwrap(); let notifier = self.notifier.lock(); - notifier.unwrap() - .as_mut() - .unwrap() - .new_frame_ready(); + notifier.unwrap().as_mut().unwrap().new_frame_ready(); } ApiMsg::ShutDown => { let notifier = self.notifier.lock(); - notifier.unwrap() - .as_mut() - .unwrap() - .shut_down(); + notifier.unwrap().as_mut().unwrap().shut_down(); break; } } } } - fn publish_frame(&mut self, - document_id: DocumentId, - frame: RendererFrame, - profile_counters: &mut BackendProfileCounters) { + fn publish_frame( + &mut self, + document_id: DocumentId, + frame: RendererFrame, + profile_counters: &mut BackendProfileCounters, + ) { let pending_update = self.resource_cache.pending_updates(); let msg = ResultMsg::NewFrame(document_id, frame, pending_update, profile_counters.clone()); self.result_tx.send(msg).unwrap(); profile_counters.reset(); } - fn publish_frame_and_notify_compositor(&mut self, - document_id: DocumentId, - frame: RendererFrame, - profile_counters: &mut BackendProfileCounters) { + fn publish_frame_and_notify_compositor( + &mut self, + document_id: DocumentId, + frame: RendererFrame, + profile_counters: &mut BackendProfileCounters, + ) { self.publish_frame(document_id, frame, profile_counters); // TODO(gw): This is kindof bogus to have to lock the notifier @@ -540,7 +570,12 @@ impl RenderBackend { // in initialization order for Servo. Perhaps find a // cleaner way to do this, or use the OnceMutex on crates.io? let mut notifier = self.notifier.lock(); - notifier.as_mut().unwrap().as_mut().unwrap().new_frame_ready(); + notifier + .as_mut() + .unwrap() + .as_mut() + .unwrap() + .new_frame_ready(); } fn notify_compositor_of_new_scroll_frame(&mut self, composite_needed: bool) { @@ -549,7 +584,12 @@ impl RenderBackend { // in initialization order for Servo. Perhaps find a // cleaner way to do this, or use the OnceMutex on crates.io? let mut notifier = self.notifier.lock(); - notifier.as_mut().unwrap().as_mut().unwrap().new_scroll_frame_ready(composite_needed); + notifier + .as_mut() + .unwrap() + .as_mut() + .unwrap() + .new_scroll_frame_ready(composite_needed); } @@ -559,9 +599,11 @@ impl RenderBackend { } #[cfg(feature = "debugger")] - fn traverse_items<'a>(&self, - traversal: &mut BuiltDisplayListIter<'a>, - node: &mut debug_server::TreeNode) { + fn traverse_items<'a>( + &self, + traversal: &mut BuiltDisplayListIter<'a>, + node: &mut debug_server::TreeNode, + ) { loop { let subtraversal = { let item = match traversal.next() { @@ -572,7 +614,8 @@ impl RenderBackend { match *item.item() { display_item @ SpecificDisplayItem::PushStackingContext(..) => { let mut subtraversal = item.sub_iter(); - let mut child_node = debug_server::TreeNode::new(&display_item.debug_string()); + let mut child_node = + debug_server::TreeNode::new(&display_item.debug_string()); self.traverse_items(&mut subtraversal, &mut child_node); node.add_child(child_node); Some(subtraversal) @@ -629,7 +672,9 @@ impl RenderBackend { // TODO(gw): Restructure the storage of clip-scroll tree, clip store // etc so this isn't so untidy. let clip_store = &doc.frame.frame_builder.as_ref().unwrap().clip_store; - doc.frame.clip_scroll_tree.print_with(clip_store, &mut builder); + doc.frame + .clip_scroll_tree + .print_with(clip_store, &mut builder); debug_root.add(builder.build()); } @@ -647,66 +692,26 @@ trait ToDebugString { impl ToDebugString for SpecificDisplayItem { fn debug_string(&self) -> String { match *self { - SpecificDisplayItem::Image(..) => { - String::from("image") - } - SpecificDisplayItem::YuvImage(..) => { - String::from("yuv_image") - } - SpecificDisplayItem::Text(..) => { - String::from("text") - } - SpecificDisplayItem::Rectangle(..) => { - String::from("rectangle") - } - SpecificDisplayItem::Line(..) => { - String::from("line") - } - SpecificDisplayItem::Gradient(..) => { - String::from("gradient") - } - SpecificDisplayItem::RadialGradient(..) => { - String::from("radial_gradient") - } - SpecificDisplayItem::BoxShadow(..) => { - String::from("box_shadow") - } - SpecificDisplayItem::Border(..) => { - String::from("border") - } - SpecificDisplayItem::PushStackingContext(..) => { - String::from("push_stacking_context") - } - SpecificDisplayItem::Iframe(..) => { - String::from("iframe") - } - SpecificDisplayItem::Clip(..) => { - String::from("clip") - } - SpecificDisplayItem::ScrollFrame(..) => { - String::from("scroll_frame") - } - SpecificDisplayItem::StickyFrame(..) => { - String::from("sticky_frame") - } - SpecificDisplayItem::PushNestedDisplayList => { - String::from("push_nested_display_list") - } - SpecificDisplayItem::PopNestedDisplayList => { - String::from("pop_nested_display_list") - } - SpecificDisplayItem::SetGradientStops => { - String::from("set_gradient_stops") - } - SpecificDisplayItem::PopStackingContext => { - String::from("pop_stacking_context") - } - SpecificDisplayItem::PushTextShadow(..) => { - String::from("push_text_shadow") - } - SpecificDisplayItem::PopTextShadow => { - String::from("pop_text_shadow") - } + SpecificDisplayItem::Image(..) => String::from("image"), + SpecificDisplayItem::YuvImage(..) => String::from("yuv_image"), + SpecificDisplayItem::Text(..) => String::from("text"), + SpecificDisplayItem::Rectangle(..) => String::from("rectangle"), + SpecificDisplayItem::Line(..) => String::from("line"), + SpecificDisplayItem::Gradient(..) => String::from("gradient"), + SpecificDisplayItem::RadialGradient(..) => String::from("radial_gradient"), + SpecificDisplayItem::BoxShadow(..) => String::from("box_shadow"), + SpecificDisplayItem::Border(..) => String::from("border"), + SpecificDisplayItem::PushStackingContext(..) => String::from("push_stacking_context"), + SpecificDisplayItem::Iframe(..) => String::from("iframe"), + SpecificDisplayItem::Clip(..) => String::from("clip"), + SpecificDisplayItem::ScrollFrame(..) => String::from("scroll_frame"), + SpecificDisplayItem::StickyFrame(..) => String::from("sticky_frame"), + SpecificDisplayItem::PushNestedDisplayList => String::from("push_nested_display_list"), + SpecificDisplayItem::PopNestedDisplayList => String::from("pop_nested_display_list"), + SpecificDisplayItem::SetGradientStops => String::from("set_gradient_stops"), + SpecificDisplayItem::PopStackingContext => String::from("pop_stacking_context"), + SpecificDisplayItem::PushTextShadow(..) => String::from("push_text_shadow"), + SpecificDisplayItem::PopTextShadow => String::from("pop_text_shadow"), } } } diff --git a/webrender/src/render_task.rs b/webrender/src/render_task.rs index 638f5281d3..6dca1d19fb 100644 --- a/webrender/src/render_task.rs +++ b/webrender/src/render_task.rs @@ -2,21 +2,21 @@ * 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 api::{ClipId, DeviceIntLength, DeviceIntPoint, DeviceIntRect, DeviceIntSize}; +use api::{FilterOp, MixBlendMode}; use api::PipelineId; use clip::{ClipSource, ClipSourcesWeakHandle, ClipStore}; use gpu_cache::GpuCacheHandle; use internal_types::HardwareCompositeOp; use prim_store::{BoxShadowPrimitiveCacheKey, PrimitiveIndex}; -use std::{cmp, f32, i32, usize}; +use std::{cmp, usize, f32, i32}; use tiling::{ClipScrollGroupIndex, PackedLayerIndex, RenderPass, RenderTargetIndex}; use tiling::{RenderTargetKind, StackingContextIndex}; -use api::{ClipId, DeviceIntLength, DeviceIntPoint, DeviceIntRect, DeviceIntSize}; -use api::{FilterOp, MixBlendMode}; const FLOATS_PER_RENDER_TASK_INFO: usize = 12; #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub struct RenderTaskId(pub u32); // TODO(gw): Make private when using GPU cache! +pub struct RenderTaskId(pub u32); // TODO(gw): Make private when using GPU cache! #[derive(Debug, Copy, Clone)] #[repr(C)] @@ -51,13 +51,16 @@ impl RenderTaskTree { } } - pub fn assign_to_passes(&self, id: RenderTaskId, pass_index: usize, passes: &mut Vec) { + pub fn assign_to_passes( + &self, + id: RenderTaskId, + pass_index: usize, + passes: &mut Vec, + ) { let task = &self.tasks[id.0 as usize]; for child in &task.children { - self.assign_to_passes(*child, - pass_index - 1, - passes); + self.assign_to_passes(*child, pass_index - 1, passes); } // Sanity check - can be relaxed if needed @@ -95,12 +98,8 @@ impl RenderTaskTree { pub fn get_task_address(&self, id: RenderTaskId) -> RenderTaskAddress { let task = &self.tasks[id.0 as usize]; match task.kind { - RenderTaskKind::Alias(alias_id) => { - RenderTaskAddress(alias_id.0) - } - _ => { - RenderTaskAddress(id.0) - } + RenderTaskKind::Alias(alias_id) => RenderTaskAddress(alias_id.0), + _ => RenderTaskAddress(id.0), } } @@ -129,9 +128,21 @@ pub enum RenderTaskLocation { pub enum AlphaRenderItem { Primitive(Option, PrimitiveIndex, i32), Blend(StackingContextIndex, RenderTaskId, FilterOp, i32), - Composite(StackingContextIndex, RenderTaskId, RenderTaskId, MixBlendMode, i32), + Composite( + StackingContextIndex, + RenderTaskId, + RenderTaskId, + MixBlendMode, + i32, + ), SplitComposite(StackingContextIndex, RenderTaskId, GpuCacheHandle, i32), - HardwareComposite(StackingContextIndex, RenderTaskId, HardwareCompositeOp, DeviceIntPoint, i32), + HardwareComposite( + StackingContextIndex, + RenderTaskId, + HardwareCompositeOp, + DeviceIntPoint, + i32, + ), } #[derive(Debug)] @@ -157,9 +168,9 @@ pub enum MaskSegment { #[derive(Debug, Copy, Clone)] #[repr(C)] pub enum MaskGeometryKind { - Default, // Draw the entire rect - CornersOnly, // Draw the corners (simple axis aligned mask) - // TODO(gw): Add more types here (e.g. 4 rectangles outside the inner rect) + Default, // Draw the entire rect + CornersOnly, // Draw the corners (simple axis aligned mask) + // TODO(gw): Add more types here (e.g. 4 rectangles outside the inner rect) } #[derive(Debug, Clone)] @@ -171,23 +182,21 @@ pub struct ClipWorkItem { impl ClipWorkItem { fn get_geometry_kind(&self, clip_store: &ClipStore) -> MaskGeometryKind { - let clips = clip_store.get_opt(&self.clip_sources) - .expect("bug: clip handle should be valid") - .clips(); + let clips = clip_store + .get_opt(&self.clip_sources) + .expect("bug: clip handle should be valid") + .clips(); let mut rounded_rect_count = 0; for &(ref clip, _) in clips { match *clip { - ClipSource::Rectangle(..) => { - if self.apply_rectangles { - return MaskGeometryKind::Default; - } - } + ClipSource::Rectangle(..) => if self.apply_rectangles { + return MaskGeometryKind::Default; + }, ClipSource::RoundedRectangle(..) => { rounded_rect_count += 1; } - ClipSource::Image(..) | - ClipSource::BorderCorner(..) => { + ClipSource::Image(..) | ClipSource::BorderCorner(..) => { return MaskGeometryKind::Default; } } @@ -235,9 +244,11 @@ pub struct RenderTask { } impl RenderTask { - pub fn new_alpha_batch(screen_origin: DeviceIntPoint, - location: RenderTaskLocation, - frame_output_pipeline_id: Option) -> RenderTask { + pub fn new_alpha_batch( + screen_origin: DeviceIntPoint, + location: RenderTaskLocation, + frame_output_pipeline_id: Option, + ) -> RenderTask { RenderTask { cache_key: None, children: Vec::new(), @@ -250,14 +261,15 @@ impl RenderTask { } } - pub fn new_dynamic_alpha_batch(rect: &DeviceIntRect, - frame_output_pipeline_id: Option) -> RenderTask { + pub fn new_dynamic_alpha_batch( + rect: &DeviceIntRect, + frame_output_pipeline_id: Option, + ) -> RenderTask { let location = RenderTaskLocation::Dynamic(None, rect.size); Self::new_alpha_batch(rect.origin, location, frame_output_pipeline_id) } - pub fn new_prim_cache(size: DeviceIntSize, - prim_index: PrimitiveIndex) -> RenderTask { + pub fn new_prim_cache(size: DeviceIntSize, prim_index: PrimitiveIndex) -> RenderTask { RenderTask { cache_key: None, children: Vec::new(), @@ -266,9 +278,11 @@ impl RenderTask { } } - pub fn new_box_shadow(key: BoxShadowPrimitiveCacheKey, - size: DeviceIntSize, - prim_index: PrimitiveIndex) -> RenderTask { + pub fn new_box_shadow( + key: BoxShadowPrimitiveCacheKey, + size: DeviceIntSize, + prim_index: PrimitiveIndex, + ) -> RenderTask { RenderTask { cache_key: Some(RenderTaskKey::BoxShadow(key)), children: Vec::new(), @@ -286,45 +300,50 @@ impl RenderTask { } } - pub fn new_mask(key: Option, - task_rect: DeviceIntRect, - raw_clips: &[ClipWorkItem], - extra_clip: Option, - prim_rect: DeviceIntRect, - clip_store: &ClipStore) - -> Option { + pub fn new_mask( + key: Option, + task_rect: DeviceIntRect, + raw_clips: &[ClipWorkItem], + extra_clip: Option, + prim_rect: DeviceIntRect, + clip_store: &ClipStore, + ) -> Option { // Filter out all the clip instances that don't contribute to the result let mut inner_rect = Some(task_rect); - let clips: Vec<_> = raw_clips.iter() - .chain(extra_clip.iter()) - .filter(|work_item| { - let clip_info = clip_store.get_opt(&work_item.clip_sources) - .expect("bug: clip item should exist"); - - // If this clip does not contribute to a mask, then ensure - // it gets filtered out here. Otherwise, if a mask is - // created (by a different clip in the list), the allocated - // rectangle for the mask could end up being much bigger - // than is actually required. - if !clip_info.is_masking() { - return false; - } - - match clip_info.bounds.inner { - Some(ref inner) if !inner.device_rect.is_empty() => { - inner_rect = inner_rect.and_then(|r| r.intersection(&inner.device_rect)); - !inner.device_rect.contains_rect(&task_rect) + let clips: Vec<_> = raw_clips + .iter() + .chain(extra_clip.iter()) + .filter(|work_item| { + let clip_info = clip_store + .get_opt(&work_item.clip_sources) + .expect("bug: clip item should exist"); + + // If this clip does not contribute to a mask, then ensure + // it gets filtered out here. Otherwise, if a mask is + // created (by a different clip in the list), the allocated + // rectangle for the mask could end up being much bigger + // than is actually required. + if !clip_info.is_masking() { + return false; } - _ => { - inner_rect = None; - true + + match clip_info.bounds.inner { + Some(ref inner) if !inner.device_rect.is_empty() => { + inner_rect = inner_rect.and_then(|r| r.intersection(&inner.device_rect)); + !inner.device_rect.contains_rect(&task_rect) + } + _ => { + inner_rect = None; + true + } } - } - }).cloned().collect(); + }) + .cloned() + .collect(); // Nothing to do, all clips are irrelevant for this case if clips.is_empty() { - return None + return None; } // TODO(gw): This optimization is very conservative for now. @@ -372,13 +391,14 @@ impl RenderTask { // | // +---- This is stored as the input task to the primitive shader. // - pub fn new_blur(blur_radius: DeviceIntLength, - src_task_id: RenderTaskId, - render_tasks: &mut RenderTaskTree) -> RenderTask { + pub fn new_blur( + blur_radius: DeviceIntLength, + src_task_id: RenderTaskId, + render_tasks: &mut RenderTaskTree, + ) -> RenderTask { let src_size = render_tasks.get(src_task_id).get_dynamic_size(); - let blur_target_size = src_size + DeviceIntSize::new(2 * blur_radius.0, - 2 * blur_radius.0); + let blur_target_size = src_size + DeviceIntSize::new(2 * blur_radius.0, 2 * blur_radius.0); let blur_task_v = RenderTask { cache_key: None, @@ -457,8 +477,7 @@ impl RenderTask { ], } } - RenderTaskKind::CachePrimitive(..) | - RenderTaskKind::BoxShadow(..) => { + RenderTaskKind::CachePrimitive(..) | RenderTaskKind::BoxShadow(..) => { let (target_rect, target_index) = self.get_target_rect(); RenderTaskData { data: [ @@ -513,7 +532,7 @@ impl RenderTask { 0.0, 0.0, 0.0, - ] + ], } } RenderTaskKind::Readback(..) => { @@ -532,35 +551,26 @@ impl RenderTask { 0.0, 0.0, 0.0, - ] - } - } - RenderTaskKind::Alias(..) => { - RenderTaskData { - data: [0.0; 12], + ], } } + RenderTaskKind::Alias(..) => RenderTaskData { data: [0.0; 12] }, } } pub fn get_dynamic_size(&self) -> DeviceIntSize { match self.location { - RenderTaskLocation::Fixed => { - DeviceIntSize::zero() - } - RenderTaskLocation::Dynamic(_, size) => { - size - } + RenderTaskLocation::Fixed => DeviceIntSize::zero(), + RenderTaskLocation::Dynamic(_, size) => size, } } pub fn get_target_rect(&self) -> (DeviceIntRect, RenderTargetIndex) { match self.location { - RenderTaskLocation::Fixed => { - (DeviceIntRect::zero(), RenderTargetIndex(0)) - } + RenderTaskLocation::Fixed => (DeviceIntRect::zero(), RenderTargetIndex(0)), RenderTaskLocation::Dynamic(origin_and_target_index, size) => { - let (origin, target_index) = origin_and_target_index.expect("Should have been allocated by now!"); + let (origin, target_index) = + origin_and_target_index.expect("Should have been allocated by now!"); (DeviceIntRect::new(origin, size), target_index) } } @@ -574,8 +584,9 @@ impl RenderTask { RenderTaskKind::Readback(..) | RenderTaskKind::HorizontalBlur(..) => RenderTargetKind::Color, - RenderTaskKind::CacheMask(..) | - RenderTaskKind::BoxShadow(..) => RenderTargetKind::Alpha, + RenderTaskKind::CacheMask(..) | RenderTaskKind::BoxShadow(..) => { + RenderTargetKind::Alpha + } RenderTaskKind::Alias(..) => { panic!("BUG: target_kind() called on invalidated task"); @@ -597,8 +608,7 @@ impl RenderTask { RenderTaskKind::Readback(..) | RenderTaskKind::HorizontalBlur(..) => false, - RenderTaskKind::CacheMask(..) | - RenderTaskKind::BoxShadow(..) => true, + RenderTaskKind::CacheMask(..) | RenderTaskKind::BoxShadow(..) => true, RenderTaskKind::Alias(..) => { panic!("BUG: is_shared() called on aliased task"); diff --git a/webrender/src/renderer.rs b/webrender/src/renderer.rs index 760fad5757..37414feba3 100644 --- a/webrender/src/renderer.rs +++ b/webrender/src/renderer.rs @@ -9,28 +9,39 @@ //! //! [renderer]: struct.Renderer.html +use api::{channel, BlobImageRenderer, FontRenderMode}; +use api::{ColorF, Epoch, PipelineId, RenderApiSender, RenderNotifier}; +use api::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DeviceUintRect, DeviceUintSize}; +use api::{ExternalImageId, ExternalImageType, ImageFormat}; +use api::{YUV_COLOR_SPACES, YUV_FORMATS}; +use api::{YuvColorSpace, YuvFormat}; #[cfg(not(feature = "debugger"))] use api::ApiMsg; +use api::DebugCommand; #[cfg(not(feature = "debugger"))] use api::channel::MsgSender; -use api::DebugCommand; use debug_colors; use debug_render::DebugRenderer; #[cfg(feature = "debugger")] use debug_server::{self, DebugServer}; -use device::{DepthFunction, Device, FrameId, Program, Texture, VertexDescriptor, GpuMarker, GpuProfiler, PBO}; -use device::{GpuTimer, TextureFilter, VAO, VertexUsageHint, FileWatcherHandler, TextureTarget, ShaderError}; -use device::{ExternalTexture, FBOId, get_gl_format_bgra, TextureSlot, VertexAttribute, VertexAttributeKind}; -use euclid::{Transform3D, rect}; +use device::{DepthFunction, Device, FrameId, GpuMarker, GpuProfiler, Program, Texture, + VertexDescriptor, PBO}; +use device::{get_gl_format_bgra, ExternalTexture, FBOId, TextureSlot, VertexAttribute, + VertexAttributeKind}; +use device::{FileWatcherHandler, GpuTimer, ShaderError, TextureFilter, TextureTarget, + VertexUsageHint, VAO}; +use euclid::{rect, Transform3D}; use frame_builder::FrameBuilderConfig; use gleam::gl; use gpu_cache::{GpuBlockData, GpuCacheUpdate, GpuCacheUpdateList}; -use gpu_types::{PrimitiveInstance}; -use internal_types::{FastHashMap, CacheTextureId, RendererFrame, ResultMsg, TextureUpdateOp}; -use internal_types::{DebugOutput, TextureUpdateList, RenderTargetMode, TextureUpdateSource}; -use internal_types::{BatchTextures, ORTHO_NEAR_PLANE, ORTHO_FAR_PLANE, SourceTexture}; -use profiler::{Profiler, BackendProfileCounters}; -use profiler::{GpuProfileTag, RendererProfileTimers, RendererProfileCounters}; +use gpu_types::PrimitiveInstance; +use internal_types::{BatchTextures, SourceTexture, ORTHO_FAR_PLANE, ORTHO_NEAR_PLANE}; +use internal_types::{CacheTextureId, FastHashMap, RendererFrame, ResultMsg, TextureUpdateOp}; +use internal_types::{DebugOutput, RenderTargetMode, TextureUpdateList, TextureUpdateSource}; +use profiler::{BackendProfileCounters, Profiler}; +use profiler::{GpuProfileTag, RendererProfileCounters, RendererProfileTimers}; +use rayon::Configuration as ThreadPoolConfig; +use rayon::ThreadPool; use record::ApiRecordingReceiver; use render_backend::RenderBackend; use render_task::RenderTaskTree; @@ -38,8 +49,8 @@ use render_task::RenderTaskTree; use serde_json; use std; use std::cmp; -use std::collections::hash_map::Entry; use std::collections::VecDeque; +use std::collections::hash_map::Entry; use std::f32; use std::mem; use std::path::PathBuf; @@ -48,49 +59,119 @@ use std::sync::{Arc, Mutex}; use std::sync::mpsc::{channel, Receiver, Sender}; use std::thread; use texture_cache::TextureCache; -use rayon::ThreadPool; -use rayon::Configuration as ThreadPoolConfig; -use tiling::{BatchKey, BatchKind, Frame, RenderTarget, TransformBatchKind}; +use thread_profiler::{register_thread_with_profiler, write_profile}; use tiling::{AlphaRenderTarget, ColorRenderTarget, RenderTargetKind}; +use tiling::{BatchKey, BatchKind, Frame, RenderTarget, TransformBatchKind}; use time::precise_time_ns; -use thread_profiler::{register_thread_with_profiler, write_profile}; use util::TransformedRectKind; -use api::{ColorF, Epoch, PipelineId, RenderApiSender, RenderNotifier}; -use api::{ExternalImageId, ExternalImageType, ImageFormat}; -use api::{DeviceIntRect, DeviceUintRect, DeviceIntPoint, DeviceIntSize, DeviceUintSize}; -use api::{BlobImageRenderer, channel, FontRenderMode}; -use api::{YuvColorSpace, YuvFormat}; -use api::{YUV_COLOR_SPACES, YUV_FORMATS}; pub const MAX_VERTEX_TEXTURE_WIDTH: usize = 1024; -const GPU_TAG_CACHE_BOX_SHADOW: GpuProfileTag = GpuProfileTag { label: "C_BoxShadow", color: debug_colors::BLACK }; -const GPU_TAG_CACHE_CLIP: GpuProfileTag = GpuProfileTag { label: "C_Clip", color: debug_colors::PURPLE }; -const GPU_TAG_CACHE_TEXT_RUN: GpuProfileTag = GpuProfileTag { label: "C_TextRun", color: debug_colors::MISTYROSE }; -const GPU_TAG_CACHE_LINE: GpuProfileTag = GpuProfileTag { label: "C_Line", color: debug_colors::BROWN }; -const GPU_TAG_SETUP_TARGET: GpuProfileTag = GpuProfileTag { label: "target", color: debug_colors::SLATEGREY }; -const GPU_TAG_SETUP_DATA: GpuProfileTag = GpuProfileTag { label: "data init", color: debug_colors::LIGHTGREY }; -const GPU_TAG_PRIM_RECT: GpuProfileTag = GpuProfileTag { label: "Rect", color: debug_colors::RED }; -const GPU_TAG_PRIM_LINE: GpuProfileTag = GpuProfileTag { label: "Line", color: debug_colors::DARKRED }; -const GPU_TAG_PRIM_IMAGE: GpuProfileTag = GpuProfileTag { label: "Image", color: debug_colors::GREEN }; -const GPU_TAG_PRIM_YUV_IMAGE: GpuProfileTag = GpuProfileTag { label: "YuvImage", color: debug_colors::DARKGREEN }; -const GPU_TAG_PRIM_BLEND: GpuProfileTag = GpuProfileTag { label: "Blend", color: debug_colors::LIGHTBLUE }; -const GPU_TAG_PRIM_HW_COMPOSITE: GpuProfileTag = GpuProfileTag { label: "HwComposite", color: debug_colors::DODGERBLUE }; -const GPU_TAG_PRIM_SPLIT_COMPOSITE: GpuProfileTag = GpuProfileTag { label: "SplitComposite", color: debug_colors::DARKBLUE }; -const GPU_TAG_PRIM_COMPOSITE: GpuProfileTag = GpuProfileTag { label: "Composite", color: debug_colors::MAGENTA }; -const GPU_TAG_PRIM_TEXT_RUN: GpuProfileTag = GpuProfileTag { label: "TextRun", color: debug_colors::BLUE }; -const GPU_TAG_PRIM_GRADIENT: GpuProfileTag = GpuProfileTag { label: "Gradient", color: debug_colors::YELLOW }; -const GPU_TAG_PRIM_ANGLE_GRADIENT: GpuProfileTag = GpuProfileTag { label: "AngleGradient", color: debug_colors::POWDERBLUE }; -const GPU_TAG_PRIM_RADIAL_GRADIENT: GpuProfileTag = GpuProfileTag { label: "RadialGradient", color: debug_colors::LIGHTPINK }; -const GPU_TAG_PRIM_BOX_SHADOW: GpuProfileTag = GpuProfileTag { label: "BoxShadow", color: debug_colors::CYAN }; -const GPU_TAG_PRIM_BORDER_CORNER: GpuProfileTag = GpuProfileTag { label: "BorderCorner", color: debug_colors::DARKSLATEGREY }; -const GPU_TAG_PRIM_BORDER_EDGE: GpuProfileTag = GpuProfileTag { label: "BorderEdge", color: debug_colors::LAVENDER }; -const GPU_TAG_PRIM_CACHE_IMAGE: GpuProfileTag = GpuProfileTag { label: "CacheImage", color: debug_colors::SILVER }; -const GPU_TAG_BLUR: GpuProfileTag = GpuProfileTag { label: "Blur", color: debug_colors::VIOLET }; - -const GPU_SAMPLER_TAG_ALPHA: GpuProfileTag = GpuProfileTag { label: "Alpha Targets", color: debug_colors::BLACK }; -const GPU_SAMPLER_TAG_OPAQUE: GpuProfileTag = GpuProfileTag { label: "Opaque Pass", color: debug_colors::BLACK }; -const GPU_SAMPLER_TAG_TRANSPARENT: GpuProfileTag = GpuProfileTag { label: "Transparent Pass", color: debug_colors::BLACK }; +const GPU_TAG_CACHE_BOX_SHADOW: GpuProfileTag = GpuProfileTag { + label: "C_BoxShadow", + color: debug_colors::BLACK, +}; +const GPU_TAG_CACHE_CLIP: GpuProfileTag = GpuProfileTag { + label: "C_Clip", + color: debug_colors::PURPLE, +}; +const GPU_TAG_CACHE_TEXT_RUN: GpuProfileTag = GpuProfileTag { + label: "C_TextRun", + color: debug_colors::MISTYROSE, +}; +const GPU_TAG_CACHE_LINE: GpuProfileTag = GpuProfileTag { + label: "C_Line", + color: debug_colors::BROWN, +}; +const GPU_TAG_SETUP_TARGET: GpuProfileTag = GpuProfileTag { + label: "target", + color: debug_colors::SLATEGREY, +}; +const GPU_TAG_SETUP_DATA: GpuProfileTag = GpuProfileTag { + label: "data init", + color: debug_colors::LIGHTGREY, +}; +const GPU_TAG_PRIM_RECT: GpuProfileTag = GpuProfileTag { + label: "Rect", + color: debug_colors::RED, +}; +const GPU_TAG_PRIM_LINE: GpuProfileTag = GpuProfileTag { + label: "Line", + color: debug_colors::DARKRED, +}; +const GPU_TAG_PRIM_IMAGE: GpuProfileTag = GpuProfileTag { + label: "Image", + color: debug_colors::GREEN, +}; +const GPU_TAG_PRIM_YUV_IMAGE: GpuProfileTag = GpuProfileTag { + label: "YuvImage", + color: debug_colors::DARKGREEN, +}; +const GPU_TAG_PRIM_BLEND: GpuProfileTag = GpuProfileTag { + label: "Blend", + color: debug_colors::LIGHTBLUE, +}; +const GPU_TAG_PRIM_HW_COMPOSITE: GpuProfileTag = GpuProfileTag { + label: "HwComposite", + color: debug_colors::DODGERBLUE, +}; +const GPU_TAG_PRIM_SPLIT_COMPOSITE: GpuProfileTag = GpuProfileTag { + label: "SplitComposite", + color: debug_colors::DARKBLUE, +}; +const GPU_TAG_PRIM_COMPOSITE: GpuProfileTag = GpuProfileTag { + label: "Composite", + color: debug_colors::MAGENTA, +}; +const GPU_TAG_PRIM_TEXT_RUN: GpuProfileTag = GpuProfileTag { + label: "TextRun", + color: debug_colors::BLUE, +}; +const GPU_TAG_PRIM_GRADIENT: GpuProfileTag = GpuProfileTag { + label: "Gradient", + color: debug_colors::YELLOW, +}; +const GPU_TAG_PRIM_ANGLE_GRADIENT: GpuProfileTag = GpuProfileTag { + label: "AngleGradient", + color: debug_colors::POWDERBLUE, +}; +const GPU_TAG_PRIM_RADIAL_GRADIENT: GpuProfileTag = GpuProfileTag { + label: "RadialGradient", + color: debug_colors::LIGHTPINK, +}; +const GPU_TAG_PRIM_BOX_SHADOW: GpuProfileTag = GpuProfileTag { + label: "BoxShadow", + color: debug_colors::CYAN, +}; +const GPU_TAG_PRIM_BORDER_CORNER: GpuProfileTag = GpuProfileTag { + label: "BorderCorner", + color: debug_colors::DARKSLATEGREY, +}; +const GPU_TAG_PRIM_BORDER_EDGE: GpuProfileTag = GpuProfileTag { + label: "BorderEdge", + color: debug_colors::LAVENDER, +}; +const GPU_TAG_PRIM_CACHE_IMAGE: GpuProfileTag = GpuProfileTag { + label: "CacheImage", + color: debug_colors::SILVER, +}; +const GPU_TAG_BLUR: GpuProfileTag = GpuProfileTag { + label: "Blur", + color: debug_colors::VIOLET, +}; + +const GPU_SAMPLER_TAG_ALPHA: GpuProfileTag = GpuProfileTag { + label: "Alpha Targets", + color: debug_colors::BLACK, +}; +const GPU_SAMPLER_TAG_OPAQUE: GpuProfileTag = GpuProfileTag { + label: "Opaque Pass", + color: debug_colors::BLACK, +}; +const GPU_SAMPLER_TAG_TRANSPARENT: GpuProfileTag = GpuProfileTag { + label: "Transparent Pass", + color: debug_colors::BLACK, +}; #[cfg(feature = "debugger")] impl BatchKind { @@ -100,29 +181,25 @@ impl BatchKind { BatchKind::HardwareComposite => "HardwareComposite", BatchKind::SplitComposite => "SplitComposite", BatchKind::Blend => "Blend", - BatchKind::Transformable(_, kind) => { - match kind { - TransformBatchKind::Rectangle(..) => "Rectangle", - TransformBatchKind::TextRun => "TextRun", - TransformBatchKind::Image(image_buffer_kind, ..) => { - match image_buffer_kind { - ImageBufferKind::Texture2D => "Image (2D)", - ImageBufferKind::TextureRect => "Image (Rect)", - ImageBufferKind::TextureExternal => "Image (External)", - ImageBufferKind::Texture2DArray => "Image (Array)", - } - }, - TransformBatchKind::YuvImage(..) => "YuvImage", - TransformBatchKind::AlignedGradient => "AlignedGradient", - TransformBatchKind::AngleGradient => "AngleGradient", - TransformBatchKind::RadialGradient => "RadialGradient", - TransformBatchKind::BoxShadow => "BoxShadow", - TransformBatchKind::CacheImage => "CacheImage", - TransformBatchKind::BorderCorner => "BorderCorner", - TransformBatchKind::BorderEdge => "BorderEdge", - TransformBatchKind::Line => "Line", - } - } + BatchKind::Transformable(_, kind) => match kind { + TransformBatchKind::Rectangle(..) => "Rectangle", + TransformBatchKind::TextRun => "TextRun", + TransformBatchKind::Image(image_buffer_kind, ..) => match image_buffer_kind { + ImageBufferKind::Texture2D => "Image (2D)", + ImageBufferKind::TextureRect => "Image (Rect)", + ImageBufferKind::TextureExternal => "Image (External)", + ImageBufferKind::Texture2DArray => "Image (Array)", + }, + TransformBatchKind::YuvImage(..) => "YuvImage", + TransformBatchKind::AlignedGradient => "AlignedGradient", + TransformBatchKind::AngleGradient => "AngleGradient", + TransformBatchKind::RadialGradient => "RadialGradient", + TransformBatchKind::BoxShadow => "BoxShadow", + TransformBatchKind::CacheImage => "CacheImage", + TransformBatchKind::BorderCorner => "BorderCorner", + TransformBatchKind::BorderEdge => "BorderEdge", + TransformBatchKind::Line => "Line", + }, } } } @@ -192,45 +269,105 @@ pub struct PackedVertex { const DESC_PRIM_INSTANCES: VertexDescriptor = VertexDescriptor { vertex_attributes: &[ - VertexAttribute { name: "aPosition", count: 2, kind: VertexAttributeKind::F32 }, + VertexAttribute { + name: "aPosition", + count: 2, + kind: VertexAttributeKind::F32, + }, ], instance_attributes: &[ - VertexAttribute { name: "aData0", count: 4, kind: VertexAttributeKind::I32 }, - VertexAttribute { name: "aData1", count: 4, kind: VertexAttributeKind::I32 }, - ] + VertexAttribute { + name: "aData0", + count: 4, + kind: VertexAttributeKind::I32, + }, + VertexAttribute { + name: "aData1", + count: 4, + kind: VertexAttributeKind::I32, + }, + ], }; const DESC_BLUR: VertexDescriptor = VertexDescriptor { vertex_attributes: &[ - VertexAttribute { name: "aPosition", count: 2, kind: VertexAttributeKind::F32 }, + VertexAttribute { + name: "aPosition", + count: 2, + kind: VertexAttributeKind::F32, + }, ], instance_attributes: &[ - VertexAttribute { name: "aBlurRenderTaskAddress", count: 1, kind: VertexAttributeKind::I32 }, - VertexAttribute { name: "aBlurSourceTaskAddress", count: 1, kind: VertexAttributeKind::I32 }, - VertexAttribute { name: "aBlurDirection", count: 1, kind: VertexAttributeKind::I32 }, - ] + VertexAttribute { + name: "aBlurRenderTaskAddress", + count: 1, + kind: VertexAttributeKind::I32, + }, + VertexAttribute { + name: "aBlurSourceTaskAddress", + count: 1, + kind: VertexAttributeKind::I32, + }, + VertexAttribute { + name: "aBlurDirection", + count: 1, + kind: VertexAttributeKind::I32, + }, + ], }; const DESC_CLIP: VertexDescriptor = VertexDescriptor { vertex_attributes: &[ - VertexAttribute { name: "aPosition", count: 2, kind: VertexAttributeKind::F32 }, + VertexAttribute { + name: "aPosition", + count: 2, + kind: VertexAttributeKind::F32, + }, ], instance_attributes: &[ - VertexAttribute { name: "aClipRenderTaskAddress", count: 1, kind: VertexAttributeKind::I32 }, - VertexAttribute { name: "aClipLayerAddress", count: 1, kind: VertexAttributeKind::I32 }, - VertexAttribute { name: "aClipSegment", count: 1, kind: VertexAttributeKind::I32 }, - VertexAttribute { name: "aClipDataResourceAddress", count: 4, kind: VertexAttributeKind::U16 }, - ] + VertexAttribute { + name: "aClipRenderTaskAddress", + count: 1, + kind: VertexAttributeKind::I32, + }, + VertexAttribute { + name: "aClipLayerAddress", + count: 1, + kind: VertexAttributeKind::I32, + }, + VertexAttribute { + name: "aClipSegment", + count: 1, + kind: VertexAttributeKind::I32, + }, + VertexAttribute { + name: "aClipDataResourceAddress", + count: 4, + kind: VertexAttributeKind::U16, + }, + ], }; const DESC_CACHE_BOX_SHADOW: VertexDescriptor = VertexDescriptor { vertex_attributes: &[ - VertexAttribute { name: "aPosition", count: 2, kind: VertexAttributeKind::F32 }, + VertexAttribute { + name: "aPosition", + count: 2, + kind: VertexAttributeKind::F32, + }, ], instance_attributes: &[ - VertexAttribute { name: "aPrimAddress", count: 2, kind: VertexAttributeKind::U16 }, - VertexAttribute { name: "aTaskIndex", count: 1, kind: VertexAttributeKind::I32 }, - ] + VertexAttribute { + name: "aPrimAddress", + count: 2, + kind: VertexAttributeKind::U16, + }, + VertexAttribute { + name: "aTaskIndex", + count: 1, + kind: VertexAttributeKind::I32, + }, + ], }; #[derive(Debug, Copy, Clone)] @@ -281,22 +418,18 @@ impl ImageBufferKind { pub fn has_platform_support(&self, gl_type: &gl::GlType) -> bool { match *gl_type { - gl::GlType::Gles => { - match *self { - ImageBufferKind::Texture2D => true, - ImageBufferKind::Texture2DArray => true, - ImageBufferKind::TextureRect => true, - ImageBufferKind::TextureExternal => true, - } - } - gl::GlType::Gl => { - match *self { - ImageBufferKind::Texture2D => true, - ImageBufferKind::Texture2DArray => true, - ImageBufferKind::TextureRect => true, - ImageBufferKind::TextureExternal => false, - } - } + gl::GlType::Gles => match *self { + ImageBufferKind::Texture2D => true, + ImageBufferKind::Texture2DArray => true, + ImageBufferKind::TextureRect => true, + ImageBufferKind::TextureExternal => true, + }, + gl::GlType::Gl => match *self { + ImageBufferKind::Texture2D => true, + ImageBufferKind::Texture2DArray => true, + ImageBufferKind::TextureRect => true, + ImageBufferKind::TextureExternal => false, + }, } } } @@ -335,10 +468,12 @@ pub struct CpuProfile { } impl CpuProfile { - fn new(frame_id: FrameId, - backend_time_ns: u64, - composite_time_ns: u64, - draw_calls: usize) -> CpuProfile { + fn new( + frame_id: FrameId, + backend_time_ns: u64, + composite_time_ns: u64, + draw_calls: usize, + ) -> CpuProfile { CpuProfile { frame_id, backend_time_ns, @@ -375,14 +510,16 @@ struct SourceTextureResolver { impl SourceTextureResolver { fn new(device: &mut Device) -> SourceTextureResolver { let mut dummy_cache_texture = device.create_texture(TextureTarget::Array); - device.init_texture(&mut dummy_cache_texture, - 1, - 1, - ImageFormat::BGRA8, - TextureFilter::Linear, - RenderTargetMode::RenderTarget, - 1, - None); + device.init_texture( + &mut dummy_cache_texture, + 1, + 1, + ImageFormat::BGRA8, + TextureFilter::Linear, + RenderTargetMode::RenderTarget, + 1, + None, + ); SourceTextureResolver { cache_texture_map: Vec::new(), @@ -401,18 +538,20 @@ impl SourceTextureResolver { } } - fn end_pass(&mut self, - pass_index: usize, - pass_count: usize, - mut a8_texture: Option, - mut rgba8_texture: Option, - a8_pool: &mut Vec, - rgba8_pool: &mut Vec) { + fn end_pass( + &mut self, + pass_index: usize, + pass_count: usize, + mut a8_texture: Option, + mut rgba8_texture: Option, + a8_pool: &mut Vec, + rgba8_pool: &mut Vec, + ) { // If we have cache textures from previous pass, return them to the pool. rgba8_pool.extend(self.cache_rgba8_texture.take()); a8_pool.extend(self.cache_a8_texture.take()); - if pass_index == pass_count-1 { + if pass_index == pass_count - 1 { // On the last pass, return the textures from this pass to the pool. if let Some(texture) = rgba8_texture.take() { rgba8_pool.push(texture); @@ -429,24 +568,25 @@ impl SourceTextureResolver { } // Bind a source texture to the device. - fn bind(&self, - texture_id: &SourceTexture, - sampler: TextureSampler, - device: &mut Device) { + fn bind(&self, texture_id: &SourceTexture, sampler: TextureSampler, device: &mut Device) { match *texture_id { SourceTexture::Invalid => {} SourceTexture::CacheA8 => { - let texture = self.cache_a8_texture.as_ref().unwrap_or(&self.dummy_cache_texture); + let texture = self.cache_a8_texture + .as_ref() + .unwrap_or(&self.dummy_cache_texture); device.bind_texture(sampler, texture); } SourceTexture::CacheRGBA8 => { - let texture = self.cache_rgba8_texture.as_ref().unwrap_or(&self.dummy_cache_texture); + let texture = self.cache_rgba8_texture + .as_ref() + .unwrap_or(&self.dummy_cache_texture); device.bind_texture(sampler, texture); } SourceTexture::External(external_image) => { let texture = self.external_images - .get(&(external_image.id, external_image.channel_index)) - .expect("BUG: External image should be resolved by now!"); + .get(&(external_image.id, external_image.channel_index)) + .expect("BUG: External image should be resolved by now!"); device.bind_external_texture(sampler, texture); } SourceTexture::TextureCache(index) => { @@ -461,21 +601,21 @@ impl SourceTextureResolver { // map for fast access. fn resolve(&self, texture_id: &SourceTexture) -> Option<&Texture> { match *texture_id { - SourceTexture::Invalid => { - None - } - SourceTexture::CacheA8 => { - Some(self.cache_a8_texture.as_ref().unwrap_or(&self.dummy_cache_texture)) - } - SourceTexture::CacheRGBA8 => { - Some(self.cache_rgba8_texture.as_ref().unwrap_or(&self.dummy_cache_texture)) - } + SourceTexture::Invalid => None, + SourceTexture::CacheA8 => Some( + self.cache_a8_texture + .as_ref() + .unwrap_or(&self.dummy_cache_texture), + ), + SourceTexture::CacheRGBA8 => Some( + self.cache_rgba8_texture + .as_ref() + .unwrap_or(&self.dummy_cache_texture), + ), SourceTexture::External(..) => { panic!("BUG: External textures cannot be resolved, they can only be bound."); } - SourceTexture::TextureCache(index) => { - Some(&self.cache_texture_map[index.0]) - } + SourceTexture::TextureCache(index) => Some(&self.cache_texture_map[index.0]), } } } @@ -497,9 +637,7 @@ struct CacheRow { impl CacheRow { fn new() -> CacheRow { - CacheRow { - is_dirty: false, - } + CacheRow { is_dirty: false } } } @@ -529,11 +667,13 @@ impl CacheTexture { device.delete_texture(self.texture); } - fn apply_patch(&mut self, - update: &GpuCacheUpdate, - blocks: &[GpuBlockData]) { + fn apply_patch(&mut self, update: &GpuCacheUpdate, blocks: &[GpuBlockData]) { match update { - &GpuCacheUpdate::Copy { block_index, block_count, address } => { + &GpuCacheUpdate::Copy { + block_index, + block_count, + address, + } => { let row = address.v as usize; // Ensure that the CPU-side shadow copy of the GPU cache data has enough @@ -542,7 +682,8 @@ impl CacheTexture { // Add a new row. self.rows.push(CacheRow::new()); // Add enough GPU blocks for this row. - self.cpu_blocks.extend_from_slice(&[GpuBlockData::empty(); MAX_VERTEX_TEXTURE_WIDTH]); + self.cpu_blocks + .extend_from_slice(&[GpuBlockData::empty(); MAX_VERTEX_TEXTURE_WIDTH]); } // This row is dirty (needs to be updated in GPU texture). @@ -550,8 +691,8 @@ impl CacheTexture { // Copy the blocks from the patch array in the shadow CPU copy. let block_offset = row * MAX_VERTEX_TEXTURE_WIDTH + address.u as usize; - let data = &mut self.cpu_blocks[block_offset..(block_offset + block_count)]; - for i in 0..block_count { + let data = &mut self.cpu_blocks[block_offset .. (block_offset + block_count)]; + for i in 0 .. block_count { data[i] = blocks[block_index + i]; } } @@ -564,14 +705,16 @@ impl CacheTexture { if updates.height > current_dimensions.height { // Create a f32 texture that can be used for the vertex shader // to fetch data from. - device.init_texture(&mut self.texture, - MAX_VERTEX_TEXTURE_WIDTH as u32, - updates.height as u32, - ImageFormat::RGBAF32, - TextureFilter::Nearest, - RenderTargetMode::None, - 1, - None); + device.init_texture( + &mut self.texture, + MAX_VERTEX_TEXTURE_WIDTH as u32, + updates.height as u32, + ImageFormat::RGBAF32, + TextureFilter::Nearest, + RenderTargetMode::None, + 1, + None, + ); // Copy the current texture into the newly resized texture. if current_dimensions.height > 0 { @@ -598,19 +741,22 @@ impl CacheTexture { if row.is_dirty { // Get the data for this row and push to the PBO. let block_index = row_index * MAX_VERTEX_TEXTURE_WIDTH; - let cpu_blocks = &self.cpu_blocks[block_index..(block_index + MAX_VERTEX_TEXTURE_WIDTH)]; + let cpu_blocks = + &self.cpu_blocks[block_index .. (block_index + MAX_VERTEX_TEXTURE_WIDTH)]; device.update_pbo_data(cpu_blocks); // Insert a command to copy the PBO data to the right place in // the GPU-side cache texture. - device.update_texture_from_pbo(&self.texture, - 0, - row_index as u32, - MAX_VERTEX_TEXTURE_WIDTH as u32, - 1, - 0, - None, - 0); + device.update_texture_from_pbo( + &self.texture, + 0, + row_index as u32, + MAX_VERTEX_TEXTURE_WIDTH as u32, + 1, + 0, + None, + 0, + ); // Orphan the PBO. This is the recommended way to hint to the // driver to detach the underlying storage from this PBO id. @@ -637,15 +783,10 @@ impl VertexDataTexture { let texture = device.create_texture(TextureTarget::Default); let pbo = device.create_pbo(); - VertexDataTexture { - texture, - pbo, - } + VertexDataTexture { texture, pbo } } - fn update(&mut self, - device: &mut Device, - data: &mut Vec) { + fn update(&mut self, device: &mut Device, data: &mut Vec) { if data.is_empty() { return; } @@ -663,7 +804,8 @@ impl VertexDataTexture { } } - let width = (MAX_VERTEX_TEXTURE_WIDTH - (MAX_VERTEX_TEXTURE_WIDTH % texels_per_item)) as u32; + let width = + (MAX_VERTEX_TEXTURE_WIDTH - (MAX_VERTEX_TEXTURE_WIDTH % texels_per_item)) as u32; let needed_height = (data.len() / items_per_row) as u32; // Determine if the texture needs to be resized. @@ -672,28 +814,23 @@ impl VertexDataTexture { if needed_height > texture_size.height { let new_height = (needed_height + 127) & !127; - device.init_texture(&mut self.texture, - width, - new_height, - ImageFormat::RGBAF32, - TextureFilter::Nearest, - RenderTargetMode::None, - 1, - None); + device.init_texture( + &mut self.texture, + width, + new_height, + ImageFormat::RGBAF32, + TextureFilter::Nearest, + RenderTargetMode::None, + 1, + None, + ); } // Bind a PBO to do the texture upload. // Updating the texture via PBO avoids CPU-side driver stalls. device.bind_pbo(Some(&self.pbo)); device.update_pbo_data(data); - device.update_texture_from_pbo(&self.texture, - 0, - 0, - width, - needed_height, - 0, - None, - 0); + device.update_texture_from_pbo(&self.texture, 0, 0, width, needed_height, 0, None, 0); // Ensure that other texture updates won't read from this PBO. device.bind_pbo(None); @@ -723,11 +860,13 @@ struct LazilyCompiledShader { } impl LazilyCompiledShader { - fn new(kind: ShaderKind, - name: &'static str, - features: &[&'static str], - device: &mut Device, - precache: bool) -> Result { + fn new( + kind: ShaderKind, + name: &'static str, + features: &[&'static str], + device: &mut Device, + precache: bool, + ) -> Result { let mut shader = LazilyCompiledShader { program: None, name, @@ -742,7 +881,12 @@ impl LazilyCompiledShader { Ok(shader) } - fn bind(&mut self, device: &mut Device, projection: &Transform3D, renderer_errors: &mut Vec) { + fn bind( + &mut self, + device: &mut Device, + projection: &Transform3D, + renderer_errors: &mut Vec, + ) { let program = match self.get(device) { Ok(program) => program, Err(e) => { @@ -802,15 +946,22 @@ impl FileWatcherHandler for FileWatcher { fn file_changed(&self, path: PathBuf) { self.result_tx.send(ResultMsg::RefreshShader(path)).ok(); let mut notifier = self.notifier.lock(); - notifier.as_mut().unwrap().as_mut().unwrap().new_frame_ready(); + notifier + .as_mut() + .unwrap() + .as_mut() + .unwrap() + .new_frame_ready(); } } impl PrimitiveShader { - fn new(name: &'static str, - device: &mut Device, - features: &[&'static str], - precache: bool) -> Result { + fn new( + name: &'static str, + device: &mut Device, + features: &[&'static str], + precache: bool, + ) -> Result { let simple = try!{ LazilyCompiledShader::new(ShaderKind::Primitive, name, @@ -830,20 +981,23 @@ impl PrimitiveShader { precache) }; - Ok(PrimitiveShader { - simple, - transform, - }) + Ok(PrimitiveShader { simple, transform }) } - fn bind(&mut self, - device: &mut Device, - transform_kind: TransformedRectKind, - projection: &Transform3D, - renderer_errors: &mut Vec) { + fn bind( + &mut self, + device: &mut Device, + transform_kind: TransformedRectKind, + projection: &Transform3D, + renderer_errors: &mut Vec, + ) { match transform_kind { - TransformedRectKind::AxisAligned => self.simple.bind(device, projection, renderer_errors), - TransformedRectKind::Complex => self.transform.bind(device, projection, renderer_errors), + TransformedRectKind::AxisAligned => { + self.simple.bind(device, projection, renderer_errors) + } + TransformedRectKind::Complex => { + self.transform.bind(device, projection, renderer_errors) + } } } @@ -853,12 +1007,16 @@ impl PrimitiveShader { } } -fn create_prim_shader(name: &'static str, - device: &mut Device, - features: &[&'static str], - vertex_format: VertexArrayKind) -> Result { - let mut prefix = format!("#define WR_MAX_VERTEX_TEXTURE_WIDTH {}\n", - MAX_VERTEX_TEXTURE_WIDTH); +fn create_prim_shader( + name: &'static str, + device: &mut Device, + features: &[&'static str], + vertex_format: VertexArrayKind, +) -> Result { + let mut prefix = format!( + "#define WR_MAX_VERTEX_TEXTURE_WIDTH {}\n", + MAX_VERTEX_TEXTURE_WIDTH + ); for feature in features { prefix.push_str(&format!("#define WR_FEATURE_{}\n", feature)); @@ -873,45 +1031,51 @@ fn create_prim_shader(name: &'static str, VertexArrayKind::CacheBoxShadow => DESC_CACHE_BOX_SHADOW, }; - let program = device.create_program(name, - &prefix, - &vertex_descriptor); + let program = device.create_program(name, &prefix, &vertex_descriptor); if let Ok(ref program) = program { - device.bind_shader_samplers(program, &[ - ("sColor0", TextureSampler::Color0), - ("sColor1", TextureSampler::Color1), - ("sColor2", TextureSampler::Color2), - ("sDither", TextureSampler::Dither), - ("sCacheA8", TextureSampler::CacheA8), - ("sCacheRGBA8", TextureSampler::CacheRGBA8), - ("sLayers", TextureSampler::Layers), - ("sRenderTasks", TextureSampler::RenderTasks), - ("sResourceCache", TextureSampler::ResourceCache), - ("sSharedCacheA8", TextureSampler::SharedCacheA8), - ]); + device.bind_shader_samplers( + program, + &[ + ("sColor0", TextureSampler::Color0), + ("sColor1", TextureSampler::Color1), + ("sColor2", TextureSampler::Color2), + ("sDither", TextureSampler::Dither), + ("sCacheA8", TextureSampler::CacheA8), + ("sCacheRGBA8", TextureSampler::CacheRGBA8), + ("sLayers", TextureSampler::Layers), + ("sRenderTasks", TextureSampler::RenderTasks), + ("sResourceCache", TextureSampler::ResourceCache), + ("sSharedCacheA8", TextureSampler::SharedCacheA8), + ], + ); } program } fn create_clip_shader(name: &'static str, device: &mut Device) -> Result { - let prefix = format!("#define WR_MAX_VERTEX_TEXTURE_WIDTH {}\n + let prefix = format!( + "#define WR_MAX_VERTEX_TEXTURE_WIDTH {}\n #define WR_FEATURE_TRANSFORM\n", - MAX_VERTEX_TEXTURE_WIDTH); + MAX_VERTEX_TEXTURE_WIDTH + ); debug!("ClipShader {}", name); let program = device.create_program(name, &prefix, &DESC_CLIP); if let Ok(ref program) = program { - device.bind_shader_samplers(program, &[ - ("sColor0", TextureSampler::Color0), - ("sLayers", TextureSampler::Layers), - ("sRenderTasks", TextureSampler::RenderTasks), - ("sResourceCache", TextureSampler::ResourceCache), - ("sSharedCacheA8", TextureSampler::SharedCacheA8), - ]); + device.bind_shader_samplers( + program, + &[ + ("sColor0", TextureSampler::Color0), + ("sLayers", TextureSampler::Layers), + ("sRenderTasks", TextureSampler::RenderTasks), + ("sResourceCache", TextureSampler::ResourceCache), + ("sSharedCacheA8", TextureSampler::SharedCacheA8), + ], + ); } program @@ -1048,11 +1212,15 @@ pub enum RendererError { } impl From for RendererError { - fn from(err: ShaderError) -> Self { RendererError::Shader(err) } + fn from(err: ShaderError) -> Self { + RendererError::Shader(err) + } } impl From for RendererError { - fn from(err: std::io::Error) -> Self { RendererError::Thread(err) } + fn from(err: std::io::Error) -> Self { + RendererError::Thread(err) + } } impl Renderer { @@ -1073,8 +1241,10 @@ impl Renderer { /// let (renderer, sender) = Renderer::new(opts); /// ``` /// [rendereroptions]: struct.RendererOptions.html - pub fn new(gl: Rc, mut options: RendererOptions) -> Result<(Renderer, RenderApiSender), RendererError> { - + pub fn new( + gl: Rc, + mut options: RendererOptions, + ) -> Result<(Renderer, RenderApiSender), RendererError> { let (api_tx, api_rx) = try!{ channel::msg_channel() }; let (payload_tx, payload_rx) = try!{ channel::payload_channel() }; let (result_tx, result_rx) = channel(); @@ -1091,7 +1261,7 @@ impl Renderer { let mut device = Device::new( gl, options.resource_override_path.clone(), - Box::new(file_watch_handler) + Box::new(file_watch_handler), ); let device_max_size = device.max_texture_size(); @@ -1100,12 +1270,18 @@ impl Renderer { // gracefully fail now than panic as soon as a texture is allocated. let min_texture_size = 512; if device_max_size < min_texture_size { - println!("Device reporting insufficient max texture size ({})", device_max_size); + println!( + "Device reporting insufficient max texture size ({})", + device_max_size + ); return Err(RendererError::MaxTextureSize); } let max_device_size = cmp::max( - cmp::min(device_max_size, options.max_texture_size.unwrap_or(device_max_size)), - min_texture_size + cmp::min( + device_max_size, + options.max_texture_size.unwrap_or(device_max_size), + ), + min_texture_size, ); register_thread_with_profiler("Compositor".to_owned()); @@ -1208,10 +1384,10 @@ impl Renderer { let mut image_features = Vec::new(); let mut ps_image: Vec> = Vec::new(); // PrimitiveShader is not clonable. Use push() to initialize the vec. - for _ in 0..IMAGE_BUFFER_KINDS.len() { + for _ in 0 .. IMAGE_BUFFER_KINDS.len() { ps_image.push(None); } - for buffer_kind in 0..IMAGE_BUFFER_KINDS.len() { + for buffer_kind in 0 .. IMAGE_BUFFER_KINDS.len() { if IMAGE_BUFFER_KINDS[buffer_kind].has_platform_support(&gl_type) { let feature_string = IMAGE_BUFFER_KINDS[buffer_kind].get_feature_string(); if feature_string != "" { @@ -1230,18 +1406,16 @@ impl Renderer { // All yuv_image configuration. let mut yuv_features = Vec::new(); - let yuv_shader_num = IMAGE_BUFFER_KINDS.len() * - YUV_FORMATS.len() * - YUV_COLOR_SPACES.len(); + let yuv_shader_num = IMAGE_BUFFER_KINDS.len() * YUV_FORMATS.len() * YUV_COLOR_SPACES.len(); let mut ps_yuv_image: Vec> = Vec::new(); // PrimitiveShader is not clonable. Use push() to initialize the vec. - for _ in 0..yuv_shader_num { + for _ in 0 .. yuv_shader_num { ps_yuv_image.push(None); } - for buffer_kind in 0..IMAGE_BUFFER_KINDS.len() { + for buffer_kind in 0 .. IMAGE_BUFFER_KINDS.len() { if IMAGE_BUFFER_KINDS[buffer_kind].has_platform_support(&gl_type) { - for format_kind in 0..YUV_FORMATS.len() { - for color_space_kind in 0..YUV_COLOR_SPACES.len() { + for format_kind in 0 .. YUV_FORMATS.len() { + for color_space_kind in 0 .. YUV_COLOR_SPACES.len() { let feature_string = IMAGE_BUFFER_KINDS[buffer_kind].get_feature_string(); if feature_string != "" { yuv_features.push(feature_string); @@ -1250,7 +1424,8 @@ impl Renderer { if feature_string != "" { yuv_features.push(feature_string); } - let feature_string = YUV_COLOR_SPACES[color_space_kind].get_feature_string(); + let feature_string = + YUV_COLOR_SPACES[color_space_kind].get_feature_string(); if feature_string != "" { yuv_features.push(feature_string); } @@ -1261,9 +1436,11 @@ impl Renderer { &yuv_features, options.precache_shaders) }; - let index = Renderer::get_yuv_shader_index(IMAGE_BUFFER_KINDS[buffer_kind], - YUV_FORMATS[format_kind], - YUV_COLOR_SPACES[color_space_kind]); + let index = Renderer::get_yuv_shader_index( + IMAGE_BUFFER_KINDS[buffer_kind], + YUV_FORMATS[format_kind], + YUV_COLOR_SPACES[color_space_kind], + ); ps_yuv_image[index] = Some(shader); yuv_features.clear(); } @@ -1373,25 +1550,83 @@ impl Renderer { let dither_matrix_texture = if options.enable_dithering { let dither_matrix: [u8; 64] = [ - 00, 48, 12, 60, 03, 51, 15, 63, - 32, 16, 44, 28, 35, 19, 47, 31, - 08, 56, 04, 52, 11, 59, 07, 55, - 40, 24, 36, 20, 43, 27, 39, 23, - 02, 50, 14, 62, 01, 49, 13, 61, - 34, 18, 46, 30, 33, 17, 45, 29, - 10, 58, 06, 54, 09, 57, 05, 53, - 42, 26, 38, 22, 41, 25, 37, 21 + 00, + 48, + 12, + 60, + 03, + 51, + 15, + 63, + 32, + 16, + 44, + 28, + 35, + 19, + 47, + 31, + 08, + 56, + 04, + 52, + 11, + 59, + 07, + 55, + 40, + 24, + 36, + 20, + 43, + 27, + 39, + 23, + 02, + 50, + 14, + 62, + 01, + 49, + 13, + 61, + 34, + 18, + 46, + 30, + 33, + 17, + 45, + 29, + 10, + 58, + 06, + 54, + 09, + 57, + 05, + 53, + 42, + 26, + 38, + 22, + 41, + 25, + 37, + 21, ]; let mut texture = device.create_texture(TextureTarget::Default); - device.init_texture(&mut texture, - 8, - 8, - ImageFormat::A8, - TextureFilter::Nearest, - RenderTargetMode::None, - 1, - Some(&dither_matrix)); + device.init_texture( + &mut texture, + 8, + 8, + ImageFormat::A8, + TextureFilter::Nearest, + RenderTargetMode::None, + 1, + Some(&dither_matrix), + ); Some(texture) } else { @@ -1405,34 +1640,23 @@ impl Renderer { let x1 = 1.0; let y1 = 1.0; - let quad_indices: [u16; 6] = [ 0, 1, 2, 2, 1, 3 ]; + let quad_indices: [u16; 6] = [0, 1, 2, 2, 1, 3]; let quad_vertices = [ - PackedVertex { - pos: [x0, y0], - }, - PackedVertex { - pos: [x1, y0], - }, - PackedVertex { - pos: [x0, y1], - }, - PackedVertex { - pos: [x1, y1], - }, + PackedVertex { pos: [x0, y0] }, + PackedVertex { pos: [x1, y0] }, + PackedVertex { pos: [x0, y1] }, + PackedVertex { pos: [x1, y1] }, ]; let prim_vao = device.create_vao(&DESC_PRIM_INSTANCES); device.bind_vao(&prim_vao); - device.update_vao_indices(&prim_vao, - &quad_indices, - VertexUsageHint::Static); - device.update_vao_main_vertices(&prim_vao, - &quad_vertices, - VertexUsageHint::Static); + device.update_vao_indices(&prim_vao, &quad_indices, VertexUsageHint::Static); + device.update_vao_main_vertices(&prim_vao, &quad_vertices, VertexUsageHint::Static); let blur_vao = device.create_vao_with_new_instances(&DESC_BLUR, &prim_vao); let clip_vao = device.create_vao_with_new_instances(&DESC_CLIP, &prim_vao); - let box_shadow_vao = device.create_vao_with_new_instances(&DESC_CACHE_BOX_SHADOW, &prim_vao); + let box_shadow_vao = + device.create_vao_with_new_instances(&DESC_CACHE_BOX_SHADOW, &prim_vao); let texture_cache_upload_pbo = device.create_pbo(); @@ -1462,11 +1686,14 @@ impl Renderer { let payload_tx_for_backend = payload_tx.clone(); let recorder = options.recorder; let worker_config = ThreadPoolConfig::new() - .thread_name(|idx|{ format!("WebRender:Worker#{}", idx) }) - .start_handler(|idx| { register_thread_with_profiler(format!("WebRender:Worker#{}", idx)); }); - let workers = options.workers.take().unwrap_or_else(||{ - Arc::new(ThreadPool::new(worker_config).unwrap()) - }); + .thread_name(|idx| format!("WebRender:Worker#{}", idx)) + .start_handler(|idx| { + register_thread_with_profiler(format!("WebRender:Worker#{}", idx)); + }); + let workers = options + .workers + .take() + .unwrap_or_else(|| Arc::new(ThreadPool::new(worker_config).unwrap())); let enable_render_on_scroll = options.enable_render_on_scroll; let blob_image_renderer = options.blob_image_renderer.take(); @@ -1574,8 +1801,13 @@ impl Renderer { } } - fn get_yuv_shader_index(buffer_kind: ImageBufferKind, format: YuvFormat, color_space: YuvColorSpace) -> usize { - ((buffer_kind as usize) * YUV_FORMATS.len() + (format as usize)) * YUV_COLOR_SPACES.len() + (color_space as usize) + fn get_yuv_shader_index( + buffer_kind: ImageBufferKind, + format: YuvFormat, + color_space: YuvColorSpace, + ) -> usize { + ((buffer_kind as usize) * YUV_FORMATS.len() + (format as usize)) * YUV_COLOR_SPACES.len() + + (color_space as usize) } /// Sets the new RenderNotifier. @@ -1607,7 +1839,12 @@ impl Renderer { // Pull any pending results and return the most recent. while let Ok(msg) = self.result_rx.try_recv() { match msg { - ResultMsg::NewFrame(_document_id, mut frame, texture_update_list, profile_counters) => { + ResultMsg::NewFrame( + _document_id, + mut frame, + texture_update_list, + profile_counters, + ) => { //TODO: associate `document_id` with target window self.pending_texture_updates.push(texture_update_list); if let Some(ref mut frame) = frame.frame { @@ -1627,7 +1864,10 @@ impl Renderer { self.current_frame = Some(frame); } - ResultMsg::UpdateResources { updates, cancel_rendering } => { + ResultMsg::UpdateResources { + updates, + cancel_rendering, + } => { self.pending_texture_updates.push(updates); self.update_texture_cache(); // If we receive a NewFrame message followed by this one within @@ -1641,14 +1881,12 @@ impl Renderer { ResultMsg::RefreshShader(path) => { self.pending_shader_updates.push(path); } - ResultMsg::DebugOutput(output) => { - match output { - DebugOutput::FetchDocuments(string) | - DebugOutput::FetchClipScrollTree(string) => { - self.debug_server.send(string); - } + ResultMsg::DebugOutput(output) => match output { + DebugOutput::FetchDocuments(string) | + DebugOutput::FetchClipScrollTree(string) => { + self.debug_server.send(string); } - } + }, ResultMsg::DebugCommand(command) => { self.handle_debug_command(command); } @@ -1667,20 +1905,39 @@ impl Renderer { fn get_passes_for_debugger(&self) -> String { let mut debug_passes = debug_server::PassList::new(); - if let Some(frame) = self.current_frame.as_ref().and_then(|frame| frame.frame.as_ref()) { + if let Some(frame) = self.current_frame + .as_ref() + .and_then(|frame| frame.frame.as_ref()) + { for pass in &frame.passes { let mut debug_pass = debug_server::Pass::new(); for target in &pass.alpha_targets.targets { let mut debug_target = debug_server::Target::new("A8"); - debug_target.add(debug_server::BatchKind::Clip, "Clear", target.clip_batcher.border_clears.len()); - debug_target.add(debug_server::BatchKind::Clip, "Borders", target.clip_batcher.borders.len()); - debug_target.add(debug_server::BatchKind::Clip, "Rectangles", target.clip_batcher.rectangles.len()); + debug_target.add( + debug_server::BatchKind::Clip, + "Clear", + target.clip_batcher.border_clears.len(), + ); + debug_target.add( + debug_server::BatchKind::Clip, + "Borders", + target.clip_batcher.borders.len(), + ); + debug_target.add( + debug_server::BatchKind::Clip, + "Rectangles", + target.clip_batcher.rectangles.len(), + ); for (_, items) in target.clip_batcher.images.iter() { debug_target.add(debug_server::BatchKind::Clip, "Image mask", items.len()); } - debug_target.add(debug_server::BatchKind::Cache, "Box Shadow", target.box_shadow_cache_prims.len()); + debug_target.add( + debug_server::BatchKind::Cache, + "Box Shadow", + target.box_shadow_cache_prims.len(), + ); debug_pass.add(debug_target); } @@ -1688,27 +1945,50 @@ impl Renderer { for target in &pass.color_targets.targets { let mut debug_target = debug_server::Target::new("RGBA8"); - debug_target.add(debug_server::BatchKind::Cache, "Vertical Blur", target.vertical_blurs.len()); - debug_target.add(debug_server::BatchKind::Cache, "Horizontal Blur", target.horizontal_blurs.len()); + debug_target.add( + debug_server::BatchKind::Cache, + "Vertical Blur", + target.vertical_blurs.len(), + ); + debug_target.add( + debug_server::BatchKind::Cache, + "Horizontal Blur", + target.horizontal_blurs.len(), + ); for (_, batch) in &target.text_run_cache_prims { - debug_target.add(debug_server::BatchKind::Cache, "Text Shadow", batch.len()); + debug_target.add( + debug_server::BatchKind::Cache, + "Text Shadow", + batch.len(), + ); } - debug_target.add(debug_server::BatchKind::Cache, "Lines", target.line_cache_prims.len()); - - for batch in target.alpha_batcher - .batch_list - .opaque_batch_list - .batches - .iter() - .rev() { - debug_target.add(debug_server::BatchKind::Opaque, batch.key.kind.debug_name(), batch.instances.len()); + debug_target.add( + debug_server::BatchKind::Cache, + "Lines", + target.line_cache_prims.len(), + ); + + for batch in target + .alpha_batcher + .batch_list + .opaque_batch_list + .batches + .iter() + .rev() + { + debug_target.add( + debug_server::BatchKind::Opaque, + batch.key.kind.debug_name(), + batch.instances.len(), + ); } - for batch in &target.alpha_batcher - .batch_list - .alpha_batch_list - .batches { - debug_target.add(debug_server::BatchKind::Alpha, batch.key.kind.debug_name(), batch.instances.len()); + for batch in &target.alpha_batcher.batch_list.alpha_batch_list.batches { + debug_target.add( + debug_server::BatchKind::Alpha, + batch.key.kind.debug_name(), + batch.instances.len(), + ); } debug_pass.add(debug_target); @@ -1723,34 +2003,26 @@ impl Renderer { fn handle_debug_command(&mut self, command: DebugCommand) { match command { - DebugCommand::EnableProfiler(enable) => { - if enable { - self.debug_flags.insert(PROFILER_DBG); - } else { - self.debug_flags.remove(PROFILER_DBG); - } - } - DebugCommand::EnableTextureCacheDebug(enable) => { - if enable { - self.debug_flags.insert(TEXTURE_CACHE_DBG); - } else { - self.debug_flags.remove(TEXTURE_CACHE_DBG); - } - } - DebugCommand::EnableRenderTargetDebug(enable) => { - if enable { - self.debug_flags.insert(RENDER_TARGET_DBG); - } else { - self.debug_flags.remove(RENDER_TARGET_DBG); - } - } - DebugCommand::EnableAlphaRectsDebug(enable) => { - if enable { - self.debug_flags.insert(ALPHA_PRIM_DBG); - } else { - self.debug_flags.remove(ALPHA_PRIM_DBG); - } - } + DebugCommand::EnableProfiler(enable) => if enable { + self.debug_flags.insert(PROFILER_DBG); + } else { + self.debug_flags.remove(PROFILER_DBG); + }, + DebugCommand::EnableTextureCacheDebug(enable) => if enable { + self.debug_flags.insert(TEXTURE_CACHE_DBG); + } else { + self.debug_flags.remove(TEXTURE_CACHE_DBG); + }, + DebugCommand::EnableRenderTargetDebug(enable) => if enable { + self.debug_flags.insert(RENDER_TARGET_DBG); + } else { + self.debug_flags.remove(RENDER_TARGET_DBG); + }, + DebugCommand::EnableAlphaRectsDebug(enable) => if enable { + self.debug_flags.insert(ALPHA_PRIM_DBG); + } else { + self.debug_flags.remove(ALPHA_PRIM_DBG); + }, DebugCommand::FetchDocuments => {} DebugCommand::FetchClipScrollTree => {} DebugCommand::FetchPasses => { @@ -1794,12 +2066,14 @@ impl Renderer { let _gm = GpuMarker::new(self.device.rc_gl(), "build samples"); // Block CPU waiting for last frame's GPU profiles to arrive. // In general this shouldn't block unless heavily GPU limited. - if let Some((gpu_frame_id, timers, samplers)) = self.gpu_profile.build_samples() { + if let Some((gpu_frame_id, timers, samplers)) = self.gpu_profile.build_samples() + { if self.max_recorded_profiles > 0 { while self.gpu_profiles.len() >= self.max_recorded_profiles { self.gpu_profiles.pop_front(); } - self.gpu_profiles.push_back(GpuProfile::new(gpu_frame_id, &timers)); + self.gpu_profiles + .push_back(GpuProfile::new(gpu_frame_id, &timers)); } profile_timers.gpu_samples = timers; profile_samplers = samplers; @@ -1821,7 +2095,10 @@ impl Renderer { self.update_gpu_cache(frame); - self.device.bind_texture(TextureSampler::ResourceCache, &self.gpu_cache_texture.texture); + self.device.bind_texture( + TextureSampler::ResourceCache, + &self.gpu_cache_texture.texture, + ); frame_id }; @@ -1840,31 +2117,37 @@ impl Renderer { while self.cpu_profiles.len() >= self.max_recorded_profiles { self.cpu_profiles.pop_front(); } - let cpu_profile = CpuProfile::new(cpu_frame_id, - self.backend_profile_counters.total_time.get(), - profile_timers.cpu_time.get(), - self.profile_counters.draw_calls.get()); + let cpu_profile = CpuProfile::new( + cpu_frame_id, + self.backend_profile_counters.total_time.get(), + profile_timers.cpu_time.get(), + self.profile_counters.draw_calls.get(), + ); self.cpu_profiles.push_back(cpu_profile); } if self.debug_flags.contains(PROFILER_DBG) { let screen_fraction = 1.0 / //TODO: take device/pixel ratio into equation? (framebuffer_size.width as f32 * framebuffer_size.height as f32); - self.profiler.draw_profile(&mut self.device, - &frame.profile_counters, - &self.backend_profile_counters, - &self.profile_counters, - &mut profile_timers, - &profile_samplers, - screen_fraction, - &mut self.debug); + self.profiler.draw_profile( + &mut self.device, + &frame.profile_counters, + &self.backend_profile_counters, + &self.profile_counters, + &mut profile_timers, + &profile_samplers, + screen_fraction, + &mut self.debug, + ); } self.profile_counters.reset(); self.profile_counters.frame_counter.inc(); - let debug_size = DeviceUintSize::new(framebuffer_size.width as u32, - framebuffer_size.height as u32); + let debug_size = DeviceUintSize::new( + framebuffer_size.width as u32, + framebuffer_size.height as u32, + ); self.debug.render(&mut self.device, &debug_size); { let _gm = GpuMarker::new(self.device.rc_gl(), "end frame"); @@ -1893,7 +2176,8 @@ impl Renderer { fn update_gpu_cache(&mut self, frame: &mut Frame) { let _gm = GpuMarker::new(self.device.rc_gl(), "gpu cache update"); for update_list in self.pending_gpu_cache_updates.drain(..) { - self.gpu_cache_texture.update(&mut self.device, &update_list); + self.gpu_cache_texture + .update(&mut self.device, &update_list); } self.update_deferred_resolves(frame); self.gpu_cache_texture.flush(&mut self.device); @@ -1906,27 +2190,43 @@ impl Renderer { for update_list in pending_texture_updates.drain(..) { for update in update_list.updates { match update.op { - TextureUpdateOp::Create { width, height, layer_count, format, filter, mode } => { + TextureUpdateOp::Create { + width, + height, + layer_count, + format, + filter, + mode, + } => { let CacheTextureId(cache_texture_index) = update.id; if self.texture_resolver.cache_texture_map.len() == cache_texture_index { // Create a new native texture, as requested by the texture cache. let texture = self.device.create_texture(TextureTarget::Array); self.texture_resolver.cache_texture_map.push(texture); } - let texture = &mut self.texture_resolver.cache_texture_map[cache_texture_index]; + let texture = + &mut self.texture_resolver.cache_texture_map[cache_texture_index]; // Ensure no PBO is bound when creating the texture storage, // or GL will attempt to read data from there. - self.device.init_texture(texture, - width, - height, - format, - filter, - mode, - layer_count, - None); + self.device.init_texture( + texture, + width, + height, + format, + filter, + mode, + layer_count, + None, + ); } - TextureUpdateOp::Update { rect, source, stride, layer_index, offset } => { + TextureUpdateOp::Update { + rect, + source, + stride, + layer_index, + offset, + } => { let texture = &self.texture_resolver.cache_texture_map[update.id.0]; // Bind a PBO to do the texture upload. @@ -1934,16 +2234,16 @@ impl Renderer { self.device.bind_pbo(Some(&self.texture_cache_upload_pbo)); match source { - TextureUpdateSource::Bytes { data } => { - self.device.update_pbo_data(&data[offset as usize..]); + TextureUpdateSource::Bytes { data } => { + self.device.update_pbo_data(&data[offset as usize ..]); } TextureUpdateSource::External { id, channel_index } => { let handler = self.external_image_handler - .as_mut() - .expect("Found external image, but no handler set!"); + .as_mut() + .expect("Found external image, but no handler set!"); match handler.lock(id, channel_index).source { ExternalImageSource::RawData(data) => { - self.device.update_pbo_data(&data[offset as usize..]); + self.device.update_pbo_data(&data[offset as usize ..]); } ExternalImageSource::Invalid => { // Create a local buffer to fill the pbo. @@ -1961,14 +2261,16 @@ impl Renderer { } } - self.device.update_texture_from_pbo(texture, - rect.origin.x, - rect.origin.y, - rect.size.width, - rect.size.height, - layer_index, - stride, - 0); + self.device.update_texture_from_pbo( + texture, + rect.origin.x, + rect.origin.y, + rect.size.width, + rect.size.height, + layer_index, + stride, + 0, + ); // Ensure that other texture updates won't read from this PBO. self.device.bind_pbo(None); @@ -1982,12 +2284,18 @@ impl Renderer { } } - fn draw_instanced_batch(&mut self, - data: &[T], - vertex_array_kind: VertexArrayKind, - textures: &BatchTextures) { - for i in 0..textures.colors.len() { - self.texture_resolver.bind(&textures.colors[i], TextureSampler::color(i), &mut self.device); + fn draw_instanced_batch( + &mut self, + data: &[T], + vertex_array_kind: VertexArrayKind, + textures: &BatchTextures, + ) { + for i in 0 .. textures.colors.len() { + self.texture_resolver.bind( + &textures.colors[i], + TextureSampler::color(i), + &mut self.device, + ); } // TODO: this probably isn't the best place for this. @@ -2005,12 +2313,15 @@ impl Renderer { self.device.bind_vao(vao); if self.enable_batcher { - self.device.update_vao_instances(vao, data, VertexUsageHint::Stream); - self.device.draw_indexed_triangles_instanced_u16(6, data.len() as i32); + self.device + .update_vao_instances(vao, data, VertexUsageHint::Stream); + self.device + .draw_indexed_triangles_instanced_u16(6, data.len() as i32); self.profile_counters.draw_calls.inc(); } else { for i in 0 .. data.len() { - self.device.update_vao_instances(vao, &data[i..i+1], VertexUsageHint::Stream); + self.device + .update_vao_instances(vao, &data[i .. i + 1], VertexUsageHint::Stream); self.device.draw_triangles_u16(0, 6); self.profile_counters.draw_calls.inc(); } @@ -2019,121 +2330,202 @@ impl Renderer { self.profile_counters.vertices.add(6 * data.len()); } - fn submit_batch(&mut self, - key: &BatchKey, - instances: &[PrimitiveInstance], - projection: &Transform3D, - render_tasks: &RenderTaskTree, - render_target: Option<(&Texture, i32)>, - target_dimensions: DeviceUintSize) { + fn submit_batch( + &mut self, + key: &BatchKey, + instances: &[PrimitiveInstance], + projection: &Transform3D, + render_tasks: &RenderTaskTree, + render_target: Option<(&Texture, i32)>, + target_dimensions: DeviceUintSize, + ) { let marker = match key.kind { BatchKind::Composite { .. } => { - self.ps_composite.bind(&mut self.device, projection, &mut self.renderer_errors); + self.ps_composite + .bind(&mut self.device, projection, &mut self.renderer_errors); GPU_TAG_PRIM_COMPOSITE } BatchKind::HardwareComposite => { - self.ps_hw_composite.bind(&mut self.device, projection, &mut self.renderer_errors); + self.ps_hw_composite + .bind(&mut self.device, projection, &mut self.renderer_errors); GPU_TAG_PRIM_HW_COMPOSITE } BatchKind::SplitComposite => { - self.ps_split_composite.bind(&mut self.device, projection, &mut self.renderer_errors); + self.ps_split_composite.bind( + &mut self.device, + projection, + &mut self.renderer_errors, + ); GPU_TAG_PRIM_SPLIT_COMPOSITE } BatchKind::Blend => { - self.ps_blend.bind(&mut self.device, projection, &mut self.renderer_errors); + self.ps_blend + .bind(&mut self.device, projection, &mut self.renderer_errors); GPU_TAG_PRIM_BLEND } - BatchKind::Transformable(transform_kind, batch_kind) => { - match batch_kind { - TransformBatchKind::Rectangle(needs_clipping) => { - debug_assert!(!needs_clipping || - match key.blend_mode { - BlendMode::Alpha | - BlendMode::PremultipliedAlpha | - BlendMode::Subpixel(..) => true, - BlendMode::None => false, - }); - - if needs_clipping { - self.ps_rectangle_clip.bind(&mut self.device, transform_kind, projection, &mut self.renderer_errors); - } else { - self.ps_rectangle.bind(&mut self.device, transform_kind, projection, &mut self.renderer_errors); - } - GPU_TAG_PRIM_RECT - } - TransformBatchKind::Line => { - self.ps_line.bind(&mut self.device, transform_kind, projection, &mut self.renderer_errors); - GPU_TAG_PRIM_LINE - } - TransformBatchKind::TextRun => { - match key.blend_mode { - BlendMode::Subpixel(..) => { - self.ps_text_run_subpixel.bind(&mut self.device, transform_kind, projection, &mut self.renderer_errors); - } + BatchKind::Transformable(transform_kind, batch_kind) => match batch_kind { + TransformBatchKind::Rectangle(needs_clipping) => { + debug_assert!( + !needs_clipping || match key.blend_mode { BlendMode::Alpha | BlendMode::PremultipliedAlpha | - BlendMode::None => { - self.ps_text_run.bind(&mut self.device, transform_kind, projection, &mut self.renderer_errors); - } - }; - GPU_TAG_PRIM_TEXT_RUN - } - TransformBatchKind::Image(image_buffer_kind) => { - self.ps_image[image_buffer_kind as usize] - .as_mut() - .expect("Unsupported image shader kind") - .bind(&mut self.device, transform_kind, projection, &mut self.renderer_errors); - GPU_TAG_PRIM_IMAGE - } - TransformBatchKind::YuvImage(image_buffer_kind, format, color_space) => { - let shader_index = Renderer::get_yuv_shader_index(image_buffer_kind, - format, - color_space); - self.ps_yuv_image[shader_index] - .as_mut() - .expect("Unsupported YUV shader kind") - .bind(&mut self.device, transform_kind, projection, &mut self.renderer_errors); - GPU_TAG_PRIM_YUV_IMAGE - } - TransformBatchKind::BorderCorner => { - self.ps_border_corner.bind(&mut self.device, transform_kind, projection, &mut self.renderer_errors); - GPU_TAG_PRIM_BORDER_CORNER - } - TransformBatchKind::BorderEdge => { - self.ps_border_edge.bind(&mut self.device, transform_kind, projection, &mut self.renderer_errors); - GPU_TAG_PRIM_BORDER_EDGE - } - TransformBatchKind::AlignedGradient => { - self.ps_gradient.bind(&mut self.device, transform_kind, projection, &mut self.renderer_errors); - GPU_TAG_PRIM_GRADIENT - } - TransformBatchKind::AngleGradient => { - self.ps_angle_gradient.bind(&mut self.device, transform_kind, projection, &mut self.renderer_errors); - GPU_TAG_PRIM_ANGLE_GRADIENT - } - TransformBatchKind::RadialGradient => { - self.ps_radial_gradient.bind(&mut self.device, transform_kind, projection, &mut self.renderer_errors); - GPU_TAG_PRIM_RADIAL_GRADIENT - } - TransformBatchKind::BoxShadow => { - self.ps_box_shadow.bind(&mut self.device, transform_kind, projection, &mut self.renderer_errors); - GPU_TAG_PRIM_BOX_SHADOW - } - TransformBatchKind::CacheImage => { - self.ps_cache_image.bind(&mut self.device, transform_kind, projection, &mut self.renderer_errors); - GPU_TAG_PRIM_CACHE_IMAGE + BlendMode::Subpixel(..) => true, + BlendMode::None => false, + } + ); + + if needs_clipping { + self.ps_rectangle_clip.bind( + &mut self.device, + transform_kind, + projection, + &mut self.renderer_errors, + ); + } else { + self.ps_rectangle.bind( + &mut self.device, + transform_kind, + projection, + &mut self.renderer_errors, + ); } + GPU_TAG_PRIM_RECT } - } + TransformBatchKind::Line => { + self.ps_line.bind( + &mut self.device, + transform_kind, + projection, + &mut self.renderer_errors, + ); + GPU_TAG_PRIM_LINE + } + TransformBatchKind::TextRun => { + match key.blend_mode { + BlendMode::Subpixel(..) => { + self.ps_text_run_subpixel.bind( + &mut self.device, + transform_kind, + projection, + &mut self.renderer_errors, + ); + } + BlendMode::Alpha | BlendMode::PremultipliedAlpha | BlendMode::None => { + self.ps_text_run.bind( + &mut self.device, + transform_kind, + projection, + &mut self.renderer_errors, + ); + } + }; + GPU_TAG_PRIM_TEXT_RUN + } + TransformBatchKind::Image(image_buffer_kind) => { + self.ps_image[image_buffer_kind as usize] + .as_mut() + .expect("Unsupported image shader kind") + .bind( + &mut self.device, + transform_kind, + projection, + &mut self.renderer_errors, + ); + GPU_TAG_PRIM_IMAGE + } + TransformBatchKind::YuvImage(image_buffer_kind, format, color_space) => { + let shader_index = + Renderer::get_yuv_shader_index(image_buffer_kind, format, color_space); + self.ps_yuv_image[shader_index] + .as_mut() + .expect("Unsupported YUV shader kind") + .bind( + &mut self.device, + transform_kind, + projection, + &mut self.renderer_errors, + ); + GPU_TAG_PRIM_YUV_IMAGE + } + TransformBatchKind::BorderCorner => { + self.ps_border_corner.bind( + &mut self.device, + transform_kind, + projection, + &mut self.renderer_errors, + ); + GPU_TAG_PRIM_BORDER_CORNER + } + TransformBatchKind::BorderEdge => { + self.ps_border_edge.bind( + &mut self.device, + transform_kind, + projection, + &mut self.renderer_errors, + ); + GPU_TAG_PRIM_BORDER_EDGE + } + TransformBatchKind::AlignedGradient => { + self.ps_gradient.bind( + &mut self.device, + transform_kind, + projection, + &mut self.renderer_errors, + ); + GPU_TAG_PRIM_GRADIENT + } + TransformBatchKind::AngleGradient => { + self.ps_angle_gradient.bind( + &mut self.device, + transform_kind, + projection, + &mut self.renderer_errors, + ); + GPU_TAG_PRIM_ANGLE_GRADIENT + } + TransformBatchKind::RadialGradient => { + self.ps_radial_gradient.bind( + &mut self.device, + transform_kind, + projection, + &mut self.renderer_errors, + ); + GPU_TAG_PRIM_RADIAL_GRADIENT + } + TransformBatchKind::BoxShadow => { + self.ps_box_shadow.bind( + &mut self.device, + transform_kind, + projection, + &mut self.renderer_errors, + ); + GPU_TAG_PRIM_BOX_SHADOW + } + TransformBatchKind::CacheImage => { + self.ps_cache_image.bind( + &mut self.device, + transform_kind, + projection, + &mut self.renderer_errors, + ); + GPU_TAG_PRIM_CACHE_IMAGE + } + }, }; // Handle special case readback for composites. match key.kind { - BatchKind::Composite { task_id, source_id, backdrop_id } => { + BatchKind::Composite { + task_id, + source_id, + backdrop_id, + } => { // composites can't be grouped together because // they may overlap and affect each other. debug_assert!(instances.len() == 1); - let cache_texture = self.texture_resolver.resolve(&SourceTexture::CacheRGBA8).unwrap(); + let cache_texture = self.texture_resolver + .resolve(&SourceTexture::CacheRGBA8) + .unwrap(); // Before submitting the composite batch, do the // framebuffer readbacks that are needed for each @@ -2154,10 +2546,13 @@ impl Renderer { // changes. The device will skip the GL call if the requested // target is already bound. let cache_draw_target = (cache_texture, readback_layer.0 as i32); - self.device.bind_draw_target(Some(cache_draw_target), Some(cache_texture_dimensions)); + self.device + .bind_draw_target(Some(cache_draw_target), Some(cache_texture_dimensions)); - let src_x = backdrop_rect.origin.x - backdrop_screen_origin.x + source_screen_origin.x; - let src_y = backdrop_rect.origin.y - backdrop_screen_origin.y + source_screen_origin.y; + let src_x = + backdrop_rect.origin.x - backdrop_screen_origin.x + source_screen_origin.x; + let src_y = + backdrop_rect.origin.y - backdrop_screen_origin.y + source_screen_origin.y; let dest_x = readback_rect.origin.x; let dest_y = readback_rect.origin.y; @@ -2165,10 +2560,14 @@ impl Renderer { let width = readback_rect.size.width; let height = readback_rect.size.height; - let mut src = DeviceIntRect::new(DeviceIntPoint::new(src_x as i32, src_y as i32), - DeviceIntSize::new(width as i32, height as i32)); - let mut dest = DeviceIntRect::new(DeviceIntPoint::new(dest_x as i32, dest_y as i32), - DeviceIntSize::new(width as i32, height as i32)); + let mut src = DeviceIntRect::new( + DeviceIntPoint::new(src_x as i32, src_y as i32), + DeviceIntSize::new(width as i32, height as i32), + ); + let mut dest = DeviceIntRect::new( + DeviceIntPoint::new(dest_x as i32, dest_y as i32), + DeviceIntSize::new(width as i32, height as i32), + ); // Need to invert the y coordinates and flip the image vertically when // reading back from the framebuffer. @@ -2182,18 +2581,18 @@ impl Renderer { self.device.blit_render_target(src, dest); // Restore draw target to current pass render target + layer. - self.device.bind_draw_target(render_target, Some(target_dimensions)); + self.device + .bind_draw_target(render_target, Some(target_dimensions)); } _ => {} } let _gm = self.gpu_profile.add_marker(marker); - self.draw_instanced_batch(instances, - VertexArrayKind::Primitive, - &key.textures); + self.draw_instanced_batch(instances, VertexArrayKind::Primitive, &key.textures); } - fn draw_color_target(&mut self, + fn draw_color_target( + &mut self, render_target: Option<(&Texture, i32)>, target: &ColorRenderTarget, target_size: DeviceUintSize, @@ -2204,7 +2603,8 @@ impl Renderer { ) { { let _gm = self.gpu_profile.add_marker(GPU_TAG_SETUP_TARGET); - self.device.bind_draw_target(render_target, Some(target_size)); + self.device + .bind_draw_target(render_target, Some(target_size)); self.device.disable_depth(); self.device.enable_depth_write(); self.device.set_blend(false); @@ -2216,9 +2616,8 @@ impl Renderer { // GPUs that I have tested with. It's possible it may be a // performance penalty on other GPU types - we should test this // and consider different code paths. - self.device.clear_target_rect(clear_color, - Some(1.0), - target.used_rect()); + self.device + .clear_target_rect(clear_color, Some(1.0), target.used_rect()); } _ => { self.device.clear_target(clear_color, Some(1.0)); @@ -2238,18 +2637,23 @@ impl Renderer { let _gm = self.gpu_profile.add_marker(GPU_TAG_BLUR); self.device.set_blend(false); - self.cs_blur.bind(&mut self.device, projection, &mut self.renderer_errors); + self.cs_blur + .bind(&mut self.device, projection, &mut self.renderer_errors); if !target.vertical_blurs.is_empty() { - self.draw_instanced_batch(&target.vertical_blurs, - VertexArrayKind::Blur, - &BatchTextures::no_texture()); + self.draw_instanced_batch( + &target.vertical_blurs, + VertexArrayKind::Blur, + &BatchTextures::no_texture(), + ); } if !target.horizontal_blurs.is_empty() { - self.draw_instanced_batch(&target.horizontal_blurs, - VertexArrayKind::Blur, - &BatchTextures::no_texture()); + self.draw_instanced_batch( + &target.horizontal_blurs, + VertexArrayKind::Blur, + &BatchTextures::no_texture(), + ); } } @@ -2264,11 +2668,14 @@ impl Renderer { self.device.set_blend_mode_alpha(); let _gm = self.gpu_profile.add_marker(GPU_TAG_CACHE_TEXT_RUN); - self.cs_text_run.bind(&mut self.device, projection, &mut self.renderer_errors); + self.cs_text_run + .bind(&mut self.device, projection, &mut self.renderer_errors); for (texture_id, instances) in &target.text_run_cache_prims { - self.draw_instanced_batch(instances, - VertexArrayKind::Primitive, - &BatchTextures::color(*texture_id)); + self.draw_instanced_batch( + instances, + VertexArrayKind::Primitive, + &BatchTextures::color(*texture_id), + ); } } if !target.line_cache_prims.is_empty() { @@ -2278,10 +2685,13 @@ impl Renderer { self.device.set_blend_mode_alpha(); let _gm = self.gpu_profile.add_marker(GPU_TAG_CACHE_LINE); - self.cs_line.bind(&mut self.device, projection, &mut self.renderer_errors); - self.draw_instanced_batch(&target.line_cache_prims, - VertexArrayKind::Primitive, - &BatchTextures::no_texture()); + self.cs_line + .bind(&mut self.device, projection, &mut self.renderer_errors); + self.draw_instanced_batch( + &target.line_cache_prims, + VertexArrayKind::Primitive, + &BatchTextures::no_texture(), + ); } //TODO: record the pixel count for cached primitives @@ -2300,18 +2710,22 @@ impl Renderer { // Draw opaque batches front-to-back for maximum // z-buffer efficiency! - for batch in target.alpha_batcher - .batch_list - .opaque_batch_list - .batches - .iter() - .rev() { - self.submit_batch(&batch.key, - &batch.instances, - &projection, - render_tasks, - render_target, - target_size); + for batch in target + .alpha_batcher + .batch_list + .opaque_batch_list + .batches + .iter() + .rev() + { + self.submit_batch( + &batch.key, + &batch.instances, + &projection, + render_tasks, + render_target, + target_size, + ); } self.device.disable_depth_write(); @@ -2351,12 +2765,14 @@ impl Renderer { } } - self.submit_batch(&batch.key, - &batch.instances, - &projection, - render_tasks, - render_target, - target_size); + self.submit_batch( + &batch.key, + &batch.instances, + &projection, + render_tasks, + render_target, + target_size, + ); } self.device.disable_depth(); @@ -2368,8 +2784,8 @@ impl Renderer { // get the texture from caller and blit it. for output in &target.outputs { let handler = self.output_image_handler - .as_mut() - .expect("Found output image, but no handler set!"); + .as_mut() + .expect("Found output image, but no handler set!"); if let Some((texture_id, output_size)) = handler.lock(output.pipeline_id) { let device = &mut self.device; let fbo_id = match self.output_targets.entry(texture_id) { @@ -2398,7 +2814,8 @@ impl Renderer { } } - fn draw_alpha_target(&mut self, + fn draw_alpha_target( + &mut self, render_target: (&Texture, i32), target: &AlphaRenderTarget, target_size: DeviceUintSize, @@ -2408,7 +2825,8 @@ impl Renderer { { let _gm = self.gpu_profile.add_marker(GPU_TAG_SETUP_TARGET); - self.device.bind_draw_target(Some(render_target), Some(target_size)); + self.device + .bind_draw_target(Some(render_target), Some(target_size)); self.device.disable_depth(); self.device.disable_depth_write(); @@ -2418,19 +2836,21 @@ impl Renderer { // performance penalty on other GPU types - we should test this // and consider different code paths. let clear_color = [1.0, 1.0, 1.0, 0.0]; - self.device.clear_target_rect(Some(clear_color), - None, - target.used_rect()); + self.device + .clear_target_rect(Some(clear_color), None, target.used_rect()); } // Draw any box-shadow caches for this target. if !target.box_shadow_cache_prims.is_empty() { self.device.set_blend(false); let _gm = self.gpu_profile.add_marker(GPU_TAG_CACHE_BOX_SHADOW); - self.cs_box_shadow.bind(&mut self.device, projection, &mut self.renderer_errors); - self.draw_instanced_batch(&target.box_shadow_cache_prims, - VertexArrayKind::CacheBoxShadow, - &BatchTextures::no_texture()); + self.cs_box_shadow + .bind(&mut self.device, projection, &mut self.renderer_errors); + self.draw_instanced_batch( + &target.box_shadow_cache_prims, + VertexArrayKind::CacheBoxShadow, + &BatchTextures::no_texture(), + ); } // Draw the clip items into the tiled alpha mask. @@ -2443,10 +2863,13 @@ impl Renderer { if !target.clip_batcher.border_clears.is_empty() { let _gm2 = GpuMarker::new(self.device.rc_gl(), "clip borders [clear]"); self.device.set_blend(false); - self.cs_clip_border.bind(&mut self.device, projection, &mut self.renderer_errors); - self.draw_instanced_batch(&target.clip_batcher.border_clears, - VertexArrayKind::Clip, - &BatchTextures::no_texture()); + self.cs_clip_border + .bind(&mut self.device, projection, &mut self.renderer_errors); + self.draw_instanced_batch( + &target.clip_batcher.border_clears, + VertexArrayKind::Clip, + &BatchTextures::no_texture(), + ); } // Draw any dots or dashes for border corners. @@ -2458,10 +2881,13 @@ impl Renderer { // a max blend mode here is fine. self.device.set_blend(true); self.device.set_blend_mode_max(); - self.cs_clip_border.bind(&mut self.device, projection, &mut self.renderer_errors); - self.draw_instanced_batch(&target.clip_batcher.borders, - VertexArrayKind::Clip, - &BatchTextures::no_texture()); + self.cs_clip_border + .bind(&mut self.device, projection, &mut self.renderer_errors); + self.draw_instanced_batch( + &target.clip_batcher.borders, + VertexArrayKind::Clip, + &BatchTextures::no_texture(), + ); } // switch to multiplicative blending @@ -2471,10 +2897,16 @@ impl Renderer { // draw rounded cornered rectangles if !target.clip_batcher.rectangles.is_empty() { let _gm2 = GpuMarker::new(self.device.rc_gl(), "clip rectangles"); - self.cs_clip_rectangle.bind(&mut self.device, projection, &mut self.renderer_errors); - self.draw_instanced_batch(&target.clip_batcher.rectangles, - VertexArrayKind::Clip, - &BatchTextures::no_texture()); + self.cs_clip_rectangle.bind( + &mut self.device, + projection, + &mut self.renderer_errors, + ); + self.draw_instanced_batch( + &target.clip_batcher.rectangles, + VertexArrayKind::Clip, + &BatchTextures::no_texture(), + ); } // draw image masks for (mask_texture_id, items) in target.clip_batcher.images.iter() { @@ -2484,12 +2916,11 @@ impl Renderer { mask_texture_id.clone(), SourceTexture::Invalid, SourceTexture::Invalid, - ] + ], }; - self.cs_clip_image.bind(&mut self.device, projection, &mut self.renderer_errors); - self.draw_instanced_batch(items, - VertexArrayKind::Clip, - &textures); + self.cs_clip_image + .bind(&mut self.device, projection, &mut self.renderer_errors); + self.draw_instanced_batch(items, VertexArrayKind::Clip, &textures); } } @@ -2503,14 +2934,15 @@ impl Renderer { // here before it's uploaded to the GPU. if !frame.deferred_resolves.is_empty() { let handler = self.external_image_handler - .as_mut() - .expect("Found external image, but no handler set!"); + .as_mut() + .expect("Found external image, but no handler set!"); for deferred_resolve in &frame.deferred_resolves { GpuMarker::fire(self.device.gl(), "deferred resolve"); let props = &deferred_resolve.image_properties; - let ext_image = props.external_image - .expect("BUG: Deferred resolves must be external images!"); + let ext_image = props + .external_image + .expect("BUG: Deferred resolves must be external images!"); let image = handler.lock(ext_image.id, ext_image.channel_index); let texture_target = match ext_image.image_type { ExternalImageType::Texture2DHandle => TextureTarget::Default, @@ -2518,8 +2950,10 @@ impl Renderer { ExternalImageType::TextureRectHandle => TextureTarget::Rect, ExternalImageType::TextureExternalHandle => TextureTarget::External, ExternalImageType::ExternalBuffer => { - panic!("{:?} is not a suitable image type in update_deferred_resolves().", - ext_image.image_type); + panic!( + "{:?} is not a suitable image type in update_deferred_resolves().", + ext_image.image_type + ); } }; @@ -2528,9 +2962,15 @@ impl Renderer { self.device.reset_state(); let texture = match image.source { - ExternalImageSource::NativeTexture(texture_id) => ExternalTexture::new(texture_id, texture_target), + ExternalImageSource::NativeTexture(texture_id) => { + ExternalTexture::new(texture_id, texture_target) + } ExternalImageSource::Invalid => { - warn!("Invalid ext-image for ext_id:{:?}, channel:{}.", ext_image.id, ext_image.channel_index); + warn!( + "Invalid ext-image for ext_id:{:?}, channel:{}.", + ext_image.id, + ext_image.channel_index + ); // Just use 0 as the gl handle for this failed case. ExternalTexture::new(0, texture_target) } @@ -2547,7 +2987,10 @@ impl Renderer { address: deferred_resolve.address, }; - let blocks = [ [image.u0, image.v0, image.u1, image.v1].into(), [0.0; 4].into() ]; + let blocks = [ + [image.u0, image.v0, image.u1, image.v1].into(), + [0.0; 4].into(), + ]; self.gpu_cache_texture.apply_patch(&update, &blocks); } } @@ -2556,8 +2999,8 @@ impl Renderer { fn unlock_external_images(&mut self) { if !self.texture_resolver.external_images.is_empty() { let handler = self.external_image_handler - .as_mut() - .expect("Found external image, but no handler set!"); + .as_mut() + .expect("Found external image, but no handler set!"); for (ext_data, _) in self.texture_resolver.external_images.drain() { handler.unlock(ext_data.0, ext_data.1); @@ -2574,21 +3017,19 @@ impl Renderer { debug_assert!(pass.alpha_texture.is_none()); if pass.needs_render_target_kind(RenderTargetKind::Color) { - pass.color_texture = Some(self.color_render_targets - .pop() - .unwrap_or_else(|| { - self.device - .create_texture(TextureTarget::Array) - })); + pass.color_texture = Some( + self.color_render_targets + .pop() + .unwrap_or_else(|| self.device.create_texture(TextureTarget::Array)), + ); } if pass.needs_render_target_kind(RenderTargetKind::Alpha) { - pass.alpha_texture = Some(self.alpha_render_targets - .pop() - .unwrap_or_else(|| { - self.device - .create_texture(TextureTarget::Array) - })); + pass.alpha_texture = Some( + self.alpha_render_targets + .pop() + .unwrap_or_else(|| self.device.create_texture(TextureTarget::Array)), + ); } } @@ -2601,77 +3042,102 @@ impl Renderer { if let Some(texture) = pass.color_texture.as_mut() { debug_assert!(pass.max_color_target_size.width > 0); debug_assert!(pass.max_color_target_size.height > 0); - self.device.init_texture(texture, - pass.max_color_target_size.width, - pass.max_color_target_size.height, - ImageFormat::BGRA8, - TextureFilter::Linear, - RenderTargetMode::RenderTarget, - color_target_count as i32, - None); + self.device.init_texture( + texture, + pass.max_color_target_size.width, + pass.max_color_target_size.height, + ImageFormat::BGRA8, + TextureFilter::Linear, + RenderTargetMode::RenderTarget, + color_target_count as i32, + None, + ); } if let Some(texture) = pass.alpha_texture.as_mut() { debug_assert!(pass.max_alpha_target_size.width > 0); debug_assert!(pass.max_alpha_target_size.height > 0); - self.device.init_texture(texture, - pass.max_alpha_target_size.width, - pass.max_alpha_target_size.height, - ImageFormat::A8, - TextureFilter::Nearest, - RenderTargetMode::RenderTarget, - alpha_target_count as i32, - None); + self.device.init_texture( + texture, + pass.max_alpha_target_size.width, + pass.max_alpha_target_size.height, + ImageFormat::A8, + TextureFilter::Nearest, + RenderTargetMode::RenderTarget, + alpha_target_count as i32, + None, + ); } } - self.layer_texture.update(&mut self.device, &mut frame.layer_texture_data); - self.render_task_texture.update(&mut self.device, &mut frame.render_tasks.task_data); + self.layer_texture + .update(&mut self.device, &mut frame.layer_texture_data); + self.render_task_texture + .update(&mut self.device, &mut frame.render_tasks.task_data); - self.device.bind_texture(TextureSampler::Layers, &self.layer_texture.texture); - self.device.bind_texture(TextureSampler::RenderTasks, &self.render_task_texture.texture); + self.device + .bind_texture(TextureSampler::Layers, &self.layer_texture.texture); + self.device.bind_texture( + TextureSampler::RenderTasks, + &self.render_task_texture.texture, + ); debug_assert!(self.texture_resolver.cache_a8_texture.is_none()); debug_assert!(self.texture_resolver.cache_rgba8_texture.is_none()); } - fn draw_tile_frame(&mut self, - frame: &mut Frame, - framebuffer_size: DeviceUintSize, - frame_id: FrameId) { + fn draw_tile_frame( + &mut self, + frame: &mut Frame, + framebuffer_size: DeviceUintSize, + frame_id: FrameId, + ) { let _gm = GpuMarker::new(self.device.rc_gl(), "tile frame draw"); // Some tests use a restricted viewport smaller than the main screen size. // Ensure we clear the framebuffer in these tests. // TODO(gw): Find a better solution for this? let needs_clear = frame.window_size.width < framebuffer_size.width || - frame.window_size.height < framebuffer_size.height; + frame.window_size.height < framebuffer_size.height; self.device.disable_depth_write(); self.device.disable_stencil(); self.device.set_blend(false); if frame.passes.is_empty() { - self.device.clear_target(Some(self.clear_color.to_array()), Some(1.0)); + self.device + .clear_target(Some(self.clear_color.to_array()), Some(1.0)); } else { self.start_frame(frame); let pass_count = frame.passes.len(); for (pass_index, pass) in frame.passes.iter_mut().enumerate() { - self.texture_resolver.bind(&SourceTexture::CacheA8, TextureSampler::CacheA8, &mut self.device); - self.texture_resolver.bind(&SourceTexture::CacheRGBA8, TextureSampler::CacheRGBA8, &mut self.device); + self.texture_resolver.bind( + &SourceTexture::CacheA8, + TextureSampler::CacheA8, + &mut self.device, + ); + self.texture_resolver.bind( + &SourceTexture::CacheRGBA8, + TextureSampler::CacheRGBA8, + &mut self.device, + ); for (target_index, target) in pass.alpha_targets.targets.iter().enumerate() { - let projection = Transform3D::ortho(0.0, - pass.max_alpha_target_size.width as f32, - 0.0, - pass.max_alpha_target_size.height as f32, - ORTHO_NEAR_PLANE, - ORTHO_FAR_PLANE); - - self.draw_alpha_target((pass.alpha_texture.as_ref().unwrap(), target_index as i32), - target, - pass.max_alpha_target_size, - &projection); + let projection = Transform3D::ortho( + 0.0, + pass.max_alpha_target_size.width as f32, + 0.0, + pass.max_alpha_target_size.height as f32, + ORTHO_NEAR_PLANE, + ORTHO_FAR_PLANE, + ); + + self.draw_alpha_target( + (pass.alpha_texture.as_ref().unwrap(), target_index as i32), + target, + pass.max_alpha_target_size, + &projection, + ); } for (target_index, target) in pass.color_targets.targets.iter().enumerate() { @@ -2681,55 +3147,67 @@ impl Renderer { if pass.is_framebuffer { clear_color = if self.clear_framebuffer || needs_clear { - Some(frame.background_color.map_or(self.clear_color.to_array(), |color| { - color.to_array() - })) + Some( + frame + .background_color + .map_or(self.clear_color.to_array(), |color| color.to_array()), + ) } else { None }; size = framebuffer_size; - projection = Transform3D::ortho(0.0, - size.width as f32, - size.height as f32, - 0.0, - ORTHO_NEAR_PLANE, - ORTHO_FAR_PLANE) + projection = Transform3D::ortho( + 0.0, + size.width as f32, + size.height as f32, + 0.0, + ORTHO_NEAR_PLANE, + ORTHO_FAR_PLANE, + ) } else { size = pass.max_color_target_size; clear_color = Some([0.0, 0.0, 0.0, 0.0]); - projection = Transform3D::ortho(0.0, - size.width as f32, - 0.0, - size.height as f32, - ORTHO_NEAR_PLANE, - ORTHO_FAR_PLANE); + projection = Transform3D::ortho( + 0.0, + size.width as f32, + 0.0, + size.height as f32, + ORTHO_NEAR_PLANE, + ORTHO_FAR_PLANE, + ); } - let render_target = pass.color_texture.as_ref().map(|texture| { - (texture, target_index as i32) - }); - self.draw_color_target(render_target, - target, - size, - clear_color, - &frame.render_tasks, - &projection, - frame_id); - + let render_target = pass.color_texture + .as_ref() + .map(|texture| (texture, target_index as i32)); + self.draw_color_target( + render_target, + target, + size, + clear_color, + &frame.render_tasks, + &projection, + frame_id, + ); } - self.texture_resolver.end_pass(pass_index, - pass_count, - pass.alpha_texture.take(), - pass.color_texture.take(), - &mut self.alpha_render_targets, - &mut self.color_render_targets); + self.texture_resolver.end_pass( + pass_index, + pass_count, + pass.alpha_texture.take(), + pass.color_texture.take(), + &mut self.alpha_render_targets, + &mut self.color_render_targets, + ); // After completing the first pass, make the A8 target available as an // input to any subsequent passes. if pass_index == 0 { - if let Some(shared_alpha_texture) = self.texture_resolver.resolve(&SourceTexture::CacheA8) { - self.device.bind_texture(TextureSampler::SharedCacheA8, shared_alpha_texture); + if let Some(shared_alpha_texture) = + self.texture_resolver.resolve(&SourceTexture::CacheA8) + { + self.device + .bind_texture(TextureSampler::SharedCacheA8, shared_alpha_texture); } } } @@ -2741,14 +3219,13 @@ impl Renderer { // Garbage collect any frame outputs that weren't used this frame. let device = &mut self.device; - self.output_targets.retain(|_, target| { - if target.last_access != frame_id { + self.output_targets + .retain(|_, target| if target.last_access != frame_id { device.delete_fbo(target.fbo_id); true } else { false - } - }); + }); } self.unlock_external_images(); @@ -2770,8 +3247,7 @@ impl Renderer { write_profile(filename); } - fn draw_render_target_debug(&mut self, - framebuffer_size: DeviceUintSize) { + fn draw_render_target_debug(&mut self, framebuffer_size: DeviceUintSize) { if !self.debug_flags.contains(RENDER_TARGET_DBG) { return; } @@ -2779,7 +3255,10 @@ impl Renderer { let mut spacing = 16; let mut size = 512; let fb_width = framebuffer_size.width as i32; - let num_textures = self.color_render_targets.iter().chain(self.alpha_render_targets.iter()).count() as i32; + let num_textures = self.color_render_targets + .iter() + .chain(self.alpha_render_targets.iter()) + .count() as i32; if num_textures * (size + spacing) > fb_width { let factor = fb_width as f32 / (num_textures * (size + spacing)) as f32; @@ -2787,14 +3266,18 @@ impl Renderer { spacing = (spacing as f32 * factor) as i32; } - for (i, texture) in self.color_render_targets.iter().chain(self.alpha_render_targets.iter()).enumerate() { + for (i, texture) in self.color_render_targets + .iter() + .chain(self.alpha_render_targets.iter()) + .enumerate() + { let dimensions = texture.get_dimensions(); - let src_rect = DeviceIntRect::new(DeviceIntPoint::zero(), - dimensions.to_i32()); + let src_rect = DeviceIntRect::new(DeviceIntPoint::zero(), dimensions.to_i32()); let layer_count = texture.get_render_target_layer_count(); - for layer_index in 0..layer_count { - self.device.bind_read_target(Some((texture, layer_index as i32))); + for layer_index in 0 .. layer_count { + self.device + .bind_read_target(Some((texture, layer_index as i32))); let x = fb_width - (spacing + size) * (i as i32 + 1); let y = spacing; @@ -2813,12 +3296,10 @@ impl Renderer { let mut size = 512; let fb_width = framebuffer_size.width as i32; let num_layers: i32 = self.texture_resolver - .cache_texture_map - .iter() - .map(|texture| { - texture.get_layer_count() - }) - .sum(); + .cache_texture_map + .iter() + .map(|texture| texture.get_layer_count()) + .sum(); if num_layers * (size + spacing) > fb_width { let factor = fb_width as f32 / (num_layers * (size + spacing)) as f32; @@ -2828,14 +3309,19 @@ impl Renderer { let mut i = 0; for texture in &self.texture_resolver.cache_texture_map { - let y = spacing + if self.debug_flags.contains(RENDER_TARGET_DBG) { 528 } else { 0 }; + let y = spacing + if self.debug_flags.contains(RENDER_TARGET_DBG) { + 528 + } else { + 0 + }; let dimensions = texture.get_dimensions(); - let src_rect = DeviceIntRect::new(DeviceIntPoint::zero(), - DeviceIntSize::new(dimensions.width as i32, - dimensions.height as i32)); + let src_rect = DeviceIntRect::new( + DeviceIntPoint::zero(), + DeviceIntSize::new(dimensions.width as i32, dimensions.height as i32), + ); let layer_count = texture.get_layer_count(); - for layer_index in 0..layer_count { + for layer_index in 0 .. layer_count { self.device.bind_read_target(Some((texture, layer_index))); let x = fb_width - (spacing + size) * (i as i32 + 1); @@ -2858,23 +3344,30 @@ impl Renderer { pixels } - pub fn read_pixels_into(&self, - rect: DeviceUintRect, - format: ReadPixelsFormat, - output: &mut [u8]) { + pub fn read_pixels_into( + &self, + rect: DeviceUintRect, + format: ReadPixelsFormat, + output: &mut [u8], + ) { let (gl_format, gl_type, size) = match format { ReadPixelsFormat::Rgba8 => (gl::RGBA, gl::UNSIGNED_BYTE, 4), ReadPixelsFormat::Bgra8 => (get_gl_format_bgra(self.device.gl()), gl::UNSIGNED_BYTE, 4), }; - assert_eq!(output.len(), (size * rect.size.width * rect.size.height) as usize); + assert_eq!( + output.len(), + (size * rect.size.width * rect.size.height) as usize + ); self.device.gl().flush(); - self.device.gl().read_pixels_into_buffer(rect.origin.x as gl::GLint, - rect.origin.y as gl::GLint, - rect.size.width as gl::GLsizei, - rect.size.height as gl::GLsizei, - gl_format, - gl_type, - output); + self.device.gl().read_pixels_into_buffer( + rect.origin.x as gl::GLint, + rect.origin.y as gl::GLint, + rect.size.width as gl::GLsizei, + rect.size.height as gl::GLsizei, + gl_format, + gl_type, + output, + ); } // De-initialize the Renderer safely, assuming the GL is still alive and active. @@ -2941,8 +3434,8 @@ impl Renderer { } pub enum ExternalImageSource<'a> { - RawData(&'a [u8]), // raw buffers. - NativeTexture(u32), // It's a gl::GLuint texture handle + RawData(&'a [u8]), // raw buffers. + NativeTexture(u32), // It's a gl::GLuint texture handle Invalid, } diff --git a/webrender/src/resource_cache.rs b/webrender/src/resource_cache.rs index d6d5cf73b8..53f18c3162 100644 --- a/webrender/src/resource_cache.rs +++ b/webrender/src/resource_cache.rs @@ -2,31 +2,31 @@ * 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 api::{AddFont, BlobImageData, BlobImageResources, ResourceUpdate, ResourceUpdates}; +use api::{BlobImageDescriptor, BlobImageError, BlobImageRenderer, BlobImageRequest}; +use api::{ColorF, FontRenderMode, SubpixelDirection}; +use api::{DevicePoint, DeviceUintRect, DeviceUintSize}; +use api::{Epoch, FontInstance, FontInstanceKey, FontKey, FontTemplate}; +use api::{ExternalImageData, ExternalImageType}; +use api::{FontInstanceOptions, FontInstancePlatformOptions}; +use api::{GlyphDimensions, GlyphKey, IdNamespace}; +use api::{ImageData, ImageDescriptor, ImageKey, ImageRendering}; +use api::{TileOffset, TileSize}; use app_units::Au; use device::TextureFilter; use frame::FrameId; use glyph_cache::GlyphCache; +use glyph_rasterizer::{GlyphRasterizer, GlyphRequest}; use gpu_cache::{GpuCache, GpuCacheAddress, GpuCacheHandle}; use internal_types::{FastHashMap, FastHashSet, SourceTexture, TextureUpdateList}; use profiler::{ResourceProfileCounters, TextureCacheProfileCounters}; +use rayon::ThreadPool; use std::collections::hash_map::Entry::{self, Occupied, Vacant}; use std::fmt::Debug; use std::hash::Hash; use std::mem; use std::sync::Arc; use texture_cache::{TextureCache, TextureCacheHandle}; -use api::{BlobImageRenderer, BlobImageDescriptor, BlobImageError, BlobImageRequest}; -use api::{BlobImageResources, BlobImageData, ResourceUpdates, ResourceUpdate, AddFont}; -use api::{DevicePoint, DeviceUintRect, DeviceUintSize}; -use api::{Epoch, FontInstance, FontInstanceKey, FontKey, FontTemplate}; -use api::{FontInstanceOptions, FontInstancePlatformOptions}; -use api::{ColorF, FontRenderMode, SubpixelDirection}; -use api::{GlyphDimensions, GlyphKey, IdNamespace}; -use api::{ImageData, ImageDescriptor, ImageKey, ImageRendering}; -use api::{TileOffset, TileSize}; -use api::{ExternalImageData, ExternalImageType}; -use rayon::ThreadPool; -use glyph_rasterizer::{GlyphRasterizer, GlyphRequest}; const DEFAULT_TILE_SIZE: TileSize = 512; @@ -69,7 +69,7 @@ struct ImageResource { descriptor: ImageDescriptor, epoch: Epoch, tiling: Option, - dirty_rect: Option + dirty_rect: Option, } #[derive(Debug)] @@ -87,7 +87,7 @@ struct ImageTemplates { impl ImageTemplates { fn new() -> Self { ImageTemplates { - images: FastHashMap::default() + images: FastHashMap::default(), } } @@ -113,12 +113,15 @@ struct CachedImageInfo { epoch: Epoch, } -pub struct ResourceClassCache { +pub struct ResourceClassCache { resources: FastHashMap, } -impl ResourceClassCache where K: Clone + Hash + Eq + Debug { - pub fn new() -> ResourceClassCache { +impl ResourceClassCache +where + K: Clone + Hash + Eq + Debug, +{ + pub fn new() -> ResourceClassCache { ResourceClassCache { resources: FastHashMap::default(), } @@ -138,7 +141,7 @@ impl ResourceClassCache where K: Clone + Hash + Eq + Debug { self.resources.get_mut(key) } - pub fn entry(&mut self, key: K) -> Entry { + pub fn entry(&mut self, key: K) -> Entry { self.resources.entry(key) } @@ -147,9 +150,11 @@ impl ResourceClassCache where K: Clone + Hash + Eq + Debug { } fn clear_keys(&mut self, key_fun: F) - where for<'r> F: Fn(&'r &K) -> bool + where + for<'r> F: Fn(&'r &K) -> bool, { - let resources_to_destroy = self.resources.keys() + let resources_to_destroy = self.resources + .keys() .filter(&key_fun) .cloned() .collect::>(); @@ -187,7 +192,9 @@ impl BlobImageResources for Resources { self.font_templates.get(&key).unwrap() } fn get_image(&self, key: ImageKey) -> Option<(&ImageData, &ImageDescriptor)> { - self.image_templates.get(key).map(|resource| { (&resource.data, &resource.descriptor) }) + self.image_templates + .get(key) + .map(|resource| (&resource.data, &resource.descriptor)) } } @@ -214,9 +221,11 @@ pub struct ResourceCache { } impl ResourceCache { - pub fn new(texture_cache: TextureCache, - workers: Arc, - blob_image_renderer: Option>) -> ResourceCache { + pub fn new( + texture_cache: TextureCache, + workers: Arc, + blob_image_renderer: Option>, + ) -> ResourceCache { ResourceCache { cached_glyphs: GlyphCache::new(), cached_images: ResourceClassCache::new(), @@ -243,19 +252,19 @@ impl ResourceCache { let limit = self.max_texture_size(); let size_check = descriptor.width > limit || descriptor.height > limit; match *data { - ImageData::Raw(_) | ImageData::Blob(_) => { size_check } + ImageData::Raw(_) | ImageData::Blob(_) => size_check, ImageData::External(info) => { // External handles already represent existing textures so it does // not make sense to tile them into smaller ones. info.image_type == ExternalImageType::ExternalBuffer && size_check - }, + } } } pub fn update_resources( &mut self, updates: ResourceUpdates, - profile_counters: &mut ResourceProfileCounters + profile_counters: &mut ResourceProfileCounters, ) { // TODO, there is potential for optimization here, by processing updates in // bulk rather than one by one (for example by sorting allocations by size or @@ -275,23 +284,26 @@ impl ResourceCache { ResourceUpdate::DeleteImage(img) => { self.delete_image_template(img); } - ResourceUpdate::AddFont(font) => { - match font { - AddFont::Raw(id, bytes, index) => { - profile_counters.font_templates.inc(bytes.len()); - self.add_font_template(id, FontTemplate::Raw(Arc::new(bytes), index)); - } - AddFont::Native(id, native_font_handle) => { - self.add_font_template(id, FontTemplate::Native(native_font_handle)); - } + ResourceUpdate::AddFont(font) => match font { + AddFont::Raw(id, bytes, index) => { + profile_counters.font_templates.inc(bytes.len()); + self.add_font_template(id, FontTemplate::Raw(Arc::new(bytes), index)); } - } + AddFont::Native(id, native_font_handle) => { + self.add_font_template(id, FontTemplate::Native(native_font_handle)); + } + }, ResourceUpdate::DeleteFont(font) => { self.delete_font_template(font); } ResourceUpdate::AddFontInstance(instance) => { - self.add_font_instance(instance.key, instance.font_key, instance.glyph_size, - instance.options, instance.platform_options); + self.add_font_instance( + instance.key, + instance.font_key, + instance.glyph_size, + instance.options, + instance.platform_options, + ); } ResourceUpdate::DeleteFontInstance(instance) => { self.delete_font_instance(instance); @@ -315,12 +327,14 @@ impl ResourceCache { } } - pub fn add_font_instance(&mut self, - instance_key: FontInstanceKey, - font_key: FontKey, - glyph_size: Au, - options: Option, - platform_options: Option) { + pub fn add_font_instance( + &mut self, + instance_key: FontInstanceKey, + font_key: FontKey, + glyph_size: Au, + options: Option, + platform_options: Option, + ) { let mut render_mode = FontRenderMode::Subpixel; let mut subpx_dir = SubpixelDirection::Horizontal; if let Some(options) = options { @@ -329,12 +343,14 @@ impl ResourceCache { subpx_dir = SubpixelDirection::None; } } - let instance = FontInstance::new(font_key, - glyph_size, - ColorF::new(0.0, 0.0, 0.0, 1.0), - render_mode, - subpx_dir, - platform_options); + let instance = FontInstance::new( + font_key, + glyph_size, + ColorF::new(0.0, 0.0, 0.0, 1.0), + render_mode, + subpx_dir, + platform_options, + ); self.resources.font_instances.insert(instance_key, instance); } @@ -349,11 +365,13 @@ impl ResourceCache { self.resources.font_instances.get(&instance_key) } - pub fn add_image_template(&mut self, - image_key: ImageKey, - descriptor: ImageDescriptor, - mut data: ImageData, - mut tiling: Option) { + pub fn add_image_template( + &mut self, + image_key: ImageKey, + descriptor: ImageDescriptor, + mut data: ImageData, + mut tiling: Option, + ) { if tiling.is_none() && self.should_tile(&descriptor, &data) { // We aren't going to be able to upload a texture this big, so tile it, even // if tiling was not requested. @@ -364,7 +382,7 @@ impl ResourceCache { self.blob_image_renderer.as_mut().unwrap().add( image_key, mem::replace(blob, BlobImageData::new()), - tiling + tiling, ); } @@ -379,13 +397,14 @@ impl ResourceCache { self.resources.image_templates.insert(image_key, resource); } - pub fn update_image_template(&mut self, - image_key: ImageKey, - descriptor: ImageDescriptor, - mut data: ImageData, - dirty_rect: Option) { + pub fn update_image_template( + &mut self, + image_key: ImageKey, + descriptor: ImageDescriptor, + mut data: ImageData, + dirty_rect: Option, + ) { let resource = if let Some(image) = self.resources.image_templates.get(image_key) { - let next_epoch = Epoch(image.epoch.0 + 1); let mut tiling = image.tiling; @@ -394,10 +413,10 @@ impl ResourceCache { } if let ImageData::Blob(ref mut blob) = data { - self.blob_image_renderer.as_mut().unwrap().update( - image_key, - mem::replace(blob, BlobImageData::new()) - ); + self.blob_image_renderer + .as_mut() + .unwrap() + .update(image_key, mem::replace(blob, BlobImageData::new())); } ImageResource { @@ -412,7 +431,10 @@ impl ResourceCache { }, } } else { - panic!("Attempt to update non-existant image (key {:?}).", image_key); + panic!( + "Attempt to update non-existant image (key {:?}).", + image_key + ); }; self.resources.image_templates.insert(image_key, resource); @@ -421,26 +443,26 @@ impl ResourceCache { pub fn delete_image_template(&mut self, image_key: ImageKey) { let value = self.resources.image_templates.remove(image_key); - self.cached_images.clear_keys(|request| request.key == image_key); + self.cached_images + .clear_keys(|request| request.key == image_key); match value { - Some(image) => { - if image.data.is_blob() { - self.blob_image_renderer.as_mut().unwrap().delete(image_key); - } - } + Some(image) => if image.data.is_blob() { + self.blob_image_renderer.as_mut().unwrap().delete(image_key); + }, None => { println!("Delete the non-exist key:{:?}", image_key); } } } - pub fn request_image(&mut self, - key: ImageKey, - rendering: ImageRendering, - tile: Option, - gpu_cache: &mut GpuCache) { - + pub fn request_image( + &mut self, + key: ImageKey, + rendering: ImageRendering, + tile: Option, + gpu_cache: &mut GpuCache, + ) { debug_assert_eq!(self.state, State::AddResources); let request = ImageRequest { key, @@ -463,17 +485,17 @@ impl ResourceCache { let needs_update = entry.get().epoch != template.epoch; (entry.into_mut(), needs_update) } - Vacant(entry) => { - (entry.insert(CachedImageInfo { + Vacant(entry) => ( + entry.insert(CachedImageInfo { epoch: template.epoch, texture_cache_handle: TextureCacheHandle::new(), - }), true) - } + }), + true, + ), }; let needs_upload = self.texture_cache - .request(&mut entry.texture_cache_handle, - gpu_cache); + .request(&mut entry.texture_cache_handle, gpu_cache); if !needs_upload && !needs_update { return; @@ -488,7 +510,11 @@ impl ResourceCache { let (offset, w, h) = match template.tiling { Some(tile_size) => { let tile_offset = request.tile.unwrap(); - let (w, h) = compute_tile_size(&template.descriptor, tile_size, tile_offset); + let (w, h) = compute_tile_size( + &template.descriptor, + tile_size, + tile_offset, + ); let offset = DevicePoint::new( tile_offset.x as f32 * tile_size as f32, tile_offset.y as f32 * tile_size as f32, @@ -496,9 +522,11 @@ impl ResourceCache { (offset, w, h) } - None => { - (DevicePoint::zero(), template.descriptor.width, template.descriptor.height) - } + None => ( + DevicePoint::zero(), + template.descriptor.width, + template.descriptor.height, + ), }; renderer.request( @@ -517,15 +545,20 @@ impl ResourceCache { } } None => { - warn!("ERROR: Trying to render deleted / non-existent key {:?}", key); + warn!( + "ERROR: Trying to render deleted / non-existent key {:?}", + key + ); } } } - pub fn request_glyphs(&mut self, - font: FontInstance, - glyph_keys: &[GlyphKey], - gpu_cache: &mut GpuCache) { + pub fn request_glyphs( + &mut self, + font: FontInstance, + glyph_keys: &[GlyphKey], + gpu_cache: &mut GpuCache, + ) { debug_assert_eq!(self.state, State::AddResources); self.glyph_rasterizer.request_glyphs( @@ -541,12 +574,16 @@ impl ResourceCache { self.texture_cache.pending_updates() } - pub fn fetch_glyphs(&self, - font: FontInstance, - glyph_keys: &[GlyphKey], - fetch_buffer: &mut Vec, - gpu_cache: &GpuCache, - mut f: F) where F: FnMut(SourceTexture, &[GlyphFetchResult]) { + pub fn fetch_glyphs( + &self, + font: FontInstance, + glyph_keys: &[GlyphKey], + fetch_buffer: &mut Vec, + gpu_cache: &GpuCache, + mut f: F, + ) where + F: FnMut(SourceTexture, &[GlyphFetchResult]), + { debug_assert_eq!(self.state, State::QueryResources); let glyph_key_cache = self.cached_glyphs.get_glyph_key_cache_for_font(&font); @@ -555,7 +592,9 @@ impl ResourceCache { for (loop_index, key) in glyph_keys.iter().enumerate() { let glyph = glyph_key_cache.get(key); - let cache_item = glyph.as_ref().map(|info| self.texture_cache.get(&info.texture_cache_handle)); + let cache_item = glyph + .as_ref() + .map(|info| self.texture_cache.get(&info.texture_cache_handle)); if let Some(cache_item) = cache_item { if current_texture_id != cache_item.texture_id { if !fetch_buffer.is_empty() { @@ -577,16 +616,19 @@ impl ResourceCache { } } - pub fn get_glyph_dimensions(&mut self, - font: &FontInstance, - key: &GlyphKey) -> Option { + pub fn get_glyph_dimensions( + &mut self, + font: &FontInstance, + key: &GlyphKey, + ) -> Option { let key = GlyphRequest::new(font, key); match self.cached_glyph_dimensions.entry(key.clone()) { Occupied(entry) => *entry.get(), - Vacant(entry) => { - *entry.insert(self.glyph_rasterizer.get_glyph_dimensions(&key.font, &key.key)) - } + Vacant(entry) => *entry.insert( + self.glyph_rasterizer + .get_glyph_dimensions(&key.font, &key.key), + ), } } @@ -595,10 +637,12 @@ impl ResourceCache { } #[inline] - pub fn get_cached_image(&self, - image_key: ImageKey, - image_rendering: ImageRendering, - tile: Option) -> CacheItem { + pub fn get_cached_image( + &self, + image_key: ImageKey, + image_rendering: ImageRendering, + tile: Option, + ) -> CacheItem { debug_assert_eq!(self.state, State::QueryResources); let key = ImageRequest { key: image_key, @@ -619,13 +663,11 @@ impl ResourceCache { ExternalImageType::Texture2DHandle | ExternalImageType::Texture2DArrayHandle | ExternalImageType::TextureRectHandle | - ExternalImageType::TextureExternalHandle => { - Some(ext_image) - }, + ExternalImageType::TextureExternalHandle => Some(ext_image), // external buffer uses resource_cache. ExternalImageType::ExternalBuffer => None, } - }, + } // raw and blob image are all using resource_cache. ImageData::Raw(..) | ImageData::Blob(..) => None, }; @@ -639,13 +681,25 @@ impl ResourceCache { } pub fn get_tiled_image_map(&self) -> TiledImageMap { - self.resources.image_templates.images.iter().filter_map(|(&key, template)| - template.tiling.map(|tile_size| (key, ImageTiling { - image_size: DeviceUintSize::new(template.descriptor.width, - template.descriptor.height), - tile_size, - })) - ).collect() + self.resources + .image_templates + .images + .iter() + .filter_map(|(&key, template)| { + template.tiling.map(|tile_size| { + ( + key, + ImageTiling { + image_size: DeviceUintSize::new( + template.descriptor.width, + template.descriptor.height, + ), + tile_size, + }, + ) + }) + }) + .collect() } pub fn begin_frame(&mut self, frame_id: FrameId) { @@ -655,9 +709,11 @@ impl ResourceCache { self.current_frame_id = frame_id; } - pub fn block_until_all_resources_added(&mut self, - gpu_cache: &mut GpuCache, - texture_cache_profile: &mut TextureCacheProfileCounters) { + pub fn block_until_all_resources_added( + &mut self, + gpu_cache: &mut GpuCache, + texture_cache_profile: &mut TextureCacheProfileCounters, + ) { profile_scope!("block_until_all_resources_added"); debug_assert_eq!(self.state, State::AddResources); @@ -688,7 +744,11 @@ impl ResourceCache { } ImageData::Blob(..) => { // Extract the rasterized image from the blob renderer. - match self.blob_image_renderer.as_mut().unwrap().resolve(request.into()) { + match self.blob_image_renderer + .as_mut() + .unwrap() + .resolve(request.into()) + { Ok(image) => ImageData::new(image.data), // TODO(nical): I think that we should handle these somewhat gracefully, // at least in the out-of-memory scenario. @@ -719,7 +779,8 @@ impl ResourceCache { let tile_size = image_template.tiling.unwrap(); let image_descriptor = &image_template.descriptor; - let (actual_width, actual_height) = compute_tile_size(image_descriptor, tile_size, tile); + let (actual_width, actual_height) = + compute_tile_size(image_descriptor, tile_size, tile); // The tiled image could be stored on the CPU as one large image or be // already broken up into tiles. This affects the way we compute the stride @@ -731,8 +792,9 @@ impl ResourceCache { } else { let bpp = image_descriptor.format.bytes_per_pixel(); let stride = image_descriptor.compute_stride(); - let offset = image_descriptor.offset + tile.y as u32 * tile_size as u32 * stride - + tile.x as u32 * tile_size as u32 * bpp; + let offset = image_descriptor.offset + + tile.y as u32 * tile_size as u32 * stride + + tile.x as u32 * tile_size as u32 * bpp; (Some(stride), offset) }; @@ -749,13 +811,15 @@ impl ResourceCache { }; let entry = self.cached_images.get_mut(&request).unwrap(); - self.texture_cache.update(&mut entry.texture_cache_handle, - descriptor, - filter, - image_data, - [0.0; 2], - image_template.dirty_rect, - gpu_cache); + self.texture_cache.update( + &mut entry.texture_cache_handle, + descriptor, + filter, + image_data, + [0.0; 2], + image_template.dirty_rect, + gpu_cache, + ); image_template.dirty_rect = None; } } @@ -780,31 +844,40 @@ impl ResourceCache { pub fn clear_namespace(&mut self, namespace: IdNamespace) { //TODO: use `retain` when we are on Rust-1.18 - let image_keys: Vec<_> = self.resources.image_templates.images.keys() - .filter(|&key| key.0 == namespace) - .cloned() - .collect(); + let image_keys: Vec<_> = self.resources + .image_templates + .images + .keys() + .filter(|&key| key.0 == namespace) + .cloned() + .collect(); for key in &image_keys { self.resources.image_templates.images.remove(key); } - let font_keys: Vec<_> = self.resources.font_templates.keys() - .filter(|&key| key.0 == namespace) - .cloned() - .collect(); + let font_keys: Vec<_> = self.resources + .font_templates + .keys() + .filter(|&key| key.0 == namespace) + .cloned() + .collect(); for key in &font_keys { self.resources.font_templates.remove(key); } - self.cached_images.clear_keys(|request| request.key.0 == namespace); - self.cached_glyphs.clear_fonts(|font| font.font_key.0 == namespace); + self.cached_images + .clear_keys(|request| request.key.0 == namespace); + self.cached_glyphs + .clear_fonts(|font| font.font_key.0 == namespace); } } // Compute the width and height of a tile depending on its position in the image. -pub fn compute_tile_size(descriptor: &ImageDescriptor, - base_size: TileSize, - tile: TileOffset) -> (u32, u32) { +pub fn compute_tile_size( + descriptor: &ImageDescriptor, + base_size: TileSize, + tile: TileOffset, +) -> (u32, u32) { let base_size = base_size as u32; // Most tiles are going to have base_size as width and height, // except for tiles around the edges that are shrunk to fit the mage data diff --git a/webrender/src/scene.rs b/webrender/src/scene.rs index 9e7a5fb3e3..215780a006 100644 --- a/webrender/src/scene.rs +++ b/webrender/src/scene.rs @@ -28,18 +28,21 @@ impl SceneProperties { self.float_properties.clear(); for property in properties.transforms { - self.transform_properties.insert(property.key.id, property.value); + self.transform_properties + .insert(property.key.id, property.value); } for property in properties.floats { - self.float_properties.insert(property.key.id, property.value); + self.float_properties + .insert(property.key.id, property.value); } } /// Get the current value for a transform property. - pub fn resolve_layout_transform(&self, - property: Option<&PropertyBinding>) - -> LayoutTransform { + pub fn resolve_layout_transform( + &self, + property: Option<&PropertyBinding>, + ) -> LayoutTransform { let property = match property { Some(property) => property, None => return LayoutTransform::identity(), @@ -47,15 +50,13 @@ impl SceneProperties { match *property { PropertyBinding::Value(matrix) => matrix, - PropertyBinding::Binding(ref key) => { - self.transform_properties - .get(&key.id) - .cloned() - .unwrap_or_else(|| { - warn!("Property binding {:?} has an invalid value.", key); - LayoutTransform::identity() - }) - } + PropertyBinding::Binding(ref key) => self.transform_properties + .get(&key.id) + .cloned() + .unwrap_or_else(|| { + warn!("Property binding {:?} has an invalid value.", key); + LayoutTransform::identity() + }), } } @@ -63,15 +64,13 @@ impl SceneProperties { pub fn resolve_float(&self, property: &PropertyBinding, default_value: f32) -> f32 { match *property { PropertyBinding::Value(value) => value, - PropertyBinding::Binding(ref key) => { - self.float_properties - .get(&key.id) - .cloned() - .unwrap_or_else(|| { - warn!("Property binding {:?} has an invalid value.", key); - default_value - }) - } + PropertyBinding::Binding(ref key) => self.float_properties + .get(&key.id) + .cloned() + .unwrap_or_else(|| { + warn!("Property binding {:?} has an invalid value.", key); + default_value + }), } } } @@ -108,13 +107,15 @@ impl Scene { self.root_pipeline_id = Some(pipeline_id); } - pub fn set_display_list(&mut self, - pipeline_id: PipelineId, - epoch: Epoch, - built_display_list: BuiltDisplayList, - background_color: Option, - viewport_size: LayerSize, - content_size: LayoutSize) { + pub fn set_display_list( + &mut self, + pipeline_id: PipelineId, + epoch: Epoch, + built_display_list: BuiltDisplayList, + background_color: Option, + viewport_size: LayerSize, + content_size: LayoutSize, + ) { self.display_lists.insert(pipeline_id, built_display_list); let new_pipeline = ScenePipeline { @@ -128,8 +129,7 @@ impl Scene { self.pipeline_map.insert(pipeline_id, new_pipeline); } - pub fn remove_pipeline(&mut self, - pipeline_id: PipelineId) { + pub fn remove_pipeline(&mut self, pipeline_id: PipelineId) { if self.root_pipeline_id == Some(pipeline_id) { self.root_pipeline_id = None; } diff --git a/webrender/src/spring.rs b/webrender/src/spring.rs index 1ce575af51..1db1204ee6 100644 --- a/webrender/src/spring.rs +++ b/webrender/src/spring.rs @@ -53,17 +53,24 @@ impl Spring { /// Run one tick of the spring animation. Return true if the animation is complete. pub fn animate(&mut self) -> bool { if !is_resting(self.cur.x, self.prev.x, self.dest.x) || - !is_resting(self.cur.y, self.prev.y, self.dest.y) { - let next = LayerPoint::new(next(self.cur.x, - self.prev.x, - self.dest.x, - self.stiffness, - self.damping), - next(self.cur.y, - self.prev.y, - self.dest.y, - self.stiffness, - self.damping)); + !is_resting(self.cur.y, self.prev.y, self.dest.y) + { + let next = LayerPoint::new( + next( + self.cur.x, + self.prev.x, + self.dest.x, + self.stiffness, + self.damping, + ), + next( + self.cur.y, + self.prev.y, + self.dest.y, + self.stiffness, + self.damping, + ), + ); let (cur, dest) = (self.cur, self.dest); self.coords(next, cur, dest); false diff --git a/webrender/src/texture_allocator.rs b/webrender/src/texture_allocator.rs index dd1c1a40db..771ab33376 100644 --- a/webrender/src/texture_allocator.rs +++ b/webrender/src/texture_allocator.rs @@ -41,17 +41,20 @@ impl GuillotineAllocator { page } - fn find_index_of_best_rect_in_bin(&self, bin: FreeListBin, requested_dimensions: &DeviceUintSize) - -> Option { + fn find_index_of_best_rect_in_bin( + &self, + bin: FreeListBin, + requested_dimensions: &DeviceUintSize, + ) -> Option { let mut smallest_index_and_area = None; for (candidate_index, candidate_rect) in self.free_list.iter(bin).enumerate() { if !requested_dimensions.fits_inside(&candidate_rect.size) { - continue + continue; } let candidate_area = candidate_rect.size.width * candidate_rect.size.height; smallest_index_and_area = Some((candidate_index, candidate_area)); - break + break; } smallest_index_and_area.map(|(index, _)| FreeListIndex(bin, index)) @@ -59,13 +62,16 @@ impl GuillotineAllocator { /// Find a suitable rect in the free list. We choose the smallest such rect /// in terms of area (Best-Area-Fit, BAF). - fn find_index_of_best_rect(&self, requested_dimensions: &DeviceUintSize) - -> Option { + fn find_index_of_best_rect( + &self, + requested_dimensions: &DeviceUintSize, + ) -> Option { let bin = FreeListBin::for_size(requested_dimensions); for &target_bin in &[FreeListBin::Small, FreeListBin::Medium, FreeListBin::Large] { if bin <= target_bin { - if let Some(index) = self.find_index_of_best_rect_in_bin(target_bin, - requested_dimensions) { + if let Some(index) = + self.find_index_of_best_rect_in_bin(target_bin, requested_dimensions) + { return Some(index); } } @@ -75,7 +81,7 @@ impl GuillotineAllocator { pub fn allocate(&mut self, requested_dimensions: &DeviceUintSize) -> Option { if requested_dimensions.width == 0 || requested_dimensions.height == 0 { - return Some(DeviceUintPoint::new(0, 0)) + return Some(DeviceUintPoint::new(0, 0)); } let index = match self.find_index_of_best_rect(requested_dimensions) { None => return None, @@ -85,18 +91,30 @@ impl GuillotineAllocator { // Remove the rect from the free list and decide how to guillotine it. We choose the split // that results in the single largest area (Min Area Split Rule, MINAS). let chosen_rect = self.free_list.remove(index); - let candidate_free_rect_to_right = - DeviceUintRect::new( - DeviceUintPoint::new(chosen_rect.origin.x + requested_dimensions.width, chosen_rect.origin.y), - DeviceUintSize::new(chosen_rect.size.width - requested_dimensions.width, requested_dimensions.height)); - let candidate_free_rect_to_bottom = - DeviceUintRect::new( - DeviceUintPoint::new(chosen_rect.origin.x, chosen_rect.origin.y + requested_dimensions.height), - DeviceUintSize::new(requested_dimensions.width, chosen_rect.size.height - requested_dimensions.height)); - let candidate_free_rect_to_right_area = candidate_free_rect_to_right.size.width * - candidate_free_rect_to_right.size.height; - let candidate_free_rect_to_bottom_area = candidate_free_rect_to_bottom.size.width * - candidate_free_rect_to_bottom.size.height; + let candidate_free_rect_to_right = DeviceUintRect::new( + DeviceUintPoint::new( + chosen_rect.origin.x + requested_dimensions.width, + chosen_rect.origin.y, + ), + DeviceUintSize::new( + chosen_rect.size.width - requested_dimensions.width, + requested_dimensions.height, + ), + ); + let candidate_free_rect_to_bottom = DeviceUintRect::new( + DeviceUintPoint::new( + chosen_rect.origin.x, + chosen_rect.origin.y + requested_dimensions.height, + ), + DeviceUintSize::new( + requested_dimensions.width, + chosen_rect.size.height - requested_dimensions.height, + ), + ); + let candidate_free_rect_to_right_area = + candidate_free_rect_to_right.size.width * candidate_free_rect_to_right.size.height; + let candidate_free_rect_to_bottom_area = + candidate_free_rect_to_bottom.size.width * candidate_free_rect_to_bottom.size.height; // Guillotine the rectangle. let new_free_rect_to_right; @@ -104,15 +122,21 @@ impl GuillotineAllocator { if candidate_free_rect_to_right_area > candidate_free_rect_to_bottom_area { new_free_rect_to_right = DeviceUintRect::new( candidate_free_rect_to_right.origin, - DeviceUintSize::new(candidate_free_rect_to_right.size.width, - chosen_rect.size.height)); + DeviceUintSize::new( + candidate_free_rect_to_right.size.width, + chosen_rect.size.height, + ), + ); new_free_rect_to_bottom = candidate_free_rect_to_bottom } else { new_free_rect_to_right = candidate_free_rect_to_right; - new_free_rect_to_bottom = - DeviceUintRect::new(candidate_free_rect_to_bottom.origin, - DeviceUintSize::new(chosen_rect.size.width, - candidate_free_rect_to_bottom.size.height)) + new_free_rect_to_bottom = DeviceUintRect::new( + candidate_free_rect_to_bottom.origin, + DeviceUintSize::new( + chosen_rect.size.width, + candidate_free_rect_to_bottom.size.height, + ), + ) } // Add the guillotined rects back to the free list. If any changes were made, we're now @@ -137,7 +161,8 @@ impl GuillotineAllocator { self.free_list = FreeRectList::new(); self.free_list.push(&DeviceUintRect::new( DeviceUintPoint::zero(), - self.texture_size)); + self.texture_size, + )); self.allocations = 0; self.dirty = false; } @@ -199,8 +224,8 @@ impl FreeListBin { fn for_size(size: &DeviceUintSize) -> FreeListBin { if size.width >= MINIMUM_LARGE_RECT_SIZE && size.height >= MINIMUM_LARGE_RECT_SIZE { FreeListBin::Large - } else if size.width >= MINIMUM_MEDIUM_RECT_SIZE && - size.height >= MINIMUM_MEDIUM_RECT_SIZE { + } else if size.width >= MINIMUM_MEDIUM_RECT_SIZE && size.height >= MINIMUM_MEDIUM_RECT_SIZE + { FreeListBin::Medium } else { debug_assert!(size.width > 0 && size.height > 0); diff --git a/webrender/src/texture_cache.rs b/webrender/src/texture_cache.rs index a204f41f10..e5dd1c55f3 100644 --- a/webrender/src/texture_cache.rs +++ b/webrender/src/texture_cache.rs @@ -2,19 +2,19 @@ * 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 api::{DeviceUintPoint, DeviceUintRect, DeviceUintSize}; +use api::{ExternalImageType, ImageData, ImageFormat}; +use api::ImageDescriptor; use device::TextureFilter; use frame::FrameId; use freelist::{FreeList, FreeListHandle, UpsertResult, WeakFreeListHandle}; use gpu_cache::{GpuCache, GpuCacheHandle}; -use internal_types::{SourceTexture, TextureUpdate, TextureUpdateOp}; use internal_types::{CacheTextureId, RenderTargetMode, TextureUpdateList, TextureUpdateSource}; +use internal_types::{SourceTexture, TextureUpdate, TextureUpdateOp}; use profiler::{ResourceProfileCounter, TextureCacheProfileCounters}; use resource_cache::CacheItem; use std::cmp; use std::mem; -use api::{ExternalImageType, ImageData, ImageFormat}; -use api::{DeviceUintRect, DeviceUintSize, DeviceUintPoint}; -use api::{ImageDescriptor}; // The fixed number of layers for the shared texture cache. // There is one array texture per image format, allocated lazily. @@ -45,9 +45,7 @@ impl CacheTextureIdList { // If nothing on the free list of texture IDs, // allocate a new one. match self.free_list.pop() { - Some(id) => { - id - } + Some(id) => id, None => { let id = CacheTextureId(self.next_id); self.next_id += 1; @@ -73,7 +71,7 @@ enum EntryKind { layer_index: u16, // The region that this entry belongs to in the layer. region_index: u16, - } + }, } // Stores information related to a single entry in the texture @@ -99,11 +97,13 @@ struct CacheEntry { impl CacheEntry { // Create a new entry for a standalone texture. - fn new_standalone(texture_id: CacheTextureId, - size: DeviceUintSize, - format: ImageFormat, - user_data: [f32; 2], - last_access: FrameId) -> CacheEntry { + fn new_standalone( + texture_id: CacheTextureId, + size: DeviceUintSize, + format: ImageFormat, + user_data: [f32; 2], + last_access: FrameId, + ) -> CacheEntry { CacheEntry { size, user_data, @@ -122,21 +122,20 @@ impl CacheEntry { fn update_gpu_cache(&mut self, gpu_cache: &mut GpuCache) { if let Some(mut request) = gpu_cache.request(&mut self.uv_rect_handle) { let (origin, layer_index) = match self.kind { - EntryKind::Standalone { .. } => { - (DeviceUintPoint::zero(), 0.0) - } - EntryKind::Cache { origin, layer_index, .. } => { - (origin, layer_index as f32) - } + EntryKind::Standalone { .. } => (DeviceUintPoint::zero(), 0.0), + EntryKind::Cache { + origin, + layer_index, + .. + } => (origin, layer_index as f32), }; - request.push([origin.x as f32, - origin.y as f32, - (origin.x + self.size.width) as f32, - (origin.y + self.size.height) as f32]); - request.push([layer_index, - self.user_data[0], - self.user_data[1], - 0.0]); + request.push([ + origin.x as f32, + origin.y as f32, + (origin.x + self.size.width) as f32, + (origin.y + self.size.height) as f32, + ]); + request.push([layer_index, self.user_data[0], self.user_data[1], 0.0]); } } } @@ -156,9 +155,7 @@ pub struct TextureCacheHandle { impl TextureCacheHandle { pub fn new() -> TextureCacheHandle { - TextureCacheHandle { - entry: None, - } + TextureCacheHandle { entry: None } } } @@ -227,10 +224,14 @@ impl TextureCache { pub fn end_frame(&mut self, texture_cache_profile: &mut TextureCacheProfileCounters) { self.expire_old_standalone_entries(); - self.array_a8.update_profile(&mut texture_cache_profile.pages_a8); - self.array_rg8.update_profile(&mut texture_cache_profile.pages_rg8); - self.array_rgb8.update_profile(&mut texture_cache_profile.pages_rgb8); - self.array_rgba8.update_profile(&mut texture_cache_profile.pages_rgba8); + self.array_a8 + .update_profile(&mut texture_cache_profile.pages_a8); + self.array_rg8 + .update_profile(&mut texture_cache_profile.pages_rg8); + self.array_rgb8 + .update_profile(&mut texture_cache_profile.pages_rgb8); + self.array_rgba8 + .update_profile(&mut texture_cache_profile.pages_rgba8); } // Request an item in the texture cache. All images that will @@ -241,9 +242,7 @@ impl TextureCache { // Returns true if the image needs to be uploaded to the // texture cache (either never uploaded, or has been // evicted on a previous frame). - pub fn request(&mut self, - handle: &mut TextureCacheHandle, - gpu_cache: &mut GpuCache) -> bool { + pub fn request(&mut self, handle: &mut TextureCacheHandle, gpu_cache: &mut GpuCache) -> bool { match handle.entry { Some(ref handle) => { match self.entries.get_opt_mut(handle) { @@ -254,14 +253,10 @@ impl TextureCache { entry.update_gpu_cache(gpu_cache); false } - None => { - true - } + None => true, } } - None => { - true - } + None => true, } } @@ -282,8 +277,8 @@ impl TextureCache { data: ImageData, user_data: [f32; 2], mut dirty_rect: Option, - gpu_cache: &mut GpuCache) { - + gpu_cache: &mut GpuCache, + ) { // Determine if we need to allocate texture cache memory // for this item. We need to reallocate if any of the following // is true: @@ -295,8 +290,8 @@ impl TextureCache { match self.entries.get_opt(handle) { Some(entry) => { entry.size.width != descriptor.width || - entry.size.height != descriptor.height || - entry.format != descriptor.format + entry.size.height != descriptor.height || + entry.format != descriptor.format } None => { // Was previously allocated but has been evicted. @@ -311,18 +306,15 @@ impl TextureCache { }; if realloc { - self.allocate(handle, - descriptor, - filter, - user_data); + self.allocate(handle, descriptor, filter, user_data); // If we reallocated, we need to upload the whole item again. dirty_rect = None; } let entry = self.entries - .get_opt_mut(handle.entry.as_ref().unwrap()) - .expect("BUG: handle must be valid now"); + .get_opt_mut(handle.entry.as_ref().unwrap()) + .expect("BUG: handle must be valid now"); // Invalidate the contents of the resource rect in the GPU cache. // This ensures that the update_gpu_cache below will add @@ -336,21 +328,23 @@ impl TextureCache { // to upload the new image data into the correct location // in GPU memory. let (layer_index, origin) = match entry.kind { - EntryKind::Standalone { .. } => { - (0, DeviceUintPoint::zero()) - } - EntryKind::Cache { layer_index, origin, .. } => { - (layer_index, origin) - } + EntryKind::Standalone { .. } => (0, DeviceUintPoint::zero()), + EntryKind::Cache { + layer_index, + origin, + .. + } => (layer_index, origin), }; - let op = TextureUpdate::new_update(data, - &descriptor, - origin, - entry.size, - entry.texture_id, - layer_index as i32, - dirty_rect); + let op = TextureUpdate::new_update( + data, + &descriptor, + origin, + entry.size, + entry.texture_id, + layer_index as i32, + dirty_rect, + ); self.pending_updates.push(op); } @@ -376,17 +370,15 @@ impl TextureCache { match handle.entry { Some(ref handle) => { let entry = self.entries - .get_opt(handle) - .expect("BUG: was dropped from cache or not updated!"); + .get_opt(handle) + .expect("BUG: was dropped from cache or not updated!"); debug_assert_eq!(entry.last_access, self.frame_id); CacheItem { uv_rect_handle: entry.uv_rect_handle, texture_id: SourceTexture::TextureCache(entry.texture_id), } } - None => { - panic!("BUG: handle not requested earlier in frame") - } + None => panic!("BUG: handle not requested earlier in frame"), } } @@ -467,15 +459,14 @@ impl TextureCache { // AND // - We have freed an item that will definitely allow us to // fit the currently requested allocation. - let needed_slab_size = SlabSize::new(required_alloc.width, - required_alloc.height).get_size(); + let needed_slab_size = + SlabSize::new(required_alloc.width, required_alloc.height).get_size(); let mut found_matching_slab = false; let mut freed_complete_page = false; let mut evicted_items = 0; for handle in eviction_candidates { - if evicted_items > 512 && - (found_matching_slab || freed_complete_page) { + if evicted_items > 512 && (found_matching_slab || freed_complete_page) { retained_entries.push(handle); } else { let entry = self.entries.free(handle); @@ -494,7 +485,7 @@ impl TextureCache { // Free a cache entry from the standalone list or shared cache. fn free(&mut self, entry: CacheEntry) -> Option<&TextureRegion> { match entry.kind { - EntryKind::Standalone { .. } => { + EntryKind::Standalone { .. } => { // This is a standalone texture allocation. Just push it back onto the free // list. self.pending_updates.push(TextureUpdate { @@ -504,7 +495,11 @@ impl TextureCache { self.cache_textures.free(entry.texture_id); None } - EntryKind::Cache { origin, region_index, .. } => { + EntryKind::Cache { + origin, + region_index, + .. + } => { // Free the block in the given region. let region = self.get_region_mut(entry.format, region_index); region.free(origin); @@ -514,9 +509,11 @@ impl TextureCache { } // Attempt to allocate a block from the shared cache. - fn allocate_from_shared_cache(&mut self, - descriptor: &ImageDescriptor, - user_data: [f32; 2]) -> Option { + fn allocate_from_shared_cache( + &mut self, + descriptor: &ImageDescriptor, + user_data: [f32; 2], + ) -> Option { // Work out which cache it goes in, based on format. let texture_array = match descriptor.format { ImageFormat::A8 => &mut self.array_a8, @@ -538,8 +535,8 @@ impl TextureCache { format: descriptor.format, filter: TextureFilter::Linear, layer_count: TEXTURE_ARRAY_LAYERS, - mode: RenderTargetMode::RenderTarget, // todo: !!!! remove me!? - } + mode: RenderTargetMode::RenderTarget, // todo: !!!! remove me!? + }, }; self.pending_updates.push(update_op); @@ -548,20 +545,24 @@ impl TextureCache { // Do the allocation. This can fail and return None // if there are no free slots or regions available. - texture_array.alloc(descriptor.width, - descriptor.height, - user_data, - self.frame_id) + texture_array.alloc( + descriptor.width, + descriptor.height, + user_data, + self.frame_id, + ) } // Allocate storage for a given image. This attempts to allocate // from the shared cache, but falls back to standalone texture // if the image is too large, or the cache is full. - fn allocate(&mut self, - handle: &mut TextureCacheHandle, - descriptor: ImageDescriptor, - filter: TextureFilter, - user_data: [f32; 2]) { + fn allocate( + &mut self, + handle: &mut TextureCacheHandle, + descriptor: ImageDescriptor, + filter: TextureFilter, + user_data: [f32; 2], + ) { assert!(descriptor.width > 0 && descriptor.height > 0); // Work out if this image qualifies to go in the shared (batching) cache. @@ -618,15 +619,17 @@ impl TextureCache { filter, mode: RenderTargetMode::RenderTarget, layer_count: 1, - } + }, }; self.pending_updates.push(update_op); - new_cache_entry = Some(CacheEntry::new_standalone(texture_id, - size, - descriptor.format, - user_data, - frame_id)); + new_cache_entry = Some(CacheEntry::new_standalone( + texture_id, + size, + descriptor.format, + user_data, + frame_id, + )); allocated_in_shared_cache = false; } @@ -655,9 +658,7 @@ impl TextureCache { self.free(old_entry); None } - UpsertResult::Inserted(new_handle) => { - Some(new_handle) - } + UpsertResult::Inserted(new_handle) => Some(new_handle), } } None => { @@ -700,12 +701,12 @@ impl SlabSize { match max_dim { 0 => unreachable!(), - 1 ... 16 => SlabSize::Size16x16, - 17 ... 32 => SlabSize::Size32x32, - 33 ... 64 => SlabSize::Size64x64, - 65 ... 128 => SlabSize::Size128x128, - 129 ... 256 => SlabSize::Size256x256, - 257 ... 512 => SlabSize::Size512x512, + 1...16 => SlabSize::Size16x16, + 17...32 => SlabSize::Size32x32, + 33...64 => SlabSize::Size64x64, + 65...128 => SlabSize::Size128x128, + 129...256 => SlabSize::Size256x256, + 257...512 => SlabSize::Size512x512, _ => panic!("Invalid dimensions for cache!"), } } @@ -751,9 +752,7 @@ struct TextureRegion { } impl TextureRegion { - fn new(region_size: u32, - layer_index: i32, - origin: DeviceUintPoint) -> TextureRegion { + fn new(region_size: u32, layer_index: i32, origin: DeviceUintPoint) -> TextureRegion { TextureRegion { layer_index, region_size, @@ -774,8 +773,8 @@ impl TextureRegion { self.slots_per_axis = self.region_size / self.slab_size; // Add each block to a freelist. - for y in 0..self.slots_per_axis { - for x in 0..self.slots_per_axis { + for y in 0 .. self.slots_per_axis { + for x in 0 .. self.slots_per_axis { self.free_slots.push(TextureLocation::new(x, y)); } } @@ -798,12 +797,12 @@ impl TextureRegion { // Attempt to allocate a fixed size block from this region. fn alloc(&mut self) -> Option { - self.free_slots - .pop() - .map(|location| { - DeviceUintPoint::new(self.origin.x + self.slab_size * location.x as u32, - self.origin.y + self.slab_size * location.y as u32) - }) + self.free_slots.pop().map(|location| { + DeviceUintPoint::new( + self.origin.x + self.slab_size * location.x as u32, + self.origin.y + self.slab_size * location.y as u32, + ) + }) } // Free a block in this region. @@ -843,10 +842,8 @@ impl TextureArray { fn update_profile(&self, counter: &mut ResourceProfileCounter) { if self.is_allocated { - let size = TEXTURE_ARRAY_LAYERS as u32 * - TEXTURE_LAYER_DIMENSIONS * - TEXTURE_LAYER_DIMENSIONS * - self.format.bytes_per_pixel(); + let size = TEXTURE_ARRAY_LAYERS as u32 * TEXTURE_LAYER_DIMENSIONS * + TEXTURE_LAYER_DIMENSIONS * self.format.bytes_per_pixel(); counter.set(TEXTURE_ARRAY_LAYERS as usize, size as usize); } else { counter.set(0, 0); @@ -854,25 +851,28 @@ impl TextureArray { } // Allocate space in this texture array. - fn alloc(&mut self, - width: u32, - height: u32, - user_data: [f32; 2], - frame_id: FrameId) -> Option { + fn alloc( + &mut self, + width: u32, + height: u32, + user_data: [f32; 2], + frame_id: FrameId, + ) -> Option { // Lazily allocate the regions if not already created. // This means that very rarely used image formats can be // added but won't allocate a cache if never used. if !self.is_allocated { debug_assert!(TEXTURE_LAYER_DIMENSIONS % TEXTURE_REGION_DIMENSIONS == 0); let regions_per_axis = TEXTURE_LAYER_DIMENSIONS / TEXTURE_REGION_DIMENSIONS; - for layer_index in 0..TEXTURE_ARRAY_LAYERS { - for y in 0..regions_per_axis { - for x in 0..regions_per_axis { - let origin = DeviceUintPoint::new(x * TEXTURE_REGION_DIMENSIONS, - y * TEXTURE_REGION_DIMENSIONS); - let region = TextureRegion::new(TEXTURE_REGION_DIMENSIONS, - layer_index, - origin); + for layer_index in 0 .. TEXTURE_ARRAY_LAYERS { + for y in 0 .. regions_per_axis { + for x in 0 .. regions_per_axis { + let origin = DeviceUintPoint::new( + x * TEXTURE_REGION_DIMENSIONS, + y * TEXTURE_REGION_DIMENSIONS, + ); + let region = + TextureRegion::new(TEXTURE_REGION_DIMENSIONS, layer_index, origin); self.regions.push(region); } } @@ -946,42 +946,38 @@ impl TextureUpdate { // Constructs a TextureUpdate operation to be passed to the // rendering thread in order to do an upload to the right // location in the texture cache. - fn new_update(data: ImageData, - descriptor: &ImageDescriptor, - origin: DeviceUintPoint, - size: DeviceUintSize, - texture_id: CacheTextureId, - layer_index: i32, - dirty_rect: Option) -> TextureUpdate { + fn new_update( + data: ImageData, + descriptor: &ImageDescriptor, + origin: DeviceUintPoint, + size: DeviceUintSize, + texture_id: CacheTextureId, + layer_index: i32, + dirty_rect: Option, + ) -> TextureUpdate { let data_src = match data { ImageData::Blob(..) => { panic!("The vector image should have been rasterized."); } - ImageData::External(ext_image) => { - match ext_image.image_type { - ExternalImageType::Texture2DHandle | - ExternalImageType::Texture2DArrayHandle | - ExternalImageType::TextureRectHandle | - ExternalImageType::TextureExternalHandle => { - panic!("External texture handle should not go through texture_cache."); - } - ExternalImageType::ExternalBuffer => { - TextureUpdateSource::External { - id: ext_image.id, - channel_index: ext_image.channel_index, - } - } + ImageData::External(ext_image) => match ext_image.image_type { + ExternalImageType::Texture2DHandle | + ExternalImageType::Texture2DArrayHandle | + ExternalImageType::TextureRectHandle | + ExternalImageType::TextureExternalHandle => { + panic!("External texture handle should not go through texture_cache."); } - } + ExternalImageType::ExternalBuffer => TextureUpdateSource::External { + id: ext_image.id, + channel_index: ext_image.channel_index, + }, + }, ImageData::Raw(bytes) => { let finish = descriptor.offset + - descriptor.width * descriptor.format.bytes_per_pixel() + - (descriptor.height-1) * descriptor.compute_stride(); + descriptor.width * descriptor.format.bytes_per_pixel() + + (descriptor.height - 1) * descriptor.compute_stride(); assert!(bytes.len() >= finish as usize); - TextureUpdateSource::Bytes { - data: bytes - } + TextureUpdateSource::Bytes { data: bytes } } }; @@ -989,8 +985,8 @@ impl TextureUpdate { Some(dirty) => { let stride = descriptor.compute_stride(); let offset = descriptor.offset + dirty.origin.y * stride + dirty.origin.x; - let origin = DeviceUintPoint::new(origin.x + dirty.origin.x, - origin.y + dirty.origin.y); + let origin = + DeviceUintPoint::new(origin.x + dirty.origin.x, origin.y + dirty.origin.y); TextureUpdateOp::Update { rect: DeviceUintRect::new(origin, dirty.size), source: data_src, @@ -999,15 +995,13 @@ impl TextureUpdate { layer_index, } } - None => { - TextureUpdateOp::Update { - rect: DeviceUintRect::new(origin, size), - source: data_src, - stride: descriptor.stride, - offset: descriptor.offset, - layer_index, - } - } + None => TextureUpdateOp::Update { + rect: DeviceUintRect::new(origin, size), + source: data_src, + stride: descriptor.stride, + offset: descriptor.offset, + layer_index, + }, }; TextureUpdate { diff --git a/webrender/src/tiling.rs b/webrender/src/tiling.rs index 9b4f8910b0..b95ac2d971 100644 --- a/webrender/src/tiling.rs +++ b/webrender/src/tiling.rs @@ -2,16 +2,21 @@ * 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 api::{BuiltDisplayList, ClipAndScrollInfo, ClipId, ColorF, DeviceIntPoint, ImageKey}; +use api::{DeviceIntRect, DeviceIntSize, DeviceUintPoint, DeviceUintSize}; +use api::{ExternalImageType, FilterOp, FontRenderMode, ImageRendering, LayerRect}; +use api::{LayerToWorldTransform, MixBlendMode, PipelineId, PropertyBinding, TransformStyle}; +use api::{LayerVector2D, TileOffset, WorldToLayerTransform, YuvColorSpace, YuvFormat}; use border::{BorderCornerInstance, BorderCornerSide}; use clip::{ClipSource, ClipStore}; use device::Texture; use gpu_cache::{GpuCache, GpuCacheAddress, GpuCacheHandle, GpuCacheUpdateList}; use gpu_types::{BlurDirection, BlurInstance, BoxShadowCacheInstance, ClipMaskInstance}; use gpu_types::{CompositePrimitiveInstance, PrimitiveInstance, SimplePrimitiveInstance}; -use internal_types::BatchTextures; use internal_types::{FastHashMap, SourceTexture}; -use prim_store::{DeferredResolve}; +use internal_types::BatchTextures; use prim_store::{PrimitiveIndex, PrimitiveKind, PrimitiveMetadata, PrimitiveStore}; +use prim_store::DeferredResolve; use profiler::FrameProfileCounters; use render_task::{AlphaRenderItem, ClipWorkItem, MaskGeometryKind, MaskSegment}; use render_task::{RenderTaskAddress, RenderTaskId, RenderTaskKey, RenderTaskKind}; @@ -19,14 +24,9 @@ use render_task::{RenderTaskLocation, RenderTaskTree}; use renderer::BlendMode; use renderer::ImageBufferKind; use resource_cache::{GlyphFetchResult, ResourceCache}; -use std::{cmp, f32, i32, usize}; +use std::{cmp, usize, f32, i32}; use texture_allocator::GuillotineAllocator; use util::{TransformedRect, TransformedRectKind}; -use api::{BuiltDisplayList, ClipAndScrollInfo, ClipId, ColorF, DeviceIntPoint, ImageKey}; -use api::{DeviceIntRect, DeviceIntSize, DeviceUintPoint, DeviceUintSize}; -use api::{ExternalImageType, FilterOp, FontRenderMode, ImageRendering, LayerRect}; -use api::{LayerToWorldTransform, MixBlendMode, PipelineId, PropertyBinding, TransformStyle}; -use api::{TileOffset, WorldToLayerTransform, YuvColorSpace, YuvFormat, LayerVector2D}; // Special sentinel value recognized by the shader. It is considered to be // a dummy task that doesn't mask out anything. @@ -36,18 +36,21 @@ const MIN_TARGET_SIZE: u32 = 2048; pub type DisplayListMap = FastHashMap; trait AlphaBatchHelpers { - fn get_blend_mode(&self, - metadata: &PrimitiveMetadata, - transform_kind: TransformedRectKind) -> BlendMode; + fn get_blend_mode( + &self, + metadata: &PrimitiveMetadata, + transform_kind: TransformedRectKind, + ) -> BlendMode; } impl AlphaBatchHelpers for PrimitiveStore { - fn get_blend_mode(&self, - metadata: &PrimitiveMetadata, - transform_kind: TransformedRectKind) -> BlendMode { - let needs_blending = !metadata.opacity.is_opaque || - metadata.clip_task_id.is_some() || - transform_kind == TransformedRectKind::Complex; + fn get_blend_mode( + &self, + metadata: &PrimitiveMetadata, + transform_kind: TransformedRectKind, + ) -> BlendMode { + let needs_blending = !metadata.opacity.is_opaque || metadata.clip_task_id.is_some() || + transform_kind == TransformedRectKind::Complex; match metadata.prim_kind { PrimitiveKind::TextRun => { @@ -61,20 +64,16 @@ impl AlphaBatchHelpers for PrimitiveStore { PrimitiveKind::AlignedGradient | PrimitiveKind::AngleGradient | PrimitiveKind::RadialGradient | - PrimitiveKind::TextShadow => { - if needs_blending { - BlendMode::PremultipliedAlpha - } else { - BlendMode::None - } - } - _ => { - if needs_blending { - BlendMode::Alpha - } else { - BlendMode::None - } - } + PrimitiveKind::TextShadow => if needs_blending { + BlendMode::PremultipliedAlpha + } else { + BlendMode::None + }, + _ => if needs_blending { + BlendMode::Alpha + } else { + BlendMode::None + }, } } } @@ -96,7 +95,7 @@ pub enum PrimitiveRunCmd { #[derive(Debug, Copy, Clone)] pub enum PrimitiveFlags { None, - Scrollbar(ClipId, f32) + Scrollbar(ClipId, f32), } #[derive(Debug, Copy, Clone)] @@ -122,9 +121,11 @@ impl AlphaBatchList { } } - fn get_suitable_batch(&mut self, - key: BatchKey, - item_bounding_rect: &DeviceIntRect) -> &mut Vec { + fn get_suitable_batch( + &mut self, + key: BatchKey, + item_bounding_rect: &DeviceIntRect, + ) -> &mut Vec { let mut selected_batch_index = None; // Composites always get added to their own batch. @@ -133,25 +134,20 @@ impl AlphaBatchList { // optimize this in the future. match key.kind { BatchKind::Composite { .. } => {} - _ => { - 'outer: for (batch_index, batch) in self.batches - .iter() - .enumerate() - .rev() - .take(10) { - if batch.key.is_compatible_with(&key) { - selected_batch_index = Some(batch_index); - break; - } + _ => 'outer: for (batch_index, batch) in self.batches.iter().enumerate().rev().take(10) + { + if batch.key.is_compatible_with(&key) { + selected_batch_index = Some(batch_index); + break; + } - // check for intersections - for item_rect in &batch.item_rects { - if item_rect.intersects(item_bounding_rect) { - break 'outer; - } + // check for intersections + for item_rect in &batch.item_rects { + if item_rect.intersects(item_bounding_rect) { + break 'outer; } } - } + }, } if selected_batch_index.is_none() { @@ -178,15 +174,10 @@ impl OpaqueBatchList { } } - fn get_suitable_batch(&mut self, - key: BatchKey) -> &mut Vec { + fn get_suitable_batch(&mut self, key: BatchKey) -> &mut Vec { let mut selected_batch_index = None; - for (batch_index, batch) in self.batches - .iter() - .enumerate() - .rev() - .take(10) { + for (batch_index, batch) in self.batches.iter().enumerate().rev().take(10) { if batch.key.is_compatible_with(&key) { selected_batch_index = Some(batch_index); break; @@ -230,15 +221,16 @@ impl BatchList { } } - fn get_suitable_batch(&mut self, - key: BatchKey, - item_bounding_rect: &DeviceIntRect) -> &mut Vec { + fn get_suitable_batch( + &mut self, + key: BatchKey, + item_bounding_rect: &DeviceIntRect, + ) -> &mut Vec { match key.blend_mode { - BlendMode::None => { - self.opaque_batch_list.get_suitable_batch(key) - } + BlendMode::None => self.opaque_batch_list.get_suitable_batch(key), BlendMode::Alpha | BlendMode::PremultipliedAlpha | BlendMode::Subpixel(..) => { - self.alpha_batch_list.get_suitable_batch(key, item_bounding_rect) + self.alpha_batch_list + .get_suitable_batch(key, item_bounding_rect) } } } @@ -256,21 +248,25 @@ pub struct AlphaBatcher { } impl AlphaRenderItem { - fn add_to_batch(&self, - batch_list: &mut BatchList, - ctx: &RenderTargetContext, - gpu_cache: &mut GpuCache, - render_tasks: &RenderTaskTree, - task_id: RenderTaskId, - task_address: RenderTaskAddress, - deferred_resolves: &mut Vec, - glyph_fetch_buffer: &mut Vec) { + fn add_to_batch( + &self, + batch_list: &mut BatchList, + ctx: &RenderTargetContext, + gpu_cache: &mut GpuCache, + render_tasks: &RenderTaskTree, + task_id: RenderTaskId, + task_address: RenderTaskAddress, + deferred_resolves: &mut Vec, + glyph_fetch_buffer: &mut Vec, + ) { match *self { AlphaRenderItem::Blend(stacking_context_index, src_id, filter, z) => { let stacking_context = &ctx.stacking_context_store[stacking_context_index.0]; - let key = BatchKey::new(BatchKind::Blend, - BlendMode::PremultipliedAlpha, - BatchTextures::no_texture()); + let key = BatchKey::new( + BatchKind::Blend, + BlendMode::PremultipliedAlpha, + BatchTextures::no_texture(), + ); let src_task_address = render_tasks.get_task_address(src_id); let (filter_mode, amount) = match filter { @@ -289,51 +285,67 @@ impl AlphaRenderItem { let amount = (amount * 65535.0).round() as i32; let batch = batch_list.get_suitable_batch(key, &stacking_context.screen_bounds); - let instance = CompositePrimitiveInstance::new(task_address, - src_task_address, - RenderTaskAddress(0), - filter_mode, - amount, - z); + let instance = CompositePrimitiveInstance::new( + task_address, + src_task_address, + RenderTaskAddress(0), + filter_mode, + amount, + z, + ); batch.push(PrimitiveInstance::from(instance)); } - AlphaRenderItem::HardwareComposite(stacking_context_index, src_id, composite_op, screen_origin, z) => { + AlphaRenderItem::HardwareComposite( + stacking_context_index, + src_id, + composite_op, + screen_origin, + z, + ) => { let stacking_context = &ctx.stacking_context_store[stacking_context_index.0]; let src_task_address = render_tasks.get_task_address(src_id); - let key = BatchKey::new(BatchKind::HardwareComposite, - composite_op.to_blend_mode(), - BatchTextures::no_texture()); + let key = BatchKey::new( + BatchKind::HardwareComposite, + composite_op.to_blend_mode(), + BatchTextures::no_texture(), + ); let batch = batch_list.get_suitable_batch(key, &stacking_context.screen_bounds); - let instance = CompositePrimitiveInstance::new(task_address, - src_task_address, - RenderTaskAddress(0), - screen_origin.x, - screen_origin.y, - z); + let instance = CompositePrimitiveInstance::new( + task_address, + src_task_address, + RenderTaskAddress(0), + screen_origin.x, + screen_origin.y, + z, + ); batch.push(PrimitiveInstance::from(instance)); } - AlphaRenderItem::Composite(stacking_context_index, - source_id, - backdrop_id, - mode, - z) => { + AlphaRenderItem::Composite(stacking_context_index, source_id, backdrop_id, mode, z) => { let stacking_context = &ctx.stacking_context_store[stacking_context_index.0]; - let key = BatchKey::new(BatchKind::Composite { task_id, source_id, backdrop_id }, - BlendMode::Alpha, - BatchTextures::no_texture()); + let key = BatchKey::new( + BatchKind::Composite { + task_id, + source_id, + backdrop_id, + }, + BlendMode::Alpha, + BatchTextures::no_texture(), + ); let batch = batch_list.get_suitable_batch(key, &stacking_context.screen_bounds); let backdrop_task_address = render_tasks.get_task_address(backdrop_id); let source_task_address = render_tasks.get_task_address(source_id); - let instance = CompositePrimitiveInstance::new(task_address, - source_task_address, - backdrop_task_address, - mode as u32 as i32, - 0, - z); + let instance = CompositePrimitiveInstance::new( + task_address, + source_task_address, + backdrop_task_address, + mode as u32 as i32, + 0, + z, + ); batch.push(PrimitiveInstance::from(instance)); } @@ -344,66 +356,92 @@ impl AlphaRenderItem { let group = &ctx.clip_scroll_group_store[group_index.0]; let bounding_rect = group.screen_bounding_rect.as_ref().unwrap(); (bounding_rect.0, group.packed_layer_index) - }, + } None => (TransformedRectKind::AxisAligned, PackedLayerIndex(0)), }; - let item_bounding_rect = ctx.prim_store.cpu_bounding_rects[prim_index.0].as_ref().unwrap(); + let item_bounding_rect = ctx.prim_store.cpu_bounding_rects[prim_index.0] + .as_ref() + .unwrap(); let prim_cache_address = gpu_cache.get_address(&prim_metadata.gpu_location); let no_textures = BatchTextures::no_texture(); - let clip_task_address = prim_metadata.clip_task_id.map_or(OPAQUE_TASK_ADDRESS, |id| { - render_tasks.get_task_address(id) - }); - let base_instance = SimplePrimitiveInstance::new(prim_cache_address, - task_address, - clip_task_address, - packed_layer_index.into(), - z); + let clip_task_address = prim_metadata + .clip_task_id + .map_or(OPAQUE_TASK_ADDRESS, |id| render_tasks.get_task_address(id)); + let base_instance = SimplePrimitiveInstance::new( + prim_cache_address, + task_address, + clip_task_address, + packed_layer_index.into(), + z, + ); let blend_mode = ctx.prim_store.get_blend_mode(prim_metadata, transform_kind); match prim_metadata.prim_kind { PrimitiveKind::Border => { - let border_cpu = &ctx.prim_store.cpu_borders[prim_metadata.cpu_prim_index.0]; + let border_cpu = + &ctx.prim_store.cpu_borders[prim_metadata.cpu_prim_index.0]; // TODO(gw): Select correct blend mode for edges and corners!! - let corner_kind = BatchKind::Transformable(transform_kind, TransformBatchKind::BorderCorner); + let corner_kind = BatchKind::Transformable( + transform_kind, + TransformBatchKind::BorderCorner, + ); let corner_key = BatchKey::new(corner_kind, blend_mode, no_textures); - let edge_kind = BatchKind::Transformable(transform_kind, TransformBatchKind::BorderEdge); + let edge_kind = BatchKind::Transformable( + transform_kind, + TransformBatchKind::BorderEdge, + ); let edge_key = BatchKey::new(edge_kind, blend_mode, no_textures); // Work around borrow ck on borrowing batch_list twice. { - let batch = batch_list.get_suitable_batch(corner_key, item_bounding_rect); - for (i, instance_kind) in border_cpu.corner_instances.iter().enumerate() { + let batch = + batch_list.get_suitable_batch(corner_key, item_bounding_rect); + for (i, instance_kind) in border_cpu.corner_instances.iter().enumerate() + { let sub_index = i as i32; match *instance_kind { BorderCornerInstance::Single => { - batch.push(base_instance.build(sub_index, - BorderCornerSide::Both as i32, 0)); + batch.push(base_instance.build( + sub_index, + BorderCornerSide::Both as i32, + 0, + )); } BorderCornerInstance::Double => { - batch.push(base_instance.build(sub_index, - BorderCornerSide::First as i32, 0)); - batch.push(base_instance.build(sub_index, - BorderCornerSide::Second as i32, 0)); + batch.push(base_instance.build( + sub_index, + BorderCornerSide::First as i32, + 0, + )); + batch.push(base_instance.build( + sub_index, + BorderCornerSide::Second as i32, + 0, + )); } } } } let batch = batch_list.get_suitable_batch(edge_key, item_bounding_rect); - for border_segment in 0..4 { + for border_segment in 0 .. 4 { batch.push(base_instance.build(border_segment, 0, 0)); } } PrimitiveKind::Rectangle => { let needs_clipping = prim_metadata.clip_task_id.is_some(); - let kind = BatchKind::Transformable(transform_kind, TransformBatchKind::Rectangle(needs_clipping)); + let kind = BatchKind::Transformable( + transform_kind, + TransformBatchKind::Rectangle(needs_clipping), + ); let key = BatchKey::new(kind, blend_mode, no_textures); let batch = batch_list.get_suitable_batch(key, item_bounding_rect); batch.push(base_instance.build(0, 0, 0)); } PrimitiveKind::Line => { - let kind = BatchKind::Transformable(transform_kind, TransformBatchKind::Line); + let kind = + BatchKind::Transformable(transform_kind, TransformBatchKind::Line); let key = BatchKey::new(kind, blend_mode, no_textures); let batch = batch_list.get_suitable_batch(key, item_bounding_rect); batch.push(base_instance.build(0, 0, 0)); @@ -411,12 +449,14 @@ impl AlphaRenderItem { PrimitiveKind::Image => { let image_cpu = &ctx.prim_store.cpu_images[prim_metadata.cpu_prim_index.0]; - let (color_texture_id, uv_address) = resolve_image(image_cpu.image_key, - image_cpu.image_rendering, - image_cpu.tile_offset, - ctx.resource_cache, - gpu_cache, - deferred_resolves); + let (color_texture_id, uv_address) = resolve_image( + image_cpu.image_key, + image_cpu.image_rendering, + image_cpu.tile_offset, + ctx.resource_cache, + gpu_cache, + deferred_resolves, + ); if color_texture_id == SourceTexture::Invalid { return; @@ -425,83 +465,125 @@ impl AlphaRenderItem { let batch_kind = match color_texture_id { SourceTexture::External(ext_image) => { match ext_image.image_type { - ExternalImageType::Texture2DHandle => TransformBatchKind::Image(ImageBufferKind::Texture2D), - ExternalImageType::Texture2DArrayHandle => TransformBatchKind::Image(ImageBufferKind::Texture2DArray), - ExternalImageType::TextureRectHandle => TransformBatchKind::Image(ImageBufferKind::TextureRect), - ExternalImageType::TextureExternalHandle => TransformBatchKind::Image(ImageBufferKind::TextureExternal), + ExternalImageType::Texture2DHandle => { + TransformBatchKind::Image(ImageBufferKind::Texture2D) + } + ExternalImageType::Texture2DArrayHandle => { + TransformBatchKind::Image(ImageBufferKind::Texture2DArray) + } + ExternalImageType::TextureRectHandle => { + TransformBatchKind::Image(ImageBufferKind::TextureRect) + } + ExternalImageType::TextureExternalHandle => { + TransformBatchKind::Image(ImageBufferKind::TextureExternal) + } ExternalImageType::ExternalBuffer => { // The ExternalImageType::ExternalBuffer should be handled by resource_cache. // It should go through the non-external case. - panic!("Non-texture handle type should be handled in other way."); + panic!( + "Non-texture handle type should be handled in other way" + ); } } } - _ => { - TransformBatchKind::Image(ImageBufferKind::Texture2DArray) - } + _ => TransformBatchKind::Image(ImageBufferKind::Texture2DArray), }; let textures = BatchTextures { - colors: [color_texture_id, SourceTexture::Invalid, SourceTexture::Invalid], + colors: [ + color_texture_id, + SourceTexture::Invalid, + SourceTexture::Invalid, + ], }; - let key = BatchKey::new(BatchKind::Transformable(transform_kind, batch_kind), blend_mode, textures); + let key = BatchKey::new( + BatchKind::Transformable(transform_kind, batch_kind), + blend_mode, + textures, + ); let batch = batch_list.get_suitable_batch(key, item_bounding_rect); batch.push(base_instance.build(uv_address.as_int(gpu_cache), 0, 0)); } PrimitiveKind::TextRun => { - let text_cpu = &ctx.prim_store.cpu_text_runs[prim_metadata.cpu_prim_index.0]; + let text_cpu = + &ctx.prim_store.cpu_text_runs[prim_metadata.cpu_prim_index.0]; let mut font = text_cpu.font.clone(); font.size = font.size.scale_by(ctx.device_pixel_ratio); - ctx.resource_cache.fetch_glyphs(font, - &text_cpu.glyph_keys, - glyph_fetch_buffer, - gpu_cache, - |texture_id, glyphs| { - let textures = BatchTextures { - colors: [texture_id, SourceTexture::Invalid, SourceTexture::Invalid], - }; - - let kind = BatchKind::Transformable(transform_kind, TransformBatchKind::TextRun); - let key = BatchKey::new(kind, blend_mode, textures); - let batch = batch_list.get_suitable_batch(key, item_bounding_rect); - - for glyph in glyphs { - batch.push(base_instance.build(glyph.index_in_text_run, - glyph.uv_rect_address.as_int(), - 0)); - } - }); + ctx.resource_cache.fetch_glyphs( + font, + &text_cpu.glyph_keys, + glyph_fetch_buffer, + gpu_cache, + |texture_id, glyphs| { + let textures = BatchTextures { + colors: [ + texture_id, + SourceTexture::Invalid, + SourceTexture::Invalid, + ], + }; + + let kind = BatchKind::Transformable( + transform_kind, + TransformBatchKind::TextRun, + ); + let key = BatchKey::new(kind, blend_mode, textures); + let batch = batch_list.get_suitable_batch(key, item_bounding_rect); + + for glyph in glyphs { + batch.push(base_instance.build( + glyph.index_in_text_run, + glyph.uv_rect_address.as_int(), + 0, + )); + } + }, + ); } PrimitiveKind::TextShadow => { - let text_shadow = &ctx.prim_store.cpu_text_shadows[prim_metadata.cpu_prim_index.0]; + let text_shadow = + &ctx.prim_store.cpu_text_shadows[prim_metadata.cpu_prim_index.0]; let cache_task_id = text_shadow.render_task_id.expect("no render task!"); let cache_task_address = render_tasks.get_task_address(cache_task_id); let textures = BatchTextures::render_target_cache(); - let kind = BatchKind::Transformable(transform_kind, TransformBatchKind::CacheImage); + let kind = BatchKind::Transformable( + transform_kind, + TransformBatchKind::CacheImage, + ); let key = BatchKey::new(kind, blend_mode, textures); let batch = batch_list.get_suitable_batch(key, item_bounding_rect); batch.push(base_instance.build(0, cache_task_address.0 as i32, 0)); } PrimitiveKind::AlignedGradient => { - let gradient_cpu = &ctx.prim_store.cpu_gradients[prim_metadata.cpu_prim_index.0]; - let kind = BatchKind::Transformable(transform_kind, TransformBatchKind::AlignedGradient); + let gradient_cpu = + &ctx.prim_store.cpu_gradients[prim_metadata.cpu_prim_index.0]; + let kind = BatchKind::Transformable( + transform_kind, + TransformBatchKind::AlignedGradient, + ); let key = BatchKey::new(kind, blend_mode, no_textures); let batch = batch_list.get_suitable_batch(key, item_bounding_rect); - for part_index in 0..(gradient_cpu.stops_count - 1) { + for part_index in 0 .. (gradient_cpu.stops_count - 1) { batch.push(base_instance.build(part_index as i32, 0, 0)); } } PrimitiveKind::AngleGradient => { - let kind = BatchKind::Transformable(transform_kind, TransformBatchKind::AngleGradient); + let kind = BatchKind::Transformable( + transform_kind, + TransformBatchKind::AngleGradient, + ); let key = BatchKey::new(kind, blend_mode, no_textures); let batch = batch_list.get_suitable_batch(key, item_bounding_rect); batch.push(base_instance.build(0, 0, 0)); } PrimitiveKind::RadialGradient => { - let kind = BatchKind::Transformable(transform_kind, TransformBatchKind::RadialGradient); + let kind = BatchKind::Transformable( + transform_kind, + TransformBatchKind::RadialGradient, + ); let key = BatchKey::new(kind, blend_mode, no_textures); let batch = batch_list.get_suitable_batch(key, item_bounding_rect); batch.push(base_instance.build(0, 0, 0)); @@ -509,20 +591,23 @@ impl AlphaRenderItem { PrimitiveKind::YuvImage => { let mut textures = BatchTextures::no_texture(); let mut uv_rect_addresses = [0; 3]; - let image_yuv_cpu = &ctx.prim_store.cpu_yuv_images[prim_metadata.cpu_prim_index.0]; + let image_yuv_cpu = + &ctx.prim_store.cpu_yuv_images[prim_metadata.cpu_prim_index.0]; //yuv channel let channel_count = image_yuv_cpu.format.get_plane_num(); debug_assert!(channel_count <= 3); - for channel in 0..channel_count { + for channel in 0 .. channel_count { let image_key = image_yuv_cpu.yuv_key[channel]; - let (texture, address) = resolve_image(image_key, - image_yuv_cpu.image_rendering, - None, - ctx.resource_cache, - gpu_cache, - deferred_resolves); + let (texture, address) = resolve_image( + image_key, + image_yuv_cpu.image_rendering, + None, + ctx.resource_cache, + gpu_cache, + deferred_resolves, + ); if texture == SourceTexture::Invalid { return; @@ -536,72 +621,95 @@ impl AlphaRenderItem { match texture { SourceTexture::External(ext_image) => { match ext_image.image_type { - ExternalImageType::Texture2DHandle => ImageBufferKind::Texture2D, - ExternalImageType::Texture2DArrayHandle => ImageBufferKind::Texture2DArray, - ExternalImageType::TextureRectHandle => ImageBufferKind::TextureRect, - ExternalImageType::TextureExternalHandle => ImageBufferKind::TextureExternal, + ExternalImageType::Texture2DHandle => { + ImageBufferKind::Texture2D + } + ExternalImageType::Texture2DArrayHandle => { + ImageBufferKind::Texture2DArray + } + ExternalImageType::TextureRectHandle => { + ImageBufferKind::TextureRect + } + ExternalImageType::TextureExternalHandle => { + ImageBufferKind::TextureExternal + } ExternalImageType::ExternalBuffer => { // The ExternalImageType::ExternalBuffer should be handled by resource_cache. // It should go through the non-external case. - panic!("Non-texture handle type should be handled in other way."); + panic!("Unexpected non-texture handle type"); } } } - _ => { - ImageBufferKind::Texture2DArray - } + _ => ImageBufferKind::Texture2DArray, } }; // All yuv textures should be the same type. let buffer_kind = get_buffer_kind(textures.colors[0]); - assert!(textures.colors[1.. image_yuv_cpu.format.get_plane_num()].iter().all( - |&tid| buffer_kind == get_buffer_kind(tid) - )); - - let kind = BatchKind::Transformable(transform_kind, - TransformBatchKind::YuvImage(buffer_kind, - image_yuv_cpu.format, - image_yuv_cpu.color_space)); + assert!( + textures.colors[1 .. image_yuv_cpu.format.get_plane_num()] + .iter() + .all(|&tid| buffer_kind == get_buffer_kind(tid)) + ); + + let kind = BatchKind::Transformable( + transform_kind, + TransformBatchKind::YuvImage( + buffer_kind, + image_yuv_cpu.format, + image_yuv_cpu.color_space, + ), + ); let key = BatchKey::new(kind, blend_mode, textures); let batch = batch_list.get_suitable_batch(key, item_bounding_rect); - batch.push(base_instance.build(uv_rect_addresses[0], - uv_rect_addresses[1], - uv_rect_addresses[2])); + batch.push(base_instance.build( + uv_rect_addresses[0], + uv_rect_addresses[1], + uv_rect_addresses[2], + )); } PrimitiveKind::BoxShadow => { - let box_shadow = &ctx.prim_store.cpu_box_shadows[prim_metadata.cpu_prim_index.0]; + let box_shadow = + &ctx.prim_store.cpu_box_shadows[prim_metadata.cpu_prim_index.0]; let cache_task_id = box_shadow.render_task_id.unwrap(); let cache_task_address = render_tasks.get_task_address(cache_task_id); let textures = BatchTextures::render_target_cache(); - let kind = BatchKind::Transformable(transform_kind, TransformBatchKind::BoxShadow); + let kind = + BatchKind::Transformable(transform_kind, TransformBatchKind::BoxShadow); let key = BatchKey::new(kind, blend_mode, textures); let batch = batch_list.get_suitable_batch(key, item_bounding_rect); - for rect_index in 0..box_shadow.rects.len() { - batch.push(base_instance.build(rect_index as i32, - cache_task_address.0 as i32, 0)); + for rect_index in 0 .. box_shadow.rects.len() { + batch.push(base_instance.build( + rect_index as i32, + cache_task_address.0 as i32, + 0, + )); } } } } AlphaRenderItem::SplitComposite(sc_index, task_id, gpu_handle, z) => { - let key = BatchKey::new(BatchKind::SplitComposite, - BlendMode::PremultipliedAlpha, - BatchTextures::no_texture()); + let key = BatchKey::new( + BatchKind::SplitComposite, + BlendMode::PremultipliedAlpha, + BatchTextures::no_texture(), + ); let stacking_context = &ctx.stacking_context_store[sc_index.0]; let batch = batch_list.get_suitable_batch(key, &stacking_context.screen_bounds); let source_task_address = render_tasks.get_task_address(task_id); let gpu_address = gpu_handle.as_int(gpu_cache); - let instance = CompositePrimitiveInstance::new(task_address, - source_task_address, - RenderTaskAddress(0), - gpu_address, - 0, - z); + let instance = CompositePrimitiveInstance::new( + task_address, + source_task_address, + RenderTaskAddress(0), + gpu_address, + 0, + z, + ); batch.push(PrimitiveInstance::from(instance)); } @@ -622,25 +730,29 @@ impl AlphaBatcher { self.tasks.push(task_id); } - fn build(&mut self, - ctx: &RenderTargetContext, - gpu_cache: &mut GpuCache, - render_tasks: &RenderTaskTree, - deferred_resolves: &mut Vec) { + fn build( + &mut self, + ctx: &RenderTargetContext, + gpu_cache: &mut GpuCache, + render_tasks: &RenderTaskTree, + deferred_resolves: &mut Vec, + ) { for task_id in &self.tasks { let task_id = *task_id; let task = render_tasks.get(task_id).as_alpha_batch(); let task_address = render_tasks.get_task_address(task_id); for item in &task.items { - item.add_to_batch(&mut self.batch_list, - ctx, - gpu_cache, - render_tasks, - task_id, - task_address, - deferred_resolves, - &mut self.glyph_fetch_buffer); + item.add_to_batch( + &mut self.batch_list, + ctx, + gpu_cache, + render_tasks, + task_id, + task_address, + deferred_resolves, + &mut self.glyph_fetch_buffer, + ); } } @@ -649,7 +761,7 @@ impl AlphaBatcher { pub fn is_empty(&self) -> bool { self.batch_list.opaque_batch_list.batches.is_empty() && - self.batch_list.alpha_batch_list.batches.is_empty() + self.batch_list.alpha_batch_list.batches.is_empty() } } @@ -674,13 +786,15 @@ impl ClipBatcher { } } - fn add(&mut self, - task_address: RenderTaskAddress, - clips: &[ClipWorkItem], - resource_cache: &ResourceCache, - gpu_cache: &GpuCache, - geometry_kind: MaskGeometryKind, - clip_store: &ClipStore) { + fn add( + &mut self, + task_address: RenderTaskAddress, + clips: &[ClipWorkItem], + resource_cache: &ResourceCache, + gpu_cache: &GpuCache, + geometry_kind: MaskGeometryKind, + clip_store: &ClipStore, + ) { for work_item in clips.iter() { let instance = ClipMaskInstance { render_task_address: task_address, @@ -689,72 +803,71 @@ impl ClipBatcher { clip_data_address: GpuCacheAddress::invalid(), resource_address: GpuCacheAddress::invalid(), }; - let info = clip_store.get_opt(&work_item.clip_sources) - .expect("bug: clip handle should be valid"); + let info = clip_store + .get_opt(&work_item.clip_sources) + .expect("bug: clip handle should be valid"); for &(ref source, ref handle) in &info.clips { let gpu_address = gpu_cache.get_address(handle); match *source { ClipSource::Image(ref mask) => { - let cache_item = resource_cache.get_cached_image(mask.image, ImageRendering::Auto, None); - self.images.entry(cache_item.texture_id) - .or_insert(Vec::new()) - .push(ClipMaskInstance { + let cache_item = + resource_cache.get_cached_image(mask.image, ImageRendering::Auto, None); + self.images + .entry(cache_item.texture_id) + .or_insert(Vec::new()) + .push(ClipMaskInstance { + clip_data_address: gpu_address, + resource_address: gpu_cache.get_address(&cache_item.uv_rect_handle), + ..instance + }); + } + ClipSource::Rectangle(..) => if work_item.apply_rectangles { + self.rectangles.push(ClipMaskInstance { clip_data_address: gpu_address, - resource_address: gpu_cache.get_address(&cache_item.uv_rect_handle), + segment: MaskSegment::All as i32, ..instance }); - } - ClipSource::Rectangle(..) => { - if work_item.apply_rectangles { + }, + ClipSource::RoundedRectangle(..) => match geometry_kind { + MaskGeometryKind::Default => { self.rectangles.push(ClipMaskInstance { clip_data_address: gpu_address, segment: MaskSegment::All as i32, ..instance }); } - } - ClipSource::RoundedRectangle(..) => { - match geometry_kind { - MaskGeometryKind::Default => { - self.rectangles.push(ClipMaskInstance { - clip_data_address: gpu_address, - segment: MaskSegment::All as i32, - ..instance - }); - } - MaskGeometryKind::CornersOnly => { - self.rectangles.push(ClipMaskInstance { - clip_data_address: gpu_address, - segment: MaskSegment::TopLeftCorner as i32, - ..instance - }); - self.rectangles.push(ClipMaskInstance { - clip_data_address: gpu_address, - segment: MaskSegment::TopRightCorner as i32, - ..instance - }); - self.rectangles.push(ClipMaskInstance { - clip_data_address: gpu_address, - segment: MaskSegment::BottomLeftCorner as i32, - ..instance - }); - self.rectangles.push(ClipMaskInstance { - clip_data_address: gpu_address, - segment: MaskSegment::BottomRightCorner as i32, - ..instance - }); - } + MaskGeometryKind::CornersOnly => { + self.rectangles.push(ClipMaskInstance { + clip_data_address: gpu_address, + segment: MaskSegment::TopLeftCorner as i32, + ..instance + }); + self.rectangles.push(ClipMaskInstance { + clip_data_address: gpu_address, + segment: MaskSegment::TopRightCorner as i32, + ..instance + }); + self.rectangles.push(ClipMaskInstance { + clip_data_address: gpu_address, + segment: MaskSegment::BottomLeftCorner as i32, + ..instance + }); + self.rectangles.push(ClipMaskInstance { + clip_data_address: gpu_address, + segment: MaskSegment::BottomRightCorner as i32, + ..instance + }); } - } + }, ClipSource::BorderCorner(ref source) => { self.border_clears.push(ClipMaskInstance { clip_data_address: gpu_address, segment: 0, ..instance }); - for clip_index in 0..source.actual_clip_count { + for clip_index in 0 .. source.actual_clip_count { self.borders.push(ClipMaskInstance { clip_data_address: gpu_address, segment: 1 + clip_index as i32, @@ -804,10 +917,8 @@ impl TextureAllocator { // TODO(gw): We need to make all the device rects // be consistent in the use of the // DeviceIntRect and DeviceUintRect types! - let origin = DeviceIntPoint::new(origin.x as i32, - origin.y as i32); - let size = DeviceIntSize::new(size.width as i32, - size.height as i32); + let origin = DeviceIntPoint::new(origin.x as i32, origin.y as i32); + let size = DeviceIntSize::new(size.width as i32, size.height as i32); let rect = DeviceIntRect::new(origin, size); self.used_rect = rect.union(&self.used_rect); } @@ -819,24 +930,29 @@ impl TextureAllocator { pub trait RenderTarget { fn new(size: Option) -> Self; fn allocate(&mut self, size: DeviceUintSize) -> Option; - fn build(&mut self, - _ctx: &RenderTargetContext, - _gpu_cache: &mut GpuCache, - _render_tasks: &mut RenderTaskTree, - _deferred_resolves: &mut Vec) {} - fn add_task(&mut self, - task_id: RenderTaskId, - ctx: &RenderTargetContext, - gpu_cache: &GpuCache, - render_tasks: &RenderTaskTree, - clip_store: &ClipStore); + fn build( + &mut self, + _ctx: &RenderTargetContext, + _gpu_cache: &mut GpuCache, + _render_tasks: &mut RenderTaskTree, + _deferred_resolves: &mut Vec, + ) { + } + fn add_task( + &mut self, + task_id: RenderTaskId, + ctx: &RenderTargetContext, + gpu_cache: &GpuCache, + render_tasks: &RenderTaskTree, + clip_store: &ClipStore, + ); fn used_rect(&self) -> DeviceIntRect; } #[derive(Debug, Copy, Clone)] pub enum RenderTargetKind { - Color, // RGBA32 - Alpha, // R8 + Color, // RGBA32 + Alpha, // R8 } pub struct RenderTargetList { @@ -850,50 +966,59 @@ impl RenderTargetList { targets.push(T::new(None)); } - RenderTargetList { - targets, - } + RenderTargetList { targets } } pub fn target_count(&self) -> usize { self.targets.len() } - fn build(&mut self, - ctx: &RenderTargetContext, - gpu_cache: &mut GpuCache, - render_tasks: &mut RenderTaskTree, - deferred_resolves: &mut Vec) { + fn build( + &mut self, + ctx: &RenderTargetContext, + gpu_cache: &mut GpuCache, + render_tasks: &mut RenderTaskTree, + deferred_resolves: &mut Vec, + ) { for target in &mut self.targets { target.build(ctx, gpu_cache, render_tasks, deferred_resolves); } } - fn add_task(&mut self, - task_id: RenderTaskId, - ctx: &RenderTargetContext, - gpu_cache: &GpuCache, - render_tasks: &mut RenderTaskTree, - clip_store: &ClipStore) { - self.targets - .last_mut() - .unwrap() - .add_task(task_id, ctx, gpu_cache, render_tasks, clip_store); + fn add_task( + &mut self, + task_id: RenderTaskId, + ctx: &RenderTargetContext, + gpu_cache: &GpuCache, + render_tasks: &mut RenderTaskTree, + clip_store: &ClipStore, + ) { + self.targets.last_mut().unwrap().add_task( + task_id, + ctx, + gpu_cache, + render_tasks, + clip_store, + ); } - fn allocate(&mut self, - alloc_size: DeviceUintSize, - target_size: DeviceUintSize) -> (DeviceUintPoint, RenderTargetIndex) { + fn allocate( + &mut self, + alloc_size: DeviceUintSize, + target_size: DeviceUintSize, + ) -> (DeviceUintPoint, RenderTargetIndex) { let existing_origin = self.targets - .last_mut() - .and_then(|target| target.allocate(alloc_size)); + .last_mut() + .and_then(|target| target.allocate(alloc_size)); let origin = match existing_origin { Some(origin) => origin, None => { let mut new_target = T::new(Some(target_size)); - let origin = new_target.allocate(alloc_size) - .expect(&format!("Each render task must allocate <= size of one target! ({:?})", alloc_size)); + let origin = new_target.allocate(alloc_size).expect(&format!( + "Each render task must allocate <= size of one target! ({:?})", + alloc_size + )); self.targets.push(new_target); origin } @@ -957,23 +1082,25 @@ impl RenderTarget for ColorRenderTarget { .used_rect } - fn build(&mut self, - ctx: &RenderTargetContext, - gpu_cache: &mut GpuCache, - render_tasks: &mut RenderTaskTree, - deferred_resolves: &mut Vec) { - self.alpha_batcher.build(ctx, - gpu_cache, - render_tasks, - deferred_resolves); + fn build( + &mut self, + ctx: &RenderTargetContext, + gpu_cache: &mut GpuCache, + render_tasks: &mut RenderTaskTree, + deferred_resolves: &mut Vec, + ) { + self.alpha_batcher + .build(ctx, gpu_cache, render_tasks, deferred_resolves); } - fn add_task(&mut self, - task_id: RenderTaskId, - ctx: &RenderTargetContext, - gpu_cache: &GpuCache, - render_tasks: &RenderTaskTree, - _: &ClipStore) { + fn add_task( + &mut self, + task_id: RenderTaskId, + ctx: &RenderTargetContext, + gpu_cache: &GpuCache, + render_tasks: &RenderTaskTree, + _: &ClipStore, + ) { let task = render_tasks.get(task_id); match task.kind { @@ -1022,42 +1149,52 @@ impl RenderTarget for ColorRenderTarget { for sub_prim_index in &prim.primitives { let sub_metadata = ctx.prim_store.get_metadata(*sub_prim_index); - let sub_prim_address = gpu_cache.get_address(&sub_metadata.gpu_location); - let instance = SimplePrimitiveInstance::new(sub_prim_address, - task_index, - RenderTaskAddress(0), - PackedLayerIndex(0).into(), - 0); // z is disabled for rendering cache primitives + let sub_prim_address = + gpu_cache.get_address(&sub_metadata.gpu_location); + let instance = SimplePrimitiveInstance::new( + sub_prim_address, + task_index, + RenderTaskAddress(0), + PackedLayerIndex(0).into(), + 0, + ); // z is disabled for rendering cache primitives match sub_metadata.prim_kind { PrimitiveKind::TextRun => { // Add instances that reference the text run GPU location. Also supply // the parent text-shadow prim address as a user data field, allowing // the shader to fetch the text-shadow parameters. - let text = &ctx.prim_store.cpu_text_runs[sub_metadata.cpu_prim_index.0]; + let text = &ctx.prim_store.cpu_text_runs + [sub_metadata.cpu_prim_index.0]; let text_run_cache_prims = &mut self.text_run_cache_prims; let mut font = text.font.clone(); font.size = font.size.scale_by(ctx.device_pixel_ratio); font.render_mode = text.shadow_render_mode; - ctx.resource_cache.fetch_glyphs(font, - &text.glyph_keys, - &mut self.glyph_fetch_buffer, - gpu_cache, - |texture_id, glyphs| { - let batch = text_run_cache_prims.entry(texture_id) - .or_insert(Vec::new()); - - for glyph in glyphs { - batch.push(instance.build(glyph.index_in_text_run, - glyph.uv_rect_address.as_int(), - prim_address)); - } - }); + ctx.resource_cache.fetch_glyphs( + font, + &text.glyph_keys, + &mut self.glyph_fetch_buffer, + gpu_cache, + |texture_id, glyphs| { + let batch = text_run_cache_prims + .entry(texture_id) + .or_insert(Vec::new()); + + for glyph in glyphs { + batch.push(instance.build( + glyph.index_in_text_run, + glyph.uv_rect_address.as_int(), + prim_address, + )); + } + }, + ); } PrimitiveKind::Line => { - self.line_cache_prims.push(instance.build(prim_address, 0, 0)); + self.line_cache_prims + .push(instance.build(prim_address, 0, 0)); } _ => { unreachable!("Unexpected sub primitive type"); @@ -1071,8 +1208,7 @@ impl RenderTarget for ColorRenderTarget { } } } - RenderTaskKind::CacheMask(..) | - RenderTaskKind::BoxShadow(..) => { + RenderTaskKind::CacheMask(..) | RenderTaskKind::BoxShadow(..) => { panic!("Should not be added to color target!"); } RenderTaskKind::Readback(device_rect) => { @@ -1105,12 +1241,14 @@ impl RenderTarget for AlphaRenderTarget { self.allocator.used_rect } - fn add_task(&mut self, - task_id: RenderTaskId, - ctx: &RenderTargetContext, - gpu_cache: &GpuCache, - render_tasks: &RenderTaskTree, - clip_store: &ClipStore) { + fn add_task( + &mut self, + task_id: RenderTaskId, + ctx: &RenderTargetContext, + gpu_cache: &GpuCache, + render_tasks: &RenderTaskTree, + clip_store: &ClipStore, + ) { let task = render_tasks.get(task_id); match task.kind { RenderTaskKind::Alias(..) => { @@ -1140,12 +1278,14 @@ impl RenderTarget for AlphaRenderTarget { } RenderTaskKind::CacheMask(ref task_info) => { let task_address = render_tasks.get_task_address(task_id); - self.clip_batcher.add(task_address, - &task_info.clips, - &ctx.resource_cache, - gpu_cache, - task_info.geometry_kind, - clip_store); + self.clip_batcher.add( + task_address, + &task_info.clips, + &ctx.resource_cache, + gpu_cache, + task_info.geometry_kind, + clip_store, + ); } } } @@ -1183,22 +1323,24 @@ impl RenderPass { } } - pub fn add_render_task(&mut self, - task_id: RenderTaskId, - size: DeviceIntSize, - target_kind: RenderTargetKind) { + pub fn add_render_task( + &mut self, + task_id: RenderTaskId, + size: DeviceIntSize, + target_kind: RenderTargetKind, + ) { match target_kind { RenderTargetKind::Color => { - self.max_color_target_size.width = cmp::max(self.max_color_target_size.width, - size.width as u32); - self.max_color_target_size.height = cmp::max(self.max_color_target_size.height, - size.height as u32); + self.max_color_target_size.width = + cmp::max(self.max_color_target_size.width, size.width as u32); + self.max_color_target_size.height = + cmp::max(self.max_color_target_size.height, size.height as u32); } RenderTargetKind::Alpha => { - self.max_alpha_target_size.width = cmp::max(self.max_alpha_target_size.width, - size.width as u32); - self.max_alpha_target_size.height = cmp::max(self.max_alpha_target_size.height, - size.height as u32); + self.max_alpha_target_size.width = + cmp::max(self.max_alpha_target_size.width, size.width as u32); + self.max_alpha_target_size.height = + cmp::max(self.max_alpha_target_size.height, size.height as u32); } } @@ -1220,12 +1362,14 @@ impl RenderPass { } } - pub fn build(&mut self, - ctx: &RenderTargetContext, - gpu_cache: &mut GpuCache, - render_tasks: &mut RenderTaskTree, - deferred_resolves: &mut Vec, - clip_store: &ClipStore) { + pub fn build( + &mut self, + ctx: &RenderTargetContext, + gpu_cache: &mut GpuCache, + render_tasks: &mut RenderTaskTree, + deferred_resolves: &mut Vec, + clip_store: &ClipStore, + ) { profile_scope!("RenderPass::build"); // Step through each task, adding to batches as appropriate. @@ -1253,26 +1397,38 @@ impl RenderPass { let alloc_size = DeviceUintSize::new(size.width as u32, size.height as u32); let (alloc_origin, target_index) = match target_kind { - RenderTargetKind::Color => self.color_targets.allocate(alloc_size, self.max_color_target_size), - RenderTargetKind::Alpha => self.alpha_targets.allocate(alloc_size, self.max_alpha_target_size), + RenderTargetKind::Color => self.color_targets + .allocate(alloc_size, self.max_color_target_size), + RenderTargetKind::Alpha => self.alpha_targets + .allocate(alloc_size, self.max_alpha_target_size), }; - let origin = Some((DeviceIntPoint::new(alloc_origin.x as i32, - alloc_origin.y as i32), - target_index)); + let origin = Some(( + DeviceIntPoint::new(alloc_origin.x as i32, alloc_origin.y as i32), + target_index, + )); task.location = RenderTaskLocation::Dynamic(origin, size); // If this task is cacheable / sharable, store it in the task hash // for this pass. if let Some(cache_key) = task.cache_key { - self.dynamic_tasks.insert(cache_key, DynamicTaskInfo { - task_id, - rect: match task.location { - RenderTaskLocation::Fixed => panic!("Dynamic tasks should not have fixed locations!"), - RenderTaskLocation::Dynamic(Some((origin, _)), size) => DeviceIntRect::new(origin, size), - RenderTaskLocation::Dynamic(None, _) => panic!("Expect the task to be already allocated here"), + self.dynamic_tasks.insert( + cache_key, + DynamicTaskInfo { + task_id, + rect: match task.location { + RenderTaskLocation::Fixed => { + panic!("Dynamic tasks should not have fixed locations!") + } + RenderTaskLocation::Dynamic(Some((origin, _)), size) => { + DeviceIntRect::new(origin, size) + } + RenderTaskLocation::Dynamic(None, _) => { + panic!("Expect the task to be already allocated here") + } + }, }, - }); + ); } } } @@ -1281,23 +1437,21 @@ impl RenderPass { }; match target_kind { - RenderTargetKind::Color => self.color_targets - .add_task(task_id, - ctx, - gpu_cache, - render_tasks, - clip_store), - RenderTargetKind::Alpha => self.alpha_targets - .add_task(task_id, - ctx, - gpu_cache, - render_tasks, - clip_store), + RenderTargetKind::Color => { + self.color_targets + .add_task(task_id, ctx, gpu_cache, render_tasks, clip_store) + } + RenderTargetKind::Alpha => { + self.alpha_targets + .add_task(task_id, ctx, gpu_cache, render_tasks, clip_store) + } } } - self.color_targets.build(ctx, gpu_cache, render_tasks, deferred_resolves); - self.alpha_targets.build(ctx, gpu_cache, render_tasks, deferred_resolves); + self.color_targets + .build(ctx, gpu_cache, render_tasks, deferred_resolves); + self.alpha_targets + .build(ctx, gpu_cache, render_tasks, deferred_resolves); } } @@ -1338,9 +1492,7 @@ pub struct BatchKey { } impl BatchKey { - fn new(kind: BatchKind, - blend_mode: BlendMode, - textures: BatchTextures) -> BatchKey { + fn new(kind: BatchKind, blend_mode: BlendMode, textures: BatchTextures) -> BatchKey { BatchKey { kind, blend_mode, @@ -1349,8 +1501,7 @@ impl BatchKey { } fn is_compatible_with(&self, other: &BatchKey) -> bool { - self.kind == other.kind && - self.blend_mode == other.blend_mode && + self.kind == other.kind && self.blend_mode == other.blend_mode && textures_compatible(self.textures.colors[0], other.textures.colors[0]) && textures_compatible(self.textures.colors[1], other.textures.colors[1]) && textures_compatible(self.textures.colors[2], other.textures.colors[2]) @@ -1452,15 +1603,16 @@ pub struct StackingContext { } impl StackingContext { - pub fn new(pipeline_id: PipelineId, - reference_frame_offset: LayerVector2D, - is_page_root: bool, - is_pipeline_root: bool, - reference_frame_id: ClipId, - transform_style: TransformStyle, - composite_ops: CompositeOps, - is_backface_visible: bool) - -> StackingContext { + pub fn new( + pipeline_id: PipelineId, + reference_frame_offset: LayerVector2D, + is_page_root: bool, + is_pipeline_root: bool, + reference_frame_id: ClipId, + transform_style: TransformStyle, + composite_ops: CompositeOps, + is_backface_visible: bool, + ) -> StackingContext { let isolation = match transform_style { TransformStyle::Flat => ContextIsolation::None, TransformStyle::Preserve3D => ContextIsolation::Items, @@ -1530,15 +1682,18 @@ impl PackedLayer { } } - pub fn set_rect(&mut self, - local_rect: &LayerRect, - screen_rect: &DeviceIntRect, - device_pixel_ratio: f32) - -> Option<(TransformedRectKind, DeviceIntRect)> { + pub fn set_rect( + &mut self, + local_rect: &LayerRect, + screen_rect: &DeviceIntRect, + device_pixel_ratio: f32, + ) -> Option<(TransformedRectKind, DeviceIntRect)> { self.local_clip_rect = *local_rect; let xf_rect = TransformedRect::new(local_rect, &self.transform, device_pixel_ratio); - xf_rect.bounding_rect.intersection(screen_rect) - .map(|rect| (xf_rect.kind, rect)) + xf_rect + .bounding_rect + .intersection(screen_rect) + .map(|rect| (xf_rect.kind, rect)) } } @@ -1555,7 +1710,7 @@ impl CompositeOps { pub fn new(filters: Vec, mix_blend_mode: Option) -> CompositeOps { CompositeOps { filters, - mix_blend_mode: mix_blend_mode + mix_blend_mode: mix_blend_mode, } } @@ -1597,12 +1752,14 @@ pub struct Frame { pub deferred_resolves: Vec, } -fn resolve_image(image_key: ImageKey, - image_rendering: ImageRendering, - tile_offset: Option, - resource_cache: &ResourceCache, - gpu_cache: &mut GpuCache, - deferred_resolves: &mut Vec) -> (SourceTexture, GpuCacheHandle) { +fn resolve_image( + image_key: ImageKey, + image_rendering: ImageRendering, + tile_offset: Option, + resource_cache: &ResourceCache, + gpu_cache: &mut GpuCache, + deferred_resolves: &mut Vec, +) -> (SourceTexture, GpuCacheHandle) { match resource_cache.get_image_properties(image_key) { Some(image_properties) => { // Check if an external image that needs to be resolved @@ -1621,9 +1778,8 @@ fn resolve_image(image_key: ImageKey, (SourceTexture::External(external_image), cache_handle) } None => { - let cache_item = resource_cache.get_cached_image(image_key, - image_rendering, - tile_offset); + let cache_item = + resource_cache.get_cached_image(image_key, image_rendering, tile_offset); (cache_item.texture_id, cache_item.uv_rect_handle) } @@ -1632,4 +1788,3 @@ fn resolve_image(image_key: ImageKey, None => (SourceTexture::Invalid, GpuCacheHandle::new()), } } - diff --git a/webrender/src/util.rs b/webrender/src/util.rs index 90b84233c2..3749d665ca 100644 --- a/webrender/src/util.rs +++ b/webrender/src/util.rs @@ -2,13 +2,13 @@ * 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 std::f32::consts::{FRAC_1_SQRT_2}; -use euclid::{Point2D, Rect, Size2D}; -use euclid::{TypedRect, TypedPoint2D, TypedSize2D, TypedTransform2D, TypedTransform3D}; -use api::{DeviceIntRect, DevicePoint, DeviceRect, DeviceSize}; -use api::{LayerRect, WorldPoint3D, LayerToWorldTransform}; use api::{BorderRadius, ComplexClipRegion, LayoutRect}; +use api::{DeviceIntRect, DevicePoint, DeviceRect, DeviceSize}; +use api::{LayerRect, LayerToWorldTransform, WorldPoint3D}; +use euclid::{Point2D, Rect, Size2D}; +use euclid::{TypedPoint2D, TypedRect, TypedSize2D, TypedTransform2D, TypedTransform3D}; use num_traits::Zero; +use std::f32::consts::FRAC_1_SQRT_2; // Matches the definition of SK_ScalarNearlyZero in Skia. const NEARLY_ZERO: f32 = 1.0 / 4096.0; @@ -69,14 +69,15 @@ impl MatrixHelpers for TypedTransform3D { fn inverse_project(&self, target: &TypedPoint2D) -> Option> { let m: TypedTransform2D; - m = TypedTransform2D::column_major(self.m11 - target.x * self.m14, - self.m21 - target.x * self.m24, - self.m41 - target.x * self.m44, - self.m12 - target.y * self.m14, - self.m22 - target.y * self.m24, - self.m42 - target.y * self.m44); - m.inverse() - .map(|inv| TypedPoint2D::new(inv.m31, inv.m32)) + m = TypedTransform2D::column_major( + self.m11 - target.x * self.m14, + self.m21 - target.x * self.m24, + self.m41 - target.x * self.m44, + self.m12 - target.y * self.m14, + self.m22 - target.y * self.m24, + self.m42 - target.y * self.m44, + ); + m.inverse().map(|inv| TypedPoint2D::new(inv.m31, inv.m32)) } fn inverse_rect_footprint(&self, rect: &TypedRect) -> TypedRect { @@ -93,24 +94,26 @@ impl MatrixHelpers for TypedTransform3D { } } -pub trait RectHelpers where Self: Sized { +pub trait RectHelpers +where + Self: Sized, +{ fn contains_rect(&self, other: &Self) -> bool; fn from_floats(x0: f32, y0: f32, x1: f32, y1: f32) -> Self; fn is_well_formed_and_nonempty(&self) -> bool; } impl RectHelpers for TypedRect { - fn contains_rect(&self, other: &Self) -> bool { - self.origin.x <= other.origin.x && - self.origin.y <= other.origin.y && - self.max_x() >= other.max_x() && - self.max_y() >= other.max_y() + self.origin.x <= other.origin.x && self.origin.y <= other.origin.y && + self.max_x() >= other.max_x() && self.max_y() >= other.max_y() } fn from_floats(x0: f32, y0: f32, x1: f32, y1: f32) -> Self { - TypedRect::new(TypedPoint2D::new(x0, y0), - TypedSize2D::new(x1 - x0, y1 - y0)) + TypedRect::new( + TypedPoint2D::new(x0, y0), + TypedSize2D::new(x1 - x0, y1 - y0), + ) } fn is_well_formed_and_nonempty(&self) -> bool { @@ -120,26 +123,24 @@ impl RectHelpers for TypedRect { // Don't use `euclid`'s `is_empty` because that has effectively has an "and" in the conditional // below instead of an "or". -pub fn rect_is_empty(rect: &TypedRect) -> bool { +pub fn rect_is_empty(rect: &TypedRect) -> bool { rect.size.width == Zero::zero() || rect.size.height == Zero::zero() } #[inline] -pub fn rect_from_points_f(x0: f32, - y0: f32, - x1: f32, - y1: f32) -> Rect { - Rect::new(Point2D::new(x0, y0), - Size2D::new(x1 - x0, y1 - y0)) +pub fn rect_from_points_f(x0: f32, y0: f32, x1: f32, y1: f32) -> Rect { + Rect::new(Point2D::new(x0, y0), Size2D::new(x1 - x0, y1 - y0)) } pub fn lerp(a: f32, b: f32, t: f32) -> f32 { (b - a) * t + a } -pub fn subtract_rect(rect: &TypedRect, - other: &TypedRect, - results: &mut Vec>) { +pub fn subtract_rect( + rect: &TypedRect, + other: &TypedRect, + results: &mut Vec>, +) { results.clear(); let int = rect.intersection(other); @@ -210,10 +211,11 @@ pub struct TransformedRect { const MAX_COORD: f32 = 1.0e9; impl TransformedRect { - pub fn new(rect: &LayerRect, - transform: &LayerToWorldTransform, - device_pixel_ratio: f32) -> TransformedRect { - + pub fn new( + rect: &LayerRect, + transform: &LayerToWorldTransform, + device_pixel_ratio: f32, + ) -> TransformedRect { let kind = if transform.preserves_2d_axis_alignment() { TransformedRectKind::AxisAligned } else { @@ -243,12 +245,18 @@ impl TransformedRect { let inner_min_dp = (DevicePoint::new(xs[1], ys[1]) * device_pixel_ratio).ceil(); let inner_max_dp = (DevicePoint::new(xs[2], ys[2]) * device_pixel_ratio).floor(); - let max_rect = DeviceRect::new(DevicePoint::new(-MAX_COORD, -MAX_COORD), - DeviceSize::new(2.0*MAX_COORD, 2.0*MAX_COORD)); + let max_rect = DeviceRect::new( + DevicePoint::new(-MAX_COORD, -MAX_COORD), + DeviceSize::new(2.0 * MAX_COORD, 2.0 * MAX_COORD), + ); let bounding_rect = DeviceRect::new(outer_min_dp, (outer_max_dp - outer_min_dp).to_size()) - .intersection(&max_rect).unwrap_or(max_rect).to_i32(); + .intersection(&max_rect) + .unwrap_or(max_rect) + .to_i32(); let inner_rect = DeviceRect::new(inner_min_dp, (inner_max_dp - inner_min_dp).to_size()) - .intersection(&max_rect).unwrap_or(max_rect).to_i32(); + .intersection(&max_rect) + .unwrap_or(max_rect) + .to_i32(); TransformedRect { local_rect: *rect, @@ -281,9 +289,11 @@ impl ComplexClipRegionHelpers for ComplexClipRegion { } #[inline] -fn extract_inner_rect_impl(rect: &TypedRect, - radii: &BorderRadius, - k: f32) -> Option> { +fn extract_inner_rect_impl( + rect: &TypedRect, + radii: &BorderRadius, + k: f32, +) -> Option> { // `k` defines how much border is taken into account // We enforce the offsets to be rounded to pixel boundaries // by `ceil`-ing and `floor`-ing them @@ -291,11 +301,14 @@ fn extract_inner_rect_impl(rect: &TypedRect, let xl = (k * radii.top_left.width.max(radii.bottom_left.width)).ceil(); let xr = (rect.size.width - k * radii.top_right.width.max(radii.bottom_right.width)).floor(); let yt = (k * radii.top_left.height.max(radii.top_right.height)).ceil(); - let yb = (rect.size.height - k * radii.bottom_left.height.max(radii.bottom_right.height)).floor(); + let yb = + (rect.size.height - k * radii.bottom_left.height.max(radii.bottom_right.height)).floor(); if xl <= xr && yt <= yb { - Some(TypedRect::new(TypedPoint2D::new(rect.origin.x + xl, rect.origin.y + yt), - TypedSize2D::new(xr-xl, yb-yt))) + Some(TypedRect::new( + TypedPoint2D::new(rect.origin.x + xl, rect.origin.y + yt), + TypedSize2D::new(xr - xl, yb - yt), + )) } else { None } @@ -303,8 +316,10 @@ fn extract_inner_rect_impl(rect: &TypedRect, /// Return an aligned rectangle that is inside the clip region and doesn't intersect /// any of the bounding rectangles of the rounded corners. -pub fn extract_inner_rect_safe(rect: &TypedRect, - radii: &BorderRadius) -> Option> { +pub fn extract_inner_rect_safe( + rect: &TypedRect, + radii: &BorderRadius, +) -> Option> { // value of `k==1.0` is used for extraction of the corner rectangles // see `SEGMENT_CORNER_*` in `clip_shared.glsl` extract_inner_rect_impl(rect, radii, 1.0) diff --git a/webrender/tests/angle_shader_validation.rs b/webrender/tests/angle_shader_validation.rs index 1250b27735..5851873973 100644 --- a/webrender/tests/angle_shader_validation.rs +++ b/webrender/tests/angle_shader_validation.rs @@ -21,74 +21,94 @@ const PRIM_FEATURES: &[&str] = &["", "TRANSFORM"]; const SHADERS: &[Shader] = &[ // Clip mask shaders Shader { - name: "cs_clip_rectangle", features: CLIP_FEATURES, + name: "cs_clip_rectangle", + features: CLIP_FEATURES, }, Shader { - name: "cs_clip_image", features: CLIP_FEATURES, + name: "cs_clip_image", + features: CLIP_FEATURES, }, Shader { - name: "cs_clip_border", features: CLIP_FEATURES, + name: "cs_clip_border", + features: CLIP_FEATURES, }, - // Cache shaders Shader { - name: "cs_blur", features: CACHE_FEATURES, + name: "cs_blur", + features: CACHE_FEATURES, }, Shader { - name: "cs_text_run", features: CACHE_FEATURES, + name: "cs_text_run", + features: CACHE_FEATURES, }, Shader { - name: "cs_box_shadow", features: CACHE_FEATURES, + name: "cs_box_shadow", + features: CACHE_FEATURES, }, - // Prim shaders Shader { - name: "ps_line", features: &["", "TRANSFORM", "CACHE"], + name: "ps_line", + features: &["", "TRANSFORM", "CACHE"], }, Shader { - name: "ps_border_corner", features: PRIM_FEATURES, + name: "ps_border_corner", + features: PRIM_FEATURES, }, Shader { - name: "ps_border_edge", features: PRIM_FEATURES, + name: "ps_border_edge", + features: PRIM_FEATURES, }, Shader { - name: "ps_box_shadow", features: PRIM_FEATURES, + name: "ps_box_shadow", + features: PRIM_FEATURES, }, Shader { - name: "ps_gradient", features: PRIM_FEATURES, + name: "ps_gradient", + features: PRIM_FEATURES, }, Shader { - name: "ps_angle_gradient", features: PRIM_FEATURES, + name: "ps_angle_gradient", + features: PRIM_FEATURES, }, Shader { - name: "ps_radial_gradient", features: PRIM_FEATURES, + name: "ps_radial_gradient", + features: PRIM_FEATURES, }, Shader { - name: "ps_cache_image", features: PRIM_FEATURES, + name: "ps_cache_image", + features: PRIM_FEATURES, }, Shader { - name: "ps_blend", features: PRIM_FEATURES, + name: "ps_blend", + features: PRIM_FEATURES, }, Shader { - name: "ps_composite", features: PRIM_FEATURES, + name: "ps_composite", + features: PRIM_FEATURES, }, Shader { - name: "ps_hardware_composite", features: PRIM_FEATURES, + name: "ps_hardware_composite", + features: PRIM_FEATURES, }, Shader { - name: "ps_split_composite", features: PRIM_FEATURES, + name: "ps_split_composite", + features: PRIM_FEATURES, }, Shader { - name: "ps_image", features: PRIM_FEATURES, + name: "ps_image", + features: PRIM_FEATURES, }, Shader { - name: "ps_yuv_image", features: PRIM_FEATURES, + name: "ps_yuv_image", + features: PRIM_FEATURES, }, Shader { - name: "ps_text_run", features: &["", "TRANSFORM", "SUBPIXEL_AA_FEATURE"], + name: "ps_text_run", + features: &["", "TRANSFORM", "SUBPIXEL_AA_FEATURE"], }, Shader { - name: "ps_rectangle", features: &["", "TRANSFORM", "CLIP_FEATURE", "TRANSFORM,CLIP_FEATURE"], + name: "ps_rectangle", + features: &["", "TRANSFORM", "CLIP_FEATURE", "TRANSFORM,CLIP_FEATURE"], }, ]; @@ -99,15 +119,11 @@ fn validate_shaders() { angle::hl::initialize().unwrap(); let resources = BuiltInResources::default(); - let vs_validator = ShaderValidator::new(VERTEX_SHADER, - ShaderSpec::Gles3, - Output::Essl, - &resources).unwrap(); + let vs_validator = + ShaderValidator::new(VERTEX_SHADER, ShaderSpec::Gles3, Output::Essl, &resources).unwrap(); - let fs_validator = ShaderValidator::new(FRAGMENT_SHADER, - ShaderSpec::Gles3, - Output::Essl, - &resources).unwrap(); + let fs_validator = + ShaderValidator::new(FRAGMENT_SHADER, ShaderSpec::Gles3, Output::Essl, &resources).unwrap(); for shader in SHADERS { for config in shader.features { @@ -118,10 +134,8 @@ fn validate_shaders() { features.push_str(&format!("#define WR_FEATURE_{}", feature)); } - let (vs, fs) = webrender::build_shader_strings(VERSION_STRING, - &features, - shader.name, - &None); + let (vs, fs) = + webrender::build_shader_strings(VERSION_STRING, &features, shader.name, &None); validate(&vs_validator, shader.name, vs); validate(&fs_validator, shader.name, fs); @@ -133,9 +147,13 @@ fn validate(validator: &ShaderValidator, name: &str, source: String) { match validator.compile_and_translate(&[&source]) { Ok(_) => { println!("Shader translated succesfully: {}", name); - }, + } Err(_) => { - panic!("Shader compilation failed: {}\n{}", name, validator.info_log()); - }, + panic!( + "Shader compilation failed: {}\n{}", + name, + validator.info_log() + ); + } } -} \ No newline at end of file +} diff --git a/webrender_api/src/api.rs b/webrender_api/src/api.rs index d81ba1c485..3c981df483 100644 --- a/webrender_api/src/api.rs +++ b/webrender_api/src/api.rs @@ -2,15 +2,16 @@ * 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 {BuiltDisplayList, BuiltDisplayListDescriptor, ClipId, ColorF, DeviceIntPoint}; +use {DeviceUintRect, DeviceUintSize, FontInstanceKey, FontKey, GlyphDimensions, GlyphKey}; +use {FontInstance, FontInstanceOptions, FontInstancePlatformOptions, NativeFontHandle, WorldPoint}; +use {ImageData, ImageDescriptor, ImageKey, LayoutPoint, LayoutSize, LayoutTransform, + LayoutVector2D}; use app_units::Au; -use channel::{self, MsgSender, Payload, PayloadSenderHelperMethods, PayloadSender}; +use channel::{self, MsgSender, Payload, PayloadSender, PayloadSenderHelperMethods}; use std::cell::Cell; use std::fmt; use std::marker::PhantomData; -use {BuiltDisplayList, BuiltDisplayListDescriptor, ClipId, ColorF, DeviceIntPoint}; -use {DeviceUintRect, DeviceUintSize, FontInstanceKey, FontKey, GlyphDimensions, GlyphKey}; -use {ImageData, ImageDescriptor, ImageKey, LayoutPoint, LayoutVector2D, LayoutSize, LayoutTransform}; -use {FontInstance, FontInstanceOptions, FontInstancePlatformOptions, NativeFontHandle, WorldPoint}; pub type TileSize = u16; @@ -43,9 +44,14 @@ impl ResourceUpdates { key: ImageKey, descriptor: ImageDescriptor, data: ImageData, - tiling: Option + tiling: Option, ) { - self.updates.push(ResourceUpdate::AddImage(AddImage { key, descriptor, data, tiling })); + self.updates.push(ResourceUpdate::AddImage(AddImage { + key, + descriptor, + data, + tiling, + })); } pub fn update_image( @@ -53,9 +59,14 @@ impl ResourceUpdates { key: ImageKey, descriptor: ImageDescriptor, data: ImageData, - dirty_rect: Option + dirty_rect: Option, ) { - self.updates.push(ResourceUpdate::UpdateImage(UpdateImage { key, descriptor, data, dirty_rect })); + self.updates.push(ResourceUpdate::UpdateImage(UpdateImage { + key, + descriptor, + data, + dirty_rect, + })); } pub fn delete_image(&mut self, key: ImageKey) { @@ -63,24 +74,35 @@ impl ResourceUpdates { } pub fn add_raw_font(&mut self, key: FontKey, bytes: Vec, index: u32) { - self.updates.push(ResourceUpdate::AddFont(AddFont::Raw(key, bytes, index))); + self.updates + .push(ResourceUpdate::AddFont(AddFont::Raw(key, bytes, index))); } pub fn add_native_font(&mut self, key: FontKey, native_handle: NativeFontHandle) { - self.updates.push(ResourceUpdate::AddFont(AddFont::Native(key, native_handle))); + self.updates + .push(ResourceUpdate::AddFont(AddFont::Native(key, native_handle))); } pub fn delete_font(&mut self, key: FontKey) { self.updates.push(ResourceUpdate::DeleteFont(key)); } - pub fn add_font_instance(&mut self, - key: FontInstanceKey, - font_key: FontKey, - glyph_size: Au, - options: Option, - platform_options: Option) { - self.updates.push(ResourceUpdate::AddFontInstance(AddFontInstance { key, font_key, glyph_size, options, platform_options })); + pub fn add_font_instance( + &mut self, + key: FontInstanceKey, + font_key: FontKey, + glyph_size: Au, + options: Option, + platform_options: Option, + ) { + self.updates + .push(ResourceUpdate::AddFontInstance(AddFontInstance { + key, + font_key, + glyph_size, + options, + platform_options, + })); } pub fn delete_font_instance(&mut self, key: FontInstanceKey) { @@ -159,13 +181,13 @@ pub enum DocumentMsg { impl fmt::Debug for DocumentMsg { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(match *self { - DocumentMsg::SetDisplayList{..} => "DocumentMsg::SetDisplayList", + DocumentMsg::SetDisplayList { .. } => "DocumentMsg::SetDisplayList", DocumentMsg::SetPageZoom(..) => "DocumentMsg::SetPageZoom", DocumentMsg::SetPinchZoom(..) => "DocumentMsg::SetPinchZoom", DocumentMsg::SetPan(..) => "DocumentMsg::SetPan", DocumentMsg::SetRootPipeline(..) => "DocumentMsg::SetRootPipeline", DocumentMsg::RemovePipeline(..) => "DocumentMsg::RemovePipeline", - DocumentMsg::SetWindowParameters{..} => "DocumentMsg::SetWindowParameters", + DocumentMsg::SetWindowParameters { .. } => "DocumentMsg::SetWindowParameters", DocumentMsg::Scroll(..) => "DocumentMsg::Scroll", DocumentMsg::ScrollNodeWithId(..) => "DocumentMsg::ScrollNodeWithId", DocumentMsg::TickScrollingBounce => "DocumentMsg::TickScrollingBounce", @@ -199,7 +221,11 @@ pub enum ApiMsg { /// Add/remove/update images and fonts. UpdateResources(ResourceUpdates), /// Gets the glyph dimensions - GetGlyphDimensions(FontInstance, Vec, MsgSender>>), + GetGlyphDimensions( + FontInstance, + Vec, + MsgSender>>, + ), /// Gets the glyph indices from a string GetGlyphIndices(FontKey, String, MsgSender>>), /// Adds a new document namespace. @@ -287,9 +313,13 @@ pub struct ExternalEvent { unsafe impl Send for ExternalEvent {} impl ExternalEvent { - pub fn from_raw(raw: usize) -> Self { ExternalEvent { raw: raw } } + pub fn from_raw(raw: usize) -> Self { + ExternalEvent { raw: raw } + } /// Consumes self to make it obvious that the event should be forwarded only once. - pub fn unwrap(self) -> usize { self.raw } + pub fn unwrap(self) -> usize { + self.raw + } } #[derive(Clone, Deserialize, Serialize)] @@ -305,9 +335,7 @@ pub struct RenderApiSender { } impl RenderApiSender { - pub fn new(api_sender: MsgSender, - payload_sender: PayloadSender) - -> Self { + pub fn new(api_sender: MsgSender, payload_sender: PayloadSender) -> Self { RenderApiSender { api_sender, payload_sender, @@ -374,10 +402,11 @@ impl RenderApi { /// Note: Internally, the internal texture cache doesn't store /// 'empty' textures (height or width = 0) /// This means that glyph dimensions e.g. for spaces (' ') will mostly be None. - pub fn get_glyph_dimensions(&self, - font: FontInstance, - glyph_keys: Vec) - -> Vec> { + pub fn get_glyph_dimensions( + &self, + font: FontInstance, + glyph_keys: Vec, + ) -> Vec> { let (tx, rx) = channel::msg_channel().unwrap(); let msg = ApiMsg::GetGlyphDimensions(font, glyph_keys, tx); self.api_sender.send(msg).unwrap(); @@ -386,9 +415,7 @@ impl RenderApi { /// Gets the glyph indices for the supplied string. These /// can be used to construct GlyphKeys. - pub fn get_glyph_indices(&self, - font_key: FontKey, - text: &str) -> Vec> { + pub fn get_glyph_indices(&self, font_key: FontKey, text: &str) -> Vec> { let (tx, rx) = channel::msg_channel().unwrap(); let msg = ApiMsg::GetGlyphIndices(font_key, text.to_string(), tx); self.api_sender.send(msg).unwrap(); @@ -406,7 +433,9 @@ impl RenderApi { if resources.updates.is_empty() { return; } - self.api_sender.send(ApiMsg::UpdateResources(resources)).unwrap(); + self.api_sender + .send(ApiMsg::UpdateResources(resources)) + .unwrap(); } pub fn send_external_event(&self, evt: ExternalEvent) { @@ -451,7 +480,9 @@ impl RenderApi { // For use in Wrench only #[doc(hidden)] pub fn send_payload(&self, data: &[u8]) { - self.payload_sender.send_payload(Payload::from_data(data)).unwrap(); + self.payload_sender + .send_payload(Payload::from_data(data)) + .unwrap(); } /// A helper method to send document messages. @@ -459,7 +490,9 @@ impl RenderApi { // This assertion fails on Servo use-cases, because it creates different // `RenderApi` instances for layout and compositor. //assert_eq!(document_id.0, self.namespace_id); - self.api_sender.send(ApiMsg::UpdateDocument(document_id, msg)).unwrap() + self.api_sender + .send(ApiMsg::UpdateDocument(document_id, msg)) + .unwrap() } /// Sets the root pipeline. @@ -521,36 +554,57 @@ impl RenderApi { resources: ResourceUpdates, ) { let (display_list_data, list_descriptor) = display_list.into_data(); - self.send(document_id, DocumentMsg::SetDisplayList { - epoch, - pipeline_id, - background, - viewport_size, - content_size, - list_descriptor, - preserve_frame_state, - resources, - }); - - self.payload_sender.send_payload(Payload { - epoch, - pipeline_id, - display_list_data, - }).unwrap(); + self.send( + document_id, + DocumentMsg::SetDisplayList { + epoch, + pipeline_id, + background, + viewport_size, + content_size, + list_descriptor, + preserve_frame_state, + resources, + }, + ); + + self.payload_sender + .send_payload(Payload { + epoch, + pipeline_id, + display_list_data, + }) + .unwrap(); } /// Scrolls the scrolling layer under the `cursor` /// /// WebRender looks for the layer closest to the user /// which has `ScrollPolicy::Scrollable` set. - pub fn scroll(&self, document_id: DocumentId, scroll_location: ScrollLocation, - cursor: WorldPoint, phase: ScrollEventPhase) { - self.send(document_id, DocumentMsg::Scroll(scroll_location, cursor, phase)); + pub fn scroll( + &self, + document_id: DocumentId, + scroll_location: ScrollLocation, + cursor: WorldPoint, + phase: ScrollEventPhase, + ) { + self.send( + document_id, + DocumentMsg::Scroll(scroll_location, cursor, phase), + ); } - pub fn scroll_node_with_id(&self, document_id: DocumentId, origin: LayoutPoint, - id: ClipId, clamp: ScrollClamping) { - self.send(document_id, DocumentMsg::ScrollNodeWithId(origin, id, clamp)); + pub fn scroll_node_with_id( + &self, + document_id: DocumentId, + origin: LayoutPoint, + id: ClipId, + clamp: ScrollClamping, + ) { + self.send( + document_id, + DocumentMsg::ScrollNodeWithId(origin, id, clamp), + ); } pub fn set_page_zoom(&self, document_id: DocumentId, page_zoom: ZoomFactor) { @@ -565,14 +619,19 @@ impl RenderApi { self.send(document_id, DocumentMsg::SetPan(pan)); } - pub fn set_window_parameters(&self, - document_id: DocumentId, - window_size: DeviceUintSize, - inner_rect: DeviceUintRect) { - self.send(document_id, DocumentMsg::SetWindowParameters { - window_size, - inner_rect, - }); + pub fn set_window_parameters( + &self, + document_id: DocumentId, + window_size: DeviceUintSize, + inner_rect: DeviceUintRect, + ) { + self.send( + document_id, + DocumentMsg::SetWindowParameters { + window_size, + inner_rect, + }, + ); } pub fn tick_scrolling_bounce_animations(&self, document_id: DocumentId) { @@ -587,18 +646,26 @@ impl RenderApi { /// Enable copying of the output of this pipeline id to /// an external texture for callers to consume. - pub fn enable_frame_output(&self, - document_id: DocumentId, - pipeline_id: PipelineId, - enable: bool) { - self.send(document_id, DocumentMsg::EnableFrameOutput(pipeline_id, enable)); + pub fn enable_frame_output( + &self, + document_id: DocumentId, + pipeline_id: PipelineId, + enable: bool, + ) { + self.send( + document_id, + DocumentMsg::EnableFrameOutput(pipeline_id, enable), + ); } /// Generate a new frame. Optionally, supply a list of animated /// property bindings that should be used to resolve bindings /// in the current display list. - pub fn generate_frame(&self, document_id: DocumentId, - property_bindings: Option) { + pub fn generate_frame( + &self, + document_id: DocumentId, + property_bindings: Option, + ) { self.send(document_id, DocumentMsg::GenerateFrame(property_bindings)); } } @@ -634,7 +701,7 @@ pub enum ScrollLocation { /// Scroll to very top of element. Start, /// Scroll to very bottom of element. - End + End, } /// Represents a zoom factor. @@ -662,7 +729,7 @@ pub struct PropertyBindingId { impl PropertyBindingId { pub fn new(value: u64) -> Self { PropertyBindingId { - namespace: IdNamespace((value>>32) as u32), + namespace: IdNamespace((value >> 32) as u32), uid: value as u32, } } @@ -679,10 +746,7 @@ pub struct PropertyBindingKey { /// Construct a property value from a given key and value. impl PropertyBindingKey { pub fn with(&self, value: T) -> PropertyValue { - PropertyValue { - key: *self, - value, - } + PropertyValue { key: *self, value } } } @@ -736,6 +800,8 @@ pub struct DynamicProperties { pub trait RenderNotifier: Send { fn new_frame_ready(&mut self); fn new_scroll_frame_ready(&mut self, composite_needed: bool); - fn external_event(&mut self, _evt: ExternalEvent) { unimplemented!() } + fn external_event(&mut self, _evt: ExternalEvent) { + unimplemented!() + } fn shut_down(&mut self) {} } diff --git a/webrender_api/src/channel.rs b/webrender_api/src/channel.rs index 1e1edf72fc..72f121ced4 100644 --- a/webrender_api/src/channel.rs +++ b/webrender_api/src/channel.rs @@ -2,9 +2,9 @@ * 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 byteorder::{LittleEndian, WriteBytesExt, ReadBytesExt}; -use std::io::{Cursor, Read}; use api::{Epoch, PipelineId}; +use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; +use std::io::{Cursor, Read}; use std::mem; #[derive(Clone)] @@ -27,14 +27,15 @@ impl Payload { /// TODO(emilio, #1049): Consider moving the IPC boundary to the /// constellation in Servo and remove this complexity from WR. pub fn to_data(&self) -> Vec { - let mut data = Vec::with_capacity(mem::size_of::() + - 2 * mem::size_of::() + - mem::size_of::() + - self.display_list_data.len()); + let mut data = Vec::with_capacity( + mem::size_of::() + 2 * mem::size_of::() + mem::size_of::() + + self.display_list_data.len(), + ); data.write_u32::(self.epoch.0).unwrap(); data.write_u32::(self.pipeline_id.0).unwrap(); data.write_u32::(self.pipeline_id.1).unwrap(); - data.write_u64::(self.display_list_data.len() as u64).unwrap(); + data.write_u64::(self.display_list_data.len() as u64) + .unwrap(); data.extend_from_slice(&self.display_list_data); data } @@ -43,12 +44,16 @@ impl Payload { pub fn from_data(data: &[u8]) -> Payload { let mut payload_reader = Cursor::new(data); let epoch = Epoch(payload_reader.read_u32::().unwrap()); - let pipeline_id = PipelineId(payload_reader.read_u32::().unwrap(), - payload_reader.read_u32::().unwrap()); + let pipeline_id = PipelineId( + payload_reader.read_u32::().unwrap(), + payload_reader.read_u32::().unwrap(), + ); let dl_size = payload_reader.read_u64::().unwrap() as usize; let mut built_display_list_data = vec![0; dl_size]; - payload_reader.read_exact(&mut built_display_list_data[..]).unwrap(); + payload_reader + .read_exact(&mut built_display_list_data[..]) + .unwrap(); assert_eq!(payload_reader.position(), data.len() as u64); diff --git a/webrender_api/src/color.rs b/webrender_api/src/color.rs index 1117fe55e5..575212f060 100644 --- a/webrender_api/src/color.rs +++ b/webrender_api/src/color.rs @@ -21,12 +21,7 @@ known_heap_size!(0, ColorF); impl ColorF { /// Constructs a new `ColorF` from its components. pub fn new(r: f32, g: f32, b: f32, a: f32) -> ColorF { - ColorF { - r, - g, - b, - a, - } + ColorF { r, g, b, a } } /// Multiply the RGB channels (but not alpha) with a given factor. @@ -53,7 +48,7 @@ impl ColorF { } // Floats don't impl Hash/Eq... -impl Eq for ColorF { } +impl Eq for ColorF {} impl Hash for ColorF { fn hash(&self, state: &mut H) { // Note: this is inconsistent with the Eq impl for -0.0 (don't care). @@ -69,7 +64,9 @@ trait ToBits { fn _to_bits(self) -> u32; } impl ToBits for f32 { - fn _to_bits(self) -> u32 { unsafe { ::std::mem::transmute(self) } } + fn _to_bits(self) -> u32 { + unsafe { ::std::mem::transmute(self) } + } } /// Represents RGBA screen colors with one byte per channel. @@ -87,12 +84,7 @@ pub struct ColorU { impl ColorU { /// Constructs a new additive `ColorU` from its components. pub fn new(r: u8, g: u8, b: u8, a: u8) -> ColorU { - ColorU { - r, - g, - b, - a, - } + ColorU { r, g, b, a } } } diff --git a/webrender_api/src/display_item.rs b/webrender_api/src/display_item.rs index b359dc22b1..3605a0e5d1 100644 --- a/webrender_api/src/display_item.rs +++ b/webrender_api/src/display_item.rs @@ -2,9 +2,10 @@ * 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 euclid::{SideOffsets2D, TypedRect, TypedSideOffsets2D}; -use {ColorF, FontInstanceKey, ImageKey, LayerPixel, LayoutPixel, LayoutPoint, LayoutRect, LayoutSize, LayoutTransform}; +use {ColorF, FontInstanceKey, ImageKey, LayerPixel, LayoutPixel, LayoutPoint, LayoutRect, + LayoutSize, LayoutTransform}; use {GlyphOptions, LayoutVector2D, PipelineId, PropertyBinding}; +use euclid::{SideOffsets2D, TypedRect, TypedSideOffsets2D}; // NOTE: some of these structs have an "IMPLICIT" comment. // This indicates that the BuiltDisplayList will have serialized @@ -255,24 +256,24 @@ pub struct BorderSide { #[repr(u32)] #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] pub enum BorderStyle { - None = 0, - Solid = 1, - Double = 2, - Dotted = 3, - Dashed = 4, - Hidden = 5, - Groove = 6, - Ridge = 7, - Inset = 8, - Outset = 9, + None = 0, + Solid = 1, + Double = 2, + Dotted = 3, + Dashed = 4, + Hidden = 5, + Groove = 6, + Ridge = 7, + Inset = 8, + Outset = 9, } #[repr(u32)] #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] pub enum BoxShadowClipMode { - None = 0, - Outset = 1, - Inset = 2, + None = 0, + Outset = 1, + Inset = 2, } #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] @@ -357,8 +358,8 @@ pub struct StackingContext { #[repr(u32)] #[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] pub enum ScrollPolicy { - Scrollable = 0, - Fixed = 1, + Scrollable = 0, + Fixed = 1, } known_heap_size!(0, ScrollPolicy); @@ -366,29 +367,29 @@ known_heap_size!(0, ScrollPolicy); #[repr(u32)] #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] pub enum TransformStyle { - Flat = 0, - Preserve3D = 1, + Flat = 0, + Preserve3D = 1, } #[repr(u32)] #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] pub enum MixBlendMode { - Normal = 0, - Multiply = 1, - Screen = 2, - Overlay = 3, - Darken = 4, - Lighten = 5, - ColorDodge = 6, - ColorBurn = 7, - HardLight = 8, - SoftLight = 9, - Difference = 10, - Exclusion = 11, - Hue = 12, - Saturation = 13, - Color = 14, - Luminosity = 15, + Normal = 0, + Multiply = 1, + Screen = 2, + Overlay = 3, + Darken = 4, + Lighten = 5, + ColorDodge = 6, + ColorBurn = 7, + HardLight = 8, + SoftLight = 9, + Difference = 10, + Exclusion = 11, + Hue = 12, + Saturation = 13, + Color = 14, + Luminosity = 15, } #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)] @@ -420,16 +421,16 @@ pub struct ImageDisplayItem { #[repr(u32)] #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] pub enum ImageRendering { - Auto = 0, - CrispEdges = 1, - Pixelated = 2, + Auto = 0, + CrispEdges = 1, + Pixelated = 2, } #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] pub struct YuvImageDisplayItem { pub yuv_data: YuvData, pub color_space: YuvColorSpace, - pub image_rendering: ImageRendering + pub image_rendering: ImageRendering, } #[repr(u32)] @@ -451,8 +452,8 @@ impl YuvColorSpace { #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] pub enum YuvData { - NV12(ImageKey, ImageKey), // (Y channel, CbCr interleaved channel) - PlanarYCbCr(ImageKey, ImageKey, ImageKey), // (Y channel, Cb channel, Cr Channel) + NV12(ImageKey, ImageKey), // (Y channel, CbCr interleaved channel) + PlanarYCbCr(ImageKey, ImageKey, ImageKey), // (Y channel, Cb channel, Cr Channel) InterleavedYCbCr(ImageKey), // (YCbCr interleaved channel) } @@ -472,7 +473,11 @@ pub enum YuvFormat { PlanarYCbCr = 1, InterleavedYCbCr = 2, } -pub const YUV_FORMATS: [YuvFormat; 3] = [YuvFormat::NV12, YuvFormat::PlanarYCbCr, YuvFormat::InterleavedYCbCr]; +pub const YUV_FORMATS: [YuvFormat; 3] = [ + YuvFormat::NV12, + YuvFormat::PlanarYCbCr, + YuvFormat::InterleavedYCbCr, +]; impl YuvFormat { pub fn get_plane_num(&self) -> usize { @@ -487,7 +492,7 @@ impl YuvFormat { match *self { YuvFormat::NV12 => "NV12", YuvFormat::PlanarYCbCr => "", - YuvFormat::InterleavedYCbCr => "INTERLEAVED_Y_CB_CR" + YuvFormat::InterleavedYCbCr => "INTERLEAVED_Y_CB_CR", } } } @@ -523,13 +528,13 @@ impl LocalClip { pub fn create_with_offset(&self, offset: &LayoutVector2D) -> LocalClip { match *self { LocalClip::Rect(rect) => LocalClip::from(rect.translate(offset)), - LocalClip::RoundedRect(rect, complex) => { - LocalClip::RoundedRect(rect.translate(offset), - ComplexClipRegion { - rect: complex.rect.translate(offset), - radii: complex.radii, - }) - } + LocalClip::RoundedRect(rect, complex) => LocalClip::RoundedRect( + rect.translate(offset), + ComplexClipRegion { + rect: complex.rect.translate(offset), + radii: complex.radii, + }, + ), } } } @@ -573,15 +578,15 @@ impl BorderRadius { pub fn is_uniform(&self) -> Option { match self.is_uniform_size() { Some(radius) if radius.width == radius.height => Some(radius.width), - _ => None + _ => None, } } pub fn is_uniform_size(&self) -> Option { let uniform_radius = self.top_left; - if self.top_right == uniform_radius && - self.bottom_left == uniform_radius && - self.bottom_right == uniform_radius { + if self.top_right == uniform_radius && self.bottom_left == uniform_radius && + self.bottom_right == uniform_radius + { Some(uniform_radius) } else { None @@ -600,10 +605,7 @@ impl BorderRadius { impl ComplexClipRegion { /// Create a new complex clip region. pub fn new(rect: LayoutRect, radii: BorderRadius) -> ComplexClipRegion { - ComplexClipRegion { - rect, - radii, - } + ComplexClipRegion { rect, radii } } } @@ -652,7 +654,7 @@ impl ClipId { pub fn is_root_scroll_node(&self) -> bool { match *self { - ClipId::Clip(0, 0, _) => true, + ClipId::Clip(0, 0, _) => true, _ => false, } } diff --git a/webrender_api/src/display_list.rs b/webrender_api/src/display_list.rs index 615d722853..e937c2d2e6 100644 --- a/webrender_api/src/display_list.rs +++ b/webrender_api/src/display_list.rs @@ -2,22 +2,25 @@ * 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 bincode; -use serde::{Deserialize, Serialize, Serializer}; -use serde::ser::{SerializeSeq, SerializeMap}; -use time::precise_time_ns; use {BorderDetails, BorderDisplayItem, BorderWidths, BoxShadowClipMode, BoxShadowDisplayItem}; use {ClipAndScrollInfo, ClipDisplayItem, ClipId, ColorF, ComplexClipRegion, DisplayItem}; use {ExtendMode, FastHashMap, FastHashSet, FilterOp, FontInstanceKey, GlyphIndex, GlyphInstance}; use {GlyphOptions, Gradient, GradientDisplayItem, GradientStop, IframeDisplayItem}; -use {ImageDisplayItem, ImageKey, ImageMask, ImageRendering, LayerPrimitiveInfo, LayoutPoint, LayoutRect, LayoutSize}; -use {LayoutTransform, LayoutVector2D, LayoutPrimitiveInfo, LineDisplayItem, LineOrientation, LineStyle, LocalClip}; -use {MixBlendMode, PipelineId, PropertyBinding, PushStackingContextDisplayItem, PrimitiveInfo, RadialGradient}; +use {ImageDisplayItem, ImageKey, ImageMask, ImageRendering, LayerPrimitiveInfo, LayoutPoint, + LayoutRect, LayoutSize}; +use {LayoutPrimitiveInfo, LayoutTransform, LayoutVector2D, LineDisplayItem, LineOrientation, + LineStyle, LocalClip}; +use {MixBlendMode, PipelineId, PrimitiveInfo, PropertyBinding, PushStackingContextDisplayItem, + RadialGradient}; use {RadialGradientDisplayItem, RectangleDisplayItem, ScrollFrameDisplayItem, ScrollPolicy}; use {ScrollSensitivity, SpecificDisplayItem, StackingContext, StickyFrameDisplayItem}; use {StickyFrameInfo, TextDisplayItem, TextShadow, TransformStyle}; use {YuvColorSpace, YuvData, YuvImageDisplayItem}; +use bincode; +use serde::{Deserialize, Serialize, Serializer}; +use serde::ser::{SerializeMap, SerializeSeq}; use std::marker::PhantomData; +use time::precise_time_ns; // We don't want to push a long text-run. If a text-run is too long, split it into several parts. // Please check the renderer::MAX_VERTEX_TEXTURE_WIDTH for the detail. @@ -33,7 +36,11 @@ pub struct ItemRange { impl Default for ItemRange { fn default() -> Self { - ItemRange { start: 0, length: 0, _boo: PhantomData } + ItemRange { + start: 0, + length: 0, + _boo: PhantomData, + } } } @@ -104,15 +111,11 @@ pub struct AuxIter<'a, T> { _boo: PhantomData, } -impl BuiltDisplayListDescriptor { -} +impl BuiltDisplayListDescriptor {} impl BuiltDisplayList { pub fn from_data(data: Vec, descriptor: BuiltDisplayListDescriptor) -> BuiltDisplayList { - BuiltDisplayList { - data, - descriptor, - } + BuiltDisplayList { data, descriptor } } pub fn into_data(mut self) -> (Vec, BuiltDisplayListDescriptor) { @@ -125,11 +128,11 @@ impl BuiltDisplayList { } pub fn item_slice(&self) -> &[u8] { - &self.data[..self.descriptor.glyph_offset] + &self.data[.. self.descriptor.glyph_offset] } pub fn glyph_slice(&self) -> &[u8] { - &self.data[self.descriptor.glyph_offset..] + &self.data[self.descriptor.glyph_offset ..] } pub fn descriptor(&self) -> &BuiltDisplayListDescriptor { @@ -137,9 +140,11 @@ impl BuiltDisplayList { } pub fn times(&self) -> (u64, u64, u64) { - (self.descriptor.builder_start_time, - self.descriptor.builder_finish_time, - self.descriptor.send_start_time) + ( + self.descriptor.builder_start_time, + self.descriptor.builder_finish_time, + self.descriptor.send_start_time, + ) } pub fn iter(&self) -> BuiltDisplayListIter { @@ -160,7 +165,10 @@ impl BuiltDisplayList { /// Returns the byte-range the slice occupied, and the number of elements /// in the slice. -fn skip_slice Deserialize<'de>>(list: &BuiltDisplayList, data: &mut &[u8]) -> (ItemRange, usize) { +fn skip_slice Deserialize<'de>>( + list: &BuiltDisplayList, + data: &mut &[u8], +) -> (ItemRange, usize) { let base = list.data.as_ptr() as usize; let start = data.as_ptr() as usize; @@ -170,10 +178,14 @@ fn skip_slice Deserialize<'de>>(list: &BuiltDisplayList, data: &mut for _ in &mut iter {} let end = iter.data.as_ptr() as usize; - let range = ItemRange { start: start - base, length: end - start, _boo: PhantomData }; + let range = ItemRange { + start: start - base, + length: end - start, + _boo: PhantomData, + }; // Adjust data pointer to skip read values - *data = &data[range.length..]; + *data = &data[range.length ..]; (range, count) } @@ -186,7 +198,8 @@ impl<'a> BuiltDisplayListIter<'a> { BuiltDisplayListIter { list, data: &data, - cur_item: DisplayItem { // Dummy data, will be overwritten by `next` + cur_item: DisplayItem { + // Dummy data, will be overwritten by `next` item: SpecificDisplayItem::PopStackingContext, clip_and_scroll: ClipAndScrollInfo::simple(ClipId::new(0, PipelineId::dummy())), info: PrimitiveInfo { @@ -213,7 +226,7 @@ impl<'a> BuiltDisplayListIter<'a> { match self.peeking { Peek::IsPeeking => { self.peeking = Peek::NotPeeking; - return Some(self.as_ref()) + return Some(self.as_ref()); } Peek::StartPeeking => { self.peeking = Peek::IsPeeking; @@ -227,11 +240,11 @@ impl<'a> BuiltDisplayListIter<'a> { loop { if self.data.len() == 0 { - return None + return None; } self.cur_item = bincode::deserialize_from(&mut self.data, bincode::Infinite) - .expect("MEH: malicious process?"); + .expect("MEH: malicious process?"); match self.cur_item.item { SetGradientStops => { @@ -240,8 +253,9 @@ impl<'a> BuiltDisplayListIter<'a> { // This is a dummy item, skip over it continue; } - Clip(_) | ScrollFrame(_) => - self.cur_complex_clip = self.skip_slice::(), + Clip(_) | ScrollFrame(_) => { + self.cur_complex_clip = self.skip_slice::() + } Text(_) => self.cur_glyphs = self.skip_slice::().0, PushStackingContext(_) => self.cur_filters = self.skip_slice::().0, _ => { /* do nothing */ } @@ -261,13 +275,15 @@ impl<'a> BuiltDisplayListIter<'a> { DisplayItemRef { iter: self } } - pub fn starting_stacking_context(&mut self) - -> Option<(StackingContext, LayoutRect, ItemRange)> { - + pub fn starting_stacking_context( + &mut self, + ) -> Option<(StackingContext, LayoutRect, ItemRange)> { self.next().and_then(|item| match *item.item() { - SpecificDisplayItem::PushStackingContext(ref specific_item) => { - Some((specific_item.stacking_context, item.rect(), item.filters())) - }, + SpecificDisplayItem::PushStackingContext(ref specific_item) => Some(( + specific_item.stacking_context, + item.rect(), + item.filters(), + )), _ => None, }) } @@ -306,10 +322,12 @@ impl<'a> Iterator for GlyphsIter<'a> { type Item = (FontInstanceKey, ColorF, ItemRange); fn next(&mut self) -> Option { - if self.data.len() == 0 { return None; } + if self.data.len() == 0 { + return None; + } let (font_key, color) = bincode::deserialize_from(&mut self.data, bincode::Infinite) - .expect("MEH: malicious process?"); + .expect("MEH: malicious process?"); let glyph_indices = skip_slice::(self.list, &mut self.data).0; Some((font_key, color, glyph_indices)) } @@ -378,12 +396,10 @@ impl<'a, 'b> DisplayItemRef<'a, 'b> { impl<'de, 'a, T: Deserialize<'de>> AuxIter<'a, T> { pub fn new(mut data: &'a [u8]) -> Self { - let size: usize = if data.len() == 0 { - 0 // Accept empty ItemRanges pointing anywhere + 0 // Accept empty ItemRanges pointing anywhere } else { - bincode::deserialize_from(&mut data, bincode::Infinite) - .expect("MEH: malicious input?") + bincode::deserialize_from(&mut data, bincode::Infinite).expect("MEH: malicious input?") }; AuxIter { @@ -402,8 +418,10 @@ impl<'a, T: for<'de> Deserialize<'de>> Iterator for AuxIter<'a, T> { None } else { self.size -= 1; - Some(bincode::deserialize_from(&mut self.data, bincode::Infinite) - .expect("MEH: malicious input?")) + Some( + bincode::deserialize_from(&mut self.data, bincode::Infinite) + .expect("MEH: malicious input?"), + ) } } @@ -412,7 +430,7 @@ impl<'a, T: for<'de> Deserialize<'de>> Iterator for AuxIter<'a, T> { } } -impl<'a, T: for<'de> Deserialize<'de>> ::std::iter::ExactSizeIterator for AuxIter<'a, T> { } +impl<'a, T: for<'de> Deserialize<'de>> ::std::iter::ExactSizeIterator for AuxIter<'a, T> {} // This is purely for the JSON writer in wrench @@ -435,27 +453,35 @@ impl<'a, 'b> Serialize for DisplayItemRef<'a, 'b> { match *self.item() { SpecificDisplayItem::Text(_) => { - map.serialize_entry("glyphs", - &self.iter.list.get(self.glyphs()).collect::>())?; + map.serialize_entry( + "glyphs", + &self.iter.list.get(self.glyphs()).collect::>(), + )?; } SpecificDisplayItem::PushStackingContext(_) => { - map.serialize_entry("filters", - &self.iter.list.get(self.filters()).collect::>())?; + map.serialize_entry( + "filters", + &self.iter.list.get(self.filters()).collect::>(), + )?; } - _ => { } + _ => {} } let &(complex_clips, number_of_complex_clips) = self.complex_clip(); let gradient_stops = self.gradient_stops(); if number_of_complex_clips > 0 { - map.serialize_entry("complex_clips", - &self.iter.list.get(complex_clips).collect::>())?; + map.serialize_entry( + "complex_clips", + &self.iter.list.get(complex_clips).collect::>(), + )?; } if !gradient_stops.is_empty() { - map.serialize_entry("gradient_stops", - &self.iter.list.get(gradient_stops).collect::>())?; + map.serialize_entry( + "gradient_stops", + &self.iter.list.get(gradient_stops).collect::>(), + )?; } map.end() @@ -482,18 +508,22 @@ impl DisplayListBuilder { Self::with_capacity(pipeline_id, content_size, 0) } - pub fn with_capacity(pipeline_id: PipelineId, - content_size: LayoutSize, - capacity: usize) -> DisplayListBuilder { + pub fn with_capacity( + pipeline_id: PipelineId, + content_size: LayoutSize, + capacity: usize, + ) -> DisplayListBuilder { let start_time = precise_time_ns(); // We start at 1 here, because the root scroll id is always 0. - const FIRST_CLIP_ID : u64 = 1; + const FIRST_CLIP_ID: u64 = 1; DisplayListBuilder { data: Vec::with_capacity(capacity), pipeline_id, - clip_stack: vec![ClipAndScrollInfo::simple(ClipId::root_scroll_node(pipeline_id))], + clip_stack: vec![ + ClipAndScrollInfo::simple(ClipId::root_scroll_node(pipeline_id)), + ], glyphs: FastHashMap::default(), next_clip_id: FIRST_CLIP_ID, builder_start_time: start_time, @@ -515,31 +545,38 @@ impl DisplayListBuilder { self.data = temp.data; } - fn push_item(&mut self, - item: SpecificDisplayItem, - info: &LayoutPrimitiveInfo) { + fn push_item(&mut self, item: SpecificDisplayItem, info: &LayoutPrimitiveInfo) { let mut new_info = info.clone(); new_info.local_clip = info.local_clip.or(Some(LocalClip::from(info.rect))); - bincode::serialize_into(&mut self.data, &DisplayItem { - item, - clip_and_scroll: *self.clip_stack.last().unwrap(), - info: new_info, - }, bincode::Infinite).unwrap(); + bincode::serialize_into( + &mut self.data, + &DisplayItem { + item, + clip_and_scroll: *self.clip_stack.last().unwrap(), + info: new_info, + }, + bincode::Infinite, + ).unwrap(); } fn push_new_empty_item(&mut self, item: SpecificDisplayItem) { let info = LayoutPrimitiveInfo::new(LayoutRect::zero()); - bincode::serialize_into(&mut self.data, &DisplayItem { - item, - clip_and_scroll: *self.clip_stack.last().unwrap(), - info, - }, bincode::Infinite).unwrap(); + bincode::serialize_into( + &mut self.data, + &DisplayItem { + item, + clip_and_scroll: *self.clip_stack.last().unwrap(), + info, + }, + bincode::Infinite, + ).unwrap(); } fn push_iter(&mut self, iter: I) - where I: IntoIterator, - I::IntoIter: ExactSizeIterator, - I::Item: Serialize, + where + I: IntoIterator, + I::IntoIter: ExactSizeIterator, + I::Item: Serialize, { let iter = iter.into_iter(); let len = iter.len(); @@ -554,39 +591,44 @@ impl DisplayListBuilder { debug_assert_eq!(len, count); } - pub fn push_rect(&mut self, - info: &LayoutPrimitiveInfo, - color: ColorF) { - let item = SpecificDisplayItem::Rectangle(RectangleDisplayItem { - color, - }); + pub fn push_rect(&mut self, info: &LayoutPrimitiveInfo, color: ColorF) { + let item = SpecificDisplayItem::Rectangle(RectangleDisplayItem { color }); self.push_item(item, info); } - pub fn push_line(&mut self, - info: &LayoutPrimitiveInfo, - baseline: f32, - start: f32, - end: f32, - orientation: LineOrientation, - width: f32, - color: ColorF, - style: LineStyle) { + pub fn push_line( + &mut self, + info: &LayoutPrimitiveInfo, + baseline: f32, + start: f32, + end: f32, + orientation: LineOrientation, + width: f32, + color: ColorF, + style: LineStyle, + ) { let item = SpecificDisplayItem::Line(LineDisplayItem { - baseline, start, end, orientation, - width, color, style, + baseline, + start, + end, + orientation, + width, + color, + style, }); self.push_item(item, info); } - pub fn push_image(&mut self, - info: &LayoutPrimitiveInfo, - stretch_size: LayoutSize, - tile_spacing: LayoutSize, - image_rendering: ImageRendering, - key: ImageKey) { + pub fn push_image( + &mut self, + info: &LayoutPrimitiveInfo, + stretch_size: LayoutSize, + tile_spacing: LayoutSize, + image_rendering: ImageRendering, + key: ImageKey, + ) { let item = SpecificDisplayItem::Image(ImageDisplayItem { image_key: key, stretch_size, @@ -598,11 +640,13 @@ impl DisplayListBuilder { } /// Push a yuv image. All planar data in yuv image should use the same buffer type. - pub fn push_yuv_image(&mut self, - info: &LayoutPrimitiveInfo, - yuv_data: YuvData, - color_space: YuvColorSpace, - image_rendering: ImageRendering) { + pub fn push_yuv_image( + &mut self, + info: &LayoutPrimitiveInfo, + yuv_data: YuvData, + color_space: YuvColorSpace, + image_rendering: ImageRendering, + ) { let item = SpecificDisplayItem::YuvImage(YuvImageDisplayItem { yuv_data, color_space, @@ -611,12 +655,14 @@ impl DisplayListBuilder { self.push_item(item, info); } - pub fn push_text(&mut self, - info: &LayoutPrimitiveInfo, - glyphs: &[GlyphInstance], - font_key: FontInstanceKey, - color: ColorF, - glyph_options: Option) { + pub fn push_text( + &mut self, + info: &LayoutPrimitiveInfo, + glyphs: &[GlyphInstance], + font_key: FontInstanceKey, + color: ColorF, + glyph_options: Option, + ) { let item = SpecificDisplayItem::Text(TextDisplayItem { color, font_key, @@ -628,16 +674,23 @@ impl DisplayListBuilder { self.push_iter(split_glyphs); // Remember that we've seen these glyphs - self.cache_glyphs(font_key, color, split_glyphs.iter().map(|glyph| glyph.index)); + self.cache_glyphs( + font_key, + color, + split_glyphs.iter().map(|glyph| glyph.index), + ); } } - fn cache_glyphs>(&mut self, - font_key: FontInstanceKey, - color: ColorF, - glyphs: I) { - let font_glyphs = self.glyphs.entry((font_key, color)) - .or_insert(FastHashSet::default()); + fn cache_glyphs>( + &mut self, + font_key: FontInstanceKey, + color: ColorF, + glyphs: I, + ) { + let font_glyphs = self.glyphs + .entry((font_key, color)) + .or_insert(FastHashSet::default()); font_glyphs.extend(glyphs); } @@ -720,13 +773,15 @@ impl DisplayListBuilder { // NOTE: gradients must be pushed in the order they're created // because create_gradient stores the stops in anticipation - pub fn create_gradient(&mut self, - start_point: LayoutPoint, - end_point: LayoutPoint, - mut stops: Vec, - extend_mode: ExtendMode) -> Gradient { - let (start_offset, - end_offset) = DisplayListBuilder::normalize_stops(&mut stops, extend_mode); + pub fn create_gradient( + &mut self, + start_point: LayoutPoint, + end_point: LayoutPoint, + mut stops: Vec, + extend_mode: ExtendMode, + ) -> Gradient { + let (start_offset, end_offset) = + DisplayListBuilder::normalize_stops(&mut stops, extend_mode); let start_to_end = end_point - start_point; @@ -741,11 +796,13 @@ impl DisplayListBuilder { // NOTE: gradients must be pushed in the order they're created // because create_gradient stores the stops in anticipation - pub fn create_radial_gradient(&mut self, - center: LayoutPoint, - radius: LayoutSize, - mut stops: Vec, - extend_mode: ExtendMode) -> RadialGradient { + pub fn create_radial_gradient( + &mut self, + center: LayoutPoint, + radius: LayoutSize, + mut stops: Vec, + extend_mode: ExtendMode, + ) -> RadialGradient { if radius.width <= 0.0 || radius.height <= 0.0 { // The shader cannot handle a non positive radius. So // reuse the stops vector and construct an equivalent @@ -775,8 +832,8 @@ impl DisplayListBuilder { }; } - let (start_offset, - end_offset) = DisplayListBuilder::normalize_stops(&mut stops, extend_mode); + let (start_offset, end_offset) = + DisplayListBuilder::normalize_stops(&mut stops, extend_mode); self.push_stops(&stops); @@ -792,15 +849,16 @@ impl DisplayListBuilder { // NOTE: gradients must be pushed in the order they're created // because create_gradient stores the stops in anticipation - pub fn create_complex_radial_gradient(&mut self, - start_center: LayoutPoint, - start_radius: f32, - end_center: LayoutPoint, - end_radius: f32, - ratio_xy: f32, - stops: Vec, - extend_mode: ExtendMode) -> RadialGradient { - + pub fn create_complex_radial_gradient( + &mut self, + start_center: LayoutPoint, + start_radius: f32, + end_center: LayoutPoint, + end_radius: f32, + ratio_xy: f32, + stops: Vec, + extend_mode: ExtendMode, + ) -> RadialGradient { self.push_stops(&stops); RadialGradient { @@ -813,27 +871,28 @@ impl DisplayListBuilder { } } - pub fn push_border(&mut self, - info: &LayoutPrimitiveInfo, - widths: BorderWidths, - details: BorderDetails) { - let item = SpecificDisplayItem::Border(BorderDisplayItem { - details, - widths, - }); + pub fn push_border( + &mut self, + info: &LayoutPrimitiveInfo, + widths: BorderWidths, + details: BorderDetails, + ) { + let item = SpecificDisplayItem::Border(BorderDisplayItem { details, widths }); self.push_item(item, info); } - pub fn push_box_shadow(&mut self, - info: &LayoutPrimitiveInfo, - box_bounds: LayoutRect, - offset: LayoutVector2D, - color: ColorF, - blur_radius: f32, - spread_radius: f32, - border_radius: f32, - clip_mode: BoxShadowClipMode) { + pub fn push_box_shadow( + &mut self, + info: &LayoutPrimitiveInfo, + box_bounds: LayoutRect, + offset: LayoutVector2D, + color: ColorF, + blur_radius: f32, + spread_radius: f32, + border_radius: f32, + clip_mode: BoxShadowClipMode, + ) { let item = SpecificDisplayItem::BoxShadow(BoxShadowDisplayItem { box_bounds, offset, @@ -847,11 +906,13 @@ impl DisplayListBuilder { self.push_item(item, info); } - pub fn push_gradient(&mut self, - info: &LayoutPrimitiveInfo, - gradient: Gradient, - tile_size: LayoutSize, - tile_spacing: LayoutSize) { + pub fn push_gradient( + &mut self, + info: &LayoutPrimitiveInfo, + gradient: Gradient, + tile_size: LayoutSize, + tile_spacing: LayoutSize, + ) { let item = SpecificDisplayItem::Gradient(GradientDisplayItem { gradient, tile_size, @@ -861,11 +922,13 @@ impl DisplayListBuilder { self.push_item(item, info); } - pub fn push_radial_gradient(&mut self, - info: &LayoutPrimitiveInfo, - gradient: RadialGradient, - tile_size: LayoutSize, - tile_spacing: LayoutSize) { + pub fn push_radial_gradient( + &mut self, + info: &LayoutPrimitiveInfo, + gradient: RadialGradient, + tile_size: LayoutSize, + tile_spacing: LayoutSize, + ) { let item = SpecificDisplayItem::RadialGradient(RadialGradientDisplayItem { gradient, tile_size, @@ -875,14 +938,16 @@ impl DisplayListBuilder { self.push_item(item, info); } - pub fn push_stacking_context(&mut self, - info: &LayoutPrimitiveInfo, - scroll_policy: ScrollPolicy, - transform: Option>, - transform_style: TransformStyle, - perspective: Option, - mix_blend_mode: MixBlendMode, - filters: Vec) { + pub fn push_stacking_context( + &mut self, + info: &LayoutPrimitiveInfo, + scroll_policy: ScrollPolicy, + transform: Option>, + transform_style: TransformStyle, + perspective: Option, + mix_blend_mode: MixBlendMode, + filters: Vec, + ) { let item = SpecificDisplayItem::PushStackingContext(PushStackingContextDisplayItem { stacking_context: StackingContext { scroll_policy, @@ -890,7 +955,7 @@ impl DisplayListBuilder { transform_style, perspective, mix_blend_mode, - } + }, }); self.push_item(item, info); @@ -903,7 +968,7 @@ impl DisplayListBuilder { pub fn push_stops(&mut self, stops: &[GradientStop]) { if stops.is_empty() { - return + return; } self.push_new_empty_item(SpecificDisplayItem::SetGradientStops); self.push_iter(stops); @@ -916,16 +981,19 @@ impl DisplayListBuilder { }) } - pub fn define_scroll_frame(&mut self, - id: Option, - content_rect: LayoutRect, - clip_rect: LayoutRect, - complex_clips: I, - image_mask: Option, - scroll_sensitivity: ScrollSensitivity) - -> ClipId - where I: IntoIterator, - I::IntoIter: ExactSizeIterator { + pub fn define_scroll_frame( + &mut self, + id: Option, + content_rect: LayoutRect, + clip_rect: LayoutRect, + complex_clips: I, + image_mask: Option, + scroll_sensitivity: ScrollSensitivity, + ) -> ClipId + where + I: IntoIterator, + I::IntoIter: ExactSizeIterator, + { let id = self.generate_clip_id(id); let item = SpecificDisplayItem::ScrollFrame(ScrollFrameDisplayItem { id: id, @@ -945,14 +1013,17 @@ impl DisplayListBuilder { id } - pub fn define_clip(&mut self, - id: Option, - clip_rect: LayoutRect, - complex_clips: I, - image_mask: Option) - -> ClipId - where I: IntoIterator, - I::IntoIter: ExactSizeIterator { + pub fn define_clip( + &mut self, + id: Option, + clip_rect: LayoutRect, + complex_clips: I, + image_mask: Option, + ) -> ClipId + where + I: IntoIterator, + I::IntoIter: ExactSizeIterator, + { let id = self.generate_clip_id(id); let item = SpecificDisplayItem::Clip(ClipDisplayItem { id, @@ -967,11 +1038,12 @@ impl DisplayListBuilder { id } - pub fn define_sticky_frame(&mut self, - id: Option, - frame_rect: LayoutRect, - sticky_frame_info: StickyFrameInfo) - -> ClipId { + pub fn define_sticky_frame( + &mut self, + id: Option, + frame_rect: LayoutRect, + sticky_frame_info: StickyFrameInfo, + ) -> ClipId { let id = self.generate_clip_id(id); let item = SpecificDisplayItem::StickyFrame(StickyFrameDisplayItem { id, @@ -1001,10 +1073,10 @@ impl DisplayListBuilder { assert!(self.clip_stack.len() > 0); } - pub fn push_iframe(&mut self, - info: &LayoutPrimitiveInfo, - pipeline_id: PipelineId) { - let item = SpecificDisplayItem::Iframe(IframeDisplayItem { pipeline_id: pipeline_id }); + pub fn push_iframe(&mut self, info: &LayoutPrimitiveInfo, pipeline_id: PipelineId) { + let item = SpecificDisplayItem::Iframe(IframeDisplayItem { + pipeline_id: pipeline_id, + }); self.push_item(item, info); } @@ -1027,9 +1099,7 @@ impl DisplayListBuilder { self.push_new_empty_item(SpecificDisplayItem::PopNestedDisplayList); } - pub fn push_text_shadow(&mut self, - info: &LayoutPrimitiveInfo, - shadow: TextShadow) { + pub fn push_text_shadow(&mut self, info: &LayoutPrimitiveInfo, shadow: TextShadow) { self.push_item(SpecificDisplayItem::PushTextShadow(shadow), info); } @@ -1038,7 +1108,6 @@ impl DisplayListBuilder { } pub fn finalize(mut self) -> (PipelineId, LayoutSize, BuiltDisplayList) { - let glyph_offset = self.data.len(); // Want to use self.push_iter, so can't borrow self @@ -1054,16 +1123,18 @@ impl DisplayListBuilder { let end_time = precise_time_ns(); - (self.pipeline_id, - self.content_size, - BuiltDisplayList { - descriptor: BuiltDisplayListDescriptor { - builder_start_time: self.builder_start_time, - builder_finish_time: end_time, - send_start_time: 0, - glyph_offset, + ( + self.pipeline_id, + self.content_size, + BuiltDisplayList { + descriptor: BuiltDisplayListDescriptor { + builder_start_time: self.builder_start_time, + builder_finish_time: end_time, + send_start_time: 0, + glyph_offset, + }, + data: self.data, }, - data: self.data, - }) + ) } } diff --git a/webrender_api/src/font.rs b/webrender_api/src/font.rs index 0e6689182c..8ca58738d2 100644 --- a/webrender_api/src/font.rs +++ b/webrender_api/src/font.rs @@ -2,16 +2,20 @@ * 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 {ColorF, ColorU, IdNamespace, LayoutPoint}; use app_units::Au; -use {ColorU, ColorF, IdNamespace, LayoutPoint}; +#[cfg(target_os = "macos")] +use core_foundation::string::CFString; +#[cfg(target_os = "macos")] +use core_graphics::font::CGFont; +#[cfg(target_os = "windows")] +use dwrote::FontDescriptor; +#[cfg(target_os = "macos")] +use serde::de::{self, Deserialize, Deserializer}; +#[cfg(target_os = "macos")] +use serde::ser::{Serialize, Serializer}; use std::sync::Arc; -#[cfg(target_os = "macos")] use core_foundation::string::CFString; -#[cfg(target_os = "macos")] use core_graphics::font::CGFont; -#[cfg(target_os = "macos")] use serde::de::{self, Deserialize, Deserializer}; -#[cfg(target_os = "macos")] use serde::ser::{Serialize, Serializer}; -#[cfg(target_os = "windows")] use dwrote::FontDescriptor; - #[cfg(target_os = "macos")] #[derive(Clone)] @@ -19,7 +23,10 @@ pub struct NativeFontHandle(pub CGFont); #[cfg(target_os = "macos")] impl Serialize for NativeFontHandle { - fn serialize(&self, serializer: S) -> Result where S: Serializer { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { let postscript_name = self.0.postscript_name().to_string(); postscript_name.serialize(serializer) } @@ -27,19 +34,25 @@ impl Serialize for NativeFontHandle { #[cfg(target_os = "macos")] impl<'de> Deserialize<'de> for NativeFontHandle { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { let postscript_name: String = try!(Deserialize::deserialize(deserializer)); match CGFont::from_name(&CFString::new(&*postscript_name)) { Ok(font) => Ok(NativeFontHandle(font)), - _ => Err(de::Error::custom("Couldn't find a font with that PostScript name!")), + _ => Err(de::Error::custom( + "Couldn't find a font with that PostScript name!", + )), } } } /// Native fonts are not used on Linux; all fonts are raw. #[cfg(not(any(target_os = "macos", target_os = "windows")))] -#[cfg_attr(not(any(target_os = "macos", target_os = "windows")), derive(Clone, Serialize, Deserialize))] +#[cfg_attr(not(any(target_os = "macos", target_os = "windows")), + derive(Clone, Serialize, Deserialize))] pub struct NativeFontHandle; #[cfg(target_os = "windows")] @@ -101,11 +114,13 @@ impl FontRenderMode { // Given the absolute position, return the quantized increment fn subpixel_quantize_offset(&self, pos: f32) -> SubpixelOffset { const SUBPIXEL_BITS: i32 = 2; - const SUBPIXEL_FIXED16_MASK: i32 = ((1 << SUBPIXEL_BITS) - 1) << (FIXED16_SHIFT - SUBPIXEL_BITS); + const SUBPIXEL_FIXED16_MASK: i32 = + ((1 << SUBPIXEL_BITS) - 1) << (FIXED16_SHIFT - SUBPIXEL_BITS); const SUBPIXEL_ROUNDING: f32 = 0.5 / (1 << SUBPIXEL_BITS) as f32; let pos = pos + SUBPIXEL_ROUNDING; - let fraction = (f32_truncate_to_fixed16(pos) & SUBPIXEL_FIXED16_MASK) >> (FIXED16_SHIFT - SUBPIXEL_BITS); + let fraction = (f32_truncate_to_fixed16(pos) & SUBPIXEL_FIXED16_MASK) >> + (FIXED16_SHIFT - SUBPIXEL_BITS); match fraction { 0 => SubpixelOffset::Zero, @@ -128,10 +143,10 @@ impl FontRenderMode { #[repr(u8)] #[derive(Hash, Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Serialize, Deserialize)] pub enum SubpixelOffset { - Zero = 0, - Quarter = 1, - Half = 2, - ThreeQuarters = 3, + Zero = 0, + Quarter = 1, + Half = 2, + ThreeQuarters = 3, } impl Into for SubpixelOffset { @@ -181,12 +196,14 @@ pub struct FontInstance { } impl FontInstance { - pub fn new(font_key: FontKey, - size: Au, - mut color: ColorF, - render_mode: FontRenderMode, - subpx_dir: SubpixelDirection, - platform_options: Option) -> FontInstance { + pub fn new( + font_key: FontKey, + size: Au, + mut color: ColorF, + render_mode: FontRenderMode, + subpx_dir: SubpixelDirection, + platform_options: Option, + ) -> FontInstance { // In alpha/mono mode, the color of the font is irrelevant. // Forcing it to black in those cases saves rasterizing glyphs // of different colors when not needed. @@ -230,10 +247,12 @@ pub struct GlyphKey { } impl GlyphKey { - pub fn new(index: u32, - point: LayoutPoint, - render_mode: FontRenderMode, - subpx_dir: SubpixelDirection) -> GlyphKey { + pub fn new( + index: u32, + point: LayoutPoint, + render_mode: FontRenderMode, + subpx_dir: SubpixelDirection, + ) -> GlyphKey { let pos = match subpx_dir { SubpixelDirection::None => 0.0, SubpixelDirection::Horizontal => point.x, diff --git a/webrender_api/src/image.rs b/webrender_api/src/image.rs index f489d8f8c4..db78c8dc1d 100644 --- a/webrender_api/src/image.rs +++ b/webrender_api/src/image.rs @@ -2,11 +2,11 @@ * 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 std::sync::Arc; -use {DeviceUintRect, DevicePoint}; -use {IdNamespace}; +use {DevicePoint, DeviceUintRect}; use {TileOffset, TileSize}; -use font::{FontKey, FontInstanceKey, FontTemplate}; +use IdNamespace; +use font::{FontInstanceKey, FontKey, FontTemplate}; +use std::sync::Arc; #[repr(C)] #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] @@ -32,10 +32,10 @@ pub struct ExternalImageId(pub u64); #[repr(u32)] #[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, Serialize, Deserialize)] pub enum ExternalImageType { - Texture2DHandle, // gl TEXTURE_2D handle - Texture2DArrayHandle, // gl TEXTURE_2D_ARRAY handle - TextureRectHandle, // gl TEXTURE_RECT handle - TextureExternalHandle, // gl TEXTURE_EXTERNAL handle + Texture2DHandle, // gl TEXTURE_2D handle + Texture2DArrayHandle, // gl TEXTURE_2D_ARRAY handle + TextureRectHandle, // gl TEXTURE_RECT handle + TextureExternalHandle, // gl TEXTURE_EXTERNAL handle ExternalBuffer, } @@ -50,12 +50,12 @@ pub struct ExternalImageData { #[repr(u32)] #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] pub enum ImageFormat { - Invalid = 0, - A8 = 1, - RGB8 = 2, - BGRA8 = 3, - RGBAF32 = 4, - RG8 = 5, + Invalid = 0, + A8 = 1, + RGB8 = 2, + BGRA8 = 3, + RGBAF32 = 4, + RG8 = 5, } impl ImageFormat { @@ -94,7 +94,8 @@ impl ImageDescriptor { } pub fn compute_stride(&self) -> u32 { - self.stride.unwrap_or(self.width * self.format.bytes_per_pixel()) + self.stride + .unwrap_or(self.width * self.format.bytes_per_pixel()) } } @@ -129,15 +130,13 @@ impl ImageData { #[inline] pub fn uses_texture_cache(&self) -> bool { match self { - &ImageData::External(ext_data) => { - match ext_data.image_type { - ExternalImageType::Texture2DHandle => false, - ExternalImageType::Texture2DArrayHandle => false, - ExternalImageType::TextureRectHandle => false, - ExternalImageType::TextureExternalHandle => false, - ExternalImageType::ExternalBuffer => true, - } - } + &ImageData::External(ext_data) => match ext_data.image_type { + ExternalImageType::Texture2DHandle => false, + ExternalImageType::Texture2DArrayHandle => false, + ExternalImageType::TextureRectHandle => false, + ExternalImageType::TextureExternalHandle => false, + ExternalImageType::ExternalBuffer => true, + }, &ImageData::Blob(_) => true, &ImageData::Raw(_) => true, } @@ -156,11 +155,13 @@ pub trait BlobImageRenderer: Send { fn delete(&mut self, key: ImageKey); - fn request(&mut self, - services: &BlobImageResources, - key: BlobImageRequest, - descriptor: &BlobImageDescriptor, - dirty_rect: Option); + fn request( + &mut self, + services: &BlobImageResources, + key: BlobImageRequest, + descriptor: &BlobImageDescriptor, + dirty_rect: Option, + ); fn resolve(&mut self, key: BlobImageRequest) -> BlobImageResult; diff --git a/webrender_api/src/lib.rs b/webrender_api/src/lib.rs index 461f065019..2f9a4d309d 100644 --- a/webrender_api/src/lib.rs +++ b/webrender_api/src/lib.rs @@ -44,9 +44,8 @@ pub use display_item::*; pub use display_list::*; pub use font::*; pub use image::*; -pub use units::*; - -use std::hash::BuildHasherDefault; use std::collections::{HashMap, HashSet}; +use std::hash::BuildHasherDefault; +pub use units::*; type FastHashMap = HashMap>; type FastHashSet = HashSet>; diff --git a/webrender_api/src/units.rs b/webrender_api/src/units.rs index 137939ead6..cf57cbbe32 100644 --- a/webrender_api/src/units.rs +++ b/webrender_api/src/units.rs @@ -12,7 +12,7 @@ //! The terms "layer" and "stacking context" can be used interchangeably //! in the context of coordinate systems. -use euclid::{Length, TypedTransform3D, TypedRect, TypedSize2D}; +use euclid::{Length, TypedRect, TypedSize2D, TypedTransform3D}; use euclid::{TypedPoint2D, TypedPoint3D, TypedVector2D, TypedVector3D}; /// Geometry in the coordinate system of the render target (screen or intermediate diff --git a/wrench/build.rs b/wrench/build.rs index 39582f00fd..974ef3180c 100644 --- a/wrench/build.rs +++ b/wrench/build.rs @@ -14,7 +14,14 @@ fn main() { println!("cargo:rerun-if-changed=res/wrench.exe.manifest"); if target.contains("windows") { let src = PathBuf::from("res/wrench.exe.manifest"); - let mut dst = out_dir.parent().unwrap().parent().unwrap().parent().unwrap().to_owned(); + let mut dst = out_dir + .parent() + .unwrap() + .parent() + .unwrap() + .parent() + .unwrap() + .to_owned(); dst.push("wrench.exe.manifest"); fs::copy(&src, &dst).unwrap(); } diff --git a/wrench/src/binary_frame_reader.rs b/wrench/src/binary_frame_reader.rs index b478b58ca3..3a6e344845 100644 --- a/wrench/src/binary_frame_reader.rs +++ b/wrench/src/binary_frame_reader.rs @@ -38,8 +38,11 @@ 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(); - assert_eq!(header, WEBRENDER_RECORDING_HEADER, - "Binary recording is missing recording header!"); + assert_eq!( + header, + WEBRENDER_RECORDING_HEADER, + "Binary recording is missing recording header!" + ); let apimsg_type_id = unsafe { assert_eq!(mem::size_of::(), mem::size_of::()); @@ -48,9 +51,11 @@ impl BinaryFrameReader { let written_apimsg_type_id = file.read_u64::().unwrap(); if written_apimsg_type_id != apimsg_type_id { - println!("Warning: binary file ApiMsg type mismatch: expected 0x{:x}, found 0x{:x}", - apimsg_type_id, - written_apimsg_type_id); + println!( + "Warning: binary file ApiMsg type mismatch: expected 0x{:x}, found 0x{:x}", + apimsg_type_id, + written_apimsg_type_id + ); } BinaryFrameReader { @@ -90,12 +95,8 @@ impl BinaryFrameReader { } match *msg { - ApiMsg::UpdateResources(..) => { - true - } - _ => { - false - } + ApiMsg::UpdateResources(..) => true, + _ => false, } } @@ -164,7 +165,8 @@ impl WrenchThing for BinaryFrameReader { } if self.eof == false && - self.file.seek(SeekFrom::Current(0)).unwrap() == self.file.metadata().unwrap().len() { + self.file.seek(SeekFrom::Current(0)).unwrap() == self.file.metadata().unwrap().len() + { self.eof = true; } @@ -176,11 +178,9 @@ impl WrenchThing for BinaryFrameReader { let frame_items = self.frame_data.clone(); for item in frame_items { match item { - Item::Message(msg) => { - if !self.should_skip_upload_msg(&msg) { - wrench.api.send_message(msg); - } - } + Item::Message(msg) => if !self.should_skip_upload_msg(&msg) { + wrench.api.send_message(msg); + }, Item::Data(buf) => { wrench.api.send_payload(&buf); } diff --git a/wrench/src/blob.rs b/wrench/src/blob.rs index ed4416c54d..eaec6d7be4 100644 --- a/wrench/src/blob.rs +++ b/wrench/src/blob.rs @@ -20,7 +20,7 @@ fn deserialize_blob(blob: &[u8]) -> Result { (Some(&r), Some(&g), Some(&b), Some(&a)) => Ok(ColorU::new(r, g, b, a)), (Some(&a), None, None, None) => Ok(ColorU::new(a, a, a, a)), _ => Err(()), - } + }; } // This is the function that applies the deserialized drawing commands and generates @@ -41,15 +41,19 @@ fn render_blob( None => true, }; - for y in 0..descriptor.height { - for x in 0..descriptor.width { + for y in 0 .. descriptor.height { + for x in 0 .. descriptor.width { // Apply the tile's offset. This is important: all drawing commands should be // translated by this offset to give correct results with tiled blob images. let x2 = x + descriptor.offset.x as u32; let y2 = y + descriptor.offset.y as u32; // Render a simple checkerboard pattern - let checker = if (x2 % 20 >= 10) != (y2 % 20 >= 10) { 1 } else { 0 }; + let checker = if (x2 % 20 >= 10) != (y2 % 20 >= 10) { + 1 + } else { + 0 + }; // ..nested in the per-tile cherkerboard pattern let tc = if tile_checker { 0 } else { (1 - checker) * 40 }; @@ -64,10 +68,9 @@ fn render_blob( texels.push(color.a * checker + tc); } _ => { - return Err(BlobImageError::Other(format!( - "Usupported image format {:?}", - descriptor.format - ))); + return Err(BlobImageError::Other( + format!("Usupported image format {:?}", descriptor.format), + )); } } } @@ -98,24 +101,28 @@ impl CheckerboardRenderer { impl BlobImageRenderer for CheckerboardRenderer { fn add(&mut self, key: ImageKey, cmds: BlobImageData, _: Option) { - self.image_cmds.insert(key, deserialize_blob(&cmds[..]).unwrap()); + self.image_cmds + .insert(key, deserialize_blob(&cmds[..]).unwrap()); } fn update(&mut self, key: ImageKey, cmds: BlobImageData) { // Here, updating is just replacing the current version of the commands with // the new one (no incremental updates). - self.image_cmds.insert(key, deserialize_blob(&cmds[..]).unwrap()); + self.image_cmds + .insert(key, deserialize_blob(&cmds[..]).unwrap()); } fn delete(&mut self, key: ImageKey) { self.image_cmds.remove(&key); } - fn request(&mut self, - _resources: &BlobImageResources, - request: BlobImageRequest, - descriptor: &BlobImageDescriptor, - _dirty_rect: Option) { + fn request( + &mut self, + _resources: &BlobImageResources, + request: BlobImageRequest, + descriptor: &BlobImageDescriptor, + _dirty_rect: Option, + ) { assert!(!self.rendered_images.contains_key(&request)); // This method is where we kick off our rendering jobs. // It should avoid doing work on the calling thread as much as possible. @@ -133,9 +140,7 @@ impl BlobImageRenderer for CheckerboardRenderer { self.rendered_images.remove(&request).unwrap() } - fn delete_font(&mut self, _key: FontKey) { } + fn delete_font(&mut self, _key: FontKey) {} - fn delete_font_instance(&mut self, _key: FontInstanceKey) { } + fn delete_font_instance(&mut self, _key: FontInstanceKey) {} } - - diff --git a/wrench/src/json_frame_writer.rs b/wrench/src/json_frame_writer.rs index 9a2804016b..f15547f6ea 100644 --- a/wrench/src/json_frame_writer.rs +++ b/wrench/src/json_frame_writer.rs @@ -7,7 +7,7 @@ #![allow(dead_code)] use app_units::Au; -use image::{ColorType, save_buffer}; +use image::{save_buffer, ColorType}; use premultiply::unpremultiply; use serde_json; use std::borrow::BorrowMut; @@ -77,13 +77,14 @@ impl JsonFrameWriter { } } - pub fn begin_write_display_list(&mut self, - _: &Epoch, - _: &PipelineId, - _: &Option, - _: &LayoutSize, - display_list: &BuiltDisplayListDescriptor) - { + pub fn begin_write_display_list( + &mut self, + _: &Epoch, + _: &PipelineId, + _: &Option, + _: &LayoutSize, + display_list: &BuiltDisplayListDescriptor, + ) { unsafe { if CURRENT_FRAME_NUMBER == self.last_frame_written { return; @@ -94,10 +95,7 @@ impl JsonFrameWriter { self.dl_descriptor = Some(display_list.clone()); } - pub fn finish_write_display_list(&mut self, - frame: u32, - data: &[u8]) - { + pub fn finish_write_display_list(&mut self, frame: u32, data: &[u8]) { let payload = Payload::from_data(data); let dl_desc = self.dl_descriptor.take().unwrap(); @@ -119,20 +117,25 @@ impl JsonFrameWriter { match *update { ResourceUpdate::AddImage(ref img) => { let stride = img.descriptor.stride.unwrap_or( - img.descriptor.width * img.descriptor.format.bytes_per_pixel() + img.descriptor.width * img.descriptor.format.bytes_per_pixel(), ); let bytes = match img.data { - ImageData::Raw(ref v) => { (**v).clone() } - ImageData::External(_) | ImageData::Blob(_) => { return; } + ImageData::Raw(ref v) => (**v).clone(), + ImageData::External(_) | ImageData::Blob(_) => { + return; + } }; - self.images.insert(img.key, CachedImage { - width: img.descriptor.width, - height: img.descriptor.height, - stride, - format: img.descriptor.format, - bytes: Some(bytes), - path: None, - }); + self.images.insert( + img.key, + CachedImage { + width: img.descriptor.width, + height: img.descriptor.height, + stride, + format: img.descriptor.format, + bytes: Some(bytes), + path: None, + }, + ); } ResourceUpdate::UpdateImage(ref img) => { if let Some(ref mut data) = self.images.get_mut(&img.key) { @@ -145,36 +148,47 @@ impl JsonFrameWriter { *data.bytes.borrow_mut() = Some((**bytes).clone()); } else { // Other existing image types only make sense within the gecko integration. - println!("Wrench only supports updating buffer images (ignoring update command)."); + println!( + "Wrench only supports updating buffer images ({}).", + "ignoring update commands" + ); } } } ResourceUpdate::DeleteImage(img) => { self.images.remove(&img); } - ResourceUpdate::AddFont(ref font) => { - match font { - &AddFont::Raw(key, ref bytes, index) => { - self.fonts.insert(key, CachedFont::Raw(Some(bytes.clone()), index, None)); - } - &AddFont::Native(key, ref handle) => { - self.fonts.insert(key, CachedFont::Native(handle.clone())); - } + ResourceUpdate::AddFont(ref font) => match font { + &AddFont::Raw(key, ref bytes, index) => { + self.fonts + .insert(key, CachedFont::Raw(Some(bytes.clone()), index, None)); } - } + &AddFont::Native(key, ref handle) => { + self.fonts.insert(key, CachedFont::Native(handle.clone())); + } + }, ResourceUpdate::DeleteFont(_) => {} ResourceUpdate::AddFontInstance(ref instance) => { - self.font_instances.insert(instance.key, CachedFontInstance { - font_key: instance.font_key, - glyph_size: instance.glyph_size, - }); + self.font_instances.insert( + instance.key, + CachedFontInstance { + font_key: instance.font_key, + glyph_size: instance.glyph_size, + }, + ); } ResourceUpdate::DeleteFontInstance(_) => {} } } } - fn next_rsrc_paths(prefix: &str, counter: &mut u32, base_path: &Path, base: &str, ext: &str) -> (PathBuf, PathBuf) { + fn next_rsrc_paths( + prefix: &str, + counter: &mut u32, + base_path: &Path, + base: &str, + ext: &str, + ) -> (PathBuf, PathBuf) { let mut path_file = base_path.to_owned(); let mut path = PathBuf::from("res"); @@ -199,44 +213,63 @@ impl JsonFrameWriter { // Remove the data to munge it let mut data = self.images.remove(&key).unwrap(); let mut bytes = data.bytes.take().unwrap(); - let (path_file, path) = Self::next_rsrc_paths(&self.rsrc_prefix, - &mut self.next_rsrc_num, - &self.rsrc_base, - "img", - "png"); + let (path_file, path) = Self::next_rsrc_paths( + &self.rsrc_prefix, + &mut self.next_rsrc_num, + &self.rsrc_base, + "img", + "png", + ); let ok = match data.format { - ImageFormat::RGB8 => { - if data.stride == data.width * 3 { - save_buffer(&path_file, &bytes, data.width, data.height, ColorType::RGB(8)).unwrap(); - true - } else { - false - } - } - ImageFormat::BGRA8 => { - if data.stride == data.width * 4 { - unpremultiply(bytes.as_mut_slice()); - save_buffer(&path_file, &bytes, data.width, data.height, ColorType::RGBA(8)).unwrap(); - true - } else { - false - } - } - ImageFormat::A8 => { - if data.stride == data.width { - save_buffer(&path_file, &bytes, data.width, data.height, ColorType::Gray(8)).unwrap(); - true - } else { - false - } - } - _ => { false } + ImageFormat::RGB8 => if data.stride == data.width * 3 { + save_buffer( + &path_file, + &bytes, + data.width, + data.height, + ColorType::RGB(8), + ).unwrap(); + true + } else { + false + }, + ImageFormat::BGRA8 => if data.stride == data.width * 4 { + unpremultiply(bytes.as_mut_slice()); + save_buffer( + &path_file, + &bytes, + data.width, + data.height, + ColorType::RGBA(8), + ).unwrap(); + true + } else { + false + }, + ImageFormat::A8 => if data.stride == data.width { + save_buffer( + &path_file, + &bytes, + data.width, + data.height, + ColorType::Gray(8), + ).unwrap(); + true + } else { + false + }, + _ => false, }; if !ok { - println!("Failed to write image with format {:?}, dimensions {}x{}, stride {}", - data.format, data.width, data.height, data.stride); + println!( + "Failed to write image with format {:?}, dimensions {}x{}, stride {}", + data.format, + data.width, + data.height, + data.stride + ); return None; } @@ -256,25 +289,28 @@ impl fmt::Debug for JsonFrameWriter { impl webrender::ApiRecordingReceiver for JsonFrameWriter { fn write_msg(&mut self, _: u32, msg: &ApiMsg) { match *msg { - ApiMsg::UpdateResources(ref updates) => { - self.update_resources(updates) - } - - ApiMsg::UpdateDocument(_, DocumentMsg::SetDisplayList { - ref epoch, - ref pipeline_id, - ref background, - ref viewport_size, - ref list_descriptor, - ref resources, - .. - }) => { + ApiMsg::UpdateResources(ref updates) => self.update_resources(updates), + + ApiMsg::UpdateDocument( + _, + DocumentMsg::SetDisplayList { + ref epoch, + ref pipeline_id, + ref background, + ref viewport_size, + ref list_descriptor, + ref resources, + .. + }, + ) => { self.update_resources(resources); - self.begin_write_display_list(epoch, - pipeline_id, - background, - viewport_size, - list_descriptor); + self.begin_write_display_list( + epoch, + pipeline_id, + background, + viewport_size, + list_descriptor, + ); } ApiMsg::CloneApi(..) => {} _ => {} diff --git a/wrench/src/main.rs b/wrench/src/main.rs index d476c3c6be..3edd8e3595 100644 --- a/wrench/src/main.rs +++ b/wrench/src/main.rs @@ -116,20 +116,21 @@ impl HeadlessContext { attribs.push(24); attribs.push(0); - let context = unsafe { - osmesa_sys::OSMesaCreateContextAttribs(attribs.as_ptr(), ptr::null_mut()) - }; + let context = + unsafe { osmesa_sys::OSMesaCreateContextAttribs(attribs.as_ptr(), ptr::null_mut()) }; assert!(!context.is_null()); let mut buffer = vec![0; (width * height) as usize]; unsafe { - let ret = osmesa_sys::OSMesaMakeCurrent(context, - buffer.as_mut_ptr() as *mut _, - gl::UNSIGNED_BYTE, - width as i32, - height as i32); + let ret = osmesa_sys::OSMesaMakeCurrent( + context, + buffer.as_mut_ptr() as *mut _, + gl::UNSIGNED_BYTE, + width as i32, + height as i32, + ); assert!(ret != 0); }; @@ -143,18 +144,13 @@ impl HeadlessContext { #[cfg(not(feature = "headless"))] fn new(width: u32, height: u32) -> HeadlessContext { - HeadlessContext { - width, - height, - } + HeadlessContext { width, height } } #[cfg(feature = "headless")] fn get_proc_address(s: &str) -> *const c_void { let c_str = CString::new(s).expect("Unable to create CString"); - unsafe { - mem::transmute(osmesa_sys::OSMesaGetProcAddress(c_str.as_ptr())) - } + unsafe { mem::transmute(osmesa_sys::OSMesaGetProcAddress(c_str.as_ptr())) } } #[cfg(not(feature = "headless"))] @@ -202,60 +198,64 @@ impl WindowWrapper { fn set_title(&mut self, title: &str) { match *self { WindowWrapper::Window(ref window, _) => window.set_title(title), - WindowWrapper::Headless(..) => () + WindowWrapper::Headless(..) => (), } } pub fn gl(&self) -> &gl::Gl { match *self { - WindowWrapper::Window(_, ref gl) | - WindowWrapper::Headless(_, ref gl) => &**gl, + WindowWrapper::Window(_, ref gl) | WindowWrapper::Headless(_, ref gl) => &**gl, } } pub fn clone_gl(&self) -> Rc { match *self { - WindowWrapper::Window(_, ref gl) | - WindowWrapper::Headless(_, ref gl) => gl.clone(), + WindowWrapper::Window(_, ref gl) | WindowWrapper::Headless(_, ref gl) => gl.clone(), } } } -fn make_window(size: DeviceUintSize, - dp_ratio: Option, - vsync: bool, - headless: bool) -> WindowWrapper { +fn make_window( + size: DeviceUintSize, + dp_ratio: Option, + vsync: bool, + headless: bool, +) -> WindowWrapper { let wrapper = if headless { let gl = match gl::GlType::default() { - gl::GlType::Gl => { - unsafe { gl::GlFns::load_with(|symbol| HeadlessContext::get_proc_address(symbol) as *const _) } - } - gl::GlType::Gles => { - unsafe { gl::GlesFns::load_with(|symbol| HeadlessContext::get_proc_address(symbol) as *const _) } - } + gl::GlType::Gl => unsafe { + gl::GlFns::load_with(|symbol| { + HeadlessContext::get_proc_address(symbol) as *const _ + }) + }, + gl::GlType::Gles => unsafe { + gl::GlesFns::load_with(|symbol| { + HeadlessContext::get_proc_address(symbol) as *const _ + }) + }, }; - WindowWrapper::Headless(HeadlessContext::new(size.width, - size.height), - gl) + WindowWrapper::Headless(HeadlessContext::new(size.width, size.height), gl) } else { let mut window = glutin::WindowBuilder::new() .with_gl(glutin::GlRequest::GlThenGles { opengl_version: (3, 2), - opengles_version: (3, 1) + opengles_version: (3, 1), }) .with_dimensions(size.width, size.height); window.opengl.vsync = vsync; let window = window.build().unwrap(); unsafe { - window.make_current().expect("unable to make context current!"); + window + .make_current() + .expect("unable to make context current!"); } let gl = match gl::GlType::default() { - gl::GlType::Gl => { - unsafe { gl::GlFns::load_with(|symbol| window.get_proc_address(symbol) as *const _) } - } - gl::GlType::Gles => { - unsafe { gl::GlesFns::load_with(|symbol| window.get_proc_address(symbol) as *const _) } - } + gl::GlType::Gl => unsafe { + gl::GlFns::load_with(|symbol| window.get_proc_address(symbol) as *const _) + }, + gl::GlType::Gles => unsafe { + gl::GlesFns::load_with(|symbol| window.get_proc_address(symbol) as *const _) + }, }; WindowWrapper::Window(window, gl) }; @@ -267,7 +267,11 @@ fn make_window(size: DeviceUintSize, let dp_ratio = dp_ratio.unwrap_or(wrapper.hidpi_factor()); println!("OpenGL version {}, {}", gl_version, gl_renderer); - println!("hidpi factor: {} (native {})", dp_ratio, wrapper.hidpi_factor()); + println!( + "hidpi factor: {} (native {})", + dp_ratio, + wrapper.hidpi_factor() + ); wrapper } @@ -284,105 +288,104 @@ fn main() { // handle some global arguments let res_path = args.value_of("shaders").map(|s| PathBuf::from(s)); let dp_ratio = args.value_of("dp_ratio").map(|v| v.parse::().unwrap()); - let limit_seconds = args.value_of("time").map(|s| time::Duration::seconds(s.parse::().unwrap())); - let save_type = args.value_of("save").map(|s| { - if s == "yaml" { - wrench::SaveType::Yaml - } else if s == "json" { - wrench::SaveType::Json - } else if s == "binary" { - wrench::SaveType::Binary - } else { - panic!("Save type must be json, yaml, or binary"); - } + let limit_seconds = args.value_of("time") + .map(|s| time::Duration::seconds(s.parse::().unwrap())); + let save_type = args.value_of("save").map(|s| if s == "yaml" { + wrench::SaveType::Yaml + } else if s == "json" { + wrench::SaveType::Json + } 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" { + let size = args.value_of("size") + .map(|s| if s == "720p" { DeviceUintSize::new(1280, 720) } else if s == "1080p" { DeviceUintSize::new(1920, 1080) } else if s == "4k" { DeviceUintSize::new(3840, 2160) } else { - let x = s.find('x').expect("Size must be specified exactly as 720p, 1080p, 4k, or widthxheight"); - let w = s[0..x].parse::().expect("Invalid size width"); - let h = s[x + 1..].parse::().expect("Invalid size height"); + let x = s.find('x').expect( + "Size must be specified exactly as 720p, 1080p, 4k, or widthxheight", + ); + let w = s[0 .. x].parse::().expect("Invalid size width"); + let h = s[x + 1 ..].parse::().expect("Invalid size height"); DeviceUintSize::new(w, h) - } - }).unwrap_or(DeviceUintSize::new(1920, 1080)); + }) + .unwrap_or(DeviceUintSize::new(1920, 1080)); let is_headless = args.is_present("headless"); - let mut window = make_window(size, - dp_ratio, - args.is_present("vsync"), - is_headless); + let mut window = make_window(size, dp_ratio, args.is_present("vsync"), is_headless); let dp_ratio = dp_ratio.unwrap_or(window.hidpi_factor()); let (width, height) = window.get_inner_size_pixels(); let dim = DeviceUintSize::new(width, height); - let mut wrench = Wrench::new(&mut window, - res_path, - dp_ratio, - save_type, - dim, - args.is_present("rebuild"), - args.is_present("no_subpixel_aa"), - args.is_present("debug"), - args.is_present("verbose"), - args.is_present("no_scissor"), - args.is_present("no_batch")); - - let mut thing = - if let Some(subargs) = args.subcommand_matches("show") { - Box::new(YamlFrameReader::new_from_args(subargs)) as Box - } else if let Some(subargs) = args.subcommand_matches("replay") { - Box::new(BinaryFrameReader::new_from_args(subargs)) as Box - } else if let Some(subargs) = args.subcommand_matches("png") { - let reader = YamlFrameReader::new_from_args(subargs); - png::png(&mut wrench, &mut window, reader); - wrench.renderer.deinit(); - return; - } else if let Some(subargs) = args.subcommand_matches("reftest") { - let (w, h) = window.get_inner_size_pixels(); - let harness = ReftestHarness::new(&mut wrench, &mut window); - let base_manifest = Path::new("reftests/reftest.list"); - let specific_reftest = subargs.value_of("REFTEST").map(|x| Path::new(x)); - let mut reftest_options = ReftestOptions::default(); - if let Some(allow_max_diff) = subargs.value_of("fuzz_tolerance") { - reftest_options.allow_max_difference = allow_max_diff.parse().unwrap_or(1); - reftest_options.allow_num_differences = w as usize * h as usize; - } - harness.run(base_manifest, specific_reftest, &reftest_options); - return; - } else if let Some(_) = args.subcommand_matches("rawtest") { - { - let harness = RawtestHarness::new(&mut wrench, &mut window); - harness.run(); - } - wrench.renderer.deinit(); - return; - } else if let Some(subargs) = args.subcommand_matches("perf") { - // Perf mode wants to benchmark the total cost of drawing - // a new displaty list each frame. - wrench.rebuild_display_lists = true; - let harness = PerfHarness::new(&mut wrench, &mut window); - let base_manifest = Path::new("benchmarks/benchmarks.list"); - let filename = subargs.value_of("filename").unwrap(); - harness.run(base_manifest, filename); - return; - } else if let Some(subargs) = args.subcommand_matches("compare_perf") { - let first_filename = subargs.value_of("first_filename").unwrap(); - let second_filename = subargs.value_of("second_filename").unwrap(); - perf::compare(first_filename, second_filename); - return; - } else { - panic!("Should never have gotten here! {:?}", args); - }; + let mut wrench = Wrench::new( + &mut window, + res_path, + dp_ratio, + save_type, + dim, + args.is_present("rebuild"), + args.is_present("no_subpixel_aa"), + args.is_present("debug"), + args.is_present("verbose"), + args.is_present("no_scissor"), + args.is_present("no_batch"), + ); + + let mut thing = if let Some(subargs) = args.subcommand_matches("show") { + Box::new(YamlFrameReader::new_from_args(subargs)) as Box + } else if let Some(subargs) = args.subcommand_matches("replay") { + Box::new(BinaryFrameReader::new_from_args(subargs)) as Box + } else if let Some(subargs) = args.subcommand_matches("png") { + let reader = YamlFrameReader::new_from_args(subargs); + png::png(&mut wrench, &mut window, reader); + wrench.renderer.deinit(); + return; + } else if let Some(subargs) = args.subcommand_matches("reftest") { + let (w, h) = window.get_inner_size_pixels(); + let harness = ReftestHarness::new(&mut wrench, &mut window); + let base_manifest = Path::new("reftests/reftest.list"); + let specific_reftest = subargs.value_of("REFTEST").map(|x| Path::new(x)); + let mut reftest_options = ReftestOptions::default(); + if let Some(allow_max_diff) = subargs.value_of("fuzz_tolerance") { + reftest_options.allow_max_difference = allow_max_diff.parse().unwrap_or(1); + reftest_options.allow_num_differences = w as usize * h as usize; + } + harness.run(base_manifest, specific_reftest, &reftest_options); + return; + } else if let Some(_) = args.subcommand_matches("rawtest") { + { + let harness = RawtestHarness::new(&mut wrench, &mut window); + harness.run(); + } + wrench.renderer.deinit(); + return; + } else if let Some(subargs) = args.subcommand_matches("perf") { + // Perf mode wants to benchmark the total cost of drawing + // a new displaty list each frame. + wrench.rebuild_display_lists = true; + let harness = PerfHarness::new(&mut wrench, &mut window); + let base_manifest = Path::new("benchmarks/benchmarks.list"); + let filename = subargs.value_of("filename").unwrap(); + harness.run(base_manifest, filename); + return; + } else if let Some(subargs) = args.subcommand_matches("compare_perf") { + let first_filename = subargs.value_of("first_filename").unwrap(); + let second_filename = subargs.value_of("second_filename").unwrap(); + perf::compare(first_filename, second_filename); + return; + } else { + panic!("Should never have gotten here! {:?}", args); + }; let mut show_help = false; let mut do_loop = false; let queue_frames = thing.queue_frames(); - for _ in 0..queue_frames { + for _ in 0 .. queue_frames { let (width, height) = window.get_inner_size_pixels(); let dim = DeviceUintSize::new(width, height); wrench.update(dim); @@ -409,8 +412,12 @@ fn main() { let mut block_avg_time = vec![]; let mut warmed_up = false; - fn as_ms(f: time::Duration) -> f64 { f.num_microseconds().unwrap() as f64 / 1000. } - fn as_fps(f: time::Duration) -> f64 { (1000.*1000.) / f.num_microseconds().unwrap() as f64 } + fn as_ms(f: time::Duration) -> f64 { + f.num_microseconds().unwrap() as f64 / 1000. + } + fn as_fps(f: time::Duration) -> f64 { + (1000. * 1000.) / f.num_microseconds().unwrap() as f64 + } 'outer: loop { if let Some(window_title) = wrench.take_title() { @@ -419,30 +426,36 @@ fn main() { if let Some(limit) = limit_seconds { if (time::SteadyTime::now() - time_start) >= limit { - let mut block_avg_ms = block_avg_time.iter() - .map(|v| as_ms(*v)) - .collect::>(); + let mut block_avg_ms = block_avg_time + .iter() + .map(|v| as_ms(*v)) + .collect::>(); block_avg_ms.sort_by(|a, b| a.partial_cmp(b).unwrap()); - let avg_ms = block_avg_ms.iter().fold(0., |sum, v| sum + v) / block_avg_ms.len() as f64; + let avg_ms = + block_avg_ms.iter().fold(0., |sum, v| sum + v) / block_avg_ms.len() as f64; let val_10th_pct = percentile(&block_avg_ms, 10); let val_90th_pct = percentile(&block_avg_ms, 90); println!("- {:7} {:7} {:7}", "10th", "avg", "90th"); - println!("ms {:4.3} {:4.3} {:4.3}", - val_10th_pct, avg_ms, val_90th_pct); - println!("fps {:4.3} {:4.3} {:4.3}", - 1000. / val_10th_pct, 1000. / avg_ms, 1000. / val_90th_pct); + println!( + "ms {:4.3} {:4.3} {:4.3}", + val_10th_pct, + avg_ms, + val_90th_pct + ); + println!( + "fps {:4.3} {:4.3} {:4.3}", + 1000. / val_10th_pct, + 1000. / avg_ms, + 1000. / val_90th_pct + ); break; } } let event = match window { - WindowWrapper::Headless(..) => { - glutin::Event::Awakened - } - WindowWrapper::Window(ref window, _) => { - window.wait_events().next().unwrap() - } + WindowWrapper::Headless(..) => glutin::Event::Awakened, + WindowWrapper::Window(ref window, _) => window.wait_events().next().unwrap(), }; if let Some(limit) = limit_seconds { @@ -491,13 +504,21 @@ fn main() { } if wrench.verbose { + print!( + "{:3.3} [{:3.3} .. {:3.3}] -- {:4.3} fps", + as_ms(avg_time), + as_ms(min_time), + as_ms(max_time), + as_fps(avg_time) + ); if warmed_up { - println!("{:3.3} [{:3.3} .. {:3.3}] -- {:4.3} fps -- (global {:3.3} .. {:3.3})", - as_ms(avg_time), as_ms(min_time), as_ms(max_time), - as_fps(avg_time), as_ms(min_min_time), as_ms(max_max_time)); + println!( + " -- (global {:3.3} .. {:3.3})", + as_ms(min_min_time), + as_ms(max_max_time) + ); } else { - println!("{:3.3} [{:3.3} .. {:3.3}] -- {:4.3} fps", - as_ms(avg_time), as_ms(min_time), as_ms(max_time), as_fps(avg_time)); + println!(""); } } @@ -519,58 +540,60 @@ fn main() { break 'outer; } - glutin::Event::KeyboardInput(ElementState::Pressed, _scan_code, Some(vk)) => { - match vk { - VirtualKeyCode::Escape | VirtualKeyCode::Q => { - break 'outer; - }, - VirtualKeyCode::P => { - let mut flags = wrench.renderer.get_debug_flags(); - flags.toggle(webrender::PROFILER_DBG); - wrench.renderer.set_debug_flags(flags); - }, - VirtualKeyCode::O => { - let mut flags = wrench.renderer.get_debug_flags(); - flags.toggle(webrender::RENDER_TARGET_DBG); - wrench.renderer.set_debug_flags(flags); - }, - VirtualKeyCode::I => { - let mut flags = wrench.renderer.get_debug_flags(); - flags.toggle(webrender::TEXTURE_CACHE_DBG); - wrench.renderer.set_debug_flags(flags); - }, - VirtualKeyCode::B => { - let mut flags = wrench.renderer.get_debug_flags(); - flags.toggle(webrender::ALPHA_PRIM_DBG); - wrench.renderer.set_debug_flags(flags); - }, - VirtualKeyCode::M => { - wrench.api.notify_memory_pressure(); - }, - VirtualKeyCode::L => { - do_loop = !do_loop; - }, - VirtualKeyCode::Left => { - thing.prev_frame(); - }, - VirtualKeyCode::Right => { - thing.next_frame(); - }, - VirtualKeyCode::H => { - show_help = !show_help; - }, - _ => () + glutin::Event::KeyboardInput(ElementState::Pressed, _scan_code, Some(vk)) => match vk { + VirtualKeyCode::Escape | VirtualKeyCode::Q => { + break 'outer; } - } - _ => () + VirtualKeyCode::P => { + let mut flags = wrench.renderer.get_debug_flags(); + flags.toggle(webrender::PROFILER_DBG); + wrench.renderer.set_debug_flags(flags); + } + VirtualKeyCode::O => { + let mut flags = wrench.renderer.get_debug_flags(); + flags.toggle(webrender::RENDER_TARGET_DBG); + wrench.renderer.set_debug_flags(flags); + } + VirtualKeyCode::I => { + let mut flags = wrench.renderer.get_debug_flags(); + flags.toggle(webrender::TEXTURE_CACHE_DBG); + wrench.renderer.set_debug_flags(flags); + } + VirtualKeyCode::B => { + let mut flags = wrench.renderer.get_debug_flags(); + flags.toggle(webrender::ALPHA_PRIM_DBG); + wrench.renderer.set_debug_flags(flags); + } + VirtualKeyCode::M => { + wrench.api.notify_memory_pressure(); + } + VirtualKeyCode::L => { + do_loop = !do_loop; + } + VirtualKeyCode::Left => { + thing.prev_frame(); + } + VirtualKeyCode::Right => { + thing.next_frame(); + } + VirtualKeyCode::H => { + show_help = !show_help; + } + _ => (), + }, + _ => (), } } if is_headless { - let pixels = window.gl().read_pixels(0, 0, - size.width as gl::GLsizei, - size.height as gl::GLsizei, - gl::RGBA, gl::UNSIGNED_BYTE); + let pixels = window.gl().read_pixels( + 0, + 0, + size.width as gl::GLsizei, + size.height as gl::GLsizei, + gl::RGBA, + gl::UNSIGNED_BYTE, + ); save_flipped("screenshot.png", &pixels, size); } diff --git a/wrench/src/parse_function.rs b/wrench/src/parse_function.rs index d59ea9a04b..82267064ce 100644 --- a/wrench/src/parse_function.rs +++ b/wrench/src/parse_function.rs @@ -26,12 +26,15 @@ pub fn parse_function(s: &str) -> (&str, Vec<&str>, &str) { self.start = k.0 + k.1.len_utf8(); self.o = self.itr.next(); } - } } let mut c = s.char_indices(); let o = c.next(); - let mut p = Parser { itr: c, start: 0, o: o }; + let mut p = Parser { + itr: c, + start: 0, + o: o, + }; p.skip_whitespace(); @@ -44,14 +47,14 @@ pub fn parse_function(s: &str) -> (&str, Vec<&str>, &str) { p.o = p.itr.next(); } - let name = &s[p.start..end]; + let name = &s[p.start .. end]; let mut args = Vec::new(); p.skip_whitespace(); if let Some(k) = p.o { if k.1 != '(' { - return (name, args, &s[p.start..]); + return (name, args, &s[p.start ..]); } p.start = k.0 + k.1.len_utf8(); p.o = p.itr.next(); @@ -69,7 +72,7 @@ pub fn parse_function(s: &str) -> (&str, Vec<&str>, &str) { p.o = p.itr.next(); } - args.push(&s[p.start..end]); + args.push(&s[p.start .. end]); p.skip_whitespace(); @@ -84,10 +87,10 @@ pub fn parse_function(s: &str) -> (&str, Vec<&str>, &str) { break; } } else { - break + break; } } - (name, args, &s[p.start..]) + (name, args, &s[p.start ..]) } #[test] diff --git a/wrench/src/perf.rs b/wrench/src/perf.rs index b878225c1c..8de1a7bc1f 100644 --- a/wrench/src/perf.rs +++ b/wrench/src/perf.rs @@ -33,7 +33,8 @@ pub struct BenchmarkManifest { impl BenchmarkManifest { pub fn new(manifest: &Path) -> BenchmarkManifest { let dir = manifest.parent().unwrap(); - let f = File::open(manifest).expect(&format!("couldn't open manifest: {}", manifest.display())); + let f = + File::open(manifest).expect(&format!("couldn't open manifest: {}", manifest.display())); let file = BufReader::new(&f); let mut benchmarks = Vec::new(); @@ -42,7 +43,7 @@ impl BenchmarkManifest { let l = line.unwrap(); // strip the comments - let s = &l[0..l.find('#').unwrap_or(l.len())]; + let s = &l[0 .. l.find('#').unwrap_or(l.len())]; let s = s.trim(); if s.is_empty() { continue; @@ -58,16 +59,14 @@ impl BenchmarkManifest { } Some(name) => { let test = dir.join(name); - benchmarks.push(Benchmark { - test, - }); + benchmarks.push(Benchmark { test }); } _ => panic!(), }; } BenchmarkManifest { - benchmarks: benchmarks + benchmarks: benchmarks, } } } @@ -88,9 +87,7 @@ struct Profile { impl Profile { fn new() -> Profile { - Profile { - tests: Vec::new(), - } + Profile { tests: Vec::new() } } fn add(&mut self, profile: TestProfile) { @@ -131,9 +128,7 @@ pub struct PerfHarness<'a> { } impl<'a> PerfHarness<'a> { - pub fn new(wrench: &'a mut Wrench, - window: &'a mut WindowWrapper) -> PerfHarness<'a> - { + pub fn new(wrench: &'a mut Wrench, window: &'a mut WindowWrapper) -> PerfHarness<'a> { // setup a notifier so we can wait for frames to be finished struct Notifier { tx: Sender<()>, @@ -145,13 +140,11 @@ impl<'a> PerfHarness<'a> { fn new_scroll_frame_ready(&mut self, _composite_needed: bool) {} } let (tx, rx) = channel(); - wrench.renderer.set_render_notifier(Box::new(Notifier { tx: tx })); + wrench + .renderer + .set_render_notifier(Box::new(Notifier { tx: tx })); - PerfHarness { - wrench, - window, - rx, - } + PerfHarness { wrench, window, rx } } pub fn run(mut self, base_manifest: &Path, filename: &str) { @@ -176,7 +169,8 @@ impl<'a> PerfHarness<'a> { let mut gpu_frame_profiles = Vec::new(); while cpu_frame_profiles.len() < MIN_SAMPLE_COUNT || - gpu_frame_profiles.len() < MIN_SAMPLE_COUNT { + gpu_frame_profiles.len() < MIN_SAMPLE_COUNT + { reader.do_frame(self.wrench); self.rx.recv().unwrap(); self.wrench.render(); @@ -188,7 +182,11 @@ impl<'a> PerfHarness<'a> { // Ensure the draw calls match in every sample. let draw_calls = cpu_frame_profiles[0].draw_calls; - assert!(cpu_frame_profiles.iter().all(|s| s.draw_calls == draw_calls)); + assert!( + cpu_frame_profiles + .iter() + .all(|s| s.draw_calls == draw_calls) + ); let composite_time_ns = extract_sample(&mut cpu_frame_profiles, |a| a.composite_time_ns); let paint_time_ns = extract_sample(&mut gpu_frame_profiles, |a| a.paint_time_ns); @@ -204,10 +202,13 @@ impl<'a> PerfHarness<'a> { } } -fn extract_sample(profiles: &mut [T], f: F) -> u64 where F: Fn(&T) -> u64 { +fn extract_sample(profiles: &mut [T], f: F) -> u64 +where + F: Fn(&T) -> u64, +{ let mut samples: Vec = profiles.iter().map(f).collect(); samples.sort(); - let useful_samples = &samples[SAMPLE_EXCLUDE_COUNT..samples.len() - SAMPLE_EXCLUDE_COUNT]; + let useful_samples = &samples[SAMPLE_EXCLUDE_COUNT .. samples.len() - SAMPLE_EXCLUDE_COUNT]; let total_time: u64 = useful_samples.iter().sum(); total_time / useful_samples.len() as u64 } @@ -230,12 +231,23 @@ pub fn compare(first_filename: &str, second_filename: &str) { let (set0, map0) = profile0.build_set_and_map_of_tests(); let (set1, map1) = profile1.build_set_and_map_of_tests(); - println!("+------------------------------------------------+--------------+------------------+------------------+"); - println!("| Test name | Draw Calls | Composite (ms) | Paint (ms) |"); - println!("+------------------------------------------------+--------------+------------------+------------------+"); + print!("+------------------------------------------------"); + println!("+--------------+------------------+------------------+"); + print!("| Test name "); + println!("| Draw Calls | Composite (ms) | Paint (ms) |"); + print!("+------------------------------------------------"); + println!("+--------------+------------------+------------------+"); for test_name in set0.symmetric_difference(&set1) { - println!("| {}{:47}{}|{:14}|{:18}|{:18}|", COLOR_MAGENTA, test_name, COLOR_DEFAULT, " -", " -", " -"); + println!( + "| {}{:47}{}|{:14}|{:18}|{:18}|", + COLOR_MAGENTA, + test_name, + COLOR_DEFAULT, + " -", + " -", + " -" + ); } for test_name in set0.intersection(&set1) { @@ -260,22 +272,24 @@ pub fn compare(first_filename: &str, second_filename: &str) { let paint_time_color = select_color(paint_time0, paint_time1); let draw_call_string = format!(" {} -> {}", test0.draw_calls, test1.draw_calls); - let composite_time_string = format!(" {:.2} -> {:.2}", composite_time0, - composite_time1); - let paint_time_string = format!(" {:.2} -> {:.2}", paint_time0, - paint_time1); - - println!("| {:47}|{}{:14}{}|{}{:18}{}|{}{:18}{}|", test_name, - draw_calls_color, - draw_call_string, - COLOR_DEFAULT, - composite_time_color, - composite_time_string, - COLOR_DEFAULT, - paint_time_color, - paint_time_string, - COLOR_DEFAULT); + let composite_time_string = format!(" {:.2} -> {:.2}", composite_time0, composite_time1); + let paint_time_string = format!(" {:.2} -> {:.2}", paint_time0, paint_time1); + + println!( + "| {:47}|{}{:14}{}|{}{:18}{}|{}{:18}{}|", + test_name, + draw_calls_color, + draw_call_string, + COLOR_DEFAULT, + composite_time_color, + composite_time_string, + COLOR_DEFAULT, + paint_time_color, + paint_time_string, + COLOR_DEFAULT + ); } - println!("+------------------------------------------------+--------------+------------------+------------------+"); + print!("+------------------------------------------------"); + println!("+--------------+------------------+------------------+"); } diff --git a/wrench/src/png.rs b/wrench/src/png.rs index d50f14d271..446cbdfbb7 100644 --- a/wrench/src/png.rs +++ b/wrench/src/png.rs @@ -16,25 +16,20 @@ pub fn save_flipped>(path: P, orig_pixels: &[u8], size: DeviceUin // flip image vertically (texture is upside down) let mut data = orig_pixels.to_owned(); let stride = size.width as usize * 4; - for y in 0..size.height as usize { + for y in 0 .. size.height as usize { let dst_start = y * stride; let src_start = (size.height as usize - y - 1) * stride; let src_slice = &orig_pixels[src_start .. src_start + stride]; - (&mut data[dst_start .. dst_start + stride]).clone_from_slice(&src_slice[..stride]); + (&mut data[dst_start .. dst_start + stride]).clone_from_slice(&src_slice[.. stride]); } let encoder = PNGEncoder::new(File::create(path).unwrap()); - encoder.encode(&data, - size.width, - size.height, - ColorType::RGBA(8)) - .expect("Unable to encode PNG!"); + encoder + .encode(&data, size.width, size.height, ColorType::RGBA(8)) + .expect("Unable to encode PNG!"); } -pub fn png(wrench: &mut Wrench, - window: &mut WindowWrapper, - mut reader: YamlFrameReader) -{ +pub fn png(wrench: &mut Wrench, window: &mut WindowWrapper, mut reader: YamlFrameReader) { // setup a notifier so we can wait for frames to be finished struct Notifier { tx: Sender<()>, @@ -46,7 +41,9 @@ pub fn png(wrench: &mut Wrench, fn new_scroll_frame_ready(&mut self, _composite_needed: bool) {} } let (tx, rx) = channel(); - wrench.renderer.set_render_notifier(Box::new(Notifier { tx: tx })); + wrench + .renderer + .set_render_notifier(Box::new(Notifier { tx: tx })); reader.do_frame(wrench); // wait for the frame @@ -55,8 +52,9 @@ pub fn png(wrench: &mut Wrench, let size = window.get_inner_size_pixels(); let device_size = DeviceUintSize::new(size.0, size.1); - let data = wrench.renderer.read_pixels_rgba8(DeviceUintRect::new(DeviceUintPoint::zero(), - device_size)); + let data = wrench + .renderer + .read_pixels_rgba8(DeviceUintRect::new(DeviceUintPoint::zero(), device_size)); let mut out_path = reader.yaml_path().clone(); out_path.set_extension("png"); diff --git a/wrench/src/premultiply.rs b/wrench/src/premultiply.rs index 539cc7d21e..ecdcce85e1 100644 --- a/wrench/src/premultiply.rs +++ b/wrench/src/premultiply.rs @@ -42,10 +42,14 @@ fn it_works() { let mut f = [0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0x00, 0x80]; premultiply(&mut f); println!("{:?}", f); - assert!(f[0] == 0x80 && f[1] == 0x80 && f[2] == 0x80 && f[3] == 0x80 && - f[4] == 0x00 && f[5] == 0x80 && f[6] == 0x00 && f[7] == 0x80); + assert!( + f[0] == 0x80 && f[1] == 0x80 && f[2] == 0x80 && f[3] == 0x80 && f[4] == 0x00 && + f[5] == 0x80 && f[6] == 0x00 && f[7] == 0x80 + ); unpremultiply(&mut f); println!("{:?}", f); - assert!(f[0] == 0xff && f[1] == 0xff && f[2] == 0xff && f[3] == 0x80 && - f[4] == 0x00 && f[5] == 0xff && f[6] == 0x00 && f[7] == 0x80); + assert!( + f[0] == 0xff && f[1] == 0xff && f[2] == 0xff && f[3] == 0x80 && f[4] == 0x00 && + f[5] == 0xff && f[6] == 0x00 && f[7] == 0x80 + ); } diff --git a/wrench/src/rawtest.rs b/wrench/src/rawtest.rs index 8c47090c69..43a781edaf 100644 --- a/wrench/src/rawtest.rs +++ b/wrench/src/rawtest.rs @@ -15,19 +15,21 @@ pub struct RawtestHarness<'a> { } impl<'a> RawtestHarness<'a> { - pub fn new(wrench: &'a mut Wrench, - window: &'a mut WindowWrapper) -> RawtestHarness<'a> - { + pub fn new(wrench: &'a mut Wrench, window: &'a mut WindowWrapper) -> RawtestHarness<'a> { // setup a notifier so we can wait for frames to be finished struct Notifier { tx: Sender<()>, }; impl RenderNotifier for Notifier { - fn new_frame_ready(&mut self) { self.tx.send(()).unwrap(); } + fn new_frame_ready(&mut self) { + self.tx.send(()).unwrap(); + } fn new_scroll_frame_ready(&mut self, _composite_needed: bool) {} } let (tx, rx) = channel(); - wrench.renderer.set_render_notifier(Box::new(Notifier { tx: tx })); + wrench + .renderer + .set_render_notifier(Box::new(Notifier { tx: tx })); RawtestHarness { wrench: wrench, @@ -53,17 +55,22 @@ impl<'a> RawtestHarness<'a> { let mut resources = ResourceUpdates::new(); let blob_img = self.wrench.api.generate_image_key(); - resources.add_image(blob_img, - ImageDescriptor::new(151, 56, ImageFormat::BGRA8, true), - ImageData::new_blob_image(blob::serialize_blob(ColorU::new(50, 50, 150, 255))), - Some(128)); + resources.add_image( + blob_img, + ImageDescriptor::new(151, 56, ImageFormat::BGRA8, true), + ImageData::new_blob_image(blob::serialize_blob(ColorU::new(50, 50, 150, 255))), + Some(128), + ); let root_background_color = Some(ColorF::new(1.0, 1.0, 1.0, 1.0)); let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size); let info = LayoutPrimitiveInfo { - rect: LayoutRect::new(LayoutPoint::new(448.899994, 74.0), LayoutSize::new(151.000031, 56.)), + rect: LayoutRect::new( + LayoutPoint::new(448.899994, 74.0), + LayoutSize::new(151.000031, 56.), + ), local_clip: None, is_backface_visible: true, }; @@ -77,14 +84,18 @@ impl<'a> RawtestHarness<'a> { blob_img, ); - self.wrench.api.set_display_list(self.wrench.document_id, - Epoch(0), - root_background_color, - layout_size, - builder.finalize(), - false, - resources); - self.wrench.api.generate_frame(self.wrench.document_id, None); + self.wrench.api.set_display_list( + self.wrench.document_id, + Epoch(0), + root_background_color, + layout_size, + builder.finalize(), + false, + resources, + ); + self.wrench + .api + .generate_frame(self.wrench.document_id, None); self.rx.recv().unwrap(); self.wrench.render(); @@ -98,18 +109,21 @@ impl<'a> RawtestHarness<'a> { let test_size = DeviceUintSize::new(400, 400); let document_id = self.wrench.document_id; - let window_rect = DeviceUintRect::new(DeviceUintPoint::new(0, window_size.height - test_size.height), - test_size); + let window_rect = DeviceUintRect::new( + DeviceUintPoint::new(0, window_size.height - test_size.height), + test_size, + ); let layout_size = LayoutSize::new(400., 400.); let mut resources = ResourceUpdates::new(); { let api = &self.wrench.api; blob_img = api.generate_image_key(); - resources.add_image(blob_img, - ImageDescriptor::new(500, 500, ImageFormat::BGRA8, true), - ImageData::new_blob_image(blob::serialize_blob(ColorU::new(50, 50, 150, 255))), - None, + resources.add_image( + blob_img, + ImageDescriptor::new(500, 500, ImageFormat::BGRA8, true), + ImageData::new_blob_image(blob::serialize_blob(ColorU::new(50, 50, 150, 255))), + None, ); } let root_background_color = Some(ColorF::new(1.0, 1.0, 1.0, 1.0)); @@ -130,13 +144,15 @@ impl<'a> RawtestHarness<'a> { blob_img, ); - self.wrench.api.set_display_list(document_id, - Epoch(0), - root_background_color, - layout_size, - builder.finalize(), - false, - resources); + self.wrench.api.set_display_list( + document_id, + Epoch(0), + root_background_color, + layout_size, + builder.finalize(), + false, + resources, + ); self.wrench.api.generate_frame(document_id, None); @@ -157,13 +173,15 @@ impl<'a> RawtestHarness<'a> { blob_img, ); - self.wrench.api.set_display_list(document_id, - Epoch(1), - root_background_color, - layout_size, - builder.finalize(), - false, - ResourceUpdates::new()); + self.wrench.api.set_display_list( + document_id, + Epoch(1), + root_background_color, + layout_size, + builder.finalize(), + false, + ResourceUpdates::new(), + ); self.wrench.api.generate_frame(document_id, None); @@ -175,6 +193,5 @@ impl<'a> RawtestHarness<'a> { // png::save_flipped("out2.png", &pixels_second, window_rect.size); assert!(pixels_first != pixels_second); - } } diff --git a/wrench/src/reftest.rs b/wrench/src/reftest.rs index e42b5f3bff..725b1d368c 100644 --- a/wrench/src/reftest.rs +++ b/wrench/src/reftest.rs @@ -41,11 +41,14 @@ pub enum ReftestOp { impl Display for ReftestOp { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { - write!(f, "{}", - match *self { - ReftestOp::Equal => "==".to_owned(), - ReftestOp::NotEqual => "!=".to_owned(), - }) + write!( + f, + "{}", + match *self { + ReftestOp::Equal => "==".to_owned(), + ReftestOp::NotEqual => "!=".to_owned(), + } + ) } } @@ -59,7 +62,13 @@ pub struct Reftest { impl Display for Reftest { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { - write!(f, "{} {} {}", self.test.display(), self.op, self.reference.display()) + write!( + f, + "{} {} {}", + self.test.display(), + self.op, + self.reference.display() + ) } } @@ -69,7 +78,10 @@ struct ReftestImage { } enum ReftestImageComparison { Equal, - NotEqual { max_difference: usize, count_different: usize }, + NotEqual { + max_difference: usize, + count_different: usize, + }, } impl ReftestImage { @@ -84,9 +96,10 @@ impl ReftestImage { for (a, b) in self.data.chunks(4).zip(other.data.chunks(4)) { if a != b { let pixel_max = a.iter() - .zip(b.iter()) - .map(|(x, y)| (*x as isize - *y as isize).abs() as usize) - .max().unwrap(); + .zip(b.iter()) + .map(|(x, y)| (*x as isize - *y as isize).abs() as usize) + .max() + .unwrap(); count += 1; max = cmp::max(max, pixel_max); @@ -110,20 +123,20 @@ impl ReftestImage { // flip image vertically (texture is upside down) let orig_pixels = self.data.clone(); let stride = width as usize * 4; - for y in 0..height as usize { + for y in 0 .. height as usize { let dst_start = y * stride; let src_start = (height as usize - y - 1) * stride; let src_slice = &orig_pixels[src_start .. src_start + stride]; - (&mut self.data[dst_start .. dst_start + stride]).clone_from_slice(&src_slice[..stride]); + (&mut self.data[dst_start .. dst_start + stride]) + .clone_from_slice(&src_slice[.. stride]); } let mut png: Vec = vec![]; { let encoder = PNGEncoder::new(&mut png); - encoder.encode(&self.data[..], - width, - height, - ColorType::RGBA(8)).expect("Unable to encode PNG!"); + encoder + .encode(&self.data[..], width, height, ColorType::RGBA(8)) + .expect("Unable to encode PNG!"); } let png_base64 = base64::encode(&png); format!("data:image/png;base64,{}", png_base64) @@ -136,7 +149,8 @@ struct ReftestManifest { impl ReftestManifest { fn new(manifest: &Path, options: &ReftestOptions) -> ReftestManifest { let dir = manifest.parent().unwrap(); - let f = File::open(manifest).expect(&format!("couldn't open manifest: {}", manifest.display())); + let f = + File::open(manifest).expect(&format!("couldn't open manifest: {}", manifest.display())); let file = BufReader::new(&f); let mut reftests = Vec::new(); @@ -145,7 +159,7 @@ impl ReftestManifest { let l = line.unwrap(); // strip the comments - let s = &l[0..l.find('#').unwrap_or(l.len())]; + let s = &l[0 .. l.find('#').unwrap_or(l.len())]; let s = s.trim(); if s.is_empty() { continue; @@ -157,16 +171,18 @@ impl ReftestManifest { "include" => { let include = dir.join(items[1]); - reftests.append(&mut ReftestManifest::new(include.as_path(), options).reftests); + reftests.append( + &mut ReftestManifest::new(include.as_path(), options).reftests, + ); } item_str => { // If the first item is "fuzzy(,)" the positions of the operator // and paths in the array are offset. // TODO: This is simple but not great because it does not support having spaces // in the fuzzy syntax, like between the arguments. - let (max, count, offset) = if item_str.starts_with("fuzzy(") { + let (max, count, offset) = if item_str.starts_with("fuzzy(") { let (_, args, _) = parse_function(item_str); - (args[0].parse().unwrap(), args[1].parse().unwrap(), 1) + (args[0].parse().unwrap(), args[1].parse().unwrap(), 1) } else { (0, 0, 0) }; @@ -182,15 +198,16 @@ impl ReftestManifest { }; } - ReftestManifest { - reftests: reftests - } + ReftestManifest { reftests: reftests } } fn find(&self, prefix: &Path) -> Vec<&Reftest> { - self.reftests.iter().filter(|x| { - x.test.starts_with(prefix) || x.reference.starts_with(prefix) - }).collect() + self.reftests + .iter() + .filter(|x| { + x.test.starts_with(prefix) || x.reference.starts_with(prefix) + }) + .collect() } } @@ -208,9 +225,7 @@ pub struct ReftestHarness<'a> { rx: Receiver<()>, } impl<'a> ReftestHarness<'a> { - pub fn new(wrench: &'a mut Wrench, - window: &'a mut WindowWrapper) -> ReftestHarness<'a> - { + pub fn new(wrench: &'a mut Wrench, window: &'a mut WindowWrapper) -> ReftestHarness<'a> { // setup a notifier so we can wait for frames to be finished struct Notifier { tx: Sender<()>, @@ -222,13 +237,11 @@ impl<'a> ReftestHarness<'a> { fn new_scroll_frame_ready(&mut self, _composite_needed: bool) {} } let (tx, rx) = channel(); - wrench.renderer.set_render_notifier(Box::new(Notifier { tx: tx })); + wrench + .renderer + .set_render_notifier(Box::new(Notifier { tx: tx })); - ReftestHarness { - wrench, - window, - rx, - } + ReftestHarness { wrench, window, rx } } pub fn run(mut self, base_manifest: &Path, reftests: Option<&Path>, options: &ReftestOptions) { @@ -246,7 +259,11 @@ impl<'a> ReftestHarness<'a> { } } - println!("REFTEST INFO | {} passing, {} failing", total_passing, failing.len()); + println!( + "REFTEST INFO | {} passing, {} failing", + total_passing, + failing.len() + ); if !failing.is_empty() { println!("\nReftests with unexpected results:"); @@ -263,8 +280,10 @@ impl<'a> ReftestHarness<'a> { fn run_reftest(&mut self, t: &Reftest) -> bool { println!("REFTEST {}", t); - let window_size = DeviceUintSize::new(self.window.get_inner_size_pixels().0, - self.window.get_inner_size_pixels().1); + let window_size = DeviceUintSize::new( + self.window.get_inner_size_pixels().0, + self.window.get_inner_size_pixels().1, + ); let reference = match t.reference.extension().unwrap().to_str().unwrap() { "yaml" => self.render_yaml(t.reference.as_path(), window_size), "png" => self.load_image(t.reference.as_path(), ImageFormat::PNG), @@ -277,28 +296,39 @@ impl<'a> ReftestHarness<'a> { match (&t.op, comparison) { (&ReftestOp::Equal, ReftestImageComparison::Equal) => true, - (&ReftestOp::Equal, - ReftestImageComparison::NotEqual { max_difference, count_different }) => { - if max_difference > t.max_difference || count_different > t.num_differences { - println!("{} | {} | {}: {}, {}: {}", - "REFTEST TEST-UNEXPECTED-FAIL", t, - "image comparison, max difference", max_difference, - "number of differing pixels", count_different); - println!("REFTEST IMAGE 1 (TEST): {}", test.create_data_uri()); - println!("REFTEST IMAGE 2 (REFERENCE): {}", reference.create_data_uri()); - println!("REFTEST TEST-END | {}", t); - - false - } else { - true - } + ( + &ReftestOp::Equal, + ReftestImageComparison::NotEqual { + max_difference, + count_different, + }, + ) => if max_difference > t.max_difference || count_different > t.num_differences { + println!( + "{} | {} | {}: {}, {}: {}", + "REFTEST TEST-UNEXPECTED-FAIL", + t, + "image comparison, max difference", + max_difference, + "number of differing pixels", + count_different + ); + println!("REFTEST IMAGE 1 (TEST): {}", test.create_data_uri()); + println!( + "REFTEST IMAGE 2 (REFERENCE): {}", + reference.create_data_uri() + ); + println!("REFTEST TEST-END | {}", t); + + false + } else { + true }, (&ReftestOp::NotEqual, ReftestImageComparison::Equal) => { println!("REFTEST TEST-UNEXPECTED-FAIL | {} | image comparison", t); println!("REFTEST TEST-END | {}", t); false - }, + } (&ReftestOp::NotEqual, ReftestImageComparison::NotEqual { .. }) => true, } } @@ -310,7 +340,7 @@ impl<'a> ReftestHarness<'a> { let size = img.dimensions(); ReftestImage { data: img.into_raw(), - size: DeviceUintSize::new(size.0, size.1) + size: DeviceUintSize::new(size.0, size.1), } } @@ -326,8 +356,7 @@ impl<'a> ReftestHarness<'a> { assert!(size.width <= window_size.0 && size.height <= window_size.1); // taking the bottom left sub-rectangle - let rect = DeviceUintRect::new(DeviceUintPoint::new(0, window_size.1 - size.height), - size); + let rect = DeviceUintRect::new(DeviceUintPoint::new(0, window_size.1 - size.height), size); let pixels = self.wrench.renderer.read_pixels_rgba8(rect); self.window.swap_buffers(); @@ -337,9 +366,6 @@ impl<'a> ReftestHarness<'a> { save_flipped(debug_path, &pixels, size); } - ReftestImage { - data: pixels, - size, - } + ReftestImage { data: pixels, size } } } diff --git a/wrench/src/scene.rs b/wrench/src/scene.rs index 77ad687dcf..e7876b2e83 100644 --- a/wrench/src/scene.rs +++ b/wrench/src/scene.rs @@ -42,23 +42,27 @@ impl Scene { self.display_lists.remove(pipeline_id); } - pub fn begin_display_list(&mut self, - pipeline_id: &PipelineId, - epoch: &Epoch, - background_color: &Option, - viewport_size: &LayerSize) { + pub fn begin_display_list( + &mut self, + pipeline_id: &PipelineId, + epoch: &Epoch, + background_color: &Option, + viewport_size: &LayerSize, + ) { let new_pipeline = ScenePipeline { - epoch: epoch.clone(), - viewport_size: viewport_size.clone(), - background_color: background_color.clone(), + epoch: epoch.clone(), + viewport_size: viewport_size.clone(), + background_color: background_color.clone(), }; self.pipeline_map.insert(pipeline_id.clone(), new_pipeline); } - pub fn finish_display_list(&mut self, - pipeline_id: PipelineId, - built_display_list: BuiltDisplayList) { + pub fn finish_display_list( + &mut self, + pipeline_id: PipelineId, + built_display_list: BuiltDisplayList, + ) { self.display_lists.insert(pipeline_id, built_display_list); } } diff --git a/wrench/src/wrench.rs b/wrench/src/wrench.rs index 1a5b7ab940..8cc57bb6e5 100644 --- a/wrench/src/wrench.rs +++ b/wrench/src/wrench.rs @@ -22,26 +22,21 @@ use time; use webrender; use webrender::api::*; use yaml_frame_writer::YamlFrameWriterReceiver; -use {WHITE_COLOR, BLACK_COLOR, WindowWrapper}; +use {WindowWrapper, BLACK_COLOR, WHITE_COLOR}; // TODO(gw): This descriptor matches what we currently support for fonts // but is quite a mess. We should at least document and // use better types for things like the style and stretch. #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub enum FontDescriptor { - Path { - path: PathBuf, - font_index: u32, - }, - Family { - name: String, - }, + Path { path: PathBuf, font_index: u32 }, + Family { name: String }, Properties { family: String, weight: u32, style: u32, stretch: u32, - } + }, } pub enum SaveType { @@ -58,10 +53,11 @@ struct Notifier { } impl Notifier { - fn new(window_proxy: Option, - timing_receiver: chase_lev::Stealer, - verbose: bool) - -> Notifier { + fn new( + window_proxy: Option, + timing_receiver: chase_lev::Stealer, + verbose: bool, + ) -> Notifier { Notifier { window_proxy, frames_notified: 0, @@ -78,8 +74,10 @@ impl RenderNotifier for Notifier { self.frames_notified += 1; if self.verbose && self.frames_notified == 600 { let elapsed = time::SteadyTime::now() - last_timing; - println!("frame latency (consider queue depth when looking at this number): {:3.6} ms", - elapsed.num_microseconds().unwrap() as f64 / 1000.); + println!( + "frame latency (consider queue depth here): {:3.6} ms", + elapsed.num_microseconds().unwrap() as f64 / 1000. + ); self.frames_notified = 0; } } @@ -105,7 +103,9 @@ pub trait WrenchThing { fn next_frame(&mut self); fn prev_frame(&mut self); fn do_frame(&mut self, &mut Wrench) -> u32; - fn queue_frames(&self) -> u32 { 0 } + fn queue_frames(&self) -> u32 { + 0 + } } pub struct Wrench { @@ -130,33 +130,30 @@ pub struct Wrench { } impl Wrench { - pub fn new(window: &mut WindowWrapper, - shader_override_path: Option, - dp_ratio: f32, - save_type: Option, - size: DeviceUintSize, - do_rebuild: bool, - no_subpixel_aa: bool, - debug: bool, - verbose: bool, - no_scissor: bool, - no_batch: bool) - -> Wrench - { + pub fn new( + window: &mut WindowWrapper, + shader_override_path: Option, + dp_ratio: f32, + save_type: Option, + size: DeviceUintSize, + do_rebuild: bool, + no_subpixel_aa: bool, + debug: bool, + verbose: bool, + no_scissor: bool, + no_batch: bool, + ) -> Wrench { println!("Shader override path: {:?}", shader_override_path); - 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 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 { @@ -169,7 +166,7 @@ impl Wrench { enable_batcher: !no_batch, max_recorded_profiles: 16, blob_image_renderer: Some(Box::new(blob::CheckerboardRenderer::new())), - .. Default::default() + ..Default::default() }; let (renderer, sender) = webrender::Renderer::new(window.clone_gl(), opts).unwrap(); @@ -210,33 +207,44 @@ impl Wrench { }; wrench.set_title("start"); - wrench.api.set_root_pipeline(wrench.document_id, wrench.root_pipeline_id); + wrench + .api + .set_root_pipeline(wrench.document_id, wrench.root_pipeline_id); wrench } - pub fn layout_simple_ascii(&self, font_key: FontKey, text: &str, size: Au) -> (Vec, Vec) { + pub fn layout_simple_ascii( + &self, + font_key: FontKey, + text: &str, + size: Au, + ) -> (Vec, Vec) { // Map the string codepoints to glyph indices in this font. // Just drop any glyph that isn't present in this font. let indices: Vec = self.api - .get_glyph_indices(font_key, text) - .iter() - .filter_map(|idx| *idx) - .collect(); + .get_glyph_indices(font_key, text) + .iter() + .filter_map(|idx| *idx) + .collect(); // Retrieve the metrics for each glyph. - let font = FontInstance::new(font_key, - size, - ColorF::new(0.0, 0.0, 0.0, 1.0), - FontRenderMode::Alpha, - SubpixelDirection::Horizontal, - None); + let font = FontInstance::new( + font_key, + size, + ColorF::new(0.0, 0.0, 0.0, 1.0), + FontRenderMode::Alpha, + SubpixelDirection::Horizontal, + None, + ); let mut keys = Vec::new(); for glyph_index in &indices { - keys.push(GlyphKey::new(*glyph_index, - LayerPoint::zero(), - FontRenderMode::Alpha, - SubpixelDirection::Horizontal)); + keys.push(GlyphKey::new( + *glyph_index, + LayerPoint::zero(), + FontRenderMode::Alpha, + SubpixelDirection::Horizontal, + )); } let metrics = self.api.get_glyph_dimensions(font, keys); @@ -244,16 +252,22 @@ impl Wrench { // has a limitation that it can't currently get dimensions for non-renderable // glyphs (e.g. spaces), so just use a rough estimate in that case. let space_advance = size.to_f32_px() / 3.0; - let advances = metrics.iter() - .map(|m| m.map(|dim| dim.advance).unwrap_or(space_advance)) - .collect(); + let advances = metrics + .iter() + .map(|m| m.map(|dim| dim.advance).unwrap_or(space_advance)) + .collect(); (indices, advances) } pub fn set_title(&mut self, extra: &str) { - self.window_title_to_set = Some(format!("Wrench: {} ({}x) - {} - {}", extra, - self.device_pixel_ratio, self.graphics_api.renderer, self.graphics_api.version)); + self.window_title_to_set = Some(format!( + "Wrench: {} ({}x) - {} - {}", + extra, + self.device_pixel_ratio, + self.graphics_api.renderer, + self.graphics_api.version + )); } pub fn take_title(&mut self) -> Option { @@ -265,8 +279,10 @@ impl Wrench { } pub fn window_size_f32(&self) -> LayoutSize { - LayoutSize::new(self.window_size.width as f32, - self.window_size.height as f32) + LayoutSize::new( + self.window_size.width as f32, + self.window_size.height as f32, + ) } #[cfg(target_os = "windows")] @@ -282,15 +298,23 @@ impl Wrench { pub fn font_key_from_name(&mut self, font_name: &str) -> FontKey { let system_fc = dwrote::FontCollection::system(); let family = system_fc.get_font_family_by_name(font_name).unwrap(); - let font = family.get_first_matching_font(dwrote::FontWeight::Regular, - dwrote::FontStretch::Normal, - dwrote::FontStyle::Normal); + let font = family.get_first_matching_font( + dwrote::FontWeight::Regular, + dwrote::FontStretch::Normal, + dwrote::FontStyle::Normal, + ); let descriptor = font.to_descriptor(); self.font_key_from_native_handle(&descriptor) } #[cfg(target_os = "windows")] - pub fn font_key_from_properties(&mut self, family: &str, weight: u32, style: u32, stretch: u32) -> FontKey { + pub fn font_key_from_properties( + &mut self, + family: &str, + weight: u32, + style: u32, + stretch: u32, + ) -> FontKey { let weight = dwrote::FontWeight::from_u32(weight); let style = dwrote::FontStyle::from_u32(style); let stretch = dwrote::FontStretch::from_u32(stretch); @@ -305,15 +329,25 @@ impl Wrench { } #[cfg(any(target_os = "linux", target_os = "macos"))] - pub fn font_key_from_properties(&mut self, family: &str, _weight: u32, _style: u32, _stretch: u32) -> FontKey { - let property = system_fonts::FontPropertyBuilder::new().family(family).build(); + pub fn font_key_from_properties( + &mut self, + family: &str, + _weight: u32, + _style: u32, + _stretch: u32, + ) -> FontKey { + let property = system_fonts::FontPropertyBuilder::new() + .family(family) + .build(); let (font, index) = system_fonts::get(&property).unwrap(); self.font_key_from_bytes(font, index as u32) } #[cfg(unix)] pub fn font_key_from_name(&mut self, font_name: &str) -> FontKey { - let property = system_fonts::FontPropertyBuilder::new().family(font_name).build(); + let property = system_fonts::FontPropertyBuilder::new() + .family(font_name) + .build(); let (font, index) = system_fonts::get(&property).unwrap(); self.font_key_from_bytes(font, index as u32) } @@ -342,7 +376,7 @@ impl Wrench { pub fn add_or_get_image(&mut self, file: &Path, tiling: Option) -> (ImageKey, LayoutSize) { let key = (file.to_owned(), tiling); if let Some(k) = self.image_map.get(&key) { - return *k + return *k; } let (descriptor, image_data) = match image::open(file) { @@ -358,45 +392,53 @@ impl Wrench { if format == ImageFormat::BGRA8 { premultiply(bytes.as_mut_slice()); } - let descriptor = ImageDescriptor::new(image_dims.0, - image_dims.1, - format, - is_image_opaque(format, &bytes[..])); + let descriptor = ImageDescriptor::new( + image_dims.0, + image_dims.1, + format, + is_image_opaque(format, &bytes[..]), + ); let data = ImageData::new(bytes); (descriptor, data) } _ => { // This is a hack but it is convenient when generating test cases and avoids // bloating the repository. - match parse_function(file.components().last().unwrap().as_os_str().to_str().unwrap()) { - ("xy-gradient", args, _) => { - generate_xy_gradient_image( - args.get(0).unwrap_or(&"1000").parse::().unwrap(), - args.get(1).unwrap_or(&"1000").parse::().unwrap() - ) - } - ("solid-color", args, _) => { - generate_solid_color_image( - args.get(0).unwrap_or(&"255").parse::().unwrap(), - args.get(1).unwrap_or(&"255").parse::().unwrap(), - args.get(2).unwrap_or(&"255").parse::().unwrap(), - args.get(3).unwrap_or(&"255").parse::().unwrap(), - args.get(4).unwrap_or(&"1000").parse::().unwrap(), - args.get(5).unwrap_or(&"1000").parse::().unwrap() - ) - } + match parse_function( + file.components() + .last() + .unwrap() + .as_os_str() + .to_str() + .unwrap(), + ) { + ("xy-gradient", args, _) => generate_xy_gradient_image( + args.get(0).unwrap_or(&"1000").parse::().unwrap(), + args.get(1).unwrap_or(&"1000").parse::().unwrap(), + ), + ("solid-color", args, _) => generate_solid_color_image( + args.get(0).unwrap_or(&"255").parse::().unwrap(), + args.get(1).unwrap_or(&"255").parse::().unwrap(), + args.get(2).unwrap_or(&"255").parse::().unwrap(), + args.get(3).unwrap_or(&"255").parse::().unwrap(), + args.get(4).unwrap_or(&"1000").parse::().unwrap(), + args.get(5).unwrap_or(&"1000").parse::().unwrap(), + ), _ => { panic!("Failed to load image {:?}", file.to_str()); } } } }; - let tiling = tiling.map(|tile_size|{ tile_size as u16 }); + let tiling = tiling.map(|tile_size| tile_size as u16); let image_key = self.api.generate_image_key(); let mut resources = ResourceUpdates::new(); resources.add_image(image_key, descriptor, image_data, tiling); self.api.update_resources(resources); - let val = (image_key, LayoutSize::new(descriptor.width as f32, descriptor.height as f32)); + let val = ( + image_key, + LayoutSize::new(descriptor.width as f32, descriptor.height as f32), + ); self.image_map.insert(key, val); val } @@ -411,10 +453,12 @@ impl Wrench { self.frame_start_sender.push(time::SteadyTime::now()); } - pub fn send_lists(&mut self, - frame_number: u32, - display_lists: Vec<(PipelineId, LayerSize, BuiltDisplayList)>, - scroll_offsets: &HashMap) { + pub fn send_lists( + &mut self, + frame_number: u32, + display_lists: Vec<(PipelineId, LayerSize, BuiltDisplayList)>, + scroll_offsets: &HashMap, + ) { let root_background_color = Some(ColorF::new(1.0, 1.0, 1.0, 1.0)); for display_list in display_lists { @@ -425,21 +469,25 @@ impl Wrench { self.window_size_f32(), display_list, false, - ResourceUpdates::new() + ResourceUpdates::new(), ); } for (id, offset) in scroll_offsets { - self.api.scroll_node_with_id(self.document_id, - *offset, - *id, - ScrollClamping::NoClamping); + self.api.scroll_node_with_id( + self.document_id, + *offset, + *id, + ScrollClamping::NoClamping, + ); } self.api.generate_frame(self.document_id, None); } - pub fn get_frame_profiles(&mut self) -> (Vec, Vec) { + pub fn get_frame_profiles( + &mut self, + ) -> (Vec, Vec) { self.renderer.get_frame_profiles() } @@ -465,7 +513,7 @@ impl Wrench { "M - Trigger memory pressure event", ]; - let color_and_offset = [ (*BLACK_COLOR, 2.0), (*WHITE_COLOR, 0.0) ]; + let color_and_offset = [(*BLACK_COLOR, 2.0), (*WHITE_COLOR, 0.0)]; let dr = self.renderer.debug_renderer(); for ref co in &color_and_offset { @@ -483,7 +531,7 @@ fn is_image_opaque(format: ImageFormat, bytes: &[u8]) -> bool { match format { ImageFormat::BGRA8 => { let mut is_opaque = true; - for i in 0..(bytes.len() / 4) { + for i in 0 .. (bytes.len() / 4) { if bytes[i * 4 + 3] != 255 { is_opaque = false; break; @@ -500,8 +548,8 @@ fn is_image_opaque(format: ImageFormat, bytes: &[u8]) -> bool { fn generate_xy_gradient_image(w: u32, h: u32) -> (ImageDescriptor, ImageData) { let mut pixels = Vec::with_capacity((w * h * 4) as usize); - for y in 0..h { - for x in 0..w { + for y in 0 .. h { + for x in 0 .. w { let grid = if x % 100 < 3 || y % 100 < 3 { 0.9 } else { 1.0 }; pixels.push((y as f32 / h as f32 * 255.0 * grid) as u8); pixels.push(0); @@ -512,11 +560,18 @@ fn generate_xy_gradient_image(w: u32, h: u32) -> (ImageDescriptor, ImageData) { ( ImageDescriptor::new(w, h, ImageFormat::BGRA8, true), - ImageData::new(pixels) + ImageData::new(pixels), ) } -fn generate_solid_color_image(r: u8, g: u8, b: u8, a: u8, w: u32, h: u32) -> (ImageDescriptor, ImageData) { +fn generate_solid_color_image( + r: u8, + g: u8, + b: u8, + a: u8, + w: u32, + h: u32, +) -> (ImageDescriptor, ImageData) { let buf_size = (w * h * 4) as usize; let mut pixels = Vec::with_capacity(buf_size); // Unsafely filling the buffer is horrible. Unfortunately doing this idiomatically @@ -535,6 +590,6 @@ fn generate_solid_color_image(r: u8, g: u8, b: u8, a: u8, w: u32, h: u32) -> (Im ( ImageDescriptor::new(w, h, ImageFormat::BGRA8, a == 255), - ImageData::new(pixels) + ImageData::new(pixels), ) } diff --git a/wrench/src/yaml_frame_reader.rs b/wrench/src/yaml_frame_reader.rs index 1886d1f9bb..87a22665f3 100644 --- a/wrench/src/yaml_frame_reader.rs +++ b/wrench/src/yaml_frame_reader.rs @@ -11,9 +11,9 @@ use std::io::Read; use std::path::{Path, PathBuf}; use webrender::api::*; use wrench::{FontDescriptor, Wrench, WrenchThing}; -use yaml_helper::{YamlHelper, StringEnum}; +use yaml_helper::{StringEnum, YamlHelper}; use yaml_rust::{Yaml, YamlLoader}; -use {WHITE_COLOR, BLACK_COLOR, PLATFORM_DEFAULT_FACE_NAME}; +use {BLACK_COLOR, PLATFORM_DEFAULT_FACE_NAME, WHITE_COLOR}; fn rsrc_path(item: &Yaml, aux_dir: &PathBuf) -> PathBuf { let filename = item.as_str().unwrap(); @@ -49,8 +49,13 @@ fn broadcast(base_vals: &[T], num_items: usize) -> Vec { return base_vals.to_vec(); } - assert_eq!(num_items % base_vals.len(), 0, - "Cannot broadcast {} elements into {}", base_vals.len(), num_items); + assert_eq!( + num_items % base_vals.len(), + 0, + "Cannot broadcast {} elements into {}", + base_vals.len(), + num_items + ); let mut vals = vec![]; loop { @@ -109,8 +114,12 @@ impl YamlFrameReader { let mut y = YamlFrameReader::new(&yaml_file); y.watch_source = args.is_present("watch"); - y.queue_depth = args.value_of("queue").map(|s| s.parse::().unwrap()).unwrap_or(1); - y.include_only = args.values_of("include").map(|v| v.map(|s| s.to_owned()).collect()).unwrap_or(vec![]); + y.queue_depth = args.value_of("queue") + .map(|s| s.parse::().unwrap()) + .unwrap_or(1); + y.include_only = args.values_of("include") + .map(|v| v.map(|s| s.to_owned()).collect()) + .unwrap_or(vec![]); y } @@ -152,16 +161,21 @@ impl YamlFrameReader { } fn to_complex_clip_region(&mut self, item: &Yaml) -> ComplexClipRegion { - let rect = item["rect"].as_rect().expect("Complex clip entry must have rect"); - let radius = item["radius"].as_border_radius().unwrap_or(BorderRadius::zero()); + let rect = item["rect"] + .as_rect() + .expect("Complex clip entry must have rect"); + let radius = item["radius"] + .as_border_radius() + .unwrap_or(BorderRadius::zero()); ComplexClipRegion::new(rect, radius) } fn to_complex_clip_regions(&mut self, item: &Yaml) -> Vec { match *item { - Yaml::Array(ref array) => { - array.iter().map(|entry| self.to_complex_clip_region(entry)).collect() - } + Yaml::Array(ref array) => array + .iter() + .map(|entry| self.to_complex_clip_region(entry)) + .collect(), Yaml::BadValue => vec![], _ => { println!("Unable to parse complex clip region {:?}", item); @@ -172,45 +186,56 @@ impl YamlFrameReader { fn to_sticky_info(&mut self, item: &Yaml) -> Option { match item.as_vec_f32() { - Some(v) => Some(StickySideConstraint { margin: v[0], max_offset: v[1] }), + Some(v) => Some(StickySideConstraint { + margin: v[0], + max_offset: v[1], + }), None => None, } } fn to_sticky_frame_info(&mut self, item: &Yaml) -> StickyFrameInfo { - StickyFrameInfo::new(self.to_sticky_info(&item["top"]), - self.to_sticky_info(&item["right"]), - self.to_sticky_info(&item["bottom"]), - self.to_sticky_info(&item["left"])) + StickyFrameInfo::new( + self.to_sticky_info(&item["top"]), + self.to_sticky_info(&item["right"]), + self.to_sticky_info(&item["bottom"]), + self.to_sticky_info(&item["left"]), + ) } fn get_or_create_font(&mut self, desc: FontDescriptor, wrench: &mut Wrench) -> FontKey { *self.fonts .entry(desc.clone()) - .or_insert_with(|| { - match desc { - FontDescriptor::Path { ref path, font_index } => { - let mut file = File::open(path).expect("Couldn't open font file"); - let mut bytes = vec![]; - file.read_to_end(&mut bytes).expect("failed to read font file"); - wrench.font_key_from_bytes(bytes, font_index) - } - FontDescriptor::Family { ref name } => { - wrench.font_key_from_name(name) - } - FontDescriptor::Properties { ref family, weight, style, stretch } => { - wrench.font_key_from_properties(family, weight, style, stretch) - } + .or_insert_with(|| match desc { + FontDescriptor::Path { + ref path, + font_index, + } => { + let mut file = File::open(path).expect("Couldn't open font file"); + let mut bytes = vec![]; + file.read_to_end(&mut bytes) + .expect("failed to read font file"); + wrench.font_key_from_bytes(bytes, font_index) } + FontDescriptor::Family { ref name } => wrench.font_key_from_name(name), + FontDescriptor::Properties { + ref family, + weight, + style, + stretch, + } => wrench.font_key_from_properties(family, weight, style, stretch), }) } - fn get_or_create_font_instance(&mut self, font_key: FontKey, size: Au, wrench: &mut Wrench) -> FontInstanceKey { + fn get_or_create_font_instance( + &mut self, + font_key: FontKey, + size: Au, + wrench: &mut Wrench, + ) -> FontInstanceKey { *self.font_instances .entry((font_key, size)) - .or_insert_with(|| { - wrench.add_font_instance(font_key, size) - }) + .or_insert_with(|| wrench.add_font_instance(font_key, size)) } fn to_image_mask(&mut self, item: &Yaml, wrench: &mut Wrench) -> Option { @@ -220,20 +245,35 @@ impl YamlFrameReader { let (image_key, image_dims) = wrench.add_or_get_image(&rsrc_path(&item["image"], &self.aux_dir), None); - let image_rect = - item["rect"].as_rect().unwrap_or(LayoutRect::new(LayoutPoint::zero(), image_dims)); + let image_rect = item["rect"] + .as_rect() + .unwrap_or(LayoutRect::new(LayoutPoint::zero(), image_dims)); let image_repeat = item["repeat"].as_bool().expect("Expected boolean"); - Some(ImageMask { image: image_key, rect: image_rect, repeat: image_repeat }) + Some(ImageMask { + image: image_key, + rect: image_rect, + repeat: image_repeat, + }) } fn to_gradient(&mut self, dl: &mut DisplayListBuilder, item: &Yaml) -> Gradient { let start = item["start"].as_point().expect("gradient must have start"); let end = item["end"].as_point().expect("gradient must have end"); - let stops = item["stops"].as_vec().expect("gradient must have stops") - .chunks(2).map(|chunk| GradientStop { - offset: chunk[0].as_force_f32().expect("gradient stop offset is not f32"), - color: chunk[1].as_colorf().expect("gradient stop color is not color"), - }).collect::>(); + let stops = item["stops"] + .as_vec() + .expect("gradient must have stops") + .chunks(2) + .map(|chunk| { + GradientStop { + offset: chunk[0] + .as_force_f32() + .expect("gradient stop offset is not f32"), + color: chunk[1] + .as_colorf() + .expect("gradient stop color is not color"), + } + }) + .collect::>(); let extend_mode = if item["repeat"].as_bool().unwrap_or(false) { ExtendMode::Repeat } else { @@ -245,13 +285,27 @@ impl YamlFrameReader { fn to_radial_gradient(&mut self, dl: &mut DisplayListBuilder, item: &Yaml) -> RadialGradient { if item["start-center"].is_badvalue() { - let center = item["center"].as_point().expect("radial gradient must have start center"); - let radius = item["radius"].as_size().expect("radial gradient must have start radius"); - let stops = item["stops"].as_vec().expect("radial gradient must have stops") - .chunks(2).map(|chunk| GradientStop { - offset: chunk[0].as_force_f32().expect("gradient stop offset is not f32"), - color: chunk[1].as_colorf().expect("gradient stop color is not color"), - }).collect::>(); + let center = item["center"] + .as_point() + .expect("radial gradient must have start center"); + let radius = item["radius"] + .as_size() + .expect("radial gradient must have start radius"); + let stops = item["stops"] + .as_vec() + .expect("radial gradient must have stops") + .chunks(2) + .map(|chunk| { + GradientStop { + offset: chunk[0] + .as_force_f32() + .expect("gradient stop offset is not f32"), + color: chunk[1] + .as_colorf() + .expect("gradient stop color is not color"), + } + }) + .collect::>(); let extend_mode = if item["repeat"].as_bool().unwrap_or(false) { ExtendMode::Repeat } else { @@ -260,51 +314,115 @@ impl YamlFrameReader { dl.create_radial_gradient(center, radius, stops, extend_mode) } else { - let start_center = item["start-center"].as_point().expect("radial gradient must have start center"); - let start_radius = item["start-radius"].as_force_f32().expect("radial gradient must have start radius"); - let end_center = item["end-center"].as_point().expect("radial gradient must have end center"); - let end_radius = item["end-radius"].as_force_f32().expect("radial gradient must have end radius"); + let start_center = item["start-center"] + .as_point() + .expect("radial gradient must have start center"); + let start_radius = item["start-radius"] + .as_force_f32() + .expect("radial gradient must have start radius"); + let end_center = item["end-center"] + .as_point() + .expect("radial gradient must have end center"); + let end_radius = item["end-radius"] + .as_force_f32() + .expect("radial gradient must have end radius"); let ratio_xy = item["ratio-xy"].as_force_f32().unwrap_or(1.0); - let stops = item["stops"].as_vec().expect("radial gradient must have stops") - .chunks(2).map(|chunk| GradientStop { - offset: chunk[0].as_force_f32().expect("gradient stop offset is not f32"), - color: chunk[1].as_colorf().expect("gradient stop color is not color"), - }).collect::>(); + let stops = item["stops"] + .as_vec() + .expect("radial gradient must have stops") + .chunks(2) + .map(|chunk| { + GradientStop { + offset: chunk[0] + .as_force_f32() + .expect("gradient stop offset is not f32"), + color: chunk[1] + .as_colorf() + .expect("gradient stop color is not color"), + } + }) + .collect::>(); let extend_mode = if item["repeat"].as_bool().unwrap_or(false) { ExtendMode::Repeat } else { ExtendMode::Clamp }; - dl.create_complex_radial_gradient(start_center, start_radius, - end_center, end_radius, - ratio_xy, stops, extend_mode) + dl.create_complex_radial_gradient( + start_center, + start_radius, + end_center, + end_radius, + ratio_xy, + stops, + extend_mode, + ) } } - fn handle_rect(&mut self, dl: &mut DisplayListBuilder, item: &Yaml, info: &mut LayoutPrimitiveInfo) { - let bounds_key = if item["type"].is_badvalue() { "rect" } else { "bounds" }; - info.rect = item[bounds_key].as_rect().expect("rect type must have bounds"); + fn handle_rect( + &mut self, + dl: &mut DisplayListBuilder, + item: &Yaml, + info: &mut LayoutPrimitiveInfo, + ) { + let bounds_key = if item["type"].is_badvalue() { + "rect" + } else { + "bounds" + }; + info.rect = item[bounds_key] + .as_rect() + .expect("rect type must have bounds"); let color = item["color"].as_colorf().unwrap_or(*WHITE_COLOR); dl.push_rect(&info, color); } - fn handle_line(&mut self, dl: &mut DisplayListBuilder, item: &Yaml, info: &mut LayoutPrimitiveInfo) { + fn handle_line( + &mut self, + dl: &mut DisplayListBuilder, + item: &Yaml, + info: &mut LayoutPrimitiveInfo, + ) { let color = item["color"].as_colorf().unwrap_or(*BLACK_COLOR); let baseline = item["baseline"].as_f32().expect("line must have baseline"); let start = item["start"].as_f32().expect("line must have start"); let end = item["end"].as_f32().expect("line must have end"); let width = item["width"].as_f32().expect("line must have width"); - let orientation = item["orientation"].as_str().and_then(LineOrientation::from_str) - .expect("line must have orientation"); - let style = item["style"].as_str().and_then(LineStyle::from_str) - .expect("line must have style"); - dl.push_line(&info, baseline, start, end, orientation, width, color, style); + let orientation = item["orientation"] + .as_str() + .and_then(LineOrientation::from_str) + .expect("line must have orientation"); + let style = item["style"] + .as_str() + .and_then(LineStyle::from_str) + .expect("line must have style"); + dl.push_line( + &info, + baseline, + start, + end, + orientation, + width, + color, + style, + ); } - fn handle_gradient(&mut self, dl: &mut DisplayListBuilder, item: &Yaml, info: &mut LayoutPrimitiveInfo) { - let bounds_key = if item["type"].is_badvalue() { "gradient" } else { "bounds" }; - let bounds = item[bounds_key].as_rect().expect("gradient must have bounds"); + fn handle_gradient( + &mut self, + dl: &mut DisplayListBuilder, + item: &Yaml, + info: &mut LayoutPrimitiveInfo, + ) { + let bounds_key = if item["type"].is_badvalue() { + "gradient" + } else { + "bounds" + }; + let bounds = item[bounds_key] + .as_rect() + .expect("gradient must have bounds"); info.rect = bounds; let gradient = self.to_gradient(dl, item); let tile_size = item["tile-size"].as_size().unwrap_or(bounds.size); @@ -313,9 +431,20 @@ impl YamlFrameReader { dl.push_gradient(&info, gradient, tile_size, tile_spacing); } - fn handle_radial_gradient(&mut self, dl: &mut DisplayListBuilder, item: &Yaml, info: &mut LayoutPrimitiveInfo) { - let bounds_key = if item["type"].is_badvalue() { "radial-gradient" } else { "bounds" }; - let bounds = item[bounds_key].as_rect().expect("radial gradient must have bounds"); + fn handle_radial_gradient( + &mut self, + dl: &mut DisplayListBuilder, + item: &Yaml, + info: &mut LayoutPrimitiveInfo, + ) { + let bounds_key = if item["type"].is_badvalue() { + "radial-gradient" + } else { + "bounds" + }; + let bounds = item[bounds_key] + .as_rect() + .expect("radial gradient must have bounds"); info.rect = bounds; let gradient = self.to_radial_gradient(dl, item); let tile_size = item["tile-size"].as_size().unwrap_or(bounds.size); @@ -324,45 +453,81 @@ impl YamlFrameReader { dl.push_radial_gradient(&info, gradient, tile_size, tile_spacing); } - fn handle_border(&mut self, - dl: &mut DisplayListBuilder, - wrench: &mut Wrench, - item: &Yaml, - info: &mut LayoutPrimitiveInfo) { - let bounds_key = if item["type"].is_badvalue() { "border" } else { "bounds" }; - info.rect = item[bounds_key].as_rect().expect("borders must have bounds"); - let widths = item["width"].as_vec_f32().expect("borders must have width(s)"); + fn handle_border( + &mut self, + dl: &mut DisplayListBuilder, + wrench: &mut Wrench, + item: &Yaml, + info: &mut LayoutPrimitiveInfo, + ) { + let bounds_key = if item["type"].is_badvalue() { + "border" + } else { + "bounds" + }; + info.rect = item[bounds_key] + .as_rect() + .expect("borders must have bounds"); + let widths = item["width"] + .as_vec_f32() + .expect("borders must have width(s)"); let widths = broadcast(&widths, 4); - let widths = BorderWidths { top: widths[0], left: widths[1], bottom: widths[2], right: widths[3] }; + let widths = BorderWidths { + top: widths[0], + left: widths[1], + bottom: widths[2], + right: widths[3], + }; let border_details = if let Some(border_type) = item["border-type"].as_str() { match border_type { "normal" => { - let colors = item["color"].as_vec_colorf().expect("borders must have color(s)"); - let styles = item["style"].as_vec_string().expect("borders must have style(s)"); - let styles = styles.iter().map(|s| match s.as_str() { - "none" => BorderStyle::None, - "solid" => BorderStyle::Solid, - "double" => BorderStyle::Double, - "dotted" => BorderStyle::Dotted, - "dashed" => BorderStyle::Dashed, - "hidden" => BorderStyle::Hidden, - "ridge" => BorderStyle::Ridge, - "inset" => BorderStyle::Inset, - "outset" => BorderStyle::Outset, - "groove" => BorderStyle::Groove, - s => { - panic!("Unknown border style '{}'", s); - } - }).collect::>(); - let radius = item["radius"].as_border_radius().unwrap_or(BorderRadius::zero()); + let colors = item["color"] + .as_vec_colorf() + .expect("borders must have color(s)"); + let styles = item["style"] + .as_vec_string() + .expect("borders must have style(s)"); + let styles = styles + .iter() + .map(|s| match s.as_str() { + "none" => BorderStyle::None, + "solid" => BorderStyle::Solid, + "double" => BorderStyle::Double, + "dotted" => BorderStyle::Dotted, + "dashed" => BorderStyle::Dashed, + "hidden" => BorderStyle::Hidden, + "ridge" => BorderStyle::Ridge, + "inset" => BorderStyle::Inset, + "outset" => BorderStyle::Outset, + "groove" => BorderStyle::Groove, + s => { + panic!("Unknown border style '{}'", s); + } + }) + .collect::>(); + let radius = item["radius"] + .as_border_radius() + .unwrap_or(BorderRadius::zero()); let colors = broadcast(&colors, 4); let styles = broadcast(&styles, 4); - let top = BorderSide { color: colors[0], style: styles[0] }; - let left = BorderSide { color: colors[1], style: styles[1] }; - let bottom = BorderSide { color: colors[2], style: styles[2] }; - let right = BorderSide { color: colors[3], style: styles[3] }; + let top = BorderSide { + color: colors[0], + style: styles[0], + }; + let left = BorderSide { + color: colors[1], + style: styles[1], + }; + let bottom = BorderSide { + color: colors[2], + style: styles[2], + }; + let right = BorderSide { + color: colors[3], + style: styles[3], + }; Some(BorderDetails::Normal(NormalBorder { top, left, @@ -370,33 +535,43 @@ impl YamlFrameReader { right, radius, })) - }, + } "image" => { - let (image_key, _) = - wrench.add_or_get_image(&rsrc_path(&item["image-source"], &self.aux_dir), None); - let image_width = item["image-width"].as_i64().expect("border must have image-width"); - let image_height = item["image-height"].as_i64().expect("border must have image-height"); + let (image_key, _) = wrench + .add_or_get_image(&rsrc_path(&item["image-source"], &self.aux_dir), None); + let image_width = item["image-width"] + .as_i64() + .expect("border must have image-width"); + let image_height = item["image-height"] + .as_i64() + .expect("border must have image-height"); let fill = item["fill"].as_bool().unwrap_or(false); let slice = item["slice"].as_vec_u32().expect("border must have slice"); let slice = broadcast(&slice, 4); - let outset = item["outset"].as_vec_f32().expect("border must have outset"); + let outset = item["outset"] + .as_vec_f32() + .expect("border must have outset"); let outset = broadcast(&outset, 4); - let repeat_horizontal = - match item["repeat-horizontal"].as_str().expect("border must have repeat-horizontal") { - "stretch" => RepeatMode::Stretch, - "repeat" => RepeatMode::Repeat, - "round" => RepeatMode::Round, - "space" => RepeatMode::Space, - s => panic!("Unknown box border image repeat mode {}", s), - }; - let repeat_vertical = - match item["repeat-vertical"].as_str().expect("border must have repeat-vertical") { - "stretch" => RepeatMode::Stretch, - "repeat" => RepeatMode::Repeat, - "round" => RepeatMode::Round, - "space" => RepeatMode::Space, - s => panic!("Unknown box border image repeat mode {}", s), - }; + let repeat_horizontal = match item["repeat-horizontal"] + .as_str() + .expect("border must have repeat-horizontal") + { + "stretch" => RepeatMode::Stretch, + "repeat" => RepeatMode::Repeat, + "round" => RepeatMode::Round, + "space" => RepeatMode::Space, + s => panic!("Unknown box border image repeat mode {}", s), + }; + let repeat_vertical = match item["repeat-vertical"] + .as_str() + .expect("border must have repeat-vertical") + { + "stretch" => RepeatMode::Stretch, + "repeat" => RepeatMode::Repeat, + "round" => RepeatMode::Round, + "space" => RepeatMode::Space, + s => panic!("Unknown box border image repeat mode {}", s), + }; Some(BorderDetails::Image(ImageBorder { image_key, patch: NinePatchDescriptor { @@ -409,29 +584,33 @@ impl YamlFrameReader { repeat_horizontal, repeat_vertical, })) - }, + } "gradient" => { let gradient = self.to_gradient(dl, item); - let outset = item["outset"].as_vec_f32().expect("borders must have outset"); + let outset = item["outset"] + .as_vec_f32() + .expect("borders must have outset"); let outset = broadcast(&outset, 4); Some(BorderDetails::Gradient(GradientBorder { gradient, outset: SideOffsets2D::new(outset[0], outset[1], outset[2], outset[3]), })) - }, + } "radial-gradient" => { let gradient = self.to_radial_gradient(dl, item); - let outset = item["outset"].as_vec_f32().expect("borders must have outset"); + let outset = item["outset"] + .as_vec_f32() + .expect("borders must have outset"); let outset = broadcast(&outset, 4); Some(BorderDetails::RadialGradient(RadialGradientBorder { gradient, outset: SideOffsets2D::new(outset[0], outset[1], outset[2], outset[3]), })) - }, + } _ => { println!("Unable to parse border {:?}", item); None - }, + } } } else { println!("Unable to parse border {:?}", item); @@ -442,13 +621,26 @@ impl YamlFrameReader { } } - fn handle_box_shadow(&mut self, dl: &mut DisplayListBuilder, item: &Yaml, info: &mut LayoutPrimitiveInfo) { - let bounds_key = if item["type"].is_badvalue() { "box-shadow" } else { "bounds" }; - let bounds = item[bounds_key].as_rect().expect("box shadow must have bounds"); + fn handle_box_shadow( + &mut self, + dl: &mut DisplayListBuilder, + item: &Yaml, + info: &mut LayoutPrimitiveInfo, + ) { + let bounds_key = if item["type"].is_badvalue() { + "box-shadow" + } else { + "bounds" + }; + let bounds = item[bounds_key] + .as_rect() + .expect("box shadow must have bounds"); info.rect = bounds; let box_bounds = item["box-bounds"].as_rect().unwrap_or(bounds); let offset = item["offset"].as_vector().unwrap_or(LayoutVector2D::zero()); - let color = item["color"].as_colorf().unwrap_or(ColorF::new(0.0, 0.0, 0.0, 1.0)); + let color = item["color"] + .as_colorf() + .unwrap_or(ColorF::new(0.0, 0.0, 0.0, 1.0)); let blur_radius = item["blur-radius"].as_force_f32().unwrap_or(0.0); let spread_radius = item["spread-radius"].as_force_f32().unwrap_or(0.0); let border_radius = item["border-radius"].as_force_f32().unwrap_or(0.0); @@ -463,120 +655,154 @@ impl YamlFrameReader { BoxShadowClipMode::None }; - dl.push_box_shadow(&info, - box_bounds, - offset, - color, - blur_radius, - spread_radius, - border_radius, - clip_mode); - } - - fn handle_image(&mut self, - dl: &mut DisplayListBuilder, - wrench: &mut Wrench, - item: &Yaml, - info: &mut LayoutPrimitiveInfo) { - let filename = &item[if item["type"].is_badvalue() { "image" } else { "src" }]; + dl.push_box_shadow( + &info, + box_bounds, + offset, + color, + blur_radius, + spread_radius, + border_radius, + clip_mode, + ); + } + + fn handle_image( + &mut self, + dl: &mut DisplayListBuilder, + wrench: &mut Wrench, + item: &Yaml, + info: &mut LayoutPrimitiveInfo, + ) { + let filename = &item[if item["type"].is_badvalue() { + "image" + } else { + "src" + }]; let tiling = item["tile-size"].as_i64(); - let (image_key, image_dims) = wrench.add_or_get_image(&rsrc_path(filename, &self.aux_dir), tiling); + let (image_key, image_dims) = + wrench.add_or_get_image(&rsrc_path(filename, &self.aux_dir), tiling); let bounds_raws = item["bounds"].as_vec_f32().unwrap(); info.rect = if bounds_raws.len() == 2 { - LayoutRect::new(LayoutPoint::new(bounds_raws[0], bounds_raws[1]), - image_dims) + LayoutRect::new(LayoutPoint::new(bounds_raws[0], bounds_raws[1]), image_dims) } else if bounds_raws.len() == 4 { - LayoutRect::new(LayoutPoint::new(bounds_raws[0], bounds_raws[1]), - LayoutSize::new(bounds_raws[2], bounds_raws[3])) + LayoutRect::new( + LayoutPoint::new(bounds_raws[0], bounds_raws[1]), + LayoutSize::new(bounds_raws[2], bounds_raws[3]), + ) } else { - panic!("image expected 2 or 4 values in bounds, got '{:?}'", item["bounds"]); + panic!( + "image expected 2 or 4 values in bounds, got '{:?}'", + item["bounds"] + ); }; - let stretch_size = item["stretch-size"].as_size() - .unwrap_or(image_dims); - let tile_spacing = item["tile-spacing"].as_size() + let stretch_size = item["stretch-size"].as_size().unwrap_or(image_dims); + let tile_spacing = item["tile-spacing"] + .as_size() .unwrap_or(LayoutSize::new(0.0, 0.0)); let rendering = match item["rendering"].as_str() { Some("auto") | None => ImageRendering::Auto, Some("crisp-edges") => ImageRendering::CrispEdges, Some("pixelated") => ImageRendering::Pixelated, - Some(_) => panic!("ImageRendering can be auto, crisp-edges, or pixelated -- got {:?}", item), + Some(_) => panic!( + "ImageRendering can be auto, crisp-edges, or pixelated -- got {:?}", + item + ), }; - dl.push_image(&info, - stretch_size, - tile_spacing, - rendering, - image_key); - } - - fn handle_text(&mut self, - dl: &mut DisplayListBuilder, - wrench: &mut Wrench, - item: &Yaml, - info: &mut LayoutPrimitiveInfo) { + dl.push_image(&info, stretch_size, tile_spacing, rendering, image_key); + } + + fn handle_text( + &mut self, + dl: &mut DisplayListBuilder, + wrench: &mut Wrench, + item: &Yaml, + info: &mut LayoutPrimitiveInfo, + ) { let size = item["size"].as_pt_to_au().unwrap_or(Au::from_f32_px(16.0)); let color = item["color"].as_colorf().unwrap_or(*BLACK_COLOR); - assert!(item["blur-radius"].is_badvalue(), - "text no longer has a blur radius, use PushTextShadow and PopTextShadow"); + assert!( + item["blur-radius"].is_badvalue(), + "text no longer has a blur radius, use PushTextShadow and PopTextShadow" + ); let desc = FontDescriptor::from_yaml(item, &self.aux_dir); let font_key = self.get_or_create_font(desc, wrench); let font_instance_key = self.get_or_create_font_instance(font_key, size, wrench); - assert!(!(item["glyphs"].is_badvalue() && item["text"].is_badvalue()), - "text item had neither text nor glyphs!"); + assert!( + !(item["glyphs"].is_badvalue() && item["text"].is_badvalue()), + "text item had neither text nor glyphs!" + ); let (glyphs, rect) = if item["text"].is_badvalue() { // if glyphs are specified, then the glyph positions can have the // origin baked in. - let origin = item["origin"].as_point().unwrap_or(LayoutPoint::new(0.0, 0.0)); + let origin = item["origin"] + .as_point() + .unwrap_or(LayoutPoint::new(0.0, 0.0)); let glyph_indices = item["glyphs"].as_vec_u32().unwrap(); let glyph_offsets = item["offsets"].as_vec_f32().unwrap(); assert_eq!(glyph_offsets.len(), glyph_indices.len() * 2); - let glyphs = glyph_indices.iter().enumerate().map(|k| { - GlyphInstance { - index: *k.1, - point: LayoutPoint::new(origin.x + glyph_offsets[k.0 * 2], - origin.y + glyph_offsets[k.0 * 2 + 1]) - } - }).collect::>(); + let glyphs = glyph_indices + .iter() + .enumerate() + .map(|k| { + GlyphInstance { + index: *k.1, + point: LayoutPoint::new( + origin.x + glyph_offsets[k.0 * 2], + origin.y + glyph_offsets[k.0 * 2 + 1], + ), + } + }) + .collect::>(); // TODO(gw): We could optionally use the WR API to query glyph dimensions // here and calculate the bounding region here if we want to. - let rect = item["bounds"].as_rect() - .expect("Text items with glyphs require bounds [for now]"); + let rect = item["bounds"] + .as_rect() + .expect("Text items with glyphs require bounds [for now]"); (glyphs, rect) } else { let text = item["text"].as_str().unwrap(); - let (glyph_indices, glyph_advances) = - wrench.layout_simple_ascii(font_key, text, size); - let origin = item["origin"].as_point() + let (glyph_indices, glyph_advances) = wrench.layout_simple_ascii(font_key, text, size); + let origin = item["origin"] + .as_point() .expect("origin required for text without glyphs"); let mut x = origin.x; let y = origin.y; - let glyphs = glyph_indices.iter().zip(glyph_advances).map(|arg| { - let gi = GlyphInstance { index: *arg.0 as u32, - point: LayoutPoint::new(x, y), }; - x += arg.1; - gi - }).collect::>(); + let glyphs = glyph_indices + .iter() + .zip(glyph_advances) + .map(|arg| { + let gi = GlyphInstance { + index: *arg.0 as u32, + point: LayoutPoint::new(x, y), + }; + x += arg.1; + gi + }) + .collect::>(); // FIXME this is incorrect! let rect = LayoutRect::new(LayoutPoint::new(0.0, 0.0), wrench.window_size_f32()); (glyphs, rect) }; info.rect = rect; - dl.push_text(&info, - &glyphs, - font_instance_key, - color, - None); + dl.push_text(&info, &glyphs, font_instance_key, color, None); } - fn handle_iframe(&mut self, dl: &mut DisplayListBuilder, item: &Yaml, info: &mut LayoutPrimitiveInfo) { + fn handle_iframe( + &mut self, + dl: &mut DisplayListBuilder, + item: &Yaml, + info: &mut LayoutPrimitiveInfo, + ) { info.rect = item["bounds"].as_rect().expect("iframe must have bounds"); let pipeline_id = item["id"].as_pipeline_id().unwrap(); dl.push_iframe(&info, pipeline_id); @@ -592,42 +818,45 @@ impl YamlFrameReader { } } - pub fn add_display_list_items_from_yaml(&mut self, dl: &mut DisplayListBuilder, wrench: &mut Wrench, yaml: &Yaml) { + pub fn add_display_list_items_from_yaml( + &mut self, + dl: &mut DisplayListBuilder, + wrench: &mut Wrench, + yaml: &Yaml, + ) { let full_clip = LayoutRect::new(LayoutPoint::zero(), wrench.window_size_f32()); for item in yaml.as_vec().unwrap() { // an explicit type can be skipped with some shorthand - let item_type = - if !item["rect"].is_badvalue() { - "rect" - } else if !item["image"].is_badvalue() { - "image" - } else if !item["text"].is_badvalue() { - "text" - } else if !item["glyphs"].is_badvalue() { - "glyphs" - } else if !item["box-shadow"].is_badvalue() { - // Note: box_shadow shorthand check has to come before border. - "box-shadow" - } else if !item["border"].is_badvalue() { - "border" - } else if !item["gradient"].is_badvalue() { - "gradient" - } else if !item["radial-gradient"].is_badvalue() { - "radial-gradient" - } else { - item["type"].as_str().unwrap_or("unknown") - }; + let item_type = if !item["rect"].is_badvalue() { + "rect" + } else if !item["image"].is_badvalue() { + "image" + } else if !item["text"].is_badvalue() { + "text" + } else if !item["glyphs"].is_badvalue() { + "glyphs" + } else if !item["box-shadow"].is_badvalue() { + // Note: box_shadow shorthand check has to come before border. + "box-shadow" + } else if !item["border"].is_badvalue() { + "border" + } else if !item["gradient"].is_badvalue() { + "gradient" + } else if !item["radial-gradient"].is_badvalue() { + "radial-gradient" + } else { + item["type"].as_str().unwrap_or("unknown") + }; // We never skip stacking contexts because they are structural elements // of the display list. - if item_type != "stacking-context" && - self.include_only.contains(&item_type.to_owned()) { + if item_type != "stacking-context" && self.include_only.contains(&item_type.to_owned()) + { continue; } - let clip_scroll_info = - item["clip-and-scroll"].as_clip_and_scroll_info(dl.pipeline_id); + let clip_scroll_info = item["clip-and-scroll"].as_clip_and_scroll_info(dl.pipeline_id); if let Some(clip_scroll_info) = clip_scroll_info { dl.push_clip_and_scroll_info(clip_scroll_info); } @@ -651,7 +880,9 @@ impl YamlFrameReader { "radial-gradient" => self.handle_radial_gradient(dl, item, &mut info), "box-shadow" => self.handle_box_shadow(dl, item, &mut info), "iframe" => self.handle_iframe(dl, item, &mut info), - "stacking-context" => self.add_stacking_context_from_yaml(dl, wrench, item, false, &mut info), + "stacking-context" => { + self.add_stacking_context_from_yaml(dl, wrench, item, false, &mut info) + } "text-shadow" => self.handle_push_text_shadow(dl, item, &mut info), "pop-text-shadow" => self.handle_pop_text_shadow(dl), _ => println!("Skipping unknown item type: {:?}", item), @@ -663,24 +894,36 @@ impl YamlFrameReader { } } - pub fn handle_scroll_frame(&mut self, dl: &mut DisplayListBuilder, wrench: &mut Wrench, yaml: &Yaml) { - let clip_rect = yaml["bounds"].as_rect().expect("scroll frame must have a bounds"); + pub fn handle_scroll_frame( + &mut self, + dl: &mut DisplayListBuilder, + wrench: &mut Wrench, + yaml: &Yaml, + ) { + let clip_rect = yaml["bounds"] + .as_rect() + .expect("scroll frame must have a bounds"); let content_size = yaml["content-size"].as_size().unwrap_or(clip_rect.size); let content_rect = LayerRect::new(clip_rect.origin, content_size); - let id = yaml["id"].as_i64().map(|id| ClipId::new(id as u64, dl.pipeline_id)); + let id = yaml["id"] + .as_i64() + .map(|id| ClipId::new(id as u64, dl.pipeline_id)); let complex_clips = self.to_complex_clip_regions(&yaml["complex"]); let image_mask = self.to_image_mask(&yaml["image-mask"], wrench); - let id = dl.define_scroll_frame(id, - content_rect, - clip_rect, - complex_clips, - image_mask, - ScrollSensitivity::Script); + let id = dl.define_scroll_frame( + id, + content_rect, + clip_rect, + complex_clips, + image_mask, + ScrollSensitivity::Script, + ); if let Some(size) = yaml["scroll-offset"].as_point() { - self.scroll_offsets.insert(id, LayerPoint::new(size.x, size.y)); + self.scroll_offsets + .insert(id, LayerPoint::new(size.x, size.y)); } dl.push_clip_id(id); @@ -690,9 +933,18 @@ impl YamlFrameReader { dl.pop_clip_id(); } - pub fn handle_sticky_frame(&mut self, dl: &mut DisplayListBuilder, wrench: &mut Wrench, yaml: &Yaml) { - let bounds = yaml["bounds"].as_rect().expect("sticky frame must have a bounds"); - let id = yaml["id"].as_i64().map(|id| ClipId::new(id as u64, dl.pipeline_id)); + pub fn handle_sticky_frame( + &mut self, + dl: &mut DisplayListBuilder, + wrench: &mut Wrench, + yaml: &Yaml, + ) { + let bounds = yaml["bounds"] + .as_rect() + .expect("sticky frame must have a bounds"); + let id = yaml["id"] + .as_i64() + .map(|id| ClipId::new(id as u64, dl.pipeline_id)); let sticky_frame_info = self.to_sticky_frame_info(&yaml["sticky-info"]); let id = dl.define_sticky_frame(id, bounds, sticky_frame_info); @@ -703,22 +955,29 @@ impl YamlFrameReader { dl.pop_clip_id(); } - pub fn handle_push_text_shadow(&mut self, - dl: &mut DisplayListBuilder, - yaml: &Yaml, - info: &mut LayoutPrimitiveInfo) { - let rect = yaml["bounds"].as_rect() - .expect("Text shadows require bounds"); + pub fn handle_push_text_shadow( + &mut self, + dl: &mut DisplayListBuilder, + yaml: &Yaml, + info: &mut LayoutPrimitiveInfo, + ) { + let rect = yaml["bounds"] + .as_rect() + .expect("Text shadows require bounds"); info.rect = rect; info.local_clip = None; let blur_radius = yaml["blur-radius"].as_f32().unwrap_or(0.0); let offset = yaml["offset"].as_vector().unwrap_or(LayoutVector2D::zero()); let color = yaml["color"].as_colorf().unwrap_or(*BLACK_COLOR); - dl.push_text_shadow(&info, - TextShadow { - blur_radius, offset, color - }); + dl.push_text_shadow( + &info, + TextShadow { + blur_radius, + offset, + color, + }, + ); } pub fn handle_pop_text_shadow(&mut self, dl: &mut DisplayListBuilder) { @@ -727,14 +986,17 @@ impl YamlFrameReader { pub fn handle_clip(&mut self, dl: &mut DisplayListBuilder, wrench: &mut Wrench, yaml: &Yaml) { let clip_rect = yaml["bounds"].as_rect().expect("clip must have a bounds"); - let id = yaml["id"].as_i64().map(|id| ClipId::new(id as u64, dl.pipeline_id)); + let id = yaml["id"] + .as_i64() + .map(|id| ClipId::new(id as u64, dl.pipeline_id)); let complex_clips = self.to_complex_clip_regions(&yaml["complex"]); let image_mask = self.to_image_mask(&yaml["image-mask"], wrench); let id = dl.define_clip(id, clip_rect, complex_clips, image_mask); if let Some(size) = yaml["scroll-offset"].as_point() { - self.scroll_offsets.insert(id, LayerPoint::new(size.x, size.y)); + self.scroll_offsets + .insert(id, LayerPoint::new(size.x, size.y)); } dl.push_clip_id(id); @@ -745,24 +1007,32 @@ impl YamlFrameReader { } pub fn get_root_size_from_yaml(&mut self, wrench: &mut Wrench, yaml: &Yaml) -> LayoutSize { - yaml["bounds"].as_rect().map(|rect| rect.size).unwrap_or(wrench.window_size_f32()) + yaml["bounds"] + .as_rect() + .map(|rect| rect.size) + .unwrap_or(wrench.window_size_f32()) } - pub fn add_stacking_context_from_yaml(&mut self, - dl: &mut DisplayListBuilder, - wrench: &mut Wrench, - yaml: &Yaml, - is_root: bool, - info: &mut LayoutPrimitiveInfo) { + pub fn add_stacking_context_from_yaml( + &mut self, + dl: &mut DisplayListBuilder, + wrench: &mut Wrench, + yaml: &Yaml, + is_root: bool, + info: &mut LayoutPrimitiveInfo, + ) { let default_bounds = LayoutRect::new(LayoutPoint::zero(), wrench.window_size_f32()); let bounds = yaml["bounds"].as_rect().unwrap_or(default_bounds); // TODO(gw): Add support for specifying the transform origin in yaml. - let transform_origin = LayoutPoint::new(bounds.origin.x + bounds.size.width * 0.5, - bounds.origin.y + bounds.size.height * 0.5); + let transform_origin = LayoutPoint::new( + bounds.origin.x + bounds.size.width * 0.5, + bounds.origin.y + bounds.size.height * 0.5, + ); - let transform = yaml["transform"].as_transform(&transform_origin).map( - |transform| transform.into()); + let transform = yaml["transform"] + .as_transform(&transform_origin) + .map(|transform| transform.into()); // TODO(gw): Support perspective-origin. let perspective = match yaml["perspective"].as_f32() { @@ -771,17 +1041,21 @@ impl YamlFrameReader { _ => yaml["perspective"].as_matrix4d(), }; - let transform_style = yaml["transform-style"].as_transform_style() - .unwrap_or(TransformStyle::Flat); - let mix_blend_mode = yaml["mix-blend-mode"].as_mix_blend_mode() - .unwrap_or(MixBlendMode::Normal); - let scroll_policy = yaml["scroll-policy"].as_scroll_policy() - .unwrap_or(ScrollPolicy::Scrollable); + let transform_style = yaml["transform-style"] + .as_transform_style() + .unwrap_or(TransformStyle::Flat); + let mix_blend_mode = yaml["mix-blend-mode"] + .as_mix_blend_mode() + .unwrap_or(MixBlendMode::Normal); + let scroll_policy = yaml["scroll-policy"] + .as_scroll_policy() + .unwrap_or(ScrollPolicy::Scrollable); if is_root { if let Some(size) = yaml["scroll-offset"].as_point() { let id = ClipId::root_scroll_node(dl.pipeline_id); - self.scroll_offsets.insert(id, LayerPoint::new(size.x, size.y)); + self.scroll_offsets + .insert(id, LayerPoint::new(size.x, size.y)); } } @@ -789,13 +1063,15 @@ impl YamlFrameReader { info.rect = bounds; info.local_clip = None; - dl.push_stacking_context(&info, - scroll_policy, - transform.into(), - transform_style, - perspective, - mix_blend_mode, - filters); + dl.push_stacking_context( + &info, + scroll_policy, + transform.into(), + transform_style, + perspective, + mix_blend_mode, + filters, + ); if !yaml["items"].is_badvalue() { self.add_display_list_items_from_yaml(dl, wrench, &yaml["items"]); @@ -816,9 +1092,11 @@ impl WrenchThing for YamlFrameReader { if !self.frame_built || wrench.should_rebuild_display_lists() { wrench.begin_frame(); - wrench.send_lists(self.frame_count, - self.display_lists.clone(), - &self.scroll_offsets); + wrench.send_lists( + self.frame_count, + self.display_lists.clone(), + &self.scroll_offsets, + ); } else { wrench.refresh(); } @@ -827,11 +1105,9 @@ impl WrenchThing for YamlFrameReader { self.frame_count } - fn next_frame(&mut self) { - } + fn next_frame(&mut self) {} - fn prev_frame(&mut self) { - } + fn prev_frame(&mut self) {} fn queue_frames(&self) -> u32 { self.queue_depth diff --git a/wrench/src/yaml_frame_writer.rs b/wrench/src/yaml_frame_writer.rs index 76209bfbc3..67e6d36294 100644 --- a/wrench/src/yaml_frame_writer.rs +++ b/wrench/src/yaml_frame_writer.rs @@ -5,8 +5,8 @@ extern crate yaml_rust; use app_units::Au; -use euclid::{TypedTransform3D, TypedPoint2D, TypedVector2D, TypedRect, TypedSize2D}; -use image::{ColorType, save_buffer}; +use euclid::{TypedPoint2D, TypedRect, TypedSize2D, TypedTransform3D, TypedVector2D}; +use image::{save_buffer, ColorType}; use premultiply::unpremultiply; use scene::Scene; use std::borrow::BorrowMut; @@ -64,7 +64,13 @@ fn color_to_string(value: ColorF) -> String { } else if value.r == 0.0 && value.g == 0.0 && value.b == 0.0 && value.a == 1.0 { "black".to_owned() } else { - format!("{} {} {} {:.4}", value.r * 255.0, value.g * 255.0, value.b * 255.0, value.a) + format!( + "{} {} {} {:.4}", + value.r * 255.0, + value.g * 255.0, + value.b * 255.0, + value.a + ) } } @@ -85,7 +91,15 @@ fn size_node(parent: &mut Table, key: &str, value: &TypedSize2D) { } fn rect_yaml(value: &TypedRect) -> Yaml { - f32_vec_yaml(&[value.origin.x, value.origin.y, value.size.width, value.size.height], false) + f32_vec_yaml( + &[ + value.origin.x, + value.origin.y, + value.size.width, + value.size.height, + ], + false, + ) } fn rect_node(parent: &mut Table, key: &str, value: &TypedRect) { @@ -280,14 +294,15 @@ impl YamlFrameWriter { } } - pub fn begin_write_display_list(&mut self, - scene: &mut Scene, - epoch: &Epoch, - pipeline_id: &PipelineId, - background_color: &Option, - viewport_size: &LayoutSize, - display_list: &BuiltDisplayListDescriptor) - { + pub fn begin_write_display_list( + &mut self, + scene: &mut Scene, + epoch: &Epoch, + pipeline_id: &PipelineId, + background_color: &Option, + viewport_size: &LayoutSize, + display_list: &BuiltDisplayListDescriptor, + ) { unsafe { if CURRENT_FRAME_NUMBER == self.last_frame_written { return; @@ -298,9 +313,7 @@ impl YamlFrameWriter { self.dl_descriptor = Some(display_list.clone()); self.pipeline_id = Some(pipeline_id.clone()); - scene.begin_display_list(pipeline_id, epoch, - background_color, - viewport_size); + scene.begin_display_list(pipeline_id, epoch, background_color, viewport_size); } pub fn finish_write_display_list(&mut self, scene: &mut Scene, data: &[u8]) { @@ -319,7 +332,11 @@ impl YamlFrameWriter { let mut root = new_table(); if let Some(root_pipeline_id) = scene.root_pipeline_id { - u32_vec_node(&mut root_dl_table, "id", &[root_pipeline_id.0, root_pipeline_id.1]); + u32_vec_node( + &mut root_dl_table, + "id", + &[root_pipeline_id.0, root_pipeline_id.1], + ); let mut referenced_pipeline_ids = vec![]; let mut traversal = dl.iter(); @@ -360,7 +377,6 @@ impl YamlFrameWriter { frame_file_name.push(format!("frame-{}.yaml", current_shown_frame)); let mut file = fs::File::create(&frame_file_name).unwrap(); file.write_all(&sb).unwrap(); - } scene.finish_display_list(self.pipeline_id.unwrap(), dl); @@ -371,21 +387,26 @@ impl YamlFrameWriter { match *update { ResourceUpdate::AddImage(ref img) => { let stride = img.descriptor.stride.unwrap_or( - img.descriptor.width * img.descriptor.format.bytes_per_pixel() + img.descriptor.width * img.descriptor.format.bytes_per_pixel(), ); let bytes = match img.data { - ImageData::Raw(ref v) => { (**v).clone() } - ImageData::External(_) | ImageData::Blob(_) => { return; } + ImageData::Raw(ref v) => (**v).clone(), + ImageData::External(_) | ImageData::Blob(_) => { + return; + } }; - self.images.insert(img.key, CachedImage { - width: img.descriptor.width, - height: img.descriptor.height, - stride, - format: img.descriptor.format, - bytes: Some(bytes), - tiling: img.tiling, - path: None, - }); + self.images.insert( + img.key, + CachedImage { + width: img.descriptor.width, + height: img.descriptor.height, + stride, + format: img.descriptor.format, + bytes: Some(bytes), + tiling: img.tiling, + path: None, + }, + ); } ResourceUpdate::UpdateImage(ref img) => { if let Some(ref mut data) = self.images.get_mut(&img.key) { @@ -398,36 +419,47 @@ impl YamlFrameWriter { *data.bytes.borrow_mut() = Some((**bytes).clone()); } else { // Other existing image types only make sense within the gecko integration. - println!("Wrench only supports updating buffer images (ignoring update command)."); + println!( + "Wrench only supports updating buffer images ({}).", + "ignoring update command" + ); } } } ResourceUpdate::DeleteImage(img) => { self.images.remove(&img); } - ResourceUpdate::AddFont(ref font) => { - match font { - &AddFont::Raw(key, ref bytes, index) => { - self.fonts.insert(key, CachedFont::Raw(Some(bytes.clone()), index, None)); - } - &AddFont::Native(key, ref handle) => { - self.fonts.insert(key, CachedFont::Native(handle.clone())); - } + ResourceUpdate::AddFont(ref font) => match font { + &AddFont::Raw(key, ref bytes, index) => { + self.fonts + .insert(key, CachedFont::Raw(Some(bytes.clone()), index, None)); } - } + &AddFont::Native(key, ref handle) => { + self.fonts.insert(key, CachedFont::Native(handle.clone())); + } + }, ResourceUpdate::DeleteFont(_) => {} ResourceUpdate::AddFontInstance(ref instance) => { - self.font_instances.insert(instance.key, CachedFontInstance { - font_key: instance.font_key, - glyph_size: instance.glyph_size, - }); + self.font_instances.insert( + instance.key, + CachedFontInstance { + font_key: instance.font_key, + glyph_size: instance.glyph_size, + }, + ); } ResourceUpdate::DeleteFontInstance(_) => {} } } } - fn next_rsrc_paths(prefix: &str, counter: &mut u32, base_path: &Path, base: &str, ext: &str) -> (PathBuf, PathBuf) { + fn next_rsrc_paths( + prefix: &str, + counter: &mut u32, + base_path: &Path, + base: &str, + ext: &str, + ) -> (PathBuf, PathBuf) { let mut path_file = base_path.to_owned(); let mut path = PathBuf::from("res"); @@ -452,26 +484,27 @@ impl YamlFrameWriter { // Remove the data to munge it let mut data = self.images.remove(&key).unwrap(); let mut bytes = data.bytes.take().unwrap(); - let (path_file, path) = Self::next_rsrc_paths(&self.rsrc_prefix, - &mut self.next_rsrc_num, - &self.rsrc_base, - "img", - "png"); + let (path_file, path) = Self::next_rsrc_paths( + &self.rsrc_prefix, + &mut self.next_rsrc_num, + &self.rsrc_base, + "img", + "png", + ); assert!(data.stride > 0); let (color_type, bpp) = match data.format { - ImageFormat::RGB8 => { - (ColorType::RGB(8), 3) - } - ImageFormat::BGRA8 => { - (ColorType::RGBA(8), 4) - } - ImageFormat::A8 => { - (ColorType::Gray(8), 1) - } + ImageFormat::RGB8 => (ColorType::RGB(8), 3), + ImageFormat::BGRA8 => (ColorType::RGBA(8), 4), + ImageFormat::A8 => (ColorType::Gray(8), 1), _ => { - println!("Failed to write image with format {:?}, dimensions {}x{}, stride {}", - data.format, data.width, data.height, data.stride); + println!( + "Failed to write image with format {:?}, dimensions {}x{}, stride {}", + data.format, + data.width, + data.height, + data.stride + ); return None; } }; @@ -484,9 +517,12 @@ impl YamlFrameWriter { } else { // takes a buffer with a stride and copies it into a new buffer that has stride == width assert!(data.stride > data.width * bpp); - let mut tmp: Vec<_> = bytes[..].chunks(data.stride as usize) - .flat_map(|chunk| chunk[..(data.width * bpp) as usize].iter().cloned()) - .collect(); + let mut tmp: Vec<_> = bytes[..] + .chunks(data.stride as usize) + .flat_map(|chunk| { + chunk[.. (data.width * bpp) as usize].iter().cloned() + }) + .collect(); if data.format == ImageFormat::BGRA8 { unpremultiply(tmp.as_mut_slice()); } @@ -503,13 +539,19 @@ impl YamlFrameWriter { fn make_complex_clip_node(&mut self, complex_clip: &ComplexClipRegion) -> Yaml { let mut t = new_table(); rect_node(&mut t, "rect", &complex_clip.rect); - yaml_node(&mut t, "radius", maybe_radius_yaml(&complex_clip.radii).unwrap()); + yaml_node( + &mut t, + "radius", + maybe_radius_yaml(&complex_clip.radii).unwrap(), + ); Yaml::Hash(t) } fn make_sticky_info_node(&mut self, sticky_info: &StickySideConstraint) -> Yaml { - Yaml::Array(vec![Yaml::Real(sticky_info.margin.to_string()), - Yaml::Real(sticky_info.max_offset.to_string())]) + Yaml::Array(vec![ + Yaml::Real(sticky_info.margin.to_string()), + Yaml::Real(sticky_info.max_offset.to_string()), + ]) } fn make_sticky_frame_info_node(&mut self, sticky_frame_info: &StickyFrameInfo) -> Yaml { @@ -529,22 +571,23 @@ impl YamlFrameWriter { Yaml::Hash(table) } - fn make_complex_clips_node(&mut self, - complex_clip_count: usize, - complex_clips: ItemRange, - list: &BuiltDisplayList) - -> Option { + fn make_complex_clips_node( + &mut self, + complex_clip_count: usize, + complex_clips: ItemRange, + list: &BuiltDisplayList, + ) -> Option { if complex_clip_count == 0 { return None; } - let complex_items = list.get(complex_clips).map(|ccx| - if ccx.radii.is_zero() { + let complex_items = list.get(complex_clips) + .map(|ccx| if ccx.radii.is_zero() { rect_yaml(&ccx.rect) } else { self.make_complex_clip_node(&ccx) - } - ).collect(); + }) + .collect(); Some(Yaml::Array(complex_items)) } @@ -563,11 +606,13 @@ impl YamlFrameWriter { Some(Yaml::Hash(mask_table)) } - fn write_display_list_items(&mut self, - list: &mut Vec, - display_list: &BuiltDisplayList, - list_iterator: &mut BuiltDisplayListIter, - clip_id_mapper: &mut ClipIdMapper) { + fn write_display_list_items( + &mut self, + list: &mut Vec, + display_list: &BuiltDisplayList, + list_iterator: &mut BuiltDisplayListIter, + clip_id_mapper: &mut ClipIdMapper, + ) { // continue_traversal is a big borrowck hack let mut continue_traversal = None; loop { @@ -589,8 +634,9 @@ impl YamlFrameWriter { let clip_and_scroll_info = clip_id_mapper.fix_ids_for_nesting(&base.clip_and_scroll()); let clip_and_scroll_yaml = match clip_id_mapper.map_info(&clip_and_scroll_info) { - (scroll_id, Some(clip_id)) => - Yaml::Array(vec![Yaml::Integer(scroll_id), Yaml::Integer(clip_id)]), + (scroll_id, Some(clip_id)) => { + Yaml::Array(vec![Yaml::Integer(scroll_id), Yaml::Integer(clip_id)]) + } (scroll_id, None) => Yaml::Integer(scroll_id), }; yaml_node(&mut v, "clip-and-scroll", clip_and_scroll_yaml); @@ -600,7 +646,7 @@ impl YamlFrameWriter { Rectangle(item) => { str_node(&mut v, "type", "rect"); color_node(&mut v, "color", item.color); - }, + } Line(item) => { str_node(&mut v, "type", "line"); f32_node(&mut v, "baseline", item.baseline); @@ -625,10 +671,17 @@ impl YamlFrameWriter { let instance = self.font_instances.entry(item.font_key).or_insert_with(|| { println!("Warning: font instance key not found in font instances table!"); - CachedFontInstance { font_key: FontKey::new(IdNamespace(0), 0), glyph_size: Au::from_px(16) } + CachedFontInstance { + font_key: FontKey::new(IdNamespace(0), 0), + glyph_size: Au::from_px(16), + } }); - f32_node(&mut v, "size", instance.glyph_size.to_f32_px() * 12.0 / 16.0); + f32_node( + &mut v, + "size", + instance.glyph_size.to_f32_px() * 12.0 / 16.0, + ); color_node(&mut v, "color", item.color); let entry = self.fonts.entry(instance.font_key).or_insert_with(|| { @@ -642,12 +695,13 @@ impl YamlFrameWriter { } &mut CachedFont::Raw(ref mut bytes_opt, index, ref mut path_opt) => { if let Some(bytes) = bytes_opt.take() { - let (path_file, path) = - Self::next_rsrc_paths(&self.rsrc_prefix, - &mut self.next_rsrc_num, - &self.rsrc_base, - "font", - "ttf"); + let (path_file, path) = Self::next_rsrc_paths( + &self.rsrc_prefix, + &mut self.next_rsrc_num, + &self.rsrc_base, + "font", + "ttf", + ); let mut file = fs::File::create(&path_file).unwrap(); file.write_all(&bytes).unwrap(); *path_opt = Some(path); @@ -659,12 +713,16 @@ impl YamlFrameWriter { } } } - }, + } Image(item) => { if let Some(path) = self.path_for_image(item.image_key) { path_node(&mut v, "image", &path); } - if let Some(&CachedImage { tiling: Some(tile_size), .. }) = self.images.get(&item.image_key) { + if let Some(&CachedImage { + tiling: Some(tile_size), + .. + }) = self.images.get(&item.image_key) + { u32_node(&mut v, "tile-size", tile_size as u32); } size_node(&mut v, "stretch-size", &item.stretch_size); @@ -674,36 +732,42 @@ impl YamlFrameWriter { ImageRendering::CrispEdges => str_node(&mut v, "rendering", "crisp-edges"), ImageRendering::Pixelated => str_node(&mut v, "rendering", "pixelated"), }; - }, + } YuvImage(_) => { str_node(&mut v, "type", "yuv-image"); // TODO println!("TODO YAML YuvImage"); - }, + } Border(item) => { str_node(&mut v, "type", "border"); match item.details { BorderDetails::Normal(ref details) => { - let trbl = vec![&details.top, &details.right, &details.bottom, &details.left]; - let widths: Vec = vec![ item.widths.top, - item.widths.right, - item.widths.bottom, - item.widths.left ]; - let colors: Vec = trbl.iter().map(|x| color_to_string(x.color)).collect(); - let styles: Vec = trbl.iter().map(|x| { - match x.style { - BorderStyle::None => "none", - BorderStyle::Solid => "solid", - BorderStyle::Double => "double", - BorderStyle::Dotted => "dotted", - BorderStyle::Dashed => "dashed", - BorderStyle::Hidden => "hidden", - BorderStyle::Ridge => "ridge", - BorderStyle::Inset => "inset", - BorderStyle::Outset => "outset", - BorderStyle::Groove => "groove", - }.to_owned() - }).collect(); + let trbl = + vec![&details.top, &details.right, &details.bottom, &details.left]; + let widths: Vec = vec![ + item.widths.top, + item.widths.right, + item.widths.bottom, + item.widths.left, + ]; + let colors: Vec = + trbl.iter().map(|x| color_to_string(x.color)).collect(); + let styles: Vec = trbl.iter() + .map(|x| { + match x.style { + BorderStyle::None => "none", + BorderStyle::Solid => "solid", + BorderStyle::Double => "double", + BorderStyle::Dotted => "dotted", + BorderStyle::Dashed => "dashed", + BorderStyle::Hidden => "hidden", + BorderStyle::Ridge => "ridge", + BorderStyle::Inset => "inset", + BorderStyle::Outset => "outset", + BorderStyle::Groove => "groove", + }.to_owned() + }) + .collect(); yaml_node(&mut v, "width", f32_vec_yaml(&widths, true)); str_node(&mut v, "border-type", "normal"); yaml_node(&mut v, "color", string_vec_yaml(&colors, true)); @@ -713,14 +777,18 @@ impl YamlFrameWriter { } } BorderDetails::Image(ref details) => { - let widths: Vec = vec![ item.widths.top, - item.widths.right, - item.widths.bottom, - item.widths.left ]; - let outset: Vec = vec![ details.outset.top, - details.outset.right, - details.outset.bottom, - details.outset.left]; + let widths: Vec = vec![ + item.widths.top, + item.widths.right, + item.widths.bottom, + item.widths.left, + ]; + let outset: Vec = vec![ + details.outset.top, + details.outset.right, + details.outset.bottom, + details.outset.left, + ]; yaml_node(&mut v, "width", f32_vec_yaml(&widths, true)); str_node(&mut v, "border-type", "image"); if let Some(path) = self.path_for_image(details.image_key) { @@ -728,34 +796,46 @@ impl YamlFrameWriter { } u32_node(&mut v, "image-width", details.patch.width); u32_node(&mut v, "image-height", details.patch.height); - let slice: Vec = vec![ details.patch.slice.top, - details.patch.slice.right, - details.patch.slice.bottom, - details.patch.slice.left ]; + let slice: Vec = vec![ + details.patch.slice.top, + details.patch.slice.right, + details.patch.slice.bottom, + details.patch.slice.left, + ]; yaml_node(&mut v, "slice", u32_vec_yaml(&slice, true)); yaml_node(&mut v, "outset", f32_vec_yaml(&outset, true)); match details.repeat_horizontal { - RepeatMode::Stretch => str_node(&mut v, "repeat-horizontal", "stretch"), - RepeatMode::Repeat => str_node(&mut v, "repeat-horizontal", "repeat"), + RepeatMode::Stretch => { + str_node(&mut v, "repeat-horizontal", "stretch") + } + RepeatMode::Repeat => { + str_node(&mut v, "repeat-horizontal", "repeat") + } RepeatMode::Round => str_node(&mut v, "repeat-horizontal", "round"), RepeatMode::Space => str_node(&mut v, "repeat-horizontal", "space"), }; match details.repeat_vertical { - RepeatMode::Stretch => str_node(&mut v, "repeat-vertical", "stretch"), + RepeatMode::Stretch => { + str_node(&mut v, "repeat-vertical", "stretch") + } RepeatMode::Repeat => str_node(&mut v, "repeat-vertical", "repeat"), RepeatMode::Round => str_node(&mut v, "repeat-vertical", "round"), RepeatMode::Space => str_node(&mut v, "repeat-vertical", "space"), }; } BorderDetails::Gradient(ref details) => { - let widths: Vec = vec![ item.widths.top, - item.widths.right, - item.widths.bottom, - item.widths.left ]; - let outset: Vec = vec![ details.outset.top, - details.outset.right, - details.outset.bottom, - details.outset.left]; + let widths: Vec = vec![ + item.widths.top, + item.widths.right, + item.widths.bottom, + item.widths.left, + ]; + let outset: Vec = vec![ + details.outset.top, + details.outset.right, + details.outset.bottom, + details.outset.left, + ]; yaml_node(&mut v, "width", f32_vec_yaml(&widths, true)); str_node(&mut v, "border-type", "gradient"); point_node(&mut v, "start", &details.gradient.start_point); @@ -766,18 +846,26 @@ impl YamlFrameWriter { stops.push(Yaml::String(color_to_string(stop.color))); } yaml_node(&mut v, "stops", Yaml::Array(stops)); - bool_node(&mut v, "repeat", details.gradient.extend_mode == ExtendMode::Repeat); + bool_node( + &mut v, + "repeat", + details.gradient.extend_mode == ExtendMode::Repeat, + ); yaml_node(&mut v, "outset", f32_vec_yaml(&outset, true)); } BorderDetails::RadialGradient(ref details) => { - let widths: Vec = vec![ item.widths.top, - item.widths.right, - item.widths.bottom, - item.widths.left ]; - let outset: Vec = vec![ details.outset.top, - details.outset.right, - details.outset.bottom, - details.outset.left]; + let widths: Vec = vec![ + item.widths.top, + item.widths.right, + item.widths.bottom, + item.widths.left, + ]; + let outset: Vec = vec![ + details.outset.top, + details.outset.right, + details.outset.bottom, + details.outset.left, + ]; yaml_node(&mut v, "width", f32_vec_yaml(&widths, true)); str_node(&mut v, "border-type", "radial-gradient"); point_node(&mut v, "start-center", &details.gradient.start_center); @@ -791,11 +879,15 @@ impl YamlFrameWriter { stops.push(Yaml::String(color_to_string(stop.color))); } yaml_node(&mut v, "stops", Yaml::Array(stops)); - bool_node(&mut v, "repeat", details.gradient.extend_mode == ExtendMode::Repeat); + bool_node( + &mut v, + "repeat", + details.gradient.extend_mode == ExtendMode::Repeat, + ); yaml_node(&mut v, "outset", f32_vec_yaml(&outset, true)); } } - }, + } BoxShadow(item) => { str_node(&mut v, "type", "box-shadow"); rect_node(&mut v, "box-bounds", &item.box_bounds); @@ -807,10 +899,10 @@ impl YamlFrameWriter { let clip_mode = match item.clip_mode { BoxShadowClipMode::None => "none", BoxShadowClipMode::Outset => "outset", - BoxShadowClipMode::Inset => "inset" + BoxShadowClipMode::Inset => "inset", }; str_node(&mut v, "clip-mode", clip_mode); - }, + } Gradient(item) => { str_node(&mut v, "type", "gradient"); point_node(&mut v, "start", &item.gradient.start_point); @@ -823,8 +915,12 @@ impl YamlFrameWriter { stops.push(Yaml::String(color_to_string(stop.color))); } yaml_node(&mut v, "stops", Yaml::Array(stops)); - bool_node(&mut v, "repeat", item.gradient.extend_mode == ExtendMode::Repeat); - }, + bool_node( + &mut v, + "repeat", + item.gradient.extend_mode == ExtendMode::Repeat, + ); + } RadialGradient(item) => { str_node(&mut v, "type", "radial-gradient"); point_node(&mut v, "start-center", &item.gradient.start_center); @@ -840,12 +936,16 @@ impl YamlFrameWriter { stops.push(Yaml::String(color_to_string(stop.color))); } yaml_node(&mut v, "stops", Yaml::Array(stops)); - bool_node(&mut v, "repeat", item.gradient.extend_mode == ExtendMode::Repeat); - }, + bool_node( + &mut v, + "repeat", + item.gradient.extend_mode == ExtendMode::Repeat, + ); + } Iframe(item) => { str_node(&mut v, "type", "iframe"); u32_vec_node(&mut v, "id", &[item.pipeline_id.0, item.pipeline_id.1]); - }, + } PushStackingContext(item) => { str_node(&mut v, "type", "stacking-context"); write_sc(&mut v, &item.stacking_context); @@ -853,16 +953,18 @@ impl YamlFrameWriter { let mut sub_iter = base.sub_iter(); self.write_display_list(&mut v, display_list, &mut sub_iter, clip_id_mapper); continue_traversal = Some(sub_iter); - }, + } Clip(item) => { str_node(&mut v, "type", "clip"); usize_node(&mut v, "id", clip_id_mapper.add_id(item.id)); size_node(&mut v, "content-size", &base.rect().size); let &(complex_clips, complex_clip_count) = base.complex_clip(); - if let Some(complex) = self.make_complex_clips_node(complex_clip_count, - complex_clips, - display_list) { + if let Some(complex) = self.make_complex_clips_node( + complex_clip_count, + complex_clips, + display_list, + ) { yaml_node(&mut v, "complex", complex); } @@ -877,9 +979,11 @@ impl YamlFrameWriter { rect_node(&mut v, "bounds", &base.local_clip().clip_rect()); let &(complex_clips, complex_clip_count) = base.complex_clip(); - if let Some(complex) = self.make_complex_clips_node(complex_clip_count, - complex_clips, - display_list) { + if let Some(complex) = self.make_complex_clips_node( + complex_clip_count, + complex_clips, + display_list, + ) { yaml_node(&mut v, "complex", complex); } @@ -891,15 +995,19 @@ impl YamlFrameWriter { str_node(&mut v, "type", "sticky-frame"); usize_node(&mut v, "id", clip_id_mapper.add_id(item.id)); rect_node(&mut v, "bounds", &base.local_clip().clip_rect()); - yaml_node(&mut v, "sticky-info", - self.make_sticky_frame_info_node(&item.sticky_frame_info)); + yaml_node( + &mut v, + "sticky-info", + self.make_sticky_frame_info_node(&item.sticky_frame_info), + ); } - PushNestedDisplayList => - clip_id_mapper.push_nested_display_list_ids(clip_and_scroll_info), + PushNestedDisplayList => { + clip_id_mapper.push_nested_display_list_ids(clip_and_scroll_info) + } PopNestedDisplayList => clip_id_mapper.pop_nested_display_list_ids(), PopStackingContext => return, - SetGradientStops => { panic!("dummy item yielded?") }, + SetGradientStops => panic!("dummy item yielded?"), PushTextShadow(shadow) => { str_node(&mut v, "type", "text-shadow"); vector_node(&mut v, "offset", &shadow.offset); @@ -908,7 +1016,7 @@ impl YamlFrameWriter { } PopTextShadow => { str_node(&mut v, "type", "pop-text-shadow"); - }, + } } if !v.is_empty() { list.push(Yaml::Hash(v)); @@ -916,11 +1024,13 @@ impl YamlFrameWriter { } } - fn write_display_list(&mut self, - parent: &mut Table, - display_list: &BuiltDisplayList, - list_iterator: &mut BuiltDisplayListIter, - clip_id_mapper: &mut ClipIdMapper) { + fn write_display_list( + &mut self, + parent: &mut Table, + display_list: &BuiltDisplayList, + list_iterator: &mut BuiltDisplayListIter, + clip_id_mapper: &mut ClipIdMapper, + ) { let mut list = vec![]; self.write_display_list_items(&mut list, display_list, list_iterator, clip_id_mapper); parent.insert(Yaml::String("items".to_owned()), Yaml::Array(list)); @@ -937,22 +1047,27 @@ impl webrender::ApiRecordingReceiver for YamlFrameWriterReceiver { ApiMsg::UpdateDocument(_, DocumentMsg::SetRootPipeline(ref pipeline_id)) => { self.scene.set_root_pipeline_id(pipeline_id.clone()); } - ApiMsg::UpdateDocument(_, DocumentMsg::SetDisplayList { - ref epoch, - ref pipeline_id, - ref background, - ref viewport_size, - ref list_descriptor, - ref resources, - .. - }) => { + ApiMsg::UpdateDocument( + _, + DocumentMsg::SetDisplayList { + ref epoch, + ref pipeline_id, + ref background, + ref viewport_size, + ref list_descriptor, + ref resources, + .. + }, + ) => { self.frame_writer.update_resources(resources); - self.frame_writer.begin_write_display_list(&mut self.scene, - epoch, - pipeline_id, - background, - viewport_size, - list_descriptor); + self.frame_writer.begin_write_display_list( + &mut self.scene, + epoch, + pipeline_id, + background, + viewport_size, + list_descriptor, + ); } ApiMsg::UpdateDocument(_, DocumentMsg::RemovePipeline(ref pipeline_id)) => { self.scene.remove_pipeline(pipeline_id); @@ -964,7 +1079,8 @@ impl webrender::ApiRecordingReceiver for YamlFrameWriterReceiver { fn write_payload(&mut self, _frame: u32, data: &[u8]) { if self.frame_writer.dl_descriptor.is_some() { - self.frame_writer.finish_write_display_list(&mut self.scene, data); + self.frame_writer + .finish_write_display_list(&mut self.scene, data); } } } @@ -994,7 +1110,8 @@ impl ClipIdMapper { } fn push_nested_display_list_ids(&mut self, info: ClipAndScrollInfo) { - self.nested_display_list_info.push((info.scroll_node_id, info.clip_node_id())); + self.nested_display_list_info + .push((info.scroll_node_id, info.clip_node_id())); } fn pop_nested_display_list_ids(&mut self) { @@ -1025,7 +1142,9 @@ impl ClipIdMapper { } fn map_info(&self, info: &ClipAndScrollInfo) -> (i64, Option) { - (self.map_id(&info.scroll_node_id) as i64, - info.clip_node_id.map(|ref id| self.map_id(id) as i64)) + ( + self.map_id(&info.scroll_node_id) as i64, + info.clip_node_id.map(|ref id| self.map_id(id) as i64), + ) } } diff --git a/wrench/src/yaml_helper.rs b/wrench/src/yaml_helper.rs index f76b98f4ac..4db2b244a1 100644 --- a/wrench/src/yaml_helper.rs +++ b/wrench/src/yaml_helper.rs @@ -46,11 +46,23 @@ fn string_to_color(color: &str) -> Option { "black" => Some(ColorF::new(0.0, 0.0, 0.0, 1.0)), "yellow" => Some(ColorF::new(1.0, 1.0, 0.0, 1.0)), s => { - let items: Vec = s.split_whitespace().map(|s| f32::from_str(s).unwrap()).collect(); + let items: Vec = s.split_whitespace() + .map(|s| f32::from_str(s).unwrap()) + .collect(); if items.len() == 3 { - Some(ColorF::new(items[0] / 255.0, items[1] / 255.0, items[2] / 255.0, 1.0)) + Some(ColorF::new( + items[0] / 255.0, + items[1] / 255.0, + items[2] / 255.0, + 1.0, + )) } else if items.len() == 4 { - Some(ColorF::new(items[0] / 255.0, items[1] / 255.0, items[2] / 255.0, items[3])) + Some(ColorF::new( + items[0] / 255.0, + items[1] / 255.0, + items[2] / 255.0, + items[3], + )) } else { None } @@ -64,7 +76,7 @@ pub trait StringEnum: Sized { } macro_rules! define_string_enum { - ($T:ident, [ $( $y:ident = $x:expr, )* ]) => { + ($T:ident, [ $( $y:ident = $x:expr ),* ]) => { impl StringEnum for $T { fn from_str(text: &str) -> Option<$T> { match text { @@ -84,62 +96,61 @@ macro_rules! define_string_enum { } } -define_string_enum!(TransformStyle, [ - Flat = "flat", - Preserve3D = "preserve-3d", -]); - -define_string_enum!(MixBlendMode, [ - Normal = "normal", - Multiply = "multiply", - Screen = "screen", - Overlay = "overlay", - Darken = "darken", - Lighten = "lighten", - ColorDodge = "color-dodge", - ColorBurn = "color-burn", - HardLight = "hard-light", - SoftLight = "soft-light", - Difference = "difference", - Exclusion = "exclusion", - Hue = "hue", - Saturation = "saturation", - Color = "color", - Luminosity = "luminosity", -]); - -define_string_enum!(ScrollPolicy, [ - Scrollable = "scrollable", - Fixed = "fixed", -]); - -define_string_enum!(LineOrientation, [ - Horizontal = "horizontal", - Vertical = "vertical", -]); - -define_string_enum!(LineStyle, [ - Solid = "solid", - Dotted = "dotted", - Dashed = "dashed", - Wavy = "wavy", -]); +define_string_enum!(TransformStyle, [Flat = "flat", Preserve3D = "preserve-3d"]); + +define_string_enum!( + MixBlendMode, + [ + Normal = "normal", + Multiply = "multiply", + Screen = "screen", + Overlay = "overlay", + Darken = "darken", + Lighten = "lighten", + ColorDodge = "color-dodge", + ColorBurn = "color-burn", + HardLight = "hard-light", + SoftLight = "soft-light", + Difference = "difference", + Exclusion = "exclusion", + Hue = "hue", + Saturation = "saturation", + Color = "color", + Luminosity = "luminosity" + ] +); + +define_string_enum!(ScrollPolicy, [Scrollable = "scrollable", Fixed = "fixed"]); + +define_string_enum!( + LineOrientation, + [Horizontal = "horizontal", Vertical = "vertical"] +); + +define_string_enum!( + LineStyle, + [ + Solid = "solid", + Dotted = "dotted", + Dashed = "dashed", + Wavy = "wavy" + ] +); // Rotate around `axis` by `degrees` angle -fn make_rotation(origin: &LayoutPoint, degrees: f32, axis_x: f32, axis_y: f32, axis_z: f32) - -> LayoutTransform { - let pre_transform = LayoutTransform::create_translation(origin.x, - origin.y, - 0.0); - let post_transform = LayoutTransform::create_translation(-origin.x, - -origin.y, - -0.0); +fn make_rotation( + origin: &LayoutPoint, + degrees: f32, + axis_x: f32, + axis_y: f32, + axis_z: f32, +) -> LayoutTransform { + let pre_transform = LayoutTransform::create_translation(origin.x, origin.y, 0.0); + let post_transform = LayoutTransform::create_translation(-origin.x, -origin.y, -0.0); let theta = 2.0f32 * f32::consts::PI - degrees.to_radians(); - let transform = LayoutTransform::identity().pre_rotate(axis_x, - axis_y, - axis_z, - Radians::new(theta)); + let transform = + LayoutTransform::identity().pre_rotate(axis_x, axis_y, axis_z, Radians::new(theta)); pre_transform.pre_mul(&transform).pre_mul(&post_transform) } @@ -150,7 +161,7 @@ impl YamlHelper for Yaml { match *self { Yaml::Integer(iv) => Some(iv as f32), Yaml::Real(ref sv) => f32::from_str(sv.as_str()).ok(), - _ => None + _ => None, } } @@ -158,33 +169,26 @@ impl YamlHelper for Yaml { match *self { Yaml::Integer(iv) => Some(iv as f32), Yaml::String(ref sv) | Yaml::Real(ref sv) => f32::from_str(sv.as_str()).ok(), - _ => None + _ => None, } } fn as_vec_f32(&self) -> Option> { match *self { - Yaml::String(ref s) | Yaml::Real(ref s) => { - s.split_whitespace() - .map(|v| f32::from_str(v)) - .collect::, _>>() - .ok() - } - Yaml::Array(ref v) => { - v.iter().map(|v| { - match *v { - Yaml::Integer(k) => Ok(k as f32), - Yaml::String(ref k) | Yaml::Real(ref k) => { - f32::from_str(k).map_err(|_| false) - }, - _ => Err(false), - } - }).collect::, _>>().ok() - } - Yaml::Integer(k) => { - Some(vec![k as f32]) - } - _ => None + Yaml::String(ref s) | Yaml::Real(ref s) => s.split_whitespace() + .map(|v| f32::from_str(v)) + .collect::, _>>() + .ok(), + Yaml::Array(ref v) => v.iter() + .map(|v| match *v { + Yaml::Integer(k) => Ok(k as f32), + Yaml::String(ref k) | Yaml::Real(ref k) => f32::from_str(k).map_err(|_| false), + _ => Err(false), + }) + .collect::, _>>() + .ok(), + Yaml::Integer(k) => Some(vec![k as f32]), + _ => None, } } @@ -212,14 +216,14 @@ impl YamlHelper for Yaml { fn as_px_to_au(&self) -> Option { match self.as_force_f32() { Some(fv) => Some(Au::from_f32_px(fv)), - None => None + None => None, } } fn as_pt_to_au(&self) -> Option { match self.as_force_f32() { Some(fv) => Some(Au::from_f32_px(fv * 16. / 12.)), - None => None + None => None, } } @@ -230,7 +234,10 @@ impl YamlHelper for Yaml { if let Some(nums) = self.as_vec_f32() { if nums.len() == 4 { - return Some(LayoutRect::new(LayoutPoint::new(nums[0], nums[1]), LayoutSize::new(nums[2], nums[3]))); + return Some(LayoutRect::new( + LayoutPoint::new(nums[0], nums[1]), + LayoutSize::new(nums[2], nums[3]), + )); } } @@ -266,16 +273,30 @@ impl YamlHelper for Yaml { } fn as_vector(&self) -> Option { - self.as_point().map(|p|{ p.to_vector() }) + self.as_point().map(|p| p.to_vector()) } fn as_matrix4d(&self) -> Option { if let Some(nums) = self.as_vec_f32() { assert_eq!(nums.len(), 16, "expected 16 floats, got '{:?}'", self); - Some(LayoutTransform::row_major(nums[0], nums[1], nums[2], nums[3], - nums[4], nums[5], nums[6], nums[7], - nums[8], nums[9], nums[10], nums[11], - nums[12], nums[13], nums[14], nums[15])) + Some(LayoutTransform::row_major( + nums[0], + nums[1], + nums[2], + nums[3], + nums[4], + nums[5], + nums[6], + nums[7], + nums[8], + nums[9], + nums[10], + nums[11], + nums[12], + nums[13], + nums[14], + nums[15], + )) } else { None } @@ -296,9 +317,11 @@ impl YamlHelper for Yaml { let mx = match function { "translate" if args.len() >= 2 => { let z = args.get(2).and_then(|a| a.parse().ok()).unwrap_or(0.); - LayoutTransform::create_translation(args[0].parse().unwrap(), - args[1].parse().unwrap(), - z) + LayoutTransform::create_translation( + args[0].parse().unwrap(), + args[1].parse().unwrap(), + z, + ) } "rotate" | "rotate-z" if args.len() == 1 => { make_rotation(transform_origin, args[0].parse().unwrap(), 0.0, 0.0, 1.0) @@ -311,22 +334,23 @@ impl YamlHelper for Yaml { } _ => { println!("unknown function {}", function); - break + break; } }; transform = transform.post_mul(&mx); } Some(transform) - }, + } Yaml::Array(ref array) => { - let transform = array.iter().fold(LayoutTransform::identity(), |u, yaml| { - match yaml.as_transform(transform_origin) { + let transform = array.iter().fold( + LayoutTransform::identity(), + |u, yaml| match yaml.as_transform(transform_origin) { Some(ref transform) => u.pre_mul(transform), None => u, - } - }); + }, + ); Some(transform) - }, + } Yaml::BadValue => None, _ => { println!("unknown transform {:?}", self); @@ -337,13 +361,21 @@ impl YamlHelper for Yaml { fn as_colorf(&self) -> Option { if let Some(mut nums) = self.as_vec_f32() { - assert!(nums.len() == 3 || nums.len() == 4, - "color expected a color name, or 3-4 floats; got '{:?}'", self); + assert!( + nums.len() == 3 || nums.len() == 4, + "color expected a color name, or 3-4 floats; got '{:?}'", + self + ); if nums.len() == 3 { nums.push(1.0); } - return Some(ColorF::new(nums[0] / 255.0, nums[1] / 255.0, nums[2] / 255.0, nums[3])); + return Some(ColorF::new( + nums[0] / 255.0, + nums[1] / 255.0, + nums[2] / 255.0, + nums[3], + )); } if let Some(s) = self.as_str() { @@ -382,20 +414,22 @@ impl YamlHelper for Yaml { fn as_clip_and_scroll_info(&self, pipeline_id: PipelineId) -> Option { match *self { - Yaml::Integer(value) => - Some(ClipAndScrollInfo::simple(ClipId::new(value as u64, pipeline_id))), + Yaml::Integer(value) => Some(ClipAndScrollInfo::simple( + ClipId::new(value as u64, pipeline_id), + )), Yaml::Array(ref array) if array.len() == 2 => { let id_ints = (array[0].as_i64(), array[1].as_i64()); if let (Some(scroll_node_id), Some(clip_node_id)) = id_ints { - Some(ClipAndScrollInfo::new(ClipId::new(scroll_node_id as u64, pipeline_id), - ClipId::new(clip_node_id as u64, pipeline_id))) + Some(ClipAndScrollInfo::new( + ClipId::new(scroll_node_id as u64, pipeline_id), + ClipId::new(clip_node_id as u64, pipeline_id), + )) } else { None } } _ => None, } - } fn as_border_radius(&self) -> Option { @@ -404,14 +438,12 @@ impl YamlHelper for Yaml { } match *self { - Yaml::BadValue => { None } + Yaml::BadValue => None, Yaml::String(ref s) | Yaml::Real(ref s) => { let fv = f32::from_str(s).unwrap(); Some(BorderRadius::uniform(fv)) } - Yaml::Integer(v) => { - Some(BorderRadius::uniform(v as f32)) - } + Yaml::Integer(v) => Some(BorderRadius::uniform(v as f32)), Yaml::Array(ref array) if array.len() == 4 => { let top_left = array[0].as_border_radius_component(); let top_right = array[1].as_border_radius_component(); @@ -485,7 +517,7 @@ impl YamlHelper for Yaml { ("sepia", ref args, _) if args.len() == 1 => { Some(FilterOp::Sepia(args[0].parse().unwrap())) } - (_, _, _) => { None } + (_, _, _) => None, } } else { None @@ -500,4 +532,3 @@ impl YamlHelper for Yaml { } } } -