use cranpose_render_common::graph::{ProjectiveTransform, RenderNode};
use cranpose_render_wgpu::CapturedFrame;
use cranpose_ui_graphics::{
GraphicsLayer, RUNTIME_SHADER_PRELUDE_WGSL, RenderEffect, RuntimeShader,
};
use crate::{
shared_test_support, support,
support::bar_scene::{BAR, HEIGHT, WIDTH},
};
fn identity_shader(declared: bool) -> RenderEffect {
let mut shader = RuntimeShader::new(&format!(
"{RUNTIME_SHADER_PRELUDE_WGSL}\n@fragment\nfn effect_fs(input: VertexOutput) -> \
@location(0) vec4<f32> {{\n return textureSample(input_texture, input_sampler, \
input.uv);\n}}\n"
));
shader.set_preserves_transparency(declared);
RenderEffect::runtime_shader(shader)
}
fn painting_shader() -> RenderEffect {
RenderEffect::runtime_shader(RuntimeShader::new(&format!(
"{RUNTIME_SHADER_PRELUDE_WGSL}\n@fragment\nfn effect_fs(input: VertexOutput) -> \
@location(0) vec4<f32> {{\n return vec4<f32>(1.0, 0.0, 0.0, 1.0);\n}}\n"
)))
}
fn page_with_empty_layer(effect: RenderEffect) -> Vec<RenderNode> {
let mut page = support::striped_page(WIDTH, HEIGHT);
page.push(RenderNode::Layer(Box::new(
shared_test_support::layer_node(
BAR,
ProjectiveTransform::identity(),
GraphicsLayer {
render_effect: Some(effect),
..Default::default()
},
vec![],
),
)));
page
}
fn capture(renderer: &mut support::LockedRenderer, page: Vec<RenderNode>) -> CapturedFrame {
support::capture_graph_settled(
renderer,
support::page_graph(WIDTH, HEIGHT, page),
WIDTH,
HEIGHT,
)
}
#[test]
fn an_empty_layer_under_a_transparency_preserving_shader_draws_nothing() {
let mut renderer = support::headless_renderer().expect("GPU required for the layer probe");
let plain = capture(&mut renderer, support::striped_page(WIDTH, HEIGHT));
let plain_passes = renderer
.last_frame_stats()
.expect("frame statistics")
.pass_count;
let undeclared = capture(&mut renderer, page_with_empty_layer(identity_shader(false)));
let stats = renderer.last_frame_stats().expect("frame statistics");
assert!(
stats.shader_pixels > 0,
"an undeclared shader over an empty layer is drawn"
);
let differing = support::differing_pixels(WIDTH, &plain.pixels, &undeclared.pixels);
assert!(
differing.is_empty(),
"the identity shader over nothing changed the page: {}",
support::describe_differing(&differing)
);
let declared = capture(&mut renderer, page_with_empty_layer(identity_shader(true)));
let stats = renderer.last_frame_stats().expect("frame statistics");
assert_eq!(stats.shader_pixels, 0, "the declared shader is not drawn");
assert_eq!(
stats.pass_count, plain_passes,
"the empty layer costs the page no pass"
);
let differing = support::differing_pixels(WIDTH, &plain.pixels, &declared.pixels);
assert!(
differing.is_empty(),
"skipping the empty layer changed the page: {}",
support::describe_differing(&differing)
);
let painted = capture(&mut renderer, page_with_empty_layer(painting_shader()));
let differing = support::differing_pixels(WIDTH, &plain.pixels, &painted.pixels);
assert_eq!(
differing.len(),
(BAR.width * BAR.height) as usize,
"a shader painting from nothing paints the whole layer"
);
}