pub enum Instruction{ Render(crate::graphics::FrameState), //UpdateModel(crate::graphics::GraphicsModelUpdate), Resize(winit::dpi::PhysicalSize,crate::settings::UserSettings), ChangeMap(strafesnet_common::map::CompleteMap), } //Ideally the graphics thread worker description is: /* WorkerDescription{ input:Immediate, output:Realtime(PoolOrdering::Ordered(3)), } */ //up to three frames in flight, dropping new frame requests when all three are busy, and dropping output frames when one renders out of order pub fn new<'a>( mut graphics:crate::graphics::GraphicsState, mut config:wgpu::SurfaceConfiguration, surface:wgpu::Surface<'a>, device:wgpu::Device, queue:wgpu::Queue, )->crate::compat_worker::INWorker<'a,Instruction>{ let mut resize=None; crate::compat_worker::INWorker::new(move |ins:Instruction|{ match ins{ Instruction::ChangeMap(map)=>{ graphics.clear(); graphics.generate_models(&device,&queue,&map); }, Instruction::Resize(size,user_settings)=>{ resize=Some((size,user_settings)); } Instruction::Render(frame_state)=>{ if let Some((size,user_settings))=resize.take(){ println!("Resizing to {:?}",size); let t0=std::time::Instant::now(); config.width=size.width.max(1); config.height=size.height.max(1); surface.configure(&device,&config); graphics.resize(&device,&config,&user_settings); println!("Resize took {:?}",t0.elapsed()); } //this has to go deeper somehow let frame=match surface.get_current_texture(){ Ok(frame)=>frame, Err(_)=>{ surface.configure(&device,&config); surface .get_current_texture() .expect("Failed to acquire next surface texture!") } }; let view=frame.texture.create_view(&wgpu::TextureViewDescriptor{ format:Some(config.view_formats[0]), ..wgpu::TextureViewDescriptor::default() }); graphics.render(&view,&device,&queue,frame_state); frame.present(); } } }) }