A region is a fraction of the output plus an offset and the shader resolves it against the window every frame, so a resize already moves the whole drawing without the CPU. Wiping the tree and drawing it again was throwing that away. `Painter::output_size` and `px_size` now record that a widget read pixels, the way reading a child's size records a dependency on it, and a resize marks only those. In the `text` example that is the two wrapping paragraphs out of forty-odd widgets; everything else keeps its drawing and the window uniform puts it in the right place. Two defects the change surfaced, both of which made a resize land somewhere a cold start would not: `redraw` climbed to the highest reader of the changed widget and drew from there, trusting that draw to reach back down. It does not: an intermediate whose own box has not changed is reused as it stands and the draw stops there. Everything between the two is now marked as well, which is the only thing that stops the reuse. Not resize-specific -- `a_change_two_levels_under_its_reader_still_reaches_it` fails on the mutation path too. `mov` cannot stretch a drawing out of a box with no relative extent. `UiScalar::within` puts a part into such a box as a plain offset from its start, and `lerp_inv`'s divide-by-zero fallback then returns a rel of 0 rather than saying it cannot invert, so the remap silently leaves the drawing its old size. `OnResize::Scale` now only reuses across a length change when the old box had a relative extent. The underlying loss belongs to the position chain, which separates the drawn box from the offered one; until then this is the honest predicate. Checked: fmt, clippy and 33 tests. `tabs` (with the image replay), `view`, `minimal` still byte-identical to `upstream/main`, and `text` unchanged at 1920x1200 and 900x1200. Driven live under the GPU as well: started at 1920x1200, resized to 900x1200 and back through sway, and each screenshot matches a cold start at that size byte for byte.
21 lines
726 B
Rust
21 lines
726 B
Rust
use crate::{LayerId, MaskIdx, PrimitiveHandle, Size, TextureHandle, UiRegion, WidgetId};
|
|
|
|
/// 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,
|
|
pub parent: Option<WidgetId>,
|
|
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>,
|
|
/// Whether it read the output's size, and so is wrong when that changes.
|
|
pub reads_output: bool,
|
|
pub mask: MaskIdx,
|
|
pub layer: LayerId,
|
|
}
|