| author | Csoregi Natalia <ncsoregi@mozilla.com> |
| Tue, 28 Jan 2020 22:56:27 +0200 | |
| changeset 512031 | dd5f0e2d407e0f8481fe15739bad434ef0fb048b |
| parent 512030 | 49d1d94d0e03af51c1f971a899f62f18a99d9e74 |
| child 512032 | 748cc6e57cd0b0fab4357ae38eb5bdae505afdac |
| push id | 37066 |
| push user | shindli@mozilla.com |
| push date | Wed, 29 Jan 2020 03:50:12 +0000 |
| treeherder | mozilla-central@31e91b3d071e [default view] [failures only] |
| perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
| bugs | 1605283 |
| milestone | 74.0a1 |
| backs out | 535ae1d4818a3f0af64d61846035135751352bd1 |
| first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
| last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
| gfx/wr/Cargo.lock | file | annotate | diff | comparison | revisions | |
| gfx/wr/tileview/Cargo.toml | file | annotate | diff | comparison | revisions | |
| gfx/wr/tileview/src/main.rs | file | annotate | diff | comparison | revisions | |
| gfx/wr/tileview/src/tilecache_base.css | file | annotate | diff | comparison | revisions | |
| gfx/wr/webrender/src/intern.rs | file | annotate | diff | comparison | revisions | |
| gfx/wr/webrender/src/picture.rs | file | annotate | diff | comparison | revisions |
--- a/gfx/wr/Cargo.lock +++ b/gfx/wr/Cargo.lock @@ -1629,17 +1629,16 @@ dependencies = [ "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tileview" version = "0.1.0" dependencies = [ - "euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", "ron 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", "webrender 0.61.0", "webrender_api 0.61.0", ] [[package]] name = "time"
--- a/gfx/wr/tileview/Cargo.toml +++ b/gfx/wr/tileview/Cargo.toml @@ -7,9 +7,8 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] ron = "0.1.7" serde = {version = "1.0.88", features = ["derive"] } webrender = {path = "../webrender", features=["capture","replay","debugger","png","profiler","no_static_freetype", "leak_checks"]} webrender_api = {path = "../webrender_api", features=["serialize","deserialize"]} -euclid = { version = "0.20.0", features = ["serde"] }
--- a/gfx/wr/tileview/src/main.rs +++ b/gfx/wr/tileview/src/main.rs @@ -7,65 +7,59 @@ use webrender::{TileSerializer, TileCach use serde::Deserialize; //use ron::de::from_reader; use std::fs::File; use std::io::prelude::*; use std::path::Path; use std::ffi::OsString; use webrender::api::enumerate_interners; use webrender::UpdateKind; -use euclid::{Rect, Transform3D}; -use webrender_api::units::{PicturePoint, PictureSize, PicturePixel, WorldPixel}; - -static RES_JAVASCRIPT: &'static str = include_str!("tilecache.js"); -static RES_BASE_CSS: &'static str = include_str!("tilecache_base.css"); #[derive(Deserialize)] pub struct Slice { - pub transform: Transform3D<f32, PicturePixel, WorldPixel>, + pub x: f32, + pub y: f32, pub tile_cache: TileCacheInstanceSerializer } // invalidation reason CSS colors static CSS_FRACTIONAL_OFFSET: &str = "fill:#4040c0;fill-opacity:0.1;"; static CSS_BACKGROUND_COLOR: &str = "fill:#10c070;fill-opacity:0.1;"; static CSS_SURFACE_OPACITY_CHANNEL: &str = "fill:#c040c0;fill-opacity:0.1;"; static CSS_NO_TEXTURE: &str = "fill:#c04040;fill-opacity:0.1;"; static CSS_NO_SURFACE: &str = "fill:#40c040;fill-opacity:0.1;"; static CSS_PRIM_COUNT: &str = "fill:#40f0f0;fill-opacity:0.1;"; static CSS_CONTENT: &str = "fill:#f04040;fill-opacity:0.1;"; static CSS_COMPOSITOR_KIND_CHANGED: &str = "fill:#f0c070;fill-opacity:0.1;"; -fn tile_node_to_svg(node: &TileNode, transform: &Transform3D<f32, PicturePixel, WorldPixel>) -> String +fn tile_node_to_svg(node: &TileNode, x: f32, y: f32) -> String { match &node.kind { TileNodeKind::Leaf { .. } => { - let rect_world = transform.transform_rect(&node.rect).unwrap(); - format!("<rect x=\"{:.2}\" y=\"{:.2}\" width=\"{:.2}\" height=\"{:.2}\" />\n", - rect_world.origin.x, - rect_world.origin.y, - rect_world.size.width, - rect_world.size.height) + format!("<rect x=\"{}\" y=\"{}\" width=\"{}\" height=\"{}\" />\n", + (node.rect.origin.x + x) as i32, + (node.rect.origin.y + y) as i32, + node.rect.size.width, node.rect.size.height) }, TileNodeKind::Node { children } => { - children.iter().fold(String::new(), |acc, child| acc + &tile_node_to_svg(child, transform) ) + children.iter().fold(String::new(), |acc, child| acc + &tile_node_to_svg(child, x, y) ) } } } fn tile_to_svg(key: TileOffset, tile: &TileSerializer, slice: &Slice, prev_tile: Option<&TileSerializer>, tile_stroke: &str, prim_class: &str, invalidation_report: &mut String, svg_width: &mut i32, svg_height: &mut i32 ) -> String { - let mut svg = format!("\n<!-- tile key {},{} ; -->\n", key.x, key.y); + let mut svg = format!("\n<!-- tile key {},{} ; slice x {} y {}-->\n", key.x, key.y, slice.x, slice.y); let tile_fill = match tile.invalidation_reason { Some(InvalidationReason::FractionalOffset) => CSS_FRACTIONAL_OFFSET.to_string(), Some(InvalidationReason::BackgroundColor) => CSS_BACKGROUND_COLOR.to_string(), Some(InvalidationReason::SurfaceOpacityChanged) => CSS_SURFACE_OPACITY_CHANNEL.to_string(), Some(InvalidationReason::NoTexture) => CSS_NO_TEXTURE.to_string(), @@ -106,68 +100,69 @@ fn tile_to_svg(key: TileOffset, if let Some(reason) = tile.invalidation_reason { invalidation_report.push_str( &format!("\n<tspan x=\"0\" dy=\"16px\">slice {} tile key ({},{}) invalidated: {:?}</tspan>\n", slice.tile_cache.slice, key.x, key.y, reason)); } svg = format!(r#"{}<rect x="{}" y="{}" width="{}" height="{}" style="{}" ></rect>"#, svg, + //TODO --bpe are these in local space or screen space? tile.rect.origin.x, tile.rect.origin.y, tile.rect.size.width, tile.rect.size.height, tile_style); svg = format!("{}\n\n<g class=\"svg_quadtree\">\n{}</g>\n", svg, - tile_node_to_svg(&tile.root, &slice.transform)); + //tile_node_to_svg(&tile.root, tile.rect.origin.x, tile.rect.origin.y)); + tile_node_to_svg(&tile.root, 0.0, 0.0)); let right = (tile.rect.origin.x + tile.rect.size.width) as i32; let bottom = (tile.rect.origin.y + tile.rect.size.height) as i32; *svg_width = if right > *svg_width { right } else { *svg_width }; *svg_height = if bottom > *svg_height { bottom } else { *svg_height }; svg += "\n<!-- primitives -->\n"; svg = format!("{}<g id=\"{}\">\n\t", svg, prim_class); for prim in &tile.current_descriptor.prims { let rect = prim.prim_clip_rect; - - // the transform could also be part of the CSS, let the browser do it; - // might be a bit faster and also enable actual 3D transforms. - let rect_pixel = Rect { - origin: PicturePoint::new(rect.x, rect.y), - size: PictureSize::new(rect.w, rect.h), - }; - let rect_world = slice.transform.transform_rect(&rect_pixel).unwrap(); + //TODO proper positioning of prims, especially when scrolling + // this version seems closest, but introduces gaps (eg in about:config) + let x = (rect.x + slice.x) as i32; + let y = (rect.y + slice.y) as i32; + // this version is .. interesting: when scrolling, nothing moves in about:config, + // instead the searchbox shifts down.. hmm.. + //let x = rect.x as i32; + //let y = rect.y as i32; + let w = rect.w as i32; + let h = rect.h as i32; let style = if let Some(prev_tile) = prev_tile { // when this O(n^2) gets too slow, stop brute-forcing and use a set or something if prev_tile.current_descriptor.prims.iter().find(|&prim| prim.prim_clip_rect == rect).is_some() { "" } else { "class=\"svg_changed_prim\" " } } else { "class=\"svg_changed_prim\" " }; - svg += &format!("<rect x=\"{:.2}\" y=\"{:.2}\" width=\"{:.2}\" height=\"{:.2}\" {}/>", - svg, - rect_world.origin.x, - rect_world.origin.y, - rect_world.size.width, - rect_world.size.height, - style); + svg = format!(r#"{}<rect x="{}" y="{}" width="{}" height="{}" {}/>"#, + svg, + x, y, w, h, + style); svg += "\n\t"; } svg += "\n</g>\n"; // nearly invisible, all we want is the toolip really let style = "style=\"fill-opacity:0.001;"; @@ -182,18 +177,17 @@ fn tile_to_svg(key: TileOffset, svg } fn slices_to_svg(slices: &[Slice], prev_slices: Option<Vec<Slice>>, svg_width: &mut i32, svg_height: &mut i32, max_slice_index: &mut usize) -> String { - let svg_begin = "<?xml\u{2d}stylesheet type\u{3d}\"text/css\" href\u{3d}\"tilecache_base.css\" ?>\n\ - <?xml\u{2d}stylesheet type\u{3d}\"text/css\" href\u{3d}\"tilecache.css\" ?>\n"; + let svg_begin = "<?xml\u{2d}stylesheet type\u{3d}\"text/css\" href\u{3d}\"tilecache.css\" ?>\n"; let mut svg = String::new(); let mut invalidation_report = String::new(); for slice in slices { let tile_cache = &slice.tile_cache; *max_slice_index = if tile_cache.slice > *max_slice_index { tile_cache.slice } else { *max_slice_index }; @@ -242,17 +236,16 @@ fn slices_to_svg(slices: &[Slice], prev_ + "\n</svg>\n" } fn write_html(output_dir: &Path, svg_files: &[String], intern_files: &[String]) { let html_head = "<!DOCTYPE html>\n\ <html>\n\ <head>\n\ <meta charset=\"UTF-8\">\n\ - <link rel=\"stylesheet\" type=\"text/css\" href=\"tilecache_base.css\"></link>\n\ <link rel=\"stylesheet\" type=\"text/css\" href=\"tilecache.css\"></link>\n\ </head>\n" .to_string(); let html_body = "<body bgcolor=\"#000000\" onload=\"load()\">\n" .to_string(); @@ -307,75 +300,120 @@ fn write_html(output_dir: &Path, svg_fil let html = format!("{}{}{}{}", html_head, html_body, script, html_end); let output_file = output_dir.join("index.html"); let mut html_output = File::create(output_file).unwrap(); html_output.write_all(html.as_bytes()).unwrap(); } fn write_css(output_dir: &Path, max_slice_index: usize) { - let mut css = String::new(); + let mut css = ".tile_svg {\n\ + float: left;\n\ + }\n\ + \n\ + .split {\n\ + position: fixed;\n\ + z-index: 1;\n\ + top: 0;\n\ + padding-top: 20px;\n\ + }\n\ + \n\ + .left {\n\ + left: 0;\n\ + }\n\ + \n\ + .right {\n\ + right: 0;\n\ + width: 20%;\n\ + height: 100%;\n\ + opacity: 90%;\n\ + }\n\ + \n\ + #intern {\n\ + position:relative;\n\ + top:60px;\n\ + width: 100%;\n\ + height: 100%;\n\ + color: orange;\n\ + background-color:white;\n\ + }\n\ + .svg_invalidated {\n\ + fill: white;\n\ + font-family:monospace;\n\ + }\n\n\n\ + #svg_ui_overlay {\n\ + position:absolute;\n\ + right:0; \n\ + top:0; \n\ + z-index:70; \n\ + color: rgb(255,255,100);\n\ + font-family:monospace;\n\ + background-color: #404040a0;\n\ + }\n\n\n\ + .svg_quadtree {\n\ + fill: none;\n\ + stroke-width: 1;\n\ + stroke: orange;\n\ + }\n\n\n\ + .svg_changed_prim {\n\ + stroke: red;\n\ + stroke-width: 2.0;\n\ + }\n\n\n\ + #svg_ui_slider {\n\ + width:90%;\n\ + }\n\n".to_string(); for ix in 0..max_slice_index + 1 { let color = ( ix % 7 ) + 1; let rgb = format!("rgb({},{},{})", if color & 2 != 0 { 205 } else { 90 }, if color & 4 != 0 { 205 } else { 90 }, if color & 1 != 0 { 225 } else { 90 }); let prim_class = format!("tile_slice{}", ix); - css += &format!("#{} {{\n\ + css = format!("{}\n\ + #{} {{\n\ fill: {};\n\ fill-opacity: 0.03;\n\ stroke-width: 0.8;\n\ stroke: {};\n\ - }}\n\n", - prim_class, - //rgb, - "none", - rgb); + }}\n\n", + css, + prim_class, + //rgb, + "none", + rgb); } let output_file = output_dir.join("tilecache.css"); let mut css_output = File::create(output_file).unwrap(); css_output.write_all(css.as_bytes()).unwrap(); } macro_rules! updatelist_to_html_macro { ( $( $name:ident: $ty:ty, )+ ) => { fn updatelist_to_html(update_lists: &TileCacheLoggerUpdateLists) -> String { - let mut html = "\ - <!DOCTYPE html>\n\ - <html> <head> <meta charset=\"UTF-8\">\n\ - <link rel=\"stylesheet\" type=\"text/css\" href=\"tilecache_base.css\"></link>\n\ - <link rel=\"stylesheet\" type=\"text/css\" href=\"tilecache.css\"></link>\n\ - </head> <body>\n".to_string(); - + let mut html = String::new(); $( - html += &format!("<div class=\"intern_header\">{}</div>\n<div class=\"intern_data\">\n", - stringify!($name)); - let mut insert_count = 0; - for update in &update_lists.$name.1.updates { - match update.kind { - UpdateKind::Insert => { - html += &format!("<div class=\"insert\">{} {}</div>\n", - update.index, - format!("({:?})", update_lists.$name.1.data[insert_count])); - insert_count = insert_count + 1; - } - _ => { - html += &format!("<div class=\"remove\">{}</div>\n", - update.index); - } + html += &format!("<h4 style=\"margin:5px;\">{}</h4>\n<font color=\"green\">\n", stringify!($name)); + let mut was_insert = true; + for update in &update_lists.$name.1 { + let is_insert = match update.kind { + UpdateKind::Insert => true, + _ => false }; + if was_insert != is_insert { + html += &format!("</font><font color=\"{}\">", if is_insert { "green" } else { "red" }); + } + html += &format!("{}, \n", update.index); + was_insert = is_insert; } - html += "</div><br/>\n"; + html += &"</font><hr/>\n"; )+ - html += "</body> </html>\n"; html } } } enumerate_interners!(updatelist_to_html_macro); fn write_tile_cache_visualizer_svg(entry: &std::fs::DirEntry, output_dir: &Path, slices: &[Slice], prev_slices: Option<Vec<Slice>>, @@ -466,13 +504,10 @@ fn main() { print!("\r"); prev_slices = Some(slices); } write_html(output_dir, &svg_files, &intern_files); write_css(output_dir, max_slice_index); - std::fs::write(output_dir.join("tilecache.js"), RES_JAVASCRIPT).unwrap(); - std::fs::write(output_dir.join("tilecache_base.css"), RES_BASE_CSS).unwrap(); - - println!("\n"); + println!("OK. For now, manually copy tilecache.js to the output folder please. "); }
deleted file mode 100644 --- a/gfx/wr/tileview/src/tilecache_base.css +++ /dev/null @@ -1,94 +0,0 @@ -.tile_svg { - float: left; -} - -#intern { - position:relative; - top:60px; - width: 100%; - height: 100%; - color: orange; - border: 0px; - overflow: auto; - background: white; -} - -.intern_header { - color: blue; - font-family: Arial; - font-weight: bold; - line-height: 200%; - background-color: lightgrey; - margin-top: 5px; - margin-bottom: 5px; -} - -.intern_data { - font-family: monospace; - font-size: small; -} - -.intern_data .insert:nth-child(even) { - background: #FFFFFF; -} -.intern_data .insert:nth-child(odd) { - background: #EFEFEF; -} - -.intern_data .insert { - color: #008000; -} - -.intern_data .remove { - color: #800000; -} - - - -.split { - position: fixed; - z-index: 1; - top: 0; - padding-top: 14px; -} - -.left { - left: 0; -} - -.right { - right: 0; - width: 25%; - height: 90%; -} - -#svg_ui_overlay { - position:absolute; - right:0; - top:0; - z-index:70; - color: rgb(255,255,100); - font-family:monospace; - background-color: #404040a0; -} - -#svg_ui_slider { - width:90%; -} - -.svg_invalidated { - fill: white; - font-family:monospace; -} - -.svg_quadtree { - fill: none; - stroke-width: 1; - stroke: orange; -} - -.svg_changed_prim { - stroke: red; - stroke-width: 2.0; -} -
--- a/gfx/wr/webrender/src/intern.rs +++ b/gfx/wr/webrender/src/intern.rs @@ -45,23 +45,21 @@ use crate::util::VecHelper; #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] #[derive(Debug, Copy, Clone, MallocSizeOf, PartialEq)] struct Epoch(u64); /// A list of updates to be applied to the data store, /// provided by the interning structure. -#[cfg_attr(feature = "capture", derive(Serialize))] -#[cfg_attr(feature = "replay", derive(Deserialize))] pub struct UpdateList<S> { /// The additions and removals to apply. pub updates: Vec<Update>, /// Actual new data to insert. - pub data: Vec<S>, + data: Vec<S>, } lazy_static! { static ref NEXT_UID: AtomicUsize = AtomicUsize::new(0); } /// A globally, unique identifier #[cfg_attr(feature = "capture", derive(Serialize))]
--- a/gfx/wr/webrender/src/picture.rs +++ b/gfx/wr/webrender/src/picture.rs @@ -75,17 +75,17 @@ use api::{DebugFlags, RasterSpace, Image use api::units::*; use crate::box_shadow::{BLUR_SAMPLE_SCALE}; use crate::clip::{ClipStore, ClipChainInstance, ClipDataHandle, ClipChainId}; use crate::clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX, ClipScrollTree, CoordinateSpaceMapping, SpatialNodeIndex, VisibleFace }; use crate::composite::{CompositorKind, CompositeState, NativeSurfaceId, NativeTileId}; use crate::debug_colors; -use euclid::{vec3, Point2D, Scale, Size2D, Vector2D, Rect, Transform3D}; +use euclid::{vec3, Point2D, Scale, Size2D, Vector2D, Rect}; use euclid::approxeq::ApproxEq; use crate::filterdata::SFilterData; use crate::frame_builder::{FrameVisibilityContext, FrameVisibilityState}; use crate::intern::ItemUid; use crate::internal_types::{FastHashMap, FastHashSet, PlaneSplitter, Filter, PlaneSplitAnchor, TextureSource}; use crate::frame_builder::{FrameBuildingContext, FrameBuildingState, PictureState, PictureContext}; use crate::gpu_cache::{GpuCache, GpuCacheAddress, GpuCacheHandle}; use crate::gpu_types::UvRectKind; @@ -107,33 +107,18 @@ use std::sync::atomic::{AtomicUsize, Ord use crate::texture_cache::TextureCacheHandle; use crate::util::{TransformedRectKind, MatrixHelpers, MaxRect, scale_factors, VecHelper, RectHelpers}; use crate::filterdata::{FilterDataHandle}; #[cfg(any(feature = "capture", feature = "replay"))] use ron; #[cfg(feature = "capture")] use crate::scene_builder_thread::InternerUpdates; #[cfg(any(feature = "capture", feature = "replay"))] -use crate::intern::{Internable, UpdateList}; -#[cfg(any(feature = "capture", feature = "replay"))] -use api::{ClipIntern, FilterDataIntern, PrimitiveKeyKind}; -#[cfg(any(feature = "capture", feature = "replay"))] -use crate::prim_store::backdrop::Backdrop; -#[cfg(any(feature = "capture", feature = "replay"))] -use crate::prim_store::borders::{ImageBorder, NormalBorderPrim}; -#[cfg(any(feature = "capture", feature = "replay"))] -use crate::prim_store::gradient::{LinearGradient, RadialGradient}; -#[cfg(any(feature = "capture", feature = "replay"))] -use crate::prim_store::image::{Image, YuvImage}; -#[cfg(any(feature = "capture", feature = "replay"))] -use crate::prim_store::line_dec::LineDecoration; -#[cfg(any(feature = "capture", feature = "replay"))] -use crate::prim_store::picture::Picture; -#[cfg(any(feature = "capture", feature = "replay"))] -use crate::prim_store::text_run::TextRun; +use crate::intern::Update; + #[cfg(feature = "capture")] use std::fs::File; #[cfg(feature = "capture")] use std::io::prelude::*; #[cfg(feature = "capture")] use std::path::PathBuf; @@ -1503,17 +1488,17 @@ impl BackdropInfo { }, } } } #[derive(Clone)] pub struct TileCacheLoggerSlice { pub serialized_slice: String, - pub local_to_world_transform: Transform3D<f32, PicturePixel, WorldPixel>, + pub local_to_world_transform: DeviceRect } #[cfg(any(feature = "capture", feature = "replay"))] macro_rules! declare_tile_cache_logger_updatelists { ( $( $name:ident : $ty:ty, )+ ) => { #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] struct TileCacheLoggerUpdateListsSerializer { @@ -1524,37 +1509,37 @@ macro_rules! declare_tile_cache_logger_u $( /// Generate storage, one per interner. /// the tuple is a workaround to avoid the need for multiple /// fields that start with $name (macro concatenation). /// the string is .ron serialized updatelist at capture time; /// the updates is the list of DataStore updates (avoid UpdateList /// due to Default() requirements on the Keys) reconstructed at /// load time. - pub $name: (String, UpdateList<<$ty as Internable>::Key>), + pub $name: (String, Vec<Update>), )+ } impl TileCacheLoggerUpdateLists { pub fn new() -> Self { TileCacheLoggerUpdateLists { $( - $name : ( String::new(), UpdateList{ updates: Vec::new(), data: Vec::new()} ), + $name : ( String::new(), Vec::<Update>::new() ), )+ } } /// serialize all interners in updates to .ron #[cfg(feature = "capture")] fn serialize_updates( &mut self, updates: &InternerUpdates ) { $( - self.$name.0 = ron::ser::to_string_pretty(&updates.$name, Default::default()).unwrap(); + self.$name.0 = ron::ser::to_string_pretty(&updates.$name.updates, Default::default()).unwrap(); )+ } fn is_empty(&self) -> bool { $( if !self.$name.0.is_empty() { return false; } )+ true @@ -1562,27 +1547,27 @@ macro_rules! declare_tile_cache_logger_u #[cfg(feature = "capture")] fn to_ron(&self) -> String { let mut serializer = TileCacheLoggerUpdateListsSerializer { ron_string: Vec::new() }; $( serializer.ron_string.push( if self.$name.0.is_empty() { - "( updates: [], data: [] )".to_string() + "[]".to_string() } else { self.$name.0.clone() }); )+ ron::ser::to_string_pretty(&serializer, Default::default()).unwrap() } #[cfg(feature = "replay")] pub fn from_ron(&mut self, text: &str) { - let serializer : TileCacheLoggerUpdateListsSerializer = + let serializer : TileCacheLoggerUpdateListsSerializer = match ron::de::from_str(&text) { Ok(data) => { data } Err(e) => { println!("ERROR: failed to deserialize updatelist: {:?}\n{:?}", &text, e); return; } }; let mut index = 0; @@ -1656,21 +1641,17 @@ impl TileCacheLogger { } } pub fn is_enabled(&self) -> bool { !self.frames.is_empty() } #[cfg(feature = "capture")] - pub fn add( - &mut self, - serialized_slice: String, - local_to_world_transform: Transform3D<f32, PicturePixel, WorldPixel> - ) { + pub fn add(&mut self, serialized_slice: String, local_to_world_transform: DeviceRect) { if !self.is_enabled() { return; } self.frames[self.write_index].slices.push( TileCacheLoggerSlice { serialized_slice, local_to_world_transform }); } @@ -1723,22 +1704,21 @@ impl TileCacheLogger { continue; } let filename = path_tile_cache.join(format!("frame{:05}.ron", files_written)); let mut output = File::create(filename).unwrap(); output.write_all(b"// slice data\n").unwrap(); output.write_all(b"[\n").unwrap(); for item in &self.frames[index].slices { - output.write_all(b"( transform:\n").unwrap(); - let transform = - ron::ser::to_string_pretty( - &item.local_to_world_transform, Default::default()).unwrap(); - output.write_all(transform.as_bytes()).unwrap(); - output.write_all(b",\n tile_cache:\n").unwrap(); + output.write_all(format!("( x: {}, y: {},\n", + item.local_to_world_transform.origin.x, + item.local_to_world_transform.origin.y) + .as_bytes()).unwrap(); + output.write_all(b"tile_cache:\n").unwrap(); output.write_all(item.serialized_slice.as_bytes()).unwrap(); output.write_all(b"\n),\n").unwrap(); } output.write_all(b"]\n\n").unwrap(); output.write_all(b"// @@@ chunk @@@\n\n").unwrap(); output.write_all(b"// interning data\n").unwrap(); @@ -3721,16 +3701,17 @@ impl PicturePrimitive { Picture3DContext::In { root_data: Some(_), .. } => { Some(PlaneSplitter::new()) } Picture3DContext::In { root_data: None, .. } => { None } }; + let unclipped = match self.raster_config { Some(ref raster_config) => { let pic_rect = PictureRect::from_untyped(&self.precise_local_rect.to_untyped()); let device_pixel_scale = frame_state .surfaces[raster_config.surface_index.0] .device_pixel_scale; @@ -4311,18 +4292,20 @@ impl PicturePrimitive { port, }); frame_state.render_tasks.add_dependency( frame_state.surfaces[parent_surface_index.0].render_tasks.unwrap().port, root, ); } + + unclipped } - None => {} + None => DeviceRect::zero() }; #[cfg(feature = "capture")] { if frame_context.debug_flags.contains(DebugFlags::TILE_CACHE_LOGGING_DBG) { if let Some(ref tile_cache) = self.tile_cache { // extract just the fields that we're interested in @@ -4339,23 +4322,24 @@ impl PicturePrimitive { fract_offset: tile.fract_offset, id: tile.id, root: tile.root.clone(), background_color: tile.background_color, invalidation_reason: tile.invalidation_reason.clone() }); } let text = ron::ser::to_string_pretty(&tile_cache_tiny, Default::default()).unwrap(); - tile_cache_logger.add(text, map_pic_to_world.get_transform()); + tile_cache_logger.add(text, unclipped); } } } #[cfg(not(feature = "capture"))] { let _tile_cache_logger = tile_cache_logger; // unused variable fix + let _unclipped = unclipped; } let state = PictureState { //TODO: check for MAX_CACHE_SIZE here? map_local_to_pic, map_pic_to_world, map_pic_to_raster, map_raster_to_world,