Bug 1673320 - Dump color linear and glyph texture cache arrays as SVG during frame captures. r=jnicol

The visualization shows texture arrays (one array per row) with allocations in blue and free space in dark gray, as well as the slab size for each region. This only dumps the texture arrays for color+linear images and glyphs since most of the interesting stuff is there, but adding other arrays will be simple if needed.

Differential Revision: https://phabricator.services.mozilla.com/D94715
This commit is contained in:
Nicolas Silva 2020-10-27 09:34:38 +00:00
Родитель 34dff9ebd1
Коммит 23aba1fe38
2 изменённых файлов: 89 добавлений и 2 удалений

Просмотреть файл

@ -1740,13 +1740,21 @@ impl RenderBackend {
let file_name = format!("scratch-{}-{}", id.namespace_id.0, id.id);
config.serialize_for_frame(&doc.scratch.primitive, file_name);
let file_name = format!("render-tasks-{}-{}.svg", id.namespace_id.0, id.id);
let mut svg_file = fs::File::create(&config.file_path_for_frame(file_name, "svg"))
let mut render_tasks_file = fs::File::create(&config.file_path_for_frame(file_name, "svg"))
.expect("Failed to open the SVG file.");
dump_render_tasks_as_svg(
&rendered_document.frame.render_tasks,
&rendered_document.frame.passes,
&mut svg_file
&mut render_tasks_file
).unwrap();
let file_name = format!("texture-cache-color-linear-{}-{}.svg", id.namespace_id.0, id.id);
let mut texture_file = fs::File::create(&config.file_path_for_frame(file_name, "svg"))
.expect("Failed to open the SVG file.");
self.resource_cache.texture_cache.dump_color8_linear_as_svg(&mut texture_file).unwrap();
let file_name = format!("texture-cache-glyphs-{}-{}.svg", id.namespace_id.0, id.id);
let mut texture_file = fs::File::create(&config.file_path_for_frame(file_name, "svg"))
.expect("Failed to open the SVG file.");
self.resource_cache.texture_cache.dump_glyphs_as_svg(&mut texture_file).unwrap();
}
let data_stores_name = format!("data-stores-{}-{}", id.namespace_id.0, id.id);

Просмотреть файл

@ -912,6 +912,14 @@ impl TextureCache {
}
}
pub fn dump_color8_linear_as_svg(&self, output: &mut dyn std::io::Write) -> std::io::Result<()> {
self.shared_textures.array_color8_linear.dump_as_svg(output)
}
pub fn dump_glyphs_as_svg(&self, output: &mut dyn std::io::Write) -> std::io::Result<()> {
self.shared_textures.array_color8_glyphs.dump_as_svg(output)
}
/// Expire picture cache tiles that haven't been referenced in the last frame.
/// The picture cache code manually keeps tiles alive by calling `request` on
/// them if it wants to retain a tile that is currently not visible.
@ -1581,6 +1589,77 @@ impl TextureArray {
shader
}
}
#[allow(dead_code)]
pub fn dump_as_svg(&self, output: &mut dyn std::io::Write) -> std::io::Result<()> {
use svg_fmt::*;
let num_arrays = self.units.len() as f32;
let num_layers = self.layers_per_allocation as f32;
let text_spacing = 15.0;
let array_spacing = 60.0;
let layer_spacing = 10.0;
let layer_size = 100.0;
let svg_w = array_spacing * 2.0 + num_layers * (layer_size + layer_spacing);
let svg_h = layer_spacing * 2.0 + num_arrays * (text_spacing * 2.0 + array_spacing + layer_size);
writeln!(output, "{}", BeginSvg { w: svg_w, h: svg_h })?;
// Background.
writeln!(output,
" {}",
rectangle(0.0, 0.0, svg_w, svg_h)
.inflate(1.0, 1.0)
.fill(rgb(50, 50, 50))
)?;
let mut x = array_spacing;
let mut y = array_spacing;
for unit in &self.units {
writeln!(output, " {}", text(x, y, format!("{:?}", unit.texture_id)).color(rgb(230, 230, 230)))?;
for region in &unit.regions {
let slab_size = region.slab_size;
let y = y + text_spacing;
let region_text = if slab_size.width == 0 {
"(empty)".to_string()
} else {
format!("{}x{}", slab_size.width, slab_size.height)
};
writeln!(output, " {}", text(x, y, region_text).color(rgb(230, 230, 230)))?;
let y = y + text_spacing;
// Texture array layer.
let layer_background = if region.is_empty() { rgb(30, 30, 30) } else { rgb(40, 40, 130) };
writeln!(output, " {}", rectangle(x, y, layer_size, layer_size).inflate(1.0, 1.0).fill(rgb(10, 10, 10)))?;
writeln!(output, " {}", rectangle(x, y, layer_size, layer_size).fill(layer_background))?;
let sw = (slab_size.width as f32 / 512.0) * layer_size;
let sh = (slab_size.height as f32 / 512.0) * layer_size;
for slot in &region.free_slots {
let sx = x + slot.0 as f32 * sw;
let sy = y + slot.1 as f32 * sh;
// Allocation slot.
writeln!(output, " {}", rectangle(sx, sy, sw, sh).inflate(-0.5, -0.5).fill(rgb(30, 30, 30)))?;
}
x += layer_spacing + layer_size;
}
y += array_spacing + layer_size;
x = array_spacing;
}
writeln!(output, "{}", EndSvg)
}
}