1use std::cell::RefCell;
2
3use wgpu::{
4 Adapter, Device, DeviceDescriptor, Features, Instance, Limits, MemoryHints, PowerPreference,
5 Queue, RenderPipeline, RequestAdapterOptions, Surface, SurfaceConfiguration,
6};
7use winit::{dpi::PhysicalSize, event_loop::EventLoopProxy, window::Window};
8
9use crate::plinth_app::PlinthApp;
10
11#[cfg(target_arch = "wasm32")]
12pub type Rc<T> = std::rc::Rc<T>;
13
14#[cfg(not(target_arch = "wasm32"))]
15pub type Rc<T> = std::sync::Arc<T>;
16
17pub async fn create_graphics(
18 window: Rc<Window>,
19 proxy: EventLoopProxy<Graphics>,
20 user_app: Rc<RefCell<dyn PlinthApp>>,
21) {
22 let instance = Instance::default();
23 let surface = instance.create_surface(Rc::clone(&window)).unwrap();
24 let adapter = instance
25 .request_adapter(&RequestAdapterOptions {
26 power_preference: PowerPreference::default(), force_fallback_adapter: false, compatible_surface: Some(&surface), })
30 .await
31 .expect("Could not get an adapter (GPU).");
32
33 let (device, queue) = adapter
34 .request_device(&DeviceDescriptor {
35 label: None,
36 required_features: Features::empty(), required_limits: Limits::downlevel_webgl2_defaults().using_resolution(adapter.limits()),
38 memory_hints: MemoryHints::Performance,
39 trace: wgpu::Trace::Off,
40 })
41 .await
42 .expect("Failed to get device");
43
44 let size = window.inner_size();
46 let width = size.width.max(1);
48 let height = size.height.max(1);
49 let surface_config = surface.get_default_config(&adapter, width, height).unwrap();
50
51 #[cfg(not(target_arch = "wasm32"))]
52 surface.configure(&device, &surface_config);
53
54 let render_pipelines = vec![];
55
56 let mut gfx = Graphics {
57 window: window.clone(),
58 _instance: instance,
59 surface,
60 surface_config,
61 _adapter: adapter,
62 device,
63 queue,
64 render_pipelines,
65 };
66
67 let render_pipeline = user_app.borrow_mut().create_pipeline(&mut gfx);
68
69 gfx.render_pipelines.push(render_pipeline);
70
71 let _ = proxy.send_event(gfx);
72}
73
74#[derive(Debug)]
75pub struct Graphics {
76 pub window: Rc<Window>,
77 pub _instance: Instance,
78 pub surface: Surface<'static>,
79 pub surface_config: SurfaceConfiguration,
80 pub _adapter: Adapter,
81 pub device: Device,
82 pub queue: Queue,
83 pub render_pipelines: Vec<RenderPipeline>,
84}
85
86impl Graphics {
87 pub fn resize(&mut self, new_size: PhysicalSize<u32>) {
88 self.surface_config.width = new_size.width.max(1);
89 self.surface_config.height = new_size.height.max(1);
90 self.surface.configure(&self.device, &self.surface_config);
91 }
92}