How can we properly separate UI thread from rendering/logic thread

Started by
4 comments, last by galop1n 7 years, 3 months ago

Hi Guys,

I am sorry if you feel this topic should be in another forum. But since it's only in windows, I guess here may be a good place to ask for it.

So the thing is I have a DX12 application need to keep running even if you are moving the window or resizing the window. If your windows messaging handling is in your rendering thread, your render will be paused when you move or resize the window (may be block in DefWindowProc)

My first approach is separating render thread and have all event handling in UI thread. But some data shared by both thread cause sync issue like ImGuiIO: ImGui event handling need to be called before or after rendering, but since they are get called in separate thread, you have to sync both thread at some point, which seems not an ideal solution to me.

So later I tried another approach: using a separate render thread, and have UI thread post needed msg to render thread' message queue by calling PostThreadMessage. So this time event handling is in the same thread as render thread, which looks good. But there are big problems: my render thread may lost important message like WM_LBUTTONDOWN/UP etc. if UI thread posting faster than render thread can process... even if I let my UI thread wait for render thread's ready signal...

Another big issue for my second approach is that not any msg can be post on to other thread's message queue. For example I am using MSFT interactioncontext library which need to handle WM_POINTEXXX events and sadly those event cannot post on to other thread...

Having so much trouble separating UI thread I feel like I must did something fundamentally wrong, so I come here for help, how to properly separate UI thread?

Thanks

Advertisement

Just put your window and message loop in a separate thread by itself, and forward in your user code things that may be of interest to your app, ( like close request, fullscreen request, loss of focus, ... ).

I usually have two extra threads, one for the window, and one for a message only window to handle raw inputs, like that, you never stall on messages whatever happen in your game/render logic.

Just put your window and message loop in a separate thread by itself, and forward in your user code things that may be of interest to your app, ( like close request, fullscreen request, loss of focus, ... ).

I usually have two extra threads, one for the window, and one for a message only window to handle raw inputs, like that, you never stall on messages whatever happen in your game/render logic.

Thanks galop1n for such a prompt reply.

Could you elaborate a little bit more on that? For example you have a model view camera class which respond to mouse related events, how to fit it into two thread scenario? make the whole camera class calls in UI thread and just have render thread pull view matrix from UI thread? or put camera related calls in render thread and have UI send all mouse event to it? ( You may miss important event when your render thread is slower than UI thread )

Or if you are familiar with ImGui, how to use it in this two thread model? (I found it's tricky to use ImGui in such cases)

Thanks

GUI are usually event driven, so unless the GUI controls are actively being interacted with, they are usually in some idle loop. A few application, if not most, will drive their event loop during the idle phase, or actively drive it whenever a control invalidate the view.

GUI are usually event driven, so unless the GUI controls are actively being interacted with, they are usually in some idle loop. A few application, if not most, will drive their event loop during the idle phase, or actively drive it whenever a control invalidate the view.

Thanks cgrant,

If I get it correctly, my case will be special then since I uses immediate mode gui: ImGui which need to call it's event handle function every frame (correct me if I got it wrong)

The windows event are not supposed to last long, that is by design, any long processing is to be banned from that message handling. You are perfectly fine recording input events from one rendered frame to an other, and resolve the actions in a single aggregate update once and for good.

This topic is closed to new replies.

Advertisement