UI Artifacts when using GLCanvas and GLJpanel

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

UI Artifacts when using GLCanvas and GLJpanel

mikaelhc
Hi,

I'm using JOGL to provide some 3D visualization in a large scientific application. The UI has a lot of tabs, which can be configured in different ways - the existing UI is all swing.

My problem is, that if I use the GLCanvas widget, I see a lot of flickering and artifacts whenever the layout of the tabs is changed (for instance when changing to a split view). For instance, it looks like the OpenGL window is temporarily placed in the top-upper corner of the screen, before being properly placed. This happens both on Windows and Mac and on several graphics cards. Another problem is, that sometimes the OpenGL canvas is not shown, but seems to be drawn behind a grey frame - then, if I invoke a context menu on the component, the OpenGL canvas appears again.

If I use the GLJPanel, there is no flickering and artifacts, but when I use the context menu, I get visual artifacts (square regions which are redrawn with content from other places in the UI). I have tried setting JPopupMenu.setDefaultLightWeightPopupEnabled(...), but with no effect. The GLJPanel artifacts are only seen on Windows.

I would be grateful for any help in solving this!

Btw, this happens both on 2.0-RC11 and the latest auto aggregated build.
Reply | Threaded
Open this post in threaded view
|

Re: UI Artifacts when using GLCanvas and GLJpanel

gouessej
Administrator
Hi

I use GLCanvas and JPopupMenu.setDefaultLightWeightPopupEnabled(false) and I don't have such troubles.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: UI Artifacts when using GLCanvas and GLJpanel

mikaelhc
GLCanvas and heavyweight menus also works fine for me, but then I get all the layout artifacts described above - which might a mixing AWT/Swing issue?

However, when using GLJPanel I get random painting artifacts when using menus.
Reply | Threaded
Open this post in threaded view
|

Re: UI Artifacts when using GLCanvas and GLJpanel

gouessej
Administrator
Yes we can't do anything against layout artifacts caused by mixing heavyweight and lightweight components except using a few hacks (noerasebackground, etc...). GLJPanel should only be used in extreme cases, for example in internal frames (JInternalFrame) when you need to draw a transparent "window" above the rest of your application (I did that once, it was really cool :)). I often put a GLCanvas into a JPanel. I understand your position, I worked for several years in scientific visualization.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: UI Artifacts when using GLCanvas and GLJpanel

Sven Gothel
Administrator
In reply to this post by mikaelhc
On 04/24/2013 10:27 AM, mikaelhc [via jogamp] wrote:
> GLCanvas and heavyweight menus also works fine for me, but then I get all the
> layout artifacts described above - which might a mixing AWT/Swing issue?
Probably .. and as we know, you mileage may vary (YMMV) here,
since some platforms behave differently.

GLJPanel should be a working last-resort.

>
> However, when using GLJPanel I get random painting artifacts.
That should not happen.
Please test w/ latest aggregated build (-> Wiki: Releases/Versions)

If possible, please file a bugreport if it is still visible in latest build.
Pls attach a unit test or demo w/ additional platform descriptions
to help reproducing the bug (-> Wiki/FAQ: Bugreport).

Thank you.

~Sven



signature.asc (911 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: UI Artifacts when using GLCanvas and GLJpanel

mikaelhc
Sven Gothel wrote
> However, when using GLJPanel I get random painting artifacts.
That should not happen.
Please test w/ latest aggregated build (-> Wiki: Releases/Versions)

If possible, please file a bugreport if it is still visible in latest build.
Pls attach a unit test or demo w/ additional platform descriptions
to help reproducing the bug (-> Wiki/FAQ: Bugreport).
The GLJPanel artifacts occur both on RC11 and the latest aggregated builds (but only on my Windows machines - not on Mac).

Notice that the OpenGL view displays fine - the artifacts happen on the other (Swing) components in the application, especially after using the context menu, but sometimes also when changing the arrangement of the tabs in the application. It looks like some arbitrary regions are drawn with graphics from other parts of the application. When an update is triggered (for instance when resizing components) the artifacts disappear.

I'm not sure that I can create a reproducible example (since the whole UI is quite complex), but I'll give it a try.  
Reply | Threaded
Open this post in threaded view
|

Re: UI Artifacts when using GLCanvas and GLJpanel

Sven Gothel
Administrator
On 04/24/2013 02:16 PM, mikaelhc [via jogamp] wrote:

>     Sven Gothel wrote
>     > However, when using GLJPanel I get random painting artifacts.
>     That should not happen.
>     Please test w/ latest aggregated build (-> Wiki: Releases/Versions)
>
>     If possible, please file a bugreport if it is still visible in latest build.
>     Pls attach a unit test or demo w/ additional platform descriptions
>     to help reproducing the bug (-> Wiki/FAQ: Bugreport).
>
> The GLJPanel artifacts occur both on RC11 and the latest aggregated builds
> (but only on my Windows machines - not on Mac).
>
> Notice that the OpenGL view displays fine - the artifacts happen on the other
> (Swing) components in the application, especially after using the context
> menu, but sometimes also when changing the arrangement of the tabs in the
> application. It looks like some arbitrary regions are drawn with graphics from
> other parts of the application. When an update is triggered (for instance when
> resizing components) the artifacts disappear.
>
> I'm not sure that I can create a reproducible example (since the whole UI is
> quite complex), but I'll give it a try.  
Sounds familiar .. I have heard about that actually.

Pls create a detailed bug report w/ most simple unit test
and I will also ask around ..

Try to disable the GLSL flipping via:
  -Djogl.gljpanel.noglsl

Pls .. reply-to/mention this in your new bug report - thx!

~Sven



signature.asc (911 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: UI Artifacts when using GLCanvas and GLJpanel

mikaelhc
I can create an error report, but after trying for several hours, I have not been able to create a demo case - the behaviour seems to depend on some timing between different UI drawing operations.

What I have noticed is the following:
- The artifacts are always on other UI elements than the JGLCanvas. They disappear when the UI elements are redrawn.
- The artifacts happen when other UI elements (context menus and modal dialogs) are drawn over the JGLCanvas. In particular the artifacts seem to manifest when the elements are created or closed. For the modal dialogs, I noticed that if I click 'Close' and the mouse pointer is located outside the JGLCanvas, I get no artifacts - the artifacts only appear if the Close button is located over the JGLCanvas.
- The artifacts depend on what the OpenGL display method does. If I draw nothing, or only a few objects, I don't see any artifacts.
- I managed to get rid of the context menu induced artifacts, by temporarily disabling the 3D drawing, when the JGLCanvas lost or got focus. But this does not work for the artifacts induced by the modal dialogs.

Setting -Djogl.gljpanel.noglsl has no effect. I've also tried enabling JOGL debug, and using the DebugGL2 context, but cannot see anything suspicious. This is on Windows (both Vista and 7) using Java 6. I'm using display lists to draw my objects, but this also happens if I use immediate mode. I'm also using some custom shaders, but disabling doesn't seem to affect the behaviour.

Any ideas for how I can get closer to the cause of this?




 

Reply | Threaded
Open this post in threaded view
|

Re: UI Artifacts when using GLCanvas and GLJpanel

gouessej
Administrator
I don't think it would solve your problem but you shouldn't use display lists. It's obsolete and badly implemented in lots of drivers.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: UI Artifacts when using GLCanvas and GLJpanel

mikaelhc
Hmm... The reason for choosing display lists was actually because I expected more hardware to support them. I have used them with OpenGL/C++ for several years, and not encountered many problems.

But I tried implementing an alternative VBO based renderer, and surprisingly I haven't seen any artifacts since. I'm not convinced they really are gone (because they seem to be timing-related), but I'll keep experimenting, and implement VBO's for all my objects.

Btw, while implementing the VBO rendering, I found what I think is another bug:

If I call "gl2.glDrawArrays(GL2.GL_TRIANGLES, 0, vertices);" with a bound buffer that has been disposed (after a OpenGL dispose), the JVM crashes (here is an excerpt):

# A fatal error has been detected by the Java Runtime Environment:
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000005193fd5f, pid=956, tid=1492
[error occurred during error reporting (printing native stack), id 0xc0000005]
...
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  jogamp.opengl.gl4.GL4bcImpl.dispatch_glDrawArrays1(IIIJ)V+0
j  jogamp.opengl.gl4.GL4bcImpl.glDrawArrays(III)V+39

It is of course an error to draw a disposed buffer, but shouldn't it be handled more gracefully?
Reply | Threaded
Open this post in threaded view
|

Re: UI Artifacts when using GLCanvas and GLJpanel

mikaelhc
Nah, changing to VBO didn't actually make a difference. Once I restored the per-pixel lighting shader, I got exactly the same artifacts.

Now I have tried to surround my display function with:

drawable.getContext().makeCurrent();
...
drawable.getContext().release();
       
And once again the artifacts seem to have disappeared, but it is probably because of the timing.  It is necessary/recommended to release the context?
Reply | Threaded
Open this post in threaded view
|

Re: UI Artifacts when using GLCanvas and GLJpanel

gouessej
Administrator
Where is your display function? Do you use a GLEventListener? You need a current OpenGL context to perform OpenGL calls.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: UI Artifacts when using GLCanvas and GLJpanel

mikaelhc
In a standard GLEventListener, overriding "public void display(final GLAutoDrawable drawable)".

The question is whether it could change something to release the context when the rendering is done, because the GLJPanel might use it in the background? (I noticed Sven mentioned a flag called 'GLSL flipping'). But I still see artifacts, so it wasn't a solution.
Reply | Threaded
Open this post in threaded view
|

Re: UI Artifacts when using GLCanvas and GLJpanel

Sven Gothel
Administrator
On 04/25/2013 09:20 PM, mikaelhc [via jogamp] wrote:
> In a standard GLEventListener, overriding "public void display(final
> GLAutoDrawable drawable)".
>
> The question is whether it could change something to release the context when
> the rendering is done, because the GLJPanel might use it in the background? (I
> noticed Sven mentioned a flag called 'GLSL flipping'). But I still see
> artifacts, so it wasn't a solution.

As far as I understood, your artifacts happen on a different 'surface'
than the GLJPanel's surface.

Is GLJPanel using 'Java 2D OpenGL pipeline' ?
Pls try turning it of via property 'jogl.gljpanel.noogl'.

We should consider to turn off the 2D OpenGL pipeline by default I guess ..

Debug property 'jogl.debug.GLJPanel' will make GLJPanel operations verbose.

~Sven



signature.asc (911 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: UI Artifacts when using GLCanvas and GLJpanel

mikaelhc
Sven Gothel wrote
As far as I understood, your artifacts happen on a different 'surface'
than the GLJPanel's surface.
Yes.

Is GLJPanel using 'Java 2D OpenGL pipeline' ?
Pls try turning it of via property 'jogl.gljpanel.noogl'.

We should consider to turn off the 2D OpenGL pipeline by default I guess ..

Debug property 'jogl.debug.GLJPanel' will make GLJPanel operations verbose.
No, I have checked it and GLJPanel does not use the Java 2D OpenGL pipeline, so disabling it has no effect. It uses the OffscreenBackend (I cloned the GLJPanel code to check what happens). It seems that on my systems Java2D.isOGLPipelineResourceCompatible() returns false.

I have enabled the debug properties, but I don't see anything posted when another window is displayed over the GLJPanel surface.





signature.asc (911 bytes) <http://forum.jogamp.org/attachment/4029034/0/signature.asc>

Reply | Threaded
Open this post in threaded view
|

Re: UI Artifacts when using GLCanvas and GLJpanel

mikaelhc
I realised that I have to enable '-Dsun.java2d.opengl=true' manually to use the "Java2D OpenGL pipeline".
But if I do this, JOGL crashes:

Checking for Java2D/OpenGL support
Java2D support: default GraphicsConfiguration = sun.java2d.opengl.WGLGraphicsConfig
java.lang.ClassNotFoundException: sun.java2d.opengl.CGLSurfaceData
	at java.net.URLClassLoader$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Unknown Source)
	at jogamp.opengl.awt.Java2D$1.run(Java2D.java:237)
	at java.security.AccessController.doPrivileged(Native Method)
	at jogamp.opengl.awt.Java2D.<clinit>(Java2D.java:118)
	at javax.media.opengl.awt.GLJPanel.<clinit>(GLJPanel.java:193)
	...
Info: Unable to find class sun.java2d.opengl.CGLSurfaceData for OS X

JOGL/Java2D OGL Pipeline active true, resourceCompatible true
Starting initialization of J2D FBO share context
java.lang.InternalError
	at jogamp.opengl.awt.Java2D.invokeWithOGLSharedContextCurrent(Java2D.java:371)
	at jogamp.opengl.awt.Java2D.initFBOShareContext(Java2D.java:610)
	at jogamp.opengl.awt.Java2D.getShareContext(Java2D.java:498)
	at javax.media.opengl.awt.GLJPanel.<clinit>(GLJPanel.java:194)
	...
Caused by: java.lang.NullPointerException
	at jogamp.opengl.awt.AWTUtil.lockToolkit(AWTUtil.java:90)
	at jogamp.opengl.awt.Java2D.invokeWithOGLSharedContextCurrent(Java2D.java:362)
	... 21 more

Notice, that I'm not on OS X, but on Windows (the first exceptions seems to search for a OS X specific class). But I guess it is the second exception that is the problem. Don't know if this sheds any light over my problem?
Reply | Threaded
Open this post in threaded view
|

Re: UI Artifacts when using GLCanvas and GLJpanel

mikaelhc
I think I finally found out why this happens.

Inside my OpenGL drawing code (the display(...) function) there was a call to a function which displayed some text in a status-bar (some mouse-over info text). It turns out this function used 'paintImmediately' to draw itself (which I wasn't aware of - it was part of some framework code written by others). This caused parts of the statusbar to be rendered on arbitrary places on the application surface. Removing the paintImmediately caused the code to work.

So it was not a JOGL error after all - it seems reasonable to require that users do not use paintImmediately in their OpenGL code.
Reply | Threaded
Open this post in threaded view
|

Re: UI Artifacts when using GLCanvas and GLJpanel

gouessej
Administrator
Thank you for investigating anyway. I hope this call was not necessary in your case.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: UI Artifacts when using GLCanvas and GLJpanel

mikaelhc
gouessej wrote
Thank you for investigating anyway. I hope this call was not necessary in your case.
Well, thanks for helping me. The statusbar update was trivial to work around, once I realized it was the problem - calling it through invokeLater solves the problem.

And I learned quite a bit about JOGL as well. I ended up implementing my own Swing JOGL component from scratch - rendering to an offscreen pbuffer (or FBO), retrieving a BufferedImage using glReadPixels(...), flipping the image, and drawing it back. Only to find that I got the same artifacts as JGLPanel.

I still have some pending  issues that I need to follow up on (crashing after returning from sleep on Windows, issues with VBO's on one of our Macs), but this was the most important.