PistonDevelopers/glutin_window

Sleeping before rendering without polling events leads to error when closing window

Closed this issue · 2 comments

Posting this here because I am not certain whether this should be solved in Glutin, through some trick in glutin_window, or change the Piston event loop behavior.

The problem is that the Piston event loop sleeps before rendering, and when closing the window while it sleeps, the OpenGL context gets destroyed. The event loop wakes up, starts rendering, and Gfx panics because it checks the errors.

This can be reproduced by modifying the "window.rs" example in the Glutin repository:

window.rs

fn main() {
    use std::time::Duration;
    use std::thread;

    let mut window = glutin::WindowBuilder::new().build().unwrap();
    window.set_title("A fantastic window!");
    window.set_window_resize_callback(Some(resize_callback as fn(u32, u32)));
    let _ = unsafe { window.make_current() };

    println!("Pixel format of the window: {:?}", window.get_pixel_format());

    let context = support::load(&window);

    'program: loop {
        for event in window.poll_events() {
            // Sleep before rendering to make time to destroy the OpenGL context.
            thread::sleep(Duration::from_millis(200));
            context.draw_frame((0.0, 1.0, 0.0, 1.0));

            println!("{:?}", event);

            match event {
                glutin::Event::Closed => {
                    println!("TEST closed");
                    break 'program;
                }
                _ => ()
            }
            let _ = window.swap_buffers();
        }
    }
}

You also need to check for the error:

support/mod.rs

pub fn draw_frame(&self, color: (f32, f32, f32, f32)) {
        unsafe {
            self.gl.ClearColor(color.0, color.1, color.2, color.3);
            let err = self.gl.GetError();
            if err != 0 {
                println!("ERROR: Invalid framebuffer operation {}", err == gl::INVALID_FRAMEBUFFER_OPERATION);
            }
            self.gl.Clear(gl::COLOR_BUFFER_BIT);

            self.gl.DrawArrays(gl::TRIANGLES, 0, 3);
        }
    }

This will print out:

ERROR: Invalid framebuffer operation true
Closed
TEST closed

There is no way to detect whether the Glutin window has been closed, unless you poll all the events.

Seems to work by adding a fix to the Piston event loop. Will open up a PR on the piston repo.