diff --git a/crates/gpu/src/fx.rs b/crates/gpu/src/fx.rs index 972ccadbea..4f265a3202 100644 --- a/crates/gpu/src/fx.rs +++ b/crates/gpu/src/fx.rs @@ -336,8 +336,10 @@ fn bands(r: Rect, rows: i32) -> Vec { let mut out = Vec::new(); let mut y = r.y0; while y < r.y1 { - out.push(Rect::new(r.x0, y, r.x1, (y + rows).min(r.y1))); - y += rows; + // Saturating near the coordinate ceiling: a wrapped edge would never reach `y1`. + let end = y.saturating_add(rows.max(1)).min(r.y1); + out.push(Rect::new(r.x0, y, r.x1, end)); + y = end; } out } diff --git a/crates/gpu/src/fx/tests.rs b/crates/gpu/src/fx/tests.rs index 1622da28e2..d796288eeb 100644 --- a/crates/gpu/src/fx/tests.rs +++ b/crates/gpu/src/fx/tests.rs @@ -308,3 +308,12 @@ fn shape_tiles_and_group_pins_hold_addresses_not_pixels() { drop(group); assert!(pins.iter().all(|w| w.strong_count() == 0), "a group's pins keep none of its pixels"); } + +#[test] +fn bands_end_at_the_coordinate_ceiling() { + let r = Rect::new(0, i32::MAX - 100, 8, i32::MAX); + let bands = super::bands(r, 64); + assert_eq!(bands.len(), 2, "{bands:?}"); + assert_eq!((bands[0].y0, bands[0].y1, bands[1].y1), (i32::MAX - 100, i32::MAX - 36, i32::MAX)); + assert_eq!(super::bands(Rect::new(0, 0, 8, 10), 0).len(), 10, "a zero step still makes progress"); +}