use valo_dl::ColorFilter;
use valo_geometry::Rect;
use crate::pool::TargetPool;
use super::draw_context::PixelArea;
use super::emit::StepEmitter;
use super::filter_output::Merge;
use super::plan_writer::PlanWriter;
use super::shading::Shading;
use super::snapshot::Snapshot;
pub(super) struct FilterPasses<'p, 'a> {
pub pool: &'p mut TargetPool,
pub emit: &'p mut StepEmitter<'a>,
pub plan: &'p mut PlanWriter,
pub format: wgpu::TextureFormat,
}
impl FilterPasses<'_, '_> {
pub fn push_resample(&mut self, source: &Snapshot, region: &Rect) -> Snapshot {
let shading = self.emit.resample_shading(source, region);
self.push_region_pass(region, shading)
}
pub fn push_recolour(
&mut self,
source: &Snapshot,
filter: ColorFilter,
input_alpha: f32,
) -> Snapshot {
let region = source.placement.coverage();
let shading = self
.emit
.recolour_pass_shading(source, ®ion, filter, input_alpha);
self.push_region_pass(®ion, shading)
}
pub fn push_merge(&mut self, first: &Snapshot, second: &Snapshot, merge: Merge) -> Snapshot {
let region = first
.placement
.coverage()
.union(&second.placement.coverage());
let shading = self.emit.merge_pass_shading(first, second, ®ion, merge);
self.push_region_pass(®ion, shading)
}
fn push_region_pass(&mut self, region: &Rect, shading: Shading) -> Snapshot {
let area = PixelArea::over(*region);
let target = self.pool.take_filter(area.size(), self.format);
let quad = Rect::new(0.0, 0.0, region.width, region.height);
self.push_pass(
target.view.clone(),
self.format,
&quad,
area.size(),
shading,
);
Snapshot {
view: target.view,
placement: area.placement(),
}
}
pub fn push_pass(
&mut self,
target: wgpu::TextureView,
format: wgpu::TextureFormat,
quad: &Rect,
extent: [u32; 2],
shading: Shading,
) {
let draw = self.emit.filter_draw(format, quad, extent, shading);
self.plan.push_filter_pass(target, draw);
}
}