Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync changes from mozilla-central gfx/wr #3846

Merged
merged 4 commits into from Jan 29, 2020
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Bug 1605283 - Improve support for invalidation debugging and testing …

…r=gw a=reland CLOSED TREE

Third iteration:

Fix broken scrolling (and incorrect positioning of quad tree lines) by
serializing the SpaceMapper(-transform) from take_context, and using it
to transform the primitive rects (instead of the previous translation
based on unclipped.origin);
Note: this is done at visualization time and not at export time to
distinguish actually moving elements from merely-scrolling ones.

Serialize the entire UpdateList, so we get the data (Keys) that's being
added; add it to the overview;

Move the static CSS code into tilecache_base.css; add this and the .js
file to the binary, write them as part of output (instead of manual
copy); clean up CSS a bit;

Differential Revision: https://phabricator.services.mozilla.com/D61049

[ghsync] From https://hg.mozilla.org/mozilla-central/rev/748cc6e57cd0b0fab4357ae38eb5bdae505afdac
  • Loading branch information
bpeersmoz authored and moz-gfx committed Jan 29, 2020
commit c1f961dcff2be6f589ff0c5df185b189e0d257eb

Some generated files are not rendered by default. Learn more.

@@ -12,3 +12,4 @@ 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"] }
@@ -12,11 +12,15 @@ 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 x: f32,
pub y: f32,
pub transform: Transform3D<f32, PicturePixel, WorldPixel>,
pub tile_cache: TileCacheInstanceSerializer
}

@@ -30,17 +34,19 @@ 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, x: f32, y: f32) -> String
fn tile_node_to_svg(node: &TileNode, transform: &Transform3D<f32, PicturePixel, WorldPixel>) -> String
{
match &node.kind {
TileNodeKind::Leaf { .. } => {
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)
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)
},
TileNodeKind::Node { children } => {
children.iter().fold(String::new(), |acc, child| acc + &tile_node_to_svg(child, x, y) )
children.iter().fold(String::new(), |acc, child| acc + &tile_node_to_svg(child, transform) )
}
}
}
@@ -54,7 +60,7 @@ fn tile_to_svg(key: TileOffset,
invalidation_report: &mut String,
svg_width: &mut i32, svg_height: &mut i32 ) -> String
{
let mut svg = format!("\n<!-- tile key {},{} ; slice x {} y {}-->\n", key.x, key.y, slice.x, slice.y);
let mut svg = format!("\n<!-- tile key {},{} ; -->\n", key.x, key.y);


let tile_fill =
@@ -105,7 +111,6 @@ fn tile_to_svg(key: TileOffset,

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,
@@ -114,8 +119,7 @@ fn tile_to_svg(key: TileOffset,

svg = format!("{}\n\n<g class=\"svg_quadtree\">\n{}</g>\n",
svg,
//tile_node_to_svg(&tile.root, tile.rect.origin.x, tile.rect.origin.y));
tile_node_to_svg(&tile.root, 0.0, 0.0));
tile_node_to_svg(&tile.root, &slice.transform));

let right = (tile.rect.origin.x + tile.rect.size.width) as i32;
let bottom = (tile.rect.origin.y + tile.rect.size.height) as i32;
@@ -131,16 +135,14 @@ fn tile_to_svg(key: TileOffset,

for prim in &tile.current_descriptor.prims {
let rect = prim.prim_clip_rect;
//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;

// 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();

let style =
if let Some(prev_tile) = prev_tile {
@@ -154,10 +156,13 @@ fn tile_to_svg(key: TileOffset,
"class=\"svg_changed_prim\" "
};

svg = format!(r#"{}<rect x="{}" y="{}" width="{}" height="{}" {}/>"#,
svg,
x, y, w, h,
style);
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 += "\n\t";
}
@@ -182,7 +187,8 @@ 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.css\" ?>\n";
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 mut svg = String::new();
let mut invalidation_report = String::new();
@@ -241,6 +247,7 @@ fn write_html(output_dir: &Path, svg_files: &[String], intern_files: &[String])
<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();
@@ -305,61 +312,7 @@ fn write_html(output_dir: &Path, svg_files: &[String], intern_files: &[String])
}

fn write_css(output_dir: &Path, max_slice_index: usize) {
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();
let mut css = String::new();

for ix in 0..max_slice_index + 1 {
let color = ( ix % 7 ) + 1;
@@ -370,18 +323,16 @@ fn write_css(output_dir: &Path, max_slice_index: usize) {

let prim_class = format!("tile_slice{}", ix);

css = format!("{}\n\
#{} {{\n\
css += &format!("#{} {{\n\
fill: {};\n\
fill-opacity: 0.03;\n\
stroke-width: 0.8;\n\
stroke: {};\n\
}}\n\n",
css,
prim_class,
//rgb,
"none",
rgb);
}}\n\n",
prim_class,
//rgb,
"none",
rgb);
}

let output_file = output_dir.join("tilecache.css");
@@ -392,23 +343,34 @@ fn write_css(output_dir: &Path, max_slice_index: usize) {
macro_rules! updatelist_to_html_macro {
( $( $name:ident: $ty:ty, )+ ) => {
fn updatelist_to_html(update_lists: &TileCacheLoggerUpdateLists) -> String {
let mut html = String::new();
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();

$(
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
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);
}
};
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 += &"</font><hr/>\n";
html += "</div><br/>\n";
)+
html += "</body> </html>\n";
html
}
}
@@ -509,5 +471,8 @@ fn main() {
write_html(output_dir, &svg_files, &intern_files);
write_css(output_dir, max_slice_index);

println!("OK. For now, manually copy tilecache.js to the output folder please. ");
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");
}
@@ -0,0 +1,94 @@
.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;
}

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.