Coalesce resize layout diagnostics
This commit is contained in:
1 parent
480f0bc99f
commit
82fa6c1123
7 files changed
+316
-28
No files matched your search
+61
-24
@@ -1,5 +1,5 @@
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
use crate::layout_diagnostics::{self as diag, Counter, TimerKind};
|
||||
use crate::layout_diagnostics::{self as diag, Counter, ReuseOutcome, TimerKind};
|
||||
use crate::{
|
||||
ActiveData, Axis, DrawLayers, IdLike, MaskIdx, MoveIdx, Moves, OnResize, Painter, PixelRegion,
|
||||
Size, StrongWidget, UiRegion, UiRsc, WidgetId, Widgets,
|
||||
@@ -37,8 +37,11 @@ impl UiRenderState {
|
||||
}
|
||||
|
||||
pub fn resize(&mut self, size: impl Into<Vec2>) {
|
||||
self.output_size = size.into();
|
||||
self.resized = true;
|
||||
let size = size.into();
|
||||
if size != self.output_size {
|
||||
self.output_size = size;
|
||||
self.resized = true;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn output_size(&self) -> Vec2 {
|
||||
@@ -77,11 +80,17 @@ impl UiRenderState {
|
||||
{
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
let _marking = diag::timer(TimerKind::ResizeMarking);
|
||||
for (&id, active) in &self.active {
|
||||
if active.reads_output {
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
diag::bump(Counter::ResizeDependents);
|
||||
rsc.widgets_mut().needs_redraw.insert(id);
|
||||
let dependents: Vec<_> = self
|
||||
.active
|
||||
.iter()
|
||||
.filter_map(|(&id, active)| active.reads_output.then_some(id))
|
||||
.collect();
|
||||
for id in dependents {
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
diag::bump(Counter::ResizeDependents);
|
||||
rsc.widgets_mut().needs_redraw.insert(id);
|
||||
if let Some(top) = self.mark_readers(id, rsc) {
|
||||
rsc.widgets_mut().needs_redraw.insert(top);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,7 +136,10 @@ impl UiRenderState {
|
||||
rsc: &mut dyn UiRsc,
|
||||
) -> Size {
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
diag::bump(Counter::DrawRequests);
|
||||
{
|
||||
diag::bump(Counter::DrawRequests);
|
||||
diag::draw_request(id, parent, region, self.px_of(parent_move, region), slotted);
|
||||
}
|
||||
let mut old_children = old_children.unwrap_or_default();
|
||||
if self.active.contains_key(&id) {
|
||||
if let Some(size) = self.try_reuse(id, region, parent_move, rsc) {
|
||||
@@ -175,6 +187,8 @@ impl UiRenderState {
|
||||
let mut widget = painter.rsc.widgets().get_dyn_dynamic(id);
|
||||
let size = widget.draw(&mut painter);
|
||||
drop(widget);
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
diag::size_reported(id, size);
|
||||
|
||||
let Painter {
|
||||
state: _,
|
||||
@@ -271,7 +285,10 @@ impl UiRenderState {
|
||||
diag::bump(Counter::ReuseAttempts);
|
||||
if rsc.widgets().needs_redraw.contains(&id) {
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
diag::bump(Counter::ReuseDirty);
|
||||
{
|
||||
diag::bump(Counter::ReuseDirty);
|
||||
diag::reuse(id, ReuseOutcome::Dirty);
|
||||
}
|
||||
return None;
|
||||
}
|
||||
let active = self.active.get(&id)?;
|
||||
@@ -279,7 +296,10 @@ impl UiRenderState {
|
||||
// longer sits in, and its slot names the wrong parent.
|
||||
if active.parent_move != parent_move {
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
diag::bump(Counter::ReuseWrongParent);
|
||||
{
|
||||
diag::bump(Counter::ReuseWrongParent);
|
||||
diag::reuse(id, ReuseOutcome::WrongParent);
|
||||
}
|
||||
return None;
|
||||
}
|
||||
let (size, old_region, slot, old_px) =
|
||||
@@ -294,7 +314,10 @@ impl UiRenderState {
|
||||
}
|
||||
if !changed.iter().any(|&c| c) && old_region == region {
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
diag::bump(Counter::ReuseExact);
|
||||
{
|
||||
diag::bump(Counter::ReuseExact);
|
||||
diag::reuse(id, ReuseOutcome::Exact);
|
||||
}
|
||||
return Some(size);
|
||||
}
|
||||
// Only a placed widget can be given a different box without drawing
|
||||
@@ -302,7 +325,10 @@ impl UiRenderState {
|
||||
// entry says where all of it went.
|
||||
if slot == parent_move {
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
diag::bump(Counter::ReuseUnslotted);
|
||||
{
|
||||
diag::bump(Counter::ReuseUnslotted);
|
||||
diag::reuse(id, ReuseOutcome::Unslotted);
|
||||
}
|
||||
return None;
|
||||
}
|
||||
if changed.iter().any(|&c| c) {
|
||||
@@ -316,12 +342,18 @@ impl UiRenderState {
|
||||
// and has to lay out around what it comes to.
|
||||
if redraws {
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
diag::bump(Counter::ReuseOwnResize);
|
||||
{
|
||||
diag::bump(Counter::ReuseOwnResize);
|
||||
diag::reuse(id, ReuseOutcome::OwnResize);
|
||||
}
|
||||
return None;
|
||||
}
|
||||
if self.redraws_under(id, changed, rsc) {
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
diag::bump(Counter::ReuseDescendantResize);
|
||||
{
|
||||
diag::bump(Counter::ReuseDescendantResize);
|
||||
diag::reuse(id, ReuseOutcome::DescendantResize);
|
||||
}
|
||||
return None;
|
||||
}
|
||||
}
|
||||
@@ -330,7 +362,10 @@ impl UiRenderState {
|
||||
active.region = region;
|
||||
active.px = px;
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
diag::bump(Counter::ReuseMoved);
|
||||
{
|
||||
diag::bump(Counter::ReuseMoved);
|
||||
diag::reuse(id, ReuseOutcome::Moved);
|
||||
}
|
||||
Some(size)
|
||||
}
|
||||
|
||||
@@ -446,14 +481,16 @@ impl UiRenderState {
|
||||
let _layout = diag::timer(TimerKind::IncrementalLayout);
|
||||
// A reader's answer is only valid after every dirty size it reads has
|
||||
// settled. Equal-depth widgets are independent, so their order does
|
||||
// not matter.
|
||||
while let Some(id) = rsc
|
||||
.widgets()
|
||||
.needs_redraw
|
||||
.iter()
|
||||
.copied()
|
||||
.max_by_key(|&id| self.depth(id))
|
||||
{
|
||||
// not matter. Resize dirtiness already marks whole reader chains, so
|
||||
// choosing their shallowest roots coalesces descendants that share a
|
||||
// reader and gives each changing box its final constraints first.
|
||||
while let Some(id) = {
|
||||
let dirty = rsc.widgets().needs_redraw.iter().copied();
|
||||
match self.resized {
|
||||
true => dirty.min_by_key(|&id| self.depth(id)),
|
||||
false => dirty.max_by_key(|&id| self.depth(id)),
|
||||
}
|
||||
} {
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
diag::bump(Counter::QueuePops);
|
||||
self.redraw(id, rsc);
|
||||
|
||||
Reference in new issue
Block a user