diff --git a/examples/scenes/src/test_scenes.rs b/examples/scenes/src/test_scenes.rs index 5e895e0fa..eda63de68 100644 --- a/examples/scenes/src/test_scenes.rs +++ b/examples/scenes/src/test_scenes.rs @@ -78,6 +78,7 @@ export_scenes!( longpathdash_round(impls::longpathdash(Cap::Round), "longpathdash (round caps)", false), mmark(crate::mmark::MMark::new(80_000), "mmark", false), many_draw_objects(many_draw_objects), + many_bins(many_bins) ); /// Implementations for the test scenes. @@ -1694,4 +1695,19 @@ mod impls { splash_screen(scene, params); } } + + /// A reproduction for + pub(super) fn many_bins(scene: &mut Scene, params: &mut SceneParams) { + params.resolution = Some(Vec2 { + x: 256. * 17., + y: 256. * 16., + }); + scene.fill( + Fill::NonZero, + Affine::IDENTITY, + Color::AQUA, + None, + &Rect::new(3000., 5., 4200., 4200.), + ); + } } diff --git a/vello_tests/src/snapshot.rs b/vello_tests/src/snapshot.rs index fe32aa667..4b03369be 100644 --- a/vello_tests/src/snapshot.rs +++ b/vello_tests/src/snapshot.rs @@ -147,14 +147,24 @@ pub fn smoke_snapshot_test_sync(scene: Scene, params: &TestParams) -> Result Result { let raw_rendered = render_then_debug(&scene, params).await?; + snapshot_test_image(raw_rendered, params, directory) +} +/// Evaluate a snapshot test on the given image. +/// +/// This is useful if a post-processing step needs to happen +/// in-between running Vello and the image. +pub fn snapshot_test_image( + raw_rendered: Image, + params: &TestParams, + directory: SnapshotDirectory, +) -> Result { let reference_path = snapshot_dir(directory) .join(¶ms.name) .with_extension("png"); diff --git a/vello_tests/tests/known_issues.rs b/vello_tests/tests/known_issues.rs new file mode 100644 index 000000000..2bc16e101 --- /dev/null +++ b/vello_tests/tests/known_issues.rs @@ -0,0 +1,67 @@ +// Copyright 2024 the Vello Authors +// SPDX-License-Identifier: Apache-2.0 OR MIT + +//! Reproductions for known bugs, to allow test driven development + +use vello::{ + kurbo::{Affine, Rect}, + peniko::{Color, Format}, + Scene, +}; +use vello_tests::TestParams; + +/// A reproduction of +fn many_bins(use_cpu: bool) { + let mut scene = Scene::new(); + scene.fill( + vello::peniko::Fill::NonZero, + Affine::IDENTITY, + Color::RED, + None, + &Rect::new(-5., -5., 256. * 20., 256. * 20.), + ); + let params = TestParams { + use_cpu, + ..TestParams::new("many_bins", 256 * 17, 256 * 17) + }; + // To view, use VELLO_DEBUG_TEST=many_bins + let image = vello_tests::render_then_debug_sync(&scene, ¶ms).unwrap(); + assert_eq!(image.format, Format::Rgba8); + let mut red_count = 0; + let mut black_count = 0; + for pixel in image.data.data().chunks_exact(4) { + let &[r, g, b, a] = pixel else { unreachable!() }; + let is_red = r == 255 && g == 0 && b == 0 && a == 255; + let is_black = r == 0 && g == 0 && b == 0 && a == 255; + if !is_red && !is_black { + panic!("{pixel:?}"); + } + match (is_red, is_black) { + (true, true) => unreachable!(), + (true, false) => red_count += 1, + (false, true) => black_count += 1, + (false, false) => panic!("Got unexpected pixel {pixel:?}"), + } + } + // When #680 is fixed, this will become: + // let drawn_bins = 17 /* x bins */ * 17 /* y bins*/; + + // The current maximum number of bins. + let drawn_bins = 256; + let expected_red_count = drawn_bins * 256 /* tiles per bin */ * 256 /* Pixels per tile */; + assert_eq!(red_count, expected_red_count); + assert!(black_count > 0); +} + +#[test] +#[cfg_attr(skip_gpu_tests, ignore)] +fn many_bins_gpu() { + many_bins(false); +} + +#[test] +#[cfg_attr(skip_gpu_tests, ignore)] +#[should_panic] +fn many_bins_cpu() { + many_bins(true); +}