use tessera_ui::{ComputeCommand, Px, renderer::command::SampleRegion};
#[derive(Debug, Clone, PartialEq)]
pub struct BlurCommand {
pub radius: f32,
pub direction: (f32, f32),
}
impl BlurCommand {
pub fn horizontal(radius: f32) -> Self {
Self {
radius,
direction: (1.0, 0.0),
}
}
pub fn vertical(radius: f32) -> Self {
Self {
radius,
direction: (0.0, 1.0),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct DualBlurCommand {
pub passes: [BlurCommand; 2],
}
pub fn downscale_factor_for_radius(radius: f32) -> u32 {
if radius <= 6.0 {
1
} else if radius <= 18.0 {
2
} else {
4
}
}
impl DualBlurCommand {
pub fn horizontal_then_vertical(radius: f32) -> Self {
Self {
passes: [
BlurCommand::horizontal(radius),
BlurCommand::vertical(radius),
],
}
}
}
impl ComputeCommand for DualBlurCommand {
fn barrier(&self) -> SampleRegion {
let max_radius = self
.passes
.iter()
.map(|pass| pass.radius)
.fold(0.0f32, f32::max);
let downscale = downscale_factor_for_radius(max_radius) as f32;
let sampling_padding = (max_radius * downscale).ceil() as i32;
SampleRegion::uniform_padding_local(Px(sampling_padding))
}
}