Screen flickering with DrawingArea

Hello again. Just as my last topic, I want to create DrawingArea with Pixbuf with an in-memory bytes buffer. Everything works fine, but I got a flickering screen when the original bytes change. I also tried ImageSurface and Picture, but it getting flickering too. I’ve searched and searched on this but am still stuck…
Here are some code snippets:

...
drawing_area.set_draw_func(move |_, cr, _, _| {
    let pixbuf = Pixbuf::from_bytes(
        &Bytes::from_static(in_memory_buffer),
        gtk::gdk_pixbuf::Colorspace::Rgb,
        true,
        8,
        current_w, 
        current_h,
        current_w * 4,
    ); 
    cr.set_source_pixbuf(&pixbuf, 0., 0.);
    cr.paint().expect("Invalid pixbuf.");
});
...

Did I miss anything? Would appreciate any suggestions.

If you say “when the original bytes change”, do you mean the in_memory_buffer is changed from another thread in the background and without synchronization with the main thread? That won’t work correctly whenever the modification and pixbuf rendering happen at the same time.

Can you maybe make a minimal’ish testcase available that shows the behaviour you’re seeing?

1 Like

Testcase was a little hard. The in-memory buffer was rendered by another program, it uses Boost IPC to share memory among processes. And I locked the resource properly, so I can make sure the buffer will not change while Pixbuf rendering.
Here is the code from my project, hope that can help.

You would set the draw function only once, and from in there whenever it is called you would then render the latest picture. It seems like currently you’re setting a new one every time a new picture is available?

Also what is the lifetime of the return value of native_get_buffer()? The way how you use it right now a 'static lifetime is inferred, which is probably not correct? Basically, the draw function can be called any time later (until the widget is gone or a new draw function is set), and that buffer needs to stay valid at least for that long.

Thanks for your patience! I checked the code on the rendering side, turns out it’s the synchronization problem. :rofl:
Again, thanks for your tips.

1 Like