aboutsummaryrefslogtreecommitdiff
path: root/vgcodec/src/approximate.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2022-11-21 19:47:13 +0100
committermetamuffin <metamuffin@disroot.org>2022-11-21 19:47:13 +0100
commitb7e7bc086ff450f6234db5e868f1dde7d3e0c51b (patch)
treeb8a0b0a0a897379c9fe631676fd7e3763e68768e /vgcodec/src/approximate.rs
parent6ef7ada9edb817ef636048d0f8fba29e7729404c (diff)
downloadvideo-codec-experiments-b7e7bc086ff450f6234db5e868f1dde7d3e0c51b.tar
video-codec-experiments-b7e7bc086ff450f6234db5e868f1dde7d3e0c51b.tar.bz2
video-codec-experiments-b7e7bc086ff450f6234db5e868f1dde7d3e0c51b.tar.zst
stuff
Diffstat (limited to 'vgcodec/src/approximate.rs')
-rw-r--r--vgcodec/src/approximate.rs119
1 files changed, 119 insertions, 0 deletions
diff --git a/vgcodec/src/approximate.rs b/vgcodec/src/approximate.rs
new file mode 100644
index 0000000..0192973
--- /dev/null
+++ b/vgcodec/src/approximate.rs
@@ -0,0 +1,119 @@
+use std::sync::Arc;
+
+use image::EncodableLayout;
+use log::info;
+use wgpu::{Extent3d, ImageCopyTexture, Origin3d, Texture, TextureUsages};
+
+use crate::{
+ app::App,
+ diff::Differ,
+ export::Exporter,
+ helper::write_texture,
+ paint::{PaintUniforms, Painter},
+};
+
+pub struct Approximator {
+ app: Arc<App>,
+ size: Extent3d,
+ differ: Differ,
+ painter: Painter,
+ exporter: Exporter,
+
+ tex_approx: Texture,
+ tex_savestate: Texture,
+ tex_target: Texture,
+}
+
+impl Approximator {
+ pub fn new(app: &Arc<App>, tex_target: Texture, size: Extent3d) -> Self {
+ let App { device, queue, .. } = app.as_ref();
+ let tex_approx = device.create_texture(&wgpu::TextureDescriptor {
+ size,
+ mip_level_count: 1,
+ sample_count: 1,
+ dimension: wgpu::TextureDimension::D2,
+ format: wgpu::TextureFormat::Rgba8Unorm,
+ usage: TextureUsages::COPY_DST
+ | TextureUsages::TEXTURE_BINDING
+ | TextureUsages::STORAGE_BINDING
+ | TextureUsages::COPY_SRC,
+ label: None,
+ });
+ let tex_savestate = device.create_texture(&wgpu::TextureDescriptor {
+ size,
+ mip_level_count: 1,
+ sample_count: 1,
+ dimension: wgpu::TextureDimension::D2,
+ format: wgpu::TextureFormat::Rgba8Unorm,
+ usage: TextureUsages::COPY_DST | TextureUsages::COPY_SRC,
+ label: None,
+ });
+
+ let img_initial = image::open("a/initial.png").unwrap().into_rgba8();
+ write_texture(queue, &tex_approx, img_initial.as_bytes(), size);
+
+ let differ = Differ::new(&app, size, &tex_approx, &tex_target);
+ let painter = Painter::new(&app, size, &tex_approx);
+ let exporter = Exporter::new(&app, size);
+
+ Approximator {
+ app: app.clone(),
+ size,
+ differ,
+ tex_savestate,
+ tex_approx,
+ tex_target,
+ painter,
+ exporter,
+ }
+ }
+
+ pub fn save(&self) {
+ self.app
+ .copy_texture(&self.tex_approx, &self.tex_savestate, self.size);
+ }
+ pub fn restore(&self) {
+ self.app
+ .copy_texture(&self.tex_savestate, &self.tex_approx, self.size);
+ }
+
+ pub async fn run(&mut self) {
+ let mut current_diff = self.differ.run().await;
+ let mut params = PaintUniforms {
+ x: 128.0,
+ y: 128.0,
+ r: 0.5,
+ g: 0.5,
+ b: 0.5,
+ radius: 64.0,
+ };
+
+ self.optimize_param(&mut current_diff, &mut params, "", |p| p.b += 0.1);
+
+ self.exporter.run(&self.tex_approx, "a/approx.png").await;
+ }
+
+ pub fn optimize_param<F>(
+ &self,
+ current_diff: &mut u32,
+ params: &mut PaintUniforms,
+ label: &'static str,
+ f: F,
+ ) where
+ F: Fn(&mut PaintUniforms) -> (),
+ {
+ let mut p = params.clone();
+ loop {
+ self.save();
+ info!("apply '{label:?}'");
+ f(&mut p);
+ self.painter.run(p);
+ let diff = pollster::block_on(self.differ.run());
+ self.restore();
+ if diff >= *current_diff {
+ break;
+ }
+ *current_diff = diff;
+ }
+ }
+}