SetSize took its declared length out of UiRegion::FULL, which is the box it was already given, so a span that had sized that box from the same hint had the fraction taken twice: .width(rel(0.5)) in a 400-wide span drew its child 100 wide. It held under a Pad or the root, which do not honour a hint, and hid under px, where 200 of a 200-wide box is all of it. The text example was 111,923 pixels from upstream/main because of it. Whoever draws a widget now takes its declared length, in its own box, which is what a fraction of one means, and is the identity for a caller that already reserved the space. rest is not taken: a share of what is left over is only a length to the widget dividing one, so it passes up in the size as it does out of a span. SetSize keeps only what it declares. A declared length is then part of the box its parent decided, so changing one has to redraw the parent; the lengths resolved into a box are kept beside it and compared. Assuming instead that any dirty widget which declares a length needs its parent costs 17% of a frame that dirties 130 of 260 widgets, and buys nothing. All five reference renders, the resize render and the image replay are byte-identical to upstream/main, the 100-seed sweep passes, and the resize fixture is 1.286 ms against 1.289 before. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
51 lines
2.3 KiB
Rust
51 lines
2.3 KiB
Rust
use crate::{
|
|
LayerId, Len, MaskIdx, MoveIdx, PrimitiveHandle, Size, TextureHandle, UiRegion, WidgetId,
|
|
util::Vec2,
|
|
};
|
|
|
|
/// important non rendering data for retained drawing
|
|
#[derive(Debug)]
|
|
pub struct ActiveData {
|
|
pub id: WidgetId,
|
|
pub region: UiRegion,
|
|
/// What the widget said it used of `region`, the last time it drew.
|
|
pub size: Size,
|
|
/// The pixel size of the box it drew against. `region` alone cannot say:
|
|
/// it is a fraction of a slot's box, and the same fraction of a box that
|
|
/// has since changed is a different number of pixels.
|
|
pub px: Vec2,
|
|
/// The pixel size of the box its parent first asked about it in, before
|
|
/// knowing what it came to. `px` may be a box derived from that answer,
|
|
/// and a size measured there is only the same answer asked again.
|
|
pub offered_px: Vec2,
|
|
pub parent: Option<WidgetId>,
|
|
/// How far down the tree it was drawn, the root being 1. Carried down a
|
|
/// draw rather than worked out by walking up, so it is right for every
|
|
/// widget a frame visits and cannot drift while one is being drawn.
|
|
pub depth: usize,
|
|
pub textures: Vec<TextureHandle>,
|
|
pub primitives: Vec<PrimitiveHandle>,
|
|
pub children: Vec<WidgetId>,
|
|
/// The children whose size this widget read while drawing.
|
|
pub size_deps: Vec<WidgetId>,
|
|
/// Offered pixel axes which flowed into this widget's reported size,
|
|
/// directly or through a child size it read.
|
|
pub size_box_inputs: [bool; 2],
|
|
/// Output axes read while producing `size`, distinct from the widget's
|
|
/// own box when that box has a fixed pixel length.
|
|
pub size_output_inputs: [bool; 2],
|
|
/// The output dimensions against which those dependencies were observed.
|
|
pub output_px: Vec2,
|
|
/// The slot its primitives are positioned through: its own if its parent
|
|
/// placed it, otherwise the nearest ancestor that has one.
|
|
pub move_idx: MoveIdx,
|
|
/// The declared lengths whoever drew this widget resolved into its box.
|
|
/// A change to one moves a box this widget cannot fix by drawing again,
|
|
/// and comparing them is what says so.
|
|
pub declared: [Option<Len>; 2],
|
|
/// The slot `region` is given in, which is whatever its parent drew in.
|
|
pub parent_move: MoveIdx,
|
|
pub mask: MaskIdx,
|
|
pub layer: LayerId,
|
|
}
|