My app has been drawing its graphics from a worker thread for over 10 years now and I've never had any problems with it. The worker thread draws to my HWND
(created by the main thread) like this:
hdc = GetDC(hwnd);
SetDIBitsToDevice() ... or StretchDIBits()
ReleaseDC(hwnd, hdc);
After having ported my app to other platforms, I began to realize that drawing from any other thread than the main thread is usually a no-go on many platforms (e.g. macOS). My research has shown that this might be true for Win32 as well but I'm still lacking a definite answer.
Thus, my question:
Is it allowed to draw to my window like shown above from a worker thread that did not create the window it is drawing to? Note that the worker thread is really the only thread that draws to the window. The main thread doesn't do any drawing. Not even in WM_PAINT
. Drawing in WM_PAINT
is unnecessary in my case because the worker thread draws at 50fps.
If it isn't allowed, what's the best way to delegate drawing from the worker thread to the main thread?
Is it allowed to draw to my window like shown above from a worker thread that did not create the window it is drawing to?
It may not be the best solution to your problem, but it's safe, as long as you respect the documented rules for GetDC
:
- Note that the handle to the DC can only be used by a single thread at any one time.
ReleaseDC
must be called from the same thread that called GetDC
.If you do render to the same device context from multiple threads, you are responsible for synchronizing accesses to it.*
As explained in the comments, a better solution would be to generate the DIB from the worker thread, and have this thread update the window by calling RedrawWindow
. The main thread can then StretchBlt
in its WM_PAINT
handler. Calling RedrawWindow
across threads implements a synchronization barrier. When the call returns, rendering on the target thread has run to completion, and it's safe to re-use the DIB.
* See Thread affinity of user interface objects, part 2: Device contexts.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With