We confirm the Java wrapping of VTK is also impacted by this behavior.
We reproduce the problem described in this post with all the Windows+Nvidia configurations we tried.
Here is our findings in case it helps:
The best workaround we have so far is to turn on the nopixfmt option: sun.awt.nopixfmt=true.
This way we always get a single configuration returned and the expected OpenGL version is used.
Looking at the Win32GraphicsDevice source code, the number of configurations returned as well as the value of the default configuration depends on the default pixel format id.
Maybe using nopixfmt has influence on the default pixel format ID and results in the expected configuration being picked?
Or maybe it has influence on the isDefaultDevice check at the start of getConfigurations()?
this workaround works for me as well, but in my opinion it would be in any case important to understand why JOGL is creating the incorrect GLContext in GLCanvas when multiple DisplayConfiguration's are returned and GraphicsDevice.getConfigurations() is called.
If there is indeed a defect in JOGL, I believe it would be preferable to fix it rather than relying on a workaround, which by the way may not be viable for everyone (e.g., for applications which indeed need the multiple "separate" GraphicsConfigurations).
Regards and thanks for your time investigating on this issue.
Any chance of seeing this fixed in the near future in JOGL?
The suggested workaround of setting "-Dsun.awt.nopixfmt=true" works 99% of the times for me, but sometimes causes JOGL to crash anyway, with some specific graphics cards / display drivers.
For instance, today I dealt with a Win 10 PC having an NVIDIA Quadro K600 graphics adapter and running the latest compatible NVIDIA display driver, and my JOGL-based canvas (VTK's vtkJoglCanvasComponent, based on GLCanvas) caused a JVM crash as soon as the canvas was displayed in my application.
This PC actually had 2 graphics adapters connected to 3 monitors:
* Basic embedded graphics adapter connected to standard PC monitor (Screen 1)
* NVIDIA Quadro K600 connected to 2 medical displays (Screen 2 and Screen 3, EIZO 3 megapixels displays)
My application was running on the medical displays, and the container panels in turn containing VTK's vtkJoglCanvasComponent were indeed using a GraphicsConfiguration related to the NVIDIA Quadro K600 adapter.
On the other side, a very similar PC with the same monitor configuration, but using an NVIDIA Quadro K2000 adapter, was running fine with no crashes with my Java + VTK + JOGL application (always specifying "-Dsun.awt.nopixfmt=true").
Maybe, if this issue is fixed "at the root" in JOGL, I could avoid adopting the "-Dsun.awt.nopixfmt=true" workaround, and my application wouldn't crash also on such hardware configurations.
In case a financial contribution could help somehow in fixing this issue faster, I will be glad to consider it.
Yes, I centralize on this repository clones all bugs and potential workaround and hence copy part of this conversation with Lucas's hint.
I unfortunatelly won't be available for a while to work on this topics.
About your problem : I once worked with people encountering crashes with NVidia QUADRO devices. Without real understanding of the root cause, we have been able to avoid the problem by removing an install of MESA from the path on this computer.
If you are 100% confident that this issue corresponds with a bug in the NVIDIA driver, then I fully understand and agree.
However, the fact that whenever GraphicsDevice.getConfigurations() returns multiple GraphicsConfigurations (which is fully legal, and happens when I set "-Dsun.java2d.noddraw=true" with all NVIDIA adapters / drivers that I've tested), a single call to GraphicsDevice.getConfigurations() causes GLCanvas to pick an OpenGL 1.1 context seems weird to me.
However, I do not know the details of how the profile selection works in GLCanvas.
So, if you JOGL experts are confident this is a driver issue, then I understand.
I've just run my test case "vtk.sample.rendering.JoglContextTestCase" (which was included in this Thread) on my development machine (NVIDIA GeForce GTX 1060 6 GB, dual screen), and setting "-Djogl.disable.opengles=true" doesn't make any difference: an OpenGL 1.1 profile is used by GLCanvas. Here is the output of my test case with this property set:
Again, the only way to make it work on my PC, and on many other NVIDIA-powered PCs that I've tested, is to set the "-Dsun.awt.nopixfmt=true" system property. At that point, the output of my "vtk.sample.rendering.JoglContextTestCase" test case is:
this afternoon I should be able to connect to another PC having a couple of on "NVIDIA Quadro K600" adapters connected to two medical displays, which was crashing with JOGL, no matter the "-Dsun.awt.nopixfmt=true" setting. Hopefully, I will be able to collect full JOGL debug information on that PC as well.
In the meanwhile, I've collected JOGL's debug logs on my development PC (NVIDIA GeForce GTX 1060 6GB, Windows 10 Pro 64-bit, NVIDIA driver version: 512.15, dual monitor) with my "vtk.sample.rendering.JoglContextTestCase" test case, without any "sun.awt.nopixfmt" system property, which is the situation in which my JOGL GLCanvas erroneously picks up an Open GL 1.1 profile:
as anticipated, I've been able to run our JOGL-based application (so, not the JoglContextTestCase test case, but our entire VTK-based JOGL-based application) on a system having two NVIDIA Quadro K600 adapters, each one connected to a 3MP medical display, and I am indeed obtaining a crash on that system.
However, for now I have no evidence that this crash is indeed connected with this issue of the incorrect Open GL context being selected - as discussed in this thread, so I prefer to open a different and brand-new thread about it.
I will post in that new thread all the debug info I've collected.
In the meanwhile, if someone has some feedback about the debug info that I've posted in this thread, I will be happy to listen.
Originally, I selected vtkJoglCanvasComponent for use in my application because, according to my tests, it was the one granting the best rendering performance as well as the best cross-platform compatibility (I managed to make it work fine on macOS as well).
However, I just modified my context test case in order to use the GLJPanel instead of GLCanvas:
In this case, without specifying any "-Dsun.awt.nopixfmt=true" system property, my "JoglJPanelContextTestCase" seems to pick up the correct OpenGL 4.6 context!
Do you have an explanation of the reason why JoglContextTestCase (using GLCanvas) is picking up an erroneous Open GL 1.1 context, while JoglJPanelContextTestCase (using GLJPanel) is picking up the correct Open GL 4.6 context on my NVIDIA-powered development PC?
I would be really nice to understand (and eventually, correct) this behavior.
I have no explanation for the GLJPanel working better than GLCanvas.
What I can say is that GLCanvas is the historical JOGL canvas which -at least some years ago- was performing on-screen rendering and not able to have Swing components rendering on top of it. GLJPanel arrived later and looking at its source code you should see that it performs offscreen rendering using an FBOBuffer, hence allowing to simply display a BufferedImage in a canvas, hence dealing with Swing components rendered on top of it. Nothing relating to your problem but a different way of working :)
I agree that fixing this would be great. However I think a major locker on improving JOGL is the pain to build and test it on so many platforms. In 2022 there are new things in the JVM that could allow to only deal with Java code when trying to invoke native OpenGL instead of using JNI+Glugen native binding. In my opinion, simplifying the low level layers of JOGL first would help having more contributors working on it.
I have tried this here if you are interested. I believe switching to such binding would allow to only work with Java code in JOGL rather Java+C code making it so painful and time consuming to build!
I agree with Martin, it would help in improving both NEWT and many aspects in the OpenGL profile management if we used Java as much as possible instead of C. Why not choosing a tiny part of JogAmp and trying to replace it by something written with Foreign Function & Memory API on at least one platform to see how it behaves? jogamp.nativewindow.windows.GDI? I'd like to give it a try for sure, the time has come.