iris: a Rect is not size-independent, and P1a's block appearance verified
The defect P1a's screenshots found, and the one that mattered: `Rect::is_size_independent()` answered `true`. A `Rect` fills whatever region it is handed, so its content *is* the region -- and `draw_inner`'s fast path, which rewrites a widget's primitives with `r.outside(&from).within(®ion)` instead of redrawing it, cannot reproduce that once a region carries both `rel` and `abs`. What it looked like: a fenced code block's background kept the height of the provisional full-region draw `Span` does in its first phase, so one fence's panel covered every block below it and every row below that, with the text underneath laid out correctly. Likely the same cause as RUST.md's older "the composer bar's grey background is not drawn". Also here: a quote's bar is a `Stack` background behind padded text rather than a two-child `Span(Dir::RIGHT)` (one widget fewer and no provisional pass), and `transcript-ui`'s `transcript` example gains a row holding one of every block kind -- the fixture's own heading, paragraph, fence and table source, plus a list and a quote, which the fixture has neither of. docs/bench/p1a-2026-09-06/ has the pairs and docs/RUST.md's P1a box names what still differs. The iris half is from the desktop backend because this emulator cannot draw iris's glyphs at all (solid boxes, reproduced on the previous commit, with Compose drawing text correctly on the same AVD); both routes to Vulkan on this AVD were tried and both fail. Bench stream phase, assertions live, no abort: p50 53.0ms p90 108.6ms p99 132.0ms against 52.8/108.1/137.3 before -- unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
64f64b54e5
commit
69525bd131
11 files changed
+355
-34
No files matched your search
+23
-1
@@ -47,8 +47,30 @@ impl Widget for Rect {
|
||||
Size::REST // fills whatever it was given -- used == available
|
||||
}
|
||||
|
||||
/// **No** -- despite drawing one primitive and nothing else.
|
||||
///
|
||||
/// `is_size_independent` asks whether the widget's *content* is
|
||||
/// unaffected by how big a region it was given, so that
|
||||
/// `draw_inner` may keep the primitives it already has and rewrite
|
||||
/// their regions in place. A `Rect`'s content **is** its region: it
|
||||
/// returns `Size::REST` and fills whatever it was handed, so the fast
|
||||
/// path's `r.outside(&from).within(®ion)` remap has to reproduce
|
||||
/// the whole of `draw` -- and it does not, because a region carries
|
||||
/// `rel` and `abs` components that the round trip cannot recover
|
||||
/// separately.
|
||||
///
|
||||
/// What that looked like: a fenced code block's background
|
||||
/// (`transcript-ui`'s `BlockFrame::Verbatim`, a `Rect` behind a
|
||||
/// `Pad` in a `Stack`) kept the height of the *provisional* full-
|
||||
/// region draw `Span` does in its first phase, so one fence's panel
|
||||
/// covered every block below it -- and every row below that -- while
|
||||
/// the text itself was laid out correctly. Visible in
|
||||
/// `docs/bench/p1a-2026-09-06/`'s history and reproduced by this
|
||||
/// crate's `transcript` example. Answering `false` costs a redraw of
|
||||
/// one primitive when a rect is resized, which is what the fast path
|
||||
/// was saving.
|
||||
fn is_size_independent(&self) -> bool {
|
||||
true // content never depends on region size
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -91,14 +91,48 @@ fn synthetic_rows() -> Vec<FoldedRow> {
|
||||
},
|
||||
]),
|
||||
msg(6, true, "Looks good, thanks!"),
|
||||
msg(
|
||||
7,
|
||||
false,
|
||||
"You're welcome. Let me know if you'd like anything else.",
|
||||
),
|
||||
// Every block kind `client_core::markdown_blocks` names, in one
|
||||
// row, so P1a's appearance can be looked at against the Compose
|
||||
// app's without a server (docs/RUST.md's P1a box). The heading,
|
||||
// paragraph, fence and table are the *same source* the bench
|
||||
// fixture carries (`app/bench-fixture/generate.py`), so the two
|
||||
// screenshots differ only in the renderer; the list and the quote
|
||||
// are extra, because the fixture has neither.
|
||||
msg(7, false, BLOCK_SAMPLER),
|
||||
]
|
||||
}
|
||||
|
||||
/// One of each markdown block, for the P1a screenshot pair. See
|
||||
/// [`synthetic_rows`].
|
||||
const BLOCK_SAMPLER: &str = "\
|
||||
## What changed
|
||||
|
||||
Iris **fold** render measure session window anchor context transcript \
|
||||
iris measure iris scroll call transcript layout *cursor* context, and a \
|
||||
[bench](https://example.com/bench) link.
|
||||
|
||||
```rust
|
||||
fn fold_event(items: Vec<Item>, seq: u64) -> Vec<Item> {
|
||||
// a comment worth keeping: this is the fold the app's own screen runs
|
||||
let mut out = items;
|
||||
out.push(Item::new(seq));
|
||||
out
|
||||
}
|
||||
```
|
||||
|
||||
| column | value |
|
||||
|---|---|
|
||||
| a | measure place draw tool call token context window anchor |
|
||||
|
||||
- one bullet
|
||||
- another, with `inline code`
|
||||
- nested one level
|
||||
1. first numbered
|
||||
2. second numbered
|
||||
|
||||
> A quoted line, to show the bar and the indent.
|
||||
";
|
||||
|
||||
impl DefaultAppState for Client {
|
||||
fn new(
|
||||
mut ui_state: DefaultUiState,
|
||||
|
||||
@@ -273,12 +273,20 @@ where
|
||||
.width(rest(1))
|
||||
.add_strong(rsc)
|
||||
.any(),
|
||||
BlockFrame::Quote => (
|
||||
rect(crate::markdown::QUOTE_BAR_COLOR).width(dp(QUOTE_BAR_DP)),
|
||||
field.width(rest(1)),
|
||||
)
|
||||
.span(Dir::RIGHT)
|
||||
.gap(dp(FRAME_PAD_DP))
|
||||
// A `Stack` (through `background`) rather than a two-child
|
||||
// `Span(Dir::RIGHT)`: the bar is drawn behind text padded past
|
||||
// it, which is the same picture with one widget fewer and
|
||||
// without `Span`'s provisional full-region pass. That pass is
|
||||
// also what first surfaced the `mov`-then-`reposition` assert
|
||||
// docs/RUST.md's P1a box records as still open, so the shape
|
||||
// with fewer passes is the one to prefer here.
|
||||
BlockFrame::Quote => field
|
||||
.width(rest(1))
|
||||
.pad(Padding {
|
||||
left: dp(QUOTE_BAR_DP + FRAME_PAD_DP),
|
||||
..Padding::ZERO
|
||||
})
|
||||
.background(rect(crate::markdown::QUOTE_BAR_COLOR).width(dp(QUOTE_BAR_DP)))
|
||||
.width(rest(1))
|
||||
.add_strong(rsc)
|
||||
.any(),
|
||||
|
||||
Reference in new issue
Block a user