openglrustglium

How to draw OpenGL triangle from other thread in Rust


I'm learning OpenGL is Rust by this example: https://github.com/glium/glium/blob/84f82d3098fbc75aa22160b47bf0a2bdada01f07/examples/triangle.rs#L141

It uses a window wrapper called glutin, and draws the triangle once like this:

let draw = move || {
    // building the uniforms
    let uniforms = uniform! {
        matrix: [
            [1.0, 0.0, 0.0, 0.0],
            [0.0, 1.0, 0.0, 0.0],
            [0.0, 0.0, 1.0, 0.0],
            [0.0, 0.0, 0.0, 1.0f32]
        ]
    };

    // drawing a frame
    let mut target = display.draw();
    target.clear_color(0.0, 0.0, 0.0, 0.0);
    target.draw(&vertex_buffer, &index_buffer, &program, &uniforms, &Default::default()).unwrap();
    target.finish().unwrap();
};

The problem is: how can I draw from other threads? In order to call draw I'd have to share it with the other thread, but types like program, index_buffer, vertex_buffer, display are not Send+Sync.

Drawing from other threads is crucial in a window application so I guess they thought of it and there should be a simple way to do it, but I'm lost.


Solution

  • You cannot do that with Glium, but this is unlikely to be a problem.

    As per issue #459, the memory model was reiterated to no longer allow for graphical resources in the API to be shared with multiple threads. Older versions of Glium were synchronizing calls through a background thread anyway, which means that there was no gain in parallelizing these calls. And although there are ways for OpenGL to have multiple contexts and to share certain resources among them, it is too complicated and inefficient for a Rust API to ensure safe and proper usage.

    Drawing from other threads is crucial in a window application

    Note that being unable to perform draw operations through multiple threads does not mean that the application itself becomes single-threaded. This is not crucial. The best way to work with this is to dedicate the same thread to rendering and channel commands from other threads into it.

    See also: