Incorrect context on GLCanvas drawable

classic Classic list List threaded Threaded
44 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Incorrect context on GLCanvas drawable

MarcoNL
This post was updated on .
Hi.
I am using JOGL (2.4.0-rc-20210111) together with VTK 9.0.1.

In particular, I am using the GLCanvas component embedded into VTK's vtkJoglCanvasComponent.

My application works quite fine (both on Windows and on macOS - with Java 8 JRE).

However, I am facing a strange sporadic crash when I invoke a function in my application which removes the GLCanvas-based GUI panel from its container, and then adds it to a newly-created JFrame (it's a kind of "full screen mode" function of my application). This crash seems to happen only on Windows, while I've been unable to reproduce it on macOS so far.

In VTK's vtkJoglCanvasComponent class, there is a GLEventListener, whose init() callback gets called both upon initial display of the GLCanvas-based GUI panel, and then again when the GLCanvas-based GUI panel is added to the newly-created JFrame. Between the two init() calls, there is a dispose() call which is invoked when the GLCanvas-based GUI panel is removed form its original container.

Upon first invocation of the init() callback, if I call 'drawable.getContext()', I obtain an OpenGL 4.6 context, and everything works like a charm.

On the other side, upon the second invocation of the init() callback (after addition of the GLCanvas to the new JFrame), **SOMETIMES** calling 'drawable.getContext()', I obtain an OpenGL 1.1 context. When this happens, then VTK crashes, because VTK 9 requires at least OpenGL 3.2 in order to work properly.

I know that my description of the problem is quite limited, but can you guess why I **SOMETIMES** get an OpenGL 1.1 context upon init() with my GLCanvas-based panel?

This happens on many different Windows PCs with many different display adapters / drivers, when I invoke this "full screen mode" feature in my application (which works as described above: remove GLCanvas from its container --> create a new JFrame --> add the GLCanvas to the new JFrame).

It may be something in VTK, but I was just wondering if you could guess where the problem might be, and maybe point us in the correct direction.

Also, let me mention that for some reason this issue seems to appear more frequently with Jetbrain's Java 8 JRE, even though I have had a few occurrences of the issue even with Adopt OpenJDK Java 8 JRE.

Thanks in advance and best regards,

Marco Sambin
Reply | Threaded
Open this post in threaded view
|

Re: Incorrect context on GLCanvas drawable

gouessej
Administrator
Hello

The OpenGL 1.1 context comes probably from Microsoft GDI renderer. You can set a flag to favor hardware accelerated OpenGL when calling GLProfile.getMaxFixedFunc(), getMaximum(), etc.

Please look at this bug report and tell me whether you use a laptop with Optimus or similar technology:
https://jogamp.org/bugzilla/show_bug.cgi?id=1305
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Incorrect context on GLCanvas drawable

MarcoNL
Hi Julien,

thanks a lot for your reply!

As far as I can see from vtkJoglCanvasComponent.java source code (https://github.com/Kitware/VTK/blob/master/Wrapping/Java/vtk/rendering/jogl/vtkJoglCanvasComponent.java), the GLCanvas is indeed initialized like this:

GLCanvas glCanvas = new GLCanvas(new GLCapabilities(GLProfile.getMaximum(true)));

In fact, when the GLCanvas-based VTK component is initially used in my application, it ALWAYS works fine. Once the GLCanvas-based panel is displayed for the first time in my application, GLEventListener.init() is called inside vtkAbstractJoglComponent.java (see https://github.com/Kitware/VTK/blob/master/Wrapping/Java/vtk/rendering/jogl/vtkAbstractJoglComponent.java). At this point, the "GLContext ctx" variable defined inside the GLEventListener.init() always corresponds with an OpenGL 4.6 context, as logged by a "ctx.toString()" call. So far, so good.

However, when a "full screen mode" function is invoked in my application, sometimes my application crashes. Here is what this "full screen mode" function does:

1) Remove the GLCanvas-based component from its container
    --> GLEventListener.dispose() is called inside vtkAbstractJoglComponent.java --> see https://github.com/Kitware/VTK/blob/master/Wrapping/Java/vtk/rendering/jogl/vtkAbstractJoglComponent.java)

2) Create a new JFrame

3) Add the existing GLCanvas-based component (i.e., the same GLCanvas which was created at point 1 above, hence apparently using the same GLCapabilities) to this newly-created JFrame
    --> GLEventListener.init() is invoked again inside vtkAbstractJoglComponent.java
However, this time, if I invoke "ctx.toString()" inside the init() callback, **SOMETIMES** I get an OpenGL 1.1 context, and when this happens, my application crashes, because VTK crashes, due to insufficient OpenGL context.

Do you have an explanation as to why the second GLEventListener.init() made on the same GLCanvas instance (following to removal of the panel from its container + add of the panel to new JFrame) **SOMETIMES** returns an OpenGL 1.1 context?

I was suspecting some threading issue, but I've verified and I am sure that all init() and all dispose() calls are always done on the same thread, which is the EDT (SwingUtilities.isEventDispatcherThread() always returns 'true' in these callbacks).

Any hint would be greatly appreciated.
Thanks in advance for your feedback.

Best regards,

Marco Sambin
Reply | Threaded
Open this post in threaded view
|

Re: Incorrect context on GLCanvas drawable

MarcoNL
Hi Julien,

to answer your specific question, no, I am not using a laptop.
I am mainly testing on my development workstation (HP z640) havong a single NVIDIA GeForce GTX 1060 graphics adapter.

But as stated in my initial post, the issue can be reproduced on many different hardware configurations.

Regards,

Marco
Reply | Threaded
Open this post in threaded view
|

Re: Incorrect context on GLCanvas drawable

gouessej
Administrator
In reply to this post by MarcoNL
Please provide a reproducer using JOGL without VTK. Maybe using a similar component but based on a GLJPanel (vtkJoglPanelComponent?) would help.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Incorrect context on GLCanvas drawable

MarcoNL
Hello Julien,

thank you for your reply.

Actually, I spent several hours in an effort to create a self-contained test case, demonstrating the crash outside my own VTK-based application, but so far I've been unable to do so.

So, for now, the question is: can you imagine any reason why JOGL's GLCanvas may correctly return a "correct" OpenGL 4.6 GLContext in my application's init() callback [calling drawable.getContext()], and then at a certain point, for the same GLCanvas, with the same GLProfile and the same GLCapabilities, return an "incorrect" OpenGL 1.1 GLContext at a later invocation of my application's init() callback [calling drawable.getContext()]?

May an incomplete / incorrect release of some OpenGL resources cause this behavior in your opinion? May some threading issues (I don't see which ones, since my init() always executes on the EDT...) cause a similar behavior? May creation of a new "root" JFrame somehow cause a similar behavior?

Sorry for asking such generic questions, but I am looking for some guidance about where to look to build a test case which indeed is able to reproduce the issue I am experiencing inside my application.

I am looking forward to hearing from you.
Thanks and best regards,

Marco Sambin
Reply | Threaded
Open this post in threaded view
|

Re: Incorrect context on GLCanvas drawable

MarcoNL
Hi again,

do you think the GraphicsConfiguration upon which I create my "root" JFrame (i.e., the one finally containing my GLCanvas-based panel) may make a difference with respect to the GLContext that GLCanvas's init() callback is able to return?
My approach in creating JFrames in my application is that I identify the GraphicsDevice corresponding to my target screen (in case of a multi-screen environment), then I use this GraphicsConfiguration:

GraphicsDevice myTargetScreenDev = ...;
GraphicsConfiguration myGraphicsConfig = myTargetScreenDev.getDefaultConfiguration();
JFrame myRootJFrame = new JFrame(myGraphicsConfig);
...

If I invoke myTargetScreenDev.getConfigurations(), I obtain 6 different GraphicsConfiguration's for my target GraphicsDevice. However, just inspecting these 6 different instances, I am unable to tell what is different in each instance.

Do you think it is worth investigating more about this, or creating my root JFrame on myTargetScreenDev.getDefaultConfiguration() is safe enough for JOGL purposes?

Thanks in advance for your comments.
Best regards,

Marco Sambin
Reply | Threaded
Open this post in threaded view
|

Re: Incorrect context on GLCanvas drawable

Martin
Hi Marco,

I have no clue for your problem, but I (may) have here a piece of code that may help you start developing a standalone reproducible example https://forum.jogamp.org/Selecting-the-highest-possible-GL-profile-at-runtime-tp4041302p4041351.html

I am interested by knowing more about your attempts as I myself tried to run VTK+JOGL on Mac 10.15 and noticed JOGL won't start on 10.15 without JOGL 2.4 (https://discourse.vtk.org/t/simplevtk-java-example-crashing-on-macos/6472/6).

Best,

Martin
Reply | Threaded
Open this post in threaded view
|

Re: Incorrect context on GLCanvas drawable

MarcoNL
Hello Martin,

thanks for your feedback.

I had read your post before, but my problem seems to be a bit different:

In fact, my application's vtkJoglCanvasComponent, in turn using JOGL's GLCanvas, is "sometimes" picking up an OpenGL 1.1 GLContext, and in those cases VTK crashes. The GLProfile seems to be always correct.

One question for the JOGL guys: I've noticed that vtkJoglCanvasComponent creates GLCanvas like this:

GLCanvas joglCanvas = new GLCanvas(new GLCapabilities(GLProfile.getMaximum(true)));

As far as I can see, VTK doesn't pass any GraphicsDevice to GLCanvas.

So, in this situation, will the GraphicsConfiguration upon which I create my root JFrame (i.e., the JFrame containing the GLCanvas containers, hence in turn also the GLCanvas itself) be relevant for the capabilities of the GLCanvas in terms of the GLContext it will be able to create?

Since my issue happens when I create a new root JFrame for my GLCanvas, I have the feeling the involved GraphicsConfigurations may have an influence.

Please notice that on my test PC I have multiple screens. However, my crash also happens on other single-screen PCs I have tested.

Let me know please.
Thanks and best regards,

Marco Sambin
Reply | Threaded
Open this post in threaded view
|

Re: Incorrect context on GLCanvas drawable

MarcoNL
Hi all.
Today I think I've made some radical progress in the analysis of my issue.

First of all, I've built a simple test program:

JoglContextTestCase.java

This test program simply creates a JFrame on the default GraphicsConfiguration for my first screen, and adds an empty GLCanvas to this JFrame.
While creating the GUI, this test program enumerates all GraphicsDevice's available on my PC, and for each GraphicsDevice, all available GraphicsConfigurations.
Finally, in the init() callback of my GLEventListener, I simply print the GLVersion of my drawable.getContext().

On my Windows 10 development PC, which has two screens attached to a NVIDIA GeForce GTX 1060 6 GB graphics adapter, here is what I get on the stdout:

==============

Screen device # 0: \Display0
Screen device # 0, configuration # 0:
Screen device # 1: \Display1
Screen device # 1, configuration # 0:
NewFrame created in thread [15], isEDT: true
* Context GL version: 4.6 (Compat profile, arb, compat[ES2, ES3, ES31, ES32], FBO, hardware) - 4.6.0 NVIDIA 456.71

==============

So far, so good. In my init() callback, I get an OpenGL 4.6 context, and that's great. VTK would work fine with such a context.

However, if I just pass "-Dsun.java2d.noddraw=true" system property to my JVM (which is required to run both JOGL and my application smoothly), here is what I get:

==============

Screen device # 0: \Display0
Screen device # 0, configuration # 0:
Screen device # 0, configuration # 1:
Screen device # 0, configuration # 2:
Screen device # 0, configuration # 3:
Screen device # 0, configuration # 4:
Screen device # 0, configuration # 5:
Screen device # 1: \Display1
Screen device # 1, configuration # 0:
Screen device # 1, configuration # 1:
Screen device # 1, configuration # 2:
Screen device # 1, configuration # 3:
Screen device # 1, configuration # 4:
Screen device # 1, configuration # 5:
NewFrame created in thread [15], isEDT: true
* Context GL version: 1.1 (Compat profile, arb, compat[], FBO, hardware) - 1.1.0

==============

As you can see, with this system property, first of all I get 6 different GraphicsConfiguration per each screen (I am uncertain why, but this certainly doesn't depend on JOGL), and then the GLContext I get in my init() callback is an OpenGL 1.1 context (and I believe this depends on JOGL and shouldn't happen)!

Even stranger, if in my test case code I simply remove the call to GraphicsDevice.getConfigurations() (but always passing "-Dsun.java2d.noddraw=true"), then again I am getting a correct OpenGL 4.6 context. Here is the output I obtain in this last test configuration:

==============

NewFrame created in thread [15], isEDT: true
* Context GL version: 4.6 (Compat profile, arb, compat[ES2, ES3, ES31, ES32], FBO, hardware) - 4.6.0 NVIDIA 456.71

==============

I looks like the fact that I call "GraphicsDevice.getConfigurations()" (which apparently should do nothing) is changing something in the way JOGL creates its GLContext in the GLCanvas.

I would really appreciate your feedback, now that I've been able to put together a complete and very simple test case.

Thanks in advance for your time.
Best regards,

Marco Sambin



Reply | Threaded
Open this post in threaded view
|

Re: Incorrect context on GLCanvas drawable

gouessej
Administrator
Actually, you're almost ready to fill a bug report. Good job.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Incorrect context on GLCanvas drawable

MarcoNL
Hello Julien,

so, are you suggesting that I should file a bug report here?

https://jogamp.org/bugzilla/buglist.cgi?chfield=ajyavfrj&order=product%2Cbug_status%2Cpriority%2Cassigned_to%2Cbug_id&query_format=advanced

Do you already have any clues as to why this issue may be happening?

Thanks a lot for your time.

Best regards,

Marco Sambin
Reply | Threaded
Open this post in threaded view
|

Re: Incorrect context on GLCanvas drawable

MarcoNL
By the way,

my issue seems to be very similar to what reported this old (and long... ;-)) thread:

https://forum.jogamp.org/Jogl-Using-Wrong-Generic-Graphics-Adapter-td4033216i20.html

However, this thread does not seem to have reached a conclusion. Maybe this time could be the "good time", since we finally have a reproducible test case.

Let me know if I can contribute further: I will do my best.

On the other side, if some financial contribution may help in speeding up the resolution of this issue, we will be happy to consider it as well.

Thanks and best regards,

Marco Sambin
Reply | Threaded
Open this post in threaded view
|

Re: Incorrect context on GLCanvas drawable

gouessej
Administrator
Contact Sven for the financial contribution, yes it may help. I think that disabling DirectDraw in Java2D seems to be the culprit but I don't see precisely why right now, maybe Java2D tries to use its OpenGL pipeline in this case and something bad happens (you could disable it too to force Java2D to use its software renderer). Your reproducer is very helpful.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Incorrect context on GLCanvas drawable

MarcoNL
Hi Julien,

thank you for your reply.
I have just written an email to Sven through this Forum. I hope he gets it.

In the meanwhile, if you discover something on the issue, please let me know.
The strangest thing is that somehow the presence of the .getConfigurations() call is making a difference for JOGL. It would be very interesting to understand why.

Thanks and best regards,

Marco Sambin
Reply | Threaded
Open this post in threaded view
|

Re: Incorrect context on GLCanvas drawable

Martin
Hi Marco,

Great you wrote a test. I could not reproduce your issue on my macOS M1 + Azul JDK 8. I should receive a new Windows machine next week and will tell you when/if I can reproduce.
Reply | Threaded
Open this post in threaded view
|

Re: Incorrect context on GLCanvas drawable

MarcoNL
Hi Martin,

thanks for your feedback.

Indeed, this seems to be a Windows-only issue, considering it seems actually related to the -Dsun.java2d.noddraw=true system property.

But until we understand the actual cause of the issue I am experiencing, I think we cannot exclude eventual impacts on other OS's as well.

Best regards,

Marco
Reply | Threaded
Open this post in threaded view
|

Re: Incorrect context on GLCanvas drawable

gouessej
Administrator
I reproduce your problem under Windows 10:
without -Dsun.java2d.noddraw=true
Screen device # 0: \Display0
Screen device # 0, configuration # 0:
NewFrame created in thread [17], isEDT: true
* Context GL version: 4.5 (Compat profile, arb, compat[ES2, ES3, ES31, ES32], FBO, hardware) - 4.5.0 NVIDIA 369.09

with -Dsun.java2d.noddraw=true
Screen device # 0: \Display0
Screen device # 0, configuration # 0:
Screen device # 0, configuration # 1:
Screen device # 0, configuration # 2:
Screen device # 0, configuration # 3:
Screen device # 0, configuration # 4:
Screen device # 0, configuration # 5:
NewFrame created in thread [17], isEDT: true
* Context GL version: 1.1 (Compat profile, arb, compat[], FBO, hardware) - 1.1.0
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Incorrect context on GLCanvas drawable

MarcoNL
Well, that's a start!

Let me know if you discover why JOGL is returning an OpenGL 1.1 context in the case where Java returns multiple GraphicsConfigurations for each GraphicsDevice (and getConfigurations() is called).

Thanks a lot in advance for your feedback.

Regards,

Marco Sambin
Reply | Threaded
Open this post in threaded view
|

Re: Incorrect context on GLCanvas drawable

gouessej
Administrator
I'll look at the source code of Java2D next week.
Julien Gouesse | Personal blog | Website
123