Threading windows' drawing

16 views
Skip to first unread message

Gonzalo Garramuño

unread,
Jul 17, 2025, 12:10:33 PMJul 17
to fltkc...@googlegroups.com
I am facing a problem with FLTK that I currently do not **yet** know how
to solve, so I am looking for advice and some understanding of FLTK's
innards.

Vulkan is a multi thread safe API, but it requires manual
synchronization to try to send all drawing commands at once, unlike
OpenGL where synchronization is handled by the driver and commands can
be sent in any order.

While this is not a problem with one window, I believe FLTK's single
threaded design is stalling my application's drawing when I have two or
more Vulkan windows open.  In my player, I get 60FPS at 4K with one
window, but about 48-50 FPS with two windows.

The current pattern I use for each window:

1. Start recording commands for Viewport (Vulkan Window)
2. Draw commands for Viewport
3. End recording commands for Viewport
4. Synchronize Viewport
5. Start recording commands for Timeline (2nd Vulkan Window)
6. Draw commands for Timeline
7. End recording commands for Timeline
8. Synchronize Timeline

Ideally, the access pattern for Vulkan should be:

1. Start recording commands for Viewport (Vulkan Window)
2. Draw commands for Viewport
3. End recording commands for Viewport
4. Start recording commands for Timeline (2nd Vulkan Window)
5. Draw commands for Timeline
6. End recording commands for Timeline
7. Synchronize Viewport **AND** Timeline together

Does anyone have a suggestion on how can this be handled sanely with
FLTK's event loop?

--
ggar...@gmail.com

Albrecht Schlosser

unread,
Jul 17, 2025, 12:54:24 PMJul 17
to fltkc...@googlegroups.com
On 7/17/25 18:10 Gonzalo Garramuño wrote:
I am facing a problem with FLTK that I currently do not **yet** know how to solve, so I am looking for advice and some understanding of FLTK's innards.

Vulkan is a multi thread safe API, but it requires manual synchronization to try to send all drawing commands at once, unlike OpenGL where synchronization is handled by the driver and commands can be sent in any order.

While this is not a problem with one window, I believe FLTK's single threaded design is stalling my application's drawing when I have two or more Vulkan windows open.  In my player, I get 60FPS at 4K with one window, but about 48-50 FPS with two windows.

Sounds reasonable: two windows need some more time to draw than one window. What do you expect with two windows?


The current pattern I use for each window:

1. Start recording commands for Viewport (Vulkan Window)
2. Draw commands for Viewport
3. End recording commands for Viewport
4. Synchronize Viewport
5. Start recording commands for Timeline (2nd Vulkan Window)
6. Draw commands for Timeline
7. End recording commands for Timeline
8. Synchronize Timeline

Ideally, the access pattern for Vulkan should be:

1. Start recording commands for Viewport (Vulkan Window)
2. Draw commands for Viewport
3. End recording commands for Viewport
4. Start recording commands for Timeline (2nd Vulkan Window)
5. Draw commands for Timeline
6. End recording commands for Timeline
7. Synchronize Viewport **AND** Timeline together

Does anyone have a suggestion on how can this be handled sanely with FLTK's event loop?

I think we need more info to give a useful answer. You wrote that "Vulkan is a multi thread safe API" but you didn't tell us what parts you are (currently) doing in worker threads and how you want to synchronize.

In my simple model I would likely (try to) do it like this:

I assume that "recording commands" and "draw commands" can be done in threads and that you don't use the draw() method for these parts. Is this correct?

If yes, this could be done in parallel for both windows. When you need to synchronize your drawing you'd call redraw() on your windows, but this would likely have to be done in the FLTK (GUI) thread and would mark both windows to be drawn. I'd suggest to use Fl::awake(your_handler, your_window) for this. If this happens somehow simultaneously, then the next Fl::flush() in the FLTK event loop would call draw() for both windows.

In your draw() method you would have to do the last part: "synchronize" your Vulkan drawings. This would hopefully happen in the same pass of the event loop for both windows, and that's what you want to achieve, if I understood correctly.

If my assumptions are wrong, please clarify what you are doing (and how you do it now in FLTK terms) for someone not knowing anything about Vulkan.

Gonzalo Garramuño

unread,
Jul 17, 2025, 2:03:57 PMJul 17
to fltkc...@googlegroups.com


El 17/7/25 a las 13:54, 'Albrecht Schlosser' via fltk.coredev escribió:
Sounds reasonable: two windows need some more time to draw than one window. What do you expect with two windows?

True, but the slowdown does not happen with OpenGL where the driver schedules automatically when the GPU redraws.  With Vulkan the scheduling has to be done manually.
I think we need more info to give a useful answer. You wrote that "Vulkan is a multi thread safe API" but you didn't tell us what parts you are (currently) doing in worker threads and how you want to synchronize.

Sure.  I'll try to clarify.

In my simple model I would likely (try to) do it like this:

I assume that "recording commands" and "draw commands" can be done in threads and that you don't use the draw() method for these parts. Is this correct?

In principle, recording/drawing could be done in threads with no issues.  Currently all my recording/drawing is still mainly done in the main FLTK thread, like it was with OpenGL.  That is, in the draw() method of my Fl_Vk_Window.  That seems fast enough, at least on my old RTX 3800.

Only drawing of thumbnails are done in auxiliary threads currently.



If yes, this could be done in parallel for both windows. When you need to synchronize your drawing you'd call redraw() on your windows, but this would likely have to be done in the FLTK (GUI) thread and would mark both windows to be drawn. I'd suggest to use Fl::awake(your_handler, your_window) for this. If this happens somehow simultaneously, then the next Fl::flush() in the FLTK event loop would call draw() for both windows.
In your draw() method you would have to do the last part: "synchronize" your Vulkan drawings. This would hopefully happen in the same pass of the event loop for both windows, and that's what you want to achieve, if I understood correctly.

That's where the problem lies.  When you call Fl::flush(), Vulkan uses vkQueueSubmit which sends all recorded commands to the GPU and then the swap_buffer() command waits for the presentation (vkQueuePresentKHR).  That's where the stall happens as these are done sequentially, IIUC.

In order to have the best performance, vkQueueSubmit  (ie flush) should be called only ONCE with all the drawing commands for **BOTH** windows so that GPU does not stall.

In summary, I am looking for a way to count the number of Fl_Vk_Windows' (FLTK's as_vk_window()) and skip the flush except for the last Vulkan window found after the drawings for **both** windows are done.


-- 
ggar...@gmail.com

Bill Spitzak

unread,
Jul 17, 2025, 4:33:49 PMJul 17
to fltkc...@googlegroups.com
My quick impression is that the “synchronize” step should be done by Fl::wait, just before it blocks waiting for events. This is done after all the drawing is done. I think it can be done by adding an idle callback, though it might be built-in to an fltk designed to draw using Vulkan.

--
You received this message because you are subscribed to the Google Groups "fltk.coredev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkcoredev...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/fltkcoredev/0fe331ad-7094-4067-9622-590b86094eb1%40gmail.com.

Gonzalo Garramuño

unread,
Jul 20, 2025, 5:04:50 PMJul 20
to fltkc...@googlegroups.com

On 7/17/2025 1:54 PM, 'Albrecht Schlosser' via fltk.coredev wrote:
> Re: [fltk.coredev] Threading windows' drawing
> On 7/17/25 18:10 Gonzalo Garramuño wrote:
>> I am facing a problem with FLTK that I currently do not **yet** know
>> how to solve, so I am looking for advice and some understanding of
>> FLTK's innards.
Thanks Albrecht and Bill for chiming in. The problem with Vulkan's
performance in my video player has now been mostly addressed.

--
ggar...@gmail.com

Reply all
Reply to author
Forward
0 new messages