Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with winit_multithread example on macOS #249

Open
Veritaris opened this issue Dec 28, 2024 · 3 comments
Open

Problem with winit_multithread example on macOS #249

Veritaris opened this issue Dec 28, 2024 · 3 comments
Labels
CoreGraphics macOS/iOS/tvOS/watchOS/visionOS backend question Further information is requested

Comments

@Veritaris
Copy link

Technical details & libs versions:
Libs:

winit = "0.30.7"
softbuffer = "0.4.6"

Machine:
MacBook Pro with M3
macOS: Sonoma 14.6.1

Hi! During developing software rendering I've decided to switch making render itself in separated thread and attempted to run example from examples/winit_multithread.rs, but got a problem that program is "stuck" at let size = window.inner_size();:

starting thread...
making surface...
waiting for render...

In docs for inner_size is see that

Platform-specific
iOS: Can only be called on the main thread.

But is it also applied to macOS platform?
I tried to remove fetching window size and it works (I've added a little code to see that different thread rendering works):

    fn render_thread(
        window: Arc<Window>,
        do_render: mpsc::Receiver<Arc<Mutex<Surface>>>,
        done: mpsc::Sender<()>,
    ) {
        let mut c: u32 = 0u32;
        loop {
            println!("waiting for render...");
            let Ok(surface) = do_render.recv() else {
                println!("main thread destroyed");
                break;
            };

            // Perform the rendering.
            let mut surface = surface.lock().unwrap();

            let (Some(width), Some(height)) = (NonZeroU32::new(1024), NonZeroU32::new(1024)) else { todo!() };

            surface.resize(width, height).unwrap();

            let mut buffer = surface.buffer_mut().unwrap();

            for y in 0..height.get() {
                for x in 0..width.get() {
                    let red = (x + c) % 255;
                    let green = (y + c) % 255;
                    let blue = (x * y + c) % 255;
                    let index = y as usize * width.get() as usize + x as usize;
                    buffer[index] = blue | (green << 8) | (red << 16);
                }
            }

            println!("presenting...");
            buffer.present().unwrap();

            // We're done, tell the main thread to keep going.
            done.send(()).ok();
            c += 1;
        }
    }
@madsmtm madsmtm added bug Something isn't working CoreGraphics macOS/iOS/tvOS/watchOS/visionOS backend labels Dec 29, 2024
@madsmtm
Copy link
Member

madsmtm commented Dec 29, 2024

iOS: Can only be called on the main thread.

But is it also applied to macOS platform?

No, it can be called from all threads on both platforms (the docs are a bit outdated on iOS), but it will block on both platforms too, waiting on the main thread to fetch the surface size.

My recommendation would be to communicate surface size changes through a channel or a mutex or something.

@madsmtm madsmtm added question Further information is requested and removed bug Something isn't working labels Dec 29, 2024
@MarijnS95
Copy link
Member

This issue seems to match what we wanted to achieve with #237, and generally rethinking when to forward window resizes into softbuffer (or not, to achieve hardware scaling).

@Veritaris
Copy link
Author

@madsmtm, yeah, I already figured it out, just wanted to highlight that recently updated example does not work 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CoreGraphics macOS/iOS/tvOS/watchOS/visionOS backend question Further information is requested
Development

No branches or pull requests

3 participants