[oden] Move graphics thread off main thread
So we can do frame pacing a little bit better maybe.
This commit is contained in:
parent
26bfcc7a94
commit
b1b97cee75
2 changed files with 79 additions and 106 deletions
|
|
@ -23,4 +23,5 @@ export function draw() {
|
|||
use_texture(the_texture);
|
||||
spr((320 - 256) / 2, 0, 256, 240, 0, 0);
|
||||
}
|
||||
// print("FRAME TIME:", since_last_frame());
|
||||
}
|
||||
|
|
|
|||
184
src/lib.rs
184
src/lib.rs
|
|
@ -1,12 +1,9 @@
|
|||
use bytemuck;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::mpsc::Receiver;
|
||||
use std::time::Instant;
|
||||
use wgpu::util::DeviceExt;
|
||||
use winit::{
|
||||
event::*,
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
window::Window,
|
||||
window::WindowBuilder,
|
||||
};
|
||||
use winit::{event::*, event_loop::EventLoop, window::Window, window::WindowBuilder};
|
||||
|
||||
mod script;
|
||||
use script::graphics::GraphicsCommand;
|
||||
|
|
@ -142,17 +139,12 @@ impl State {
|
|||
format: surface_format,
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
present_mode: surface_caps.present_modes[0],
|
||||
present_mode: wgpu::PresentMode::Fifo,
|
||||
alpha_mode: surface_caps.alpha_modes[0],
|
||||
view_formats: vec![],
|
||||
};
|
||||
surface.configure(&device, &config);
|
||||
|
||||
// TODO: DELETE THIS
|
||||
// let diffuse_bytes = include_bytes!("happy-tree.png");
|
||||
// let diffuse_texture =
|
||||
// texture::Texture::from_bytes(&device, &queue, diffuse_bytes, "happy-tree.png").unwrap();
|
||||
|
||||
let sprite_bind_group_layout =
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
entries: &[
|
||||
|
|
@ -475,116 +467,96 @@ impl State {
|
|||
self.queue.submit(std::iter::once(encoder.finish()));
|
||||
}
|
||||
|
||||
// {
|
||||
// // BEGIN GARBAGE
|
||||
// let r: f64 = (self.mouse_x / f64::from(self.size.width)).clamp(0.0, 1.0) * 0.1;
|
||||
// let g: f64 = (self.mouse_y / f64::from(self.size.height)).clamp(0.0, 1.0) * 0.2;
|
||||
// // END GARBAGE
|
||||
|
||||
// let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
// label: Some("Render Pass"),
|
||||
// color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||
// view: &view,
|
||||
// resolve_target: None,
|
||||
// ops: wgpu::Operations {
|
||||
// load: wgpu::LoadOp::Clear(wgpu::Color {
|
||||
// r, //0.1,
|
||||
// g, //0.2,
|
||||
// b: 0.3,
|
||||
// a: 1.0,
|
||||
// }),
|
||||
// store: true,
|
||||
// },
|
||||
// })],
|
||||
// depth_stencil_attachment: None,
|
||||
// });
|
||||
|
||||
// render_pass.set_pipeline(&self.render_pipeline);
|
||||
// render_pass.set_bind_group(0, &self.diffuse_bind_group, &[]);
|
||||
// render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
|
||||
// render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16);
|
||||
// render_pass.draw_indexed(0..self.num_indices, 0, 0..1);
|
||||
// }
|
||||
|
||||
output.present();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
struct UIEvent {
|
||||
winit: Event<'static, ()>,
|
||||
#[allow(unused)]
|
||||
time: Instant,
|
||||
}
|
||||
|
||||
// TODO: flume? (https://docs.rs/flume/latest/flume/)
|
||||
|
||||
fn main_thread(state: State, reciever: Receiver<UIEvent>) {
|
||||
let mut state = state;
|
||||
let mut context = script::ScriptContext::new();
|
||||
context.init();
|
||||
|
||||
loop {
|
||||
while let Ok(event) = reciever.try_recv() {
|
||||
match event.winit {
|
||||
Event::WindowEvent {
|
||||
ref event,
|
||||
window_id,
|
||||
} if window_id == state.window().id() => {
|
||||
if !state.input(event) {
|
||||
match event {
|
||||
WindowEvent::CursorMoved { position, .. } => {
|
||||
state.mouse_x = position.x;
|
||||
state.mouse_y = position.y;
|
||||
}
|
||||
|
||||
WindowEvent::Resized(physical_size) => {
|
||||
state.resize(*physical_size);
|
||||
}
|
||||
|
||||
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
|
||||
// new_inner_size is &&mut so we have to dereference it twice
|
||||
state.resize(**new_inner_size);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
context.update();
|
||||
state.update();
|
||||
|
||||
match state.render(context.render()) {
|
||||
Ok(_) => {}
|
||||
// Reconfigure the surface if lost
|
||||
Err(wgpu::SurfaceError::Lost) => state.resize(state.size),
|
||||
// The system is out of memory, we should probably quit
|
||||
Err(wgpu::SurfaceError::OutOfMemory) => panic!("Out of memory"),
|
||||
// All other errors (Outdated, Timeout) should be resolved by the next frame
|
||||
Err(e) => eprintln!("{:?}", e),
|
||||
}
|
||||
|
||||
// TODO: FRAME PACING.
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run() {
|
||||
env_logger::init();
|
||||
let event_loop = EventLoop::new();
|
||||
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
||||
|
||||
let mut state = State::new(window).await;
|
||||
let state = State::new(window).await;
|
||||
let (sender, reciever) = std::sync::mpsc::channel();
|
||||
|
||||
let mut context = script::ScriptContext::new();
|
||||
context.init();
|
||||
std::thread::spawn(move || {
|
||||
main_thread(state, reciever);
|
||||
});
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
control_flow.set_poll();
|
||||
|
||||
match event {
|
||||
Event::WindowEvent {
|
||||
ref event,
|
||||
window_id,
|
||||
} if window_id == state.window().id() => {
|
||||
if !state.input(event) {
|
||||
match event {
|
||||
WindowEvent::CloseRequested
|
||||
| WindowEvent::KeyboardInput {
|
||||
input:
|
||||
KeyboardInput {
|
||||
state: ElementState::Pressed,
|
||||
virtual_keycode: Some(VirtualKeyCode::Escape),
|
||||
..
|
||||
},
|
||||
..
|
||||
} => *control_flow = ControlFlow::Exit,
|
||||
|
||||
WindowEvent::CursorMoved { position, .. } => {
|
||||
state.mouse_x = position.x;
|
||||
state.mouse_y = position.y;
|
||||
state.window().request_redraw();
|
||||
}
|
||||
|
||||
WindowEvent::Resized(physical_size) => {
|
||||
state.resize(*physical_size);
|
||||
}
|
||||
|
||||
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
|
||||
// new_inner_size is &&mut so we have to dereference it twice
|
||||
state.resize(**new_inner_size);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
|
||||
context.update();
|
||||
state.update();
|
||||
|
||||
match state.render(context.render()) {
|
||||
Ok(_) => {}
|
||||
// Reconfigure the surface if lost
|
||||
Err(wgpu::SurfaceError::Lost) => state.resize(state.size),
|
||||
// The system is out of memory, we should probably quit
|
||||
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
|
||||
// All other errors (Outdated, Timeout) should be resolved by the next frame
|
||||
Err(e) => eprintln!("{:?}", e),
|
||||
}
|
||||
}
|
||||
|
||||
Event::MainEventsCleared => {
|
||||
// RedrawRequested will only trigger once, unless we manually
|
||||
// request it.
|
||||
state.window().request_redraw();
|
||||
}
|
||||
|
||||
_ => {}
|
||||
if let Some(e) = event.to_static() {
|
||||
sender
|
||||
.send(UIEvent {
|
||||
winit: e,
|
||||
time: Instant::now(),
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue