2

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.

Guerlando OCs
  • 1,886
  • 9
  • 61
  • 150

1 Answers1

3

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:

E_net4
  • 27,810
  • 13
  • 101
  • 139
  • So I must draw from the main thread, right? That means I must write to my pixel buffers from the main thread, which is inneficcient. Any thread could be responsible for writing to pixel buffers, and then I should call draw from the main thread. Currently I have to write to the pixel buffers and call draw on the same thread. My event loop is playing at 15 fps only, and if I comment the pixel buffer write and draw call it runs at 240 fps. (also, if I make the window smaller, the fps gets bigger, don't know why) – Guerlando OCs Oct 08 '20 at 22:38
  • The way I see it, nothing forces you to pass or share pixel buffers around. The performance problem is likely some other case of poor design. Better turn that into a new question. – E_net4 Oct 09 '20 at 08:27
  • PixelBuffer cannot be sent to other threads, that's why I ask. I'm having to fill them in the main thread – Guerlando OCs Oct 09 '20 at 15:06