Having a wxGLCanvas inside a wxPanel (and probably something else that is not a top window), does not work. Calling MSWDisableComposited() fixes it.
Reproducible in the cube sample:
diff --git "a/samples/opengl/cube/cube.cpp" "b/samples/opengl/cube/cube.cpp" index 83fe9bab0f..919d77bc14 100644 --- "a/samples/opengl/cube/cube.cpp" +++ "b/samples/opengl/cube/cube.cpp" @@ -460,7 +460,12 @@ MyFrame::MyFrame( bool stereoWindow ) { int stereoAttribList[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_STEREO, 0 }; - new TestGLCanvas(this, stereoWindow ? stereoAttribList : nullptr); + wxPanel* panel = new wxPanel(this); + wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); + panel->SetSizer(sizer); + //panel->MSWDisableComposited(); + TestGLCanvas* canvas = new TestGLCanvas(panel, stereoWindow ? stereoAttribList : nullptr); + sizer->Add(canvas, wxSizerFlags().Expand().Proportion(1)); SetIcon(wxICON(sample));
Maybe WS_EX_COMPOSITED should be disabled for wxGLCanvas?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Maybe
WS_EX_COMPOSITEDshould be disabled forwxGLCanvas?
It seems that wxGLCanvas has window class using CS_OWNDC style
https://github.com/wxWidgets/wxWidgets/blob/78a041f2ed63505d1a563da2885728f4af282b66/src/msw/glcanvas.cpp#L715
However, Microsoft docs for WS_EX_COMPOSITED state
This cannot be used if the window has a class style of either CS_OWNDC or CS_CLASSDC.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Thanks for noticing the problem! Just to be clear, the bug is that using arrow keys in the sample doesn't work, right? Or do you see something different? The weird thing is that I can't rotate the cube manually by pressing these keys in the (modified) sample, but pressing Space still works, i.e. it still updates when refreshed on a timer. I don't really understand why is so.
In any case, my first thought was also about CS_OWNDC. I was curious why it was added and the explanation seems to be this comment from 53fcd32 (unregister GL windows classes on program termination, fixes problem with wx being used in a DLL which is being unloaded and reloaded again, 2004-09-08) which got removed later:
/* From Angel Popov <ju...@bitex.com> Here are two snips from a dicussion in the OpenGL Gamedev list that explains how this problem can be fixed: "There are 5 common DCs available in Win95. These are aquired when you call GetDC or GetDCEx from a window that does _not_ have the OWNDC flag. OWNDC flagged windows do not get their DC from the common DC pool, the issue is they require 800 bytes each from the limited 64Kb local heap for GDI." "The deal is, if you hold onto one of the 5 shared DC's too long (as GL apps do), Win95 will actually "steal" it from you. MakeCurrent fails, apparently, because Windows re-assigns the HDC to a different window. The only way to prevent this, the only reliable means, is to set CS_OWNDC." */
I seriously doubt that any of the things mentioned there are still relevant and so I think we should indeed stop using CS_OWNDC here, but, unfortunately, doing it doesn't change the behaviour I see.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Wait, the arrow keys don't work in the modified sample just because wxPanel intercepts them for dialog navigation, so TestGLCanvas::OnKeyDown() never gets called at all. Using any other kind of keys (e.g. h, j, k, l) works just fine for me.
I suspect you might be seeing something different from what I see after all... Could you please explain how exactly is it broken for you?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
I see the same maarten does, i.e., the patched sample just drawing leftovers instead of a cube on the black background; setting environment variable wx_msw_window_no_composited to 1 fixes it.
I can also confirm that removing CS_OWNDC from MSWCreate() does not help.
Windows 10 22H2 build 19045.2364, Windows Feature Experience Pack 120.2212.4190.0.
GPU: NVIDIA GeForce RTX 2060
Displays: https://raw.githubusercontent.com/PBfordev/wxsysinfoframe/master/screenshots/displays.png
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
OK, thanks for confirming this, I have no idea why do I still see it, but I'll try testing it under another system a.s.a.p. Sorry for misunderstanding the problem initially.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Hmm, on another machine (Windows 10 VM) I get src\msw\glcanvas.cpp(762): assert ""Assert failure"" failed in Create(): Can't find a pixel format for the requested attributes.
Debugging shows that this is due to using WGL_SAMPLE_BUFFERS_ARB and WGL_SAMPLES_ARB as neither doesn't seem to be supported by VMware OpenGL driver. So it's clearly problematic to use these ones unconditionally... I can work around this in the sample but failing by default is not nice at all. @Manolo-ES I wonder if you have any suggestions about what to do here.
But after fixing this, by explicitly using { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 } instead of the default attributes, the sample works fine for me, i.e. I still see the cube. So it looks like it's OpenGL driver dependent, which is not really surprising, but very annoying in practice because I can't test any fixes for it.
Maarten or PB, could you please check if calling MSWDisableComposited() in wxGLCanvas::Create() actually fixes the problem for you? If it does, we should at least do this for now...
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Maarten or PB, could you please check if calling
MSWDisableComposited()inwxGLCanvas::Create()actually fixes the problem for you? If it does, we should at least do this for now...
This indeed fixes the problem:
diff --git "a/src/msw/glcanvas.cpp" "b/src/msw/glcanvas.cpp" index 0f419543c6..47c9acd9e8 100644 --- "a/src/msw/glcanvas.cpp" +++ "b/src/msw/glcanvas.cpp" @@ -753,6 +753,8 @@ bool wxGLCanvas::Create(wxWindow *parent, if ( !CreateWindow(parent, id, pos, size, style, name) ) return false; + MSWDisableComposited(); + // Choose a matching pixel format. // Need a PIXELFORMATDESCRIPTOR for SetPixelFormat() PIXELFORMATDESCRIPTOR pfd;
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Same as @vadz comment above, running the modified cube sample I can see the cube. Pressing SPACE key makes the cude rotates as expected, although the arrow keys don't work as explained above!
Tested on:
Windows 10 Professionnel
Version 21H2
Build 19044.2364
Windows Feature Experience Pack 120.2212.4190.0
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
It seems indeed OpenGL / graphics card related. When I switch on the same device Nvidia and Intel, the first one doesn't show the cube, the second one does.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
It seems indeed OpenGL / graphics card related. When I switch on the same device between Nvidia and Intel, the first one doesn't show the cube, the second one does.
Indeed, I have an integrated Intel(R) HD Graphics 4000 card. so maybe this is not a Windows problem but rather a device/driver problem !!
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Speaking of VM failure due to multisampling I've already told at e11ea1b#commitcomment-85572808 that asking for this feature in 'Defaults()' is not a good idea, I'd remove it letting the user ask for it if needed.
I don't think it's a driver issue, but sure it is a VM lack.
Regarding the composite or not composite thing, I don't understand why would any body set this mode for wxGLCanvas, because the OGL-driver writes to the display, despite of if the OS wants to also draw in the canvas. If it's needed when gl's parent window has it may explain it, not complitely for me.
Regarding owning th DC, I think that old reason VZ resurfaced is not valid nowadays. A thing to be tested.
Removing that CS_OWNDC is easy and requires some minor changes (retrieving the current DC when it's asked for).
Regarding Intel or NVidia drivers... well, Nvidia is famous at "every thing works, even when the specifications say other thing". Not good as a test environment. The other way is true: if it fails on Nvidia likely will fail every where.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Maarten or PB, could you please check if calling
MSWDisableComposited()inwxGLCanvas::Create()actually fixes the problem for you? If it does, we should at least do this for now...
This indeed fixes the problem:
diff --git "a/src/msw/glcanvas.cpp" "b/src/msw/glcanvas.cpp" index 0f419543c6..47c9acd9e8 100644 --- "a/src/msw/glcanvas.cpp" +++ "b/src/msw/glcanvas.cpp" @@ -753,6 +753,8 @@ bool wxGLCanvas::Create(wxWindow *parent, if ( !CreateWindow(parent, id, pos, size, style, name) ) return false; + MSWDisableComposited(); + // Choose a matching pixel format. // Need a PIXELFORMATDESCRIPTOR for SetPixelFormat() PIXELFORMATDESCRIPTOR pfd;
Just wanted to confirm that adding MSWDisableComposited fixes the GL canvas for me as well. Something in wxWidgets must have changed recently, as an older executable of mine from half a year ago still rendered fine (on the same NVIDIA drivers) and it broke when I pulled master.
Windows 10.0.19045
Vendor: 'NVIDIA Corporation'
Renderer: 'NVIDIA GeForce RTX 2080/PCIe/SSE2'
Version: '3.3.0 NVIDIA 527.56'
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Yes, the change is that we enable WS_EX_COMPOSITED by default now and we didn't do it before.
It's not, of course, a problem to not turn it on for the OpenGL window itself. The problem is that this style seems to (even though I've never seen this mentioned in the official documentation) cascade down, so this is not enough (well, again, I'm unable to test this myself as I don't have any nVidia cards here), i.e. just resetting it for the window itself probably doesn't fix the problem -- although I'd be grateful if somebody could please test this too, just in case it does, i.e. apply this patch:
diff --git a/src/msw/glcanvas.cpp b/src/msw/glcanvas.cpp index 0f419543c6..a0fd3ec9bd 100644 --- a/src/msw/glcanvas.cpp +++ b/src/msw/glcanvas.cpp @@ -28,6 +28,7 @@ #endif #include "wx/msw/private.h" +#include "wx/msw/private/winstyle.h" #include "wx/glcanvas.h" @@ -753,6 +754,8 @@ bool wxGLCanvas::Create(wxWindow *parent, if ( !CreateWindow(parent, id, pos, size, style, name) ) return false; + wxMSWWinExStyleUpdater(GetHwnd()).TurnOff(WS_EX_COMPOSITED);
+
// Choose a matching pixel format.
// Need a PIXELFORMATDESCRIPTOR for SetPixelFormat()
PIXELFORMATDESCRIPTOR pfd;It would be very much preferable to apply this if it does work because it would still keep using compositing for the sibling windows but, again, I suspect it's not going to...
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Applying the above diff does not fix the issue on Win10 computer with NVIDIA GeForce RTX 2060 (Driver Version: 31.0.15.2802; Driver Date: 22.12.2022).
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Thanks for checking this!
I'll add MSWDisableComposited() but we'll probably have to somehow document the fact that any windows that are siblings of an OpenGL one (or of a wxListCtrl...) may flicker. Unless we end up reverting the change enabling the use of WS_EX_COMPOSITED entirely by 3.3.0 which I suspect may well still happen...
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Closed #23112 as completed via 2d37e9f.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()