M8: a test for stacked background blurs drawn in bands; the eight-band wording

From the review of #1496: three background blurs stacked on each other across the band
boundaries draw the same in bands as in one piece (within anti-aliasing), so the bands'
overlap, the reach of the largest blur, is enough, as it is for the desktop's parallel bands;
pinned by a test. The docs and the `MAX_BANDS` comment no longer put the longest frame at "an
eighth of the render": a frame draws at least a band, a part of the render rather than the
whole, and the numbers measured for #1496 are cited instead.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
samhyun
2026-10-29 23:08:12 +09:00
co-authored by Claude Fable 5.1
parent 6d8b0e68f0
commit 3f896453b6
3 changed files with 35 additions and 5 deletions
+28
View File
@@ -345,3 +345,31 @@ fn a_reused_or_patched_render_needs_no_steps() {
let panned = View { origin: (12.0, 0.0), ..v };
assert!(matches!(r.begin(&s.doc, s.page, &panned, &Options::default(), 40), Some(crate::Begun::Done(_, _, Work::Partial { .. }))));
}
/// Background blurs stacked on each other (the upper reads the lower's blurred pixels) across the
/// band boundaries: the bands' overlap, the reach of the largest blur, is enough for the image to
/// match one drawn in one piece, as it is for the desktop's parallel bands.
#[test]
fn stacked_backdrop_blurs_draw_the_same_in_bands() {
fonts();
let mut d = Document::new("stacked");
let page = d.first_page().unwrap();
// Stripes to blur, then three translucent blurred panels overlapping each other.
for i in 0..40 {
let r = d.create(page, NodeKind::Rectangle, "S", 0.0, f64::from(i) * 10.0, 400.0, 5.0).unwrap();
solid(d.get_mut(r).unwrap(), if i % 2 == 0 { "E03030" } else { "3070E0" });
}
for (x, y) in [(40.0, 60.0), (120.0, 120.0), (60.0, 200.0)] {
let b = d.create(page, NodeKind::Rectangle, "B", x, y, 220.0, 160.0).unwrap();
d.get_mut(b).unwrap().fills = vec![Paint::solid(Color::new(1.0, 1.0, 1.0, 0.25))];
d.get_mut(b).unwrap().effects.push(Effect { kind: EffectKind::BackgroundBlur(figcraft_doc::Blur::uniform(24.0)), visible: true });
}
let doc = Arc::new(d);
let v = View { origin: (0.0, 0.0), scale: 1.0, width: 400, height: 400 };
for band_h in [64, 100, 200] {
let mut r = Retained::default();
let (shown, pix, n) = stepped(&mut r, &doc, page, &v, band_h);
assert!(n >= 3, "{n} bands of {band_h} rows");
assert_same(&pix, &render_view(&doc, page, &shown, &Options::default()).unwrap(), &format!("bands of {band_h} rows"));
}
}
+4 -3
View File
@@ -42,9 +42,10 @@ pub const SETTLE_MS: u64 = 120;
pub const STEP_MS: f64 = 24.0;
/// Bands are at least this many rows ...
const MIN_BAND_ROWS: u32 = 64;
/// ... and a view has at most this many: the longest frame of a render drawn in steps is about a
/// band's, an eighth of the render plus its overlap (more bands would repeat more of the overlap
/// and of the per-band work).
/// ... and a view has at most this many: a frame draws at least one band, so the longest frame of
/// a render drawn in steps is about a band's time, a part of the render rather than the whole of it
/// (0.7–1.4 s where the render took 3.7–4.0 s, measured for #1496; more bands would repeat more of
/// the overlap and of the per-band work).
const MAX_BANDS: u32 = 8;
#[derive(Clone)]
+3 -2
View File
@@ -274,8 +274,9 @@ No alpha blockers: the alpha gate in [`roadmap.md`](roadmap.md#alpha-gate) passe
page, a zoom after quick renders), a watchdog thread previews any such render still running
after 12 ms (desktop only; the browser renders inline).
- **Landed (2026-10-29):** the browser draws a zoom's full render a band at a time (`Retained::begin`,
`Steps`; at most eight bands, so the longest frame is about an eighth of the render where it was
the whole of it), so input is handled while it draws: a pan or an edit meanwhile is patched into
`Steps`; at least a band a frame and at most eight bands, so a frame draws a part of the render
where it drew the whole of it: 0.7–1.4 s where the render took 3.7–4.0 s in the measurement of
#1496), so input is handled while it draws: a pan or an edit meanwhile is patched into
the render once drawn (or it is drawn again, the first shown till then), a zoom drops it. Bands
overlap by what background blurs read, as the desktop's parallel bands do, and the bands together
take longer than one render (each repeats its overlap and some per-band work).