remove ASSERT nearly always triggered in wxGLCanvas::SetCurrent
|Reported by:||Remdul||Owned by:||VZ|
|Keywords:||assert SetCurrent wxGLCanvas||Cc:||dgud@…|
A race condition causes an ASSERT to be triggered (sometimes multiple times in succession) when wxGLCanvas::SetCurrent is called in typical usage. This happens mainly on Linux (tested Ubuntu, Linux Mint). This happens because on most Linux platforms, because X does not guarantee a window to be shown, even when it is instructed by wx through ::Show (or other wx methods).
The comment in the code is also incorrect. On Linux, MakeCurrent can be called just fine when a window is invisible. IIRC, it is on *Windows*, that this may be a problem, not Linux.
Secondly, the ASSERT is logically, technically and practically impossible to workaround. While it is possible to delay GL initialization by calling ::SetCurrent in the first canvas ::Paint() even, on all platforms I tested ::Paint() is often triggered *before* the window is visible (e.g. when a window state is changed to maximized on startup). All attempts to force the window to be shown before ::Paint() will fail, because X by design and specification does not guarantee a window to be shown even when it is specifically instructed to do so. ::IsShownOnScreen() will return false, even after a call to ::Show (again because the window manager/X etc hasn't actually made it visible yet; it simply doesn't guarantee that).
Calling wxYield after ::Show will also not help in this situation. Even putting xwYield in a loop, and repeating it for several (milli)seconds will not work. The window is simply never be guaranteed to be visible, ever, and thus the assert WILL be triggered, always. It is only by accident that it won't be triggered; when the X finishes the command queue and shows the window just in time *before* ::SetCurrent is invoked). I suppose thats why this bug hasn't been caught in tests for so long. On all systems I tested the bug happens ~80% to 100%, more frequent depending on CPU usage (the busier X server is, the more frequent). XFCE systems are particularly prone to this issue.
Of course, all of this is moot, since the ASSERT is needless. MakeCurrent can just be called even when the window is invisible, at least on Linux. All applications work fine with this patch applied, including all of my own software.
This bug has been an issue for me since wx2.8.0. I assumed it would be fixed by someone, but strangely it still hasn't. So here it is. I believe this bug was first introduced in wx2.8, presumably because the behavior of ::IsShownOnScreen was changed (judging by SVN log of glcmn.cpp, the assert has always been there).
Change History (15)
Changed 10 months ago by Remdul
comment:13 Changed 9 months ago by VZ
- Owner set to VZ
- Resolution set to fixed
- Status changed from new to closed