control_flow/util/
fill.rs1#[allow(unused_imports)]
11pub use platform::cleanup_window;
12pub use platform::fill_window;
13
14#[cfg(all(feature = "rwh_05", not(any(target_os = "android", target_os = "ios"))))]
15mod platform {
16 use std::cell::RefCell;
17 use std::collections::HashMap;
18 use std::mem;
19 use std::mem::ManuallyDrop;
20 use std::num::NonZeroU32;
21
22 use softbuffer::{Context, Surface};
23 use winit::window::{Window, WindowId};
24
25 thread_local! {
26 static GC: ManuallyDrop<RefCell<Option<GraphicsContext>>> = const { ManuallyDrop::new(RefCell::new(None)) };
32 }
33
34 struct GraphicsContext {
36 context: RefCell<Context<&'static Window>>,
38
39 surfaces: HashMap<WindowId, Surface<&'static Window, &'static Window>>,
41 }
42
43 impl GraphicsContext {
44 fn new(w: &Window) -> Self {
45 Self {
46 context: RefCell::new(
47 Context::new(unsafe { mem::transmute::<&'_ Window, &'static Window>(w) })
48 .expect("Failed to create a softbuffer context"),
49 ),
50 surfaces: HashMap::new(),
51 }
52 }
53
54 fn create_surface(
55 &mut self,
56 window: &Window,
57 ) -> &mut Surface<&'static Window, &'static Window> {
58 self.surfaces.entry(window.id()).or_insert_with(|| {
59 Surface::new(&self.context.borrow(), unsafe {
60 mem::transmute::<&'_ Window, &'static Window>(window)
61 })
62 .expect("Failed to create a softbuffer surface")
63 })
64 }
65
66 fn destroy_surface(&mut self, window: &Window) {
67 self.surfaces.remove(&window.id());
68 }
69 }
70
71 pub fn fill_window(window: &Window) {
72 GC.with(|gc| {
73 let size = window.inner_size();
74 let (Some(width), Some(height)) =
75 (NonZeroU32::new(size.width), NonZeroU32::new(size.height))
76 else {
77 return;
78 };
79
80 let mut gc = gc.borrow_mut();
82 let surface =
83 gc.get_or_insert_with(|| GraphicsContext::new(window)).create_surface(window);
84
85 const DARK_GRAY: u32 = 0xff181818;
87
88 surface.resize(width, height).expect("Failed to resize the softbuffer surface");
89
90 let mut buffer = surface.buffer_mut().expect("Failed to get the softbuffer buffer");
91 buffer.fill(DARK_GRAY);
92 buffer.present().expect("Failed to present the softbuffer buffer");
93 })
94 }
95
96 #[allow(dead_code)]
97 pub fn cleanup_window(window: &Window) {
98 GC.with(|gc| {
99 let mut gc = gc.borrow_mut();
100 if let Some(context) = gc.as_mut() {
101 context.destroy_surface(window);
102 }
103 });
104 }
105}
106
107#[cfg(not(all(feature = "rwh_05", not(any(target_os = "android", target_os = "ios")))))]
108mod platform {
109 pub fn fill_window(_window: &winit::window::Window) {
110 }
112
113 #[allow(dead_code)]
114 pub fn cleanup_window(_window: &winit::window::Window) {
115 }
117}