Hello, I'm using JOGL 2.3.2 with an Eclipse RCP application. Recently I changed the SWT_AWT Canvas
to NewtCanvasSWT. On Windows everything works fine, on MacOSX I have a problem with the parenting when I switch a perspective or change to fullscreen (coordinates are still from the parent composite!) but more important on Linux (tested on Ubuntu 18.10) the following error occurs (shortened to the important exception): !ENTRY org.eclipse.e4.ui.workbench.swt 4 2 2019-01-29 12:09:52.725 !MESSAGE Problems occurred when invoking code from plug-in: "org.eclipse.e4.ui.workbench.swt". !STACK 0 java.lang.ExceptionInInitializerError at com.jogamp.newt.swt.NewtCanvasSWT.<init>(NewtCanvasSWT.java:127) Caused by: com.jogamp.nativewindow.NativeWindowException: java.lang.NoSuchFieldException: GTK_VERSION at com.jogamp.nativewindow.swt.SWTAccessor.<clinit>(SWTAccessor.java:203) ... 154 more Caused by: java.lang.NoSuchFieldException: GTK_VERSION at java.base/java.lang.Class.getField(Class.java:2000) at com.jogamp.nativewindow.swt.SWTAccessor.<clinit>(SWTAccessor.java:183) ... 154 more Is there a workaround or new built available for the bug. I think this bug was already mentioned here: http://forum.jogamp.org/com-jogamp-opengl-swt-GLCanvas-does-not-work-with-Eclipse-4-8-under-Linux-td4039229.html |
Administrator
|
Would an unofficial build work for you? I could potentially take a look at this (since SWT/Eclipse is the area where I use JOGL as well), but I can only make unofficial builds that I post in my own GitHub (I did one to make JOGL work with Java 11, for example).
|
Administrator
|
In reply to this post by Marcel
I know how to fix that, I already worked on this bug:
http://forum.jogamp.org/com-jogamp-opengl-swt-GLCanvas-does-not-work-with-Eclipse-4-8-under-Linux-td4039229.html
Julien Gouesse | Personal blog | Website
|
Thank you both for the answers.
@gouessej Is this fix somewhere already available or will be 2.3.3 released any time soon? @wade walker I use OpenJDK 11, too and added several calls, e.g. like --add-opens java.desktop/sun.java2d.opengl=ALL-UNNAMED to avoid the warnings as vm arguments. |
Administrator
|
Julien's fix looks like it should work; I'll try it out on Ubuntu. I need to rebuild my VM first though; my previous one is too old to be representative. I found a JUnit test that will sensitize this error, so I'll first confirm that it fails when I upgrade the SWT JARs in the build.
|
Administrator
|
If you have a simple program to test that, I can run it under Mageia Linux.
Julien Gouesse | Personal blog | Website
|
This post was updated on .
Apropos, when I close the perspective which embedds the NewtCanvasSWT (I have several perspectives) I get an widget disposed exception in method getParentLocationOnScreen() from class NewtCanvasSWT on MacOSX.
But not when I close the view directly. I simply copied the NewtCanvasSWT class in my workspace and changed the method to the following to avoid the exception on MacOSX (see NewtCanvasSWT.this.isDisposed() == false): private Point getParentLocationOnScreen() { final org.eclipse.swt.graphics.Point[] parentLoc = new org.eclipse.swt.graphics.Point[] { null }; SWTAccessor.invoke(true, new Runnable() { public void run() { if (NewtCanvasSWT.this.isDisposed() == false) { parentLoc[0] = getParent().toDisplay(0, 0); } else { parentLoc[0] = new org.eclipse.swt.graphics.Point(0,0); } } }); return new Point(parentLoc[0].x, parentLoc[0].y); } I also changed the Debug variable in SWTAccessor (which I also simply copied) to false because i by default it prints debug messages on the error stream, see: https://github.com/sgothel/jogl/blob/master/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java#L56 https://github.com/sgothel/jogl/blob/master/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java#L225 @gouessej, Wade Walker: I could also test your fix on Ubuntu 18.10 |
Administrator
|
Please can you mention your change somewhere in our bug tracker?
Julien Gouesse | Personal blog | Website
|
Administrator
|
Making progress! I got my VMWare virtual machine set up with Ubuntu 18.04, then installed Java/Eclipse/Ant/gcc/etc, built gluegen/JOGL from source, and verified that the unit test com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTGLn hits the line of code in com.jogamp.nativewindow.swt.SWTAccessor that accesses GTK_VERSION.
The next step is to update JOGL's copy of the SWT JARs to the latest version, then verify that the OP's bug is replicated. After that, it should be a straightforward fix as Julien explained in the bug ticket. |
Administrator
|
I replicated the OP's bug, and started on the fix. It's a little more involved than just getting GTK_VERSION from org.eclipse.swt.internal.gtk.GTK instead of org.eclipse.swt.internal.gtk.OS. There are also several functions that migrated from org.eclipse.swt.internal.gtk.OS to a new class org.eclipse.swt.internal.gtk.GDK in newer versions of SWT, and the function gdk_window_set_back_pixmap() seems to have disappeared altogether in newer versions of GTK. Luckily, we're only ever setting the back pixmap to null, so we can replace that call with gdk_window_set_background_pattern() as they did in https://git.eclipse.org/r/#/c/56351/3/bundles/org.eclipse.swt/Eclipse+SWT/gtk/org/eclipse/swt/widgets/Composite.java.
|
In reply to this post by gouessej
Yes, I would do so but I need an account for that.
|
Here my regeistered account.
|
Administrator
|
In reply to this post by Marcel
Do you want me to create an account for you in our bug tracker?
Julien Gouesse | Personal blog | Website
|
Administrator
|
I put in the fixes, and the unit tests seem to work, but they throw some GTK errors/exceptions at shutdown:
SWT:14860): Gdk-CRITICAL **: 17:47:49.569: The window 0x7f71e51ac640 already has a drawing context. You cannot call gdk_window_begin_draw_frame() without calling gdk_window_end_draw_frame() first. (SWT:14860): Gdk-CRITICAL **: 17:47:49.569: gdk_drawing_context_get_cairo_context: assertion 'GDK_IS_DRAWING_CONTEXT (context)' failed I'll need to dig into this a little and see what's going on. It seems like GTK 3+ throws a lot of these (judging from what I've seen in the logs of other programs), but I'm not sure how serious it is or how hard it will be to fix. |
Administrator
|
In reply to this post by Wade Walker
I confirmed that the new bugs I see only occur with SWT 4.10/GTK 3.22.30. The previous version we used, SWT 4.3/GTK 2.24.32, didn't show this behavior. They may be due to my fix for the deprecated GTK gdk_window_set_back_pixmap(), which I replaced with gdk_window_set_background_pattern() after finding that Eclipse did the same thing. I'll dig in here and see if there's another solution.
|
Administrator
|
OK, it doesn't seem like the gdk_window_set_back_pixmap() --> gdk_window_set_background_pattern() replacement is causing the problem. It looks like the test is somehow consuming Cairo handles as its window proc is called, so if I let it run freely, it eats up all the handles and dies. But if I put in a breakpoint and step through slowly, it works :) So I need to figure out where in the chain a handle isn't being freed. This could be a tough error, since NewtCanvasSWT was probably never tested on GTK 3, but I'll keep poking and see what comes up.
|
Administrator
|
This bug may require Sven to do a fix. To summarize the work so far:
- When users try to use JOGL with GTK 3, they get an exception when JOGL tries to read GTK_VERSION from org.eclipse.swt.internal.gtk.OS (its location in GTK 2) - If you fix JOGL to read GTK_VERSION from its new location in org.eclipse.swt.internal.gtk.GTK (where it moved in GTK 3), then you get another problem: (SWT:14860): Gdk-CRITICAL **: 17:47:49.569: The window 0x7f71e51ac640 already has a drawing context. You cannot call gdk_window_begin_draw_frame() without calling gdk_window_end_draw_frame() first. (SWT:14860): Gdk-CRITICAL **: 17:47:49.569: gdk_drawing_context_get_cairo_context: assertion 'GDK_IS_DRAWING_CONTEXT (context)' failed org.eclipse.swt.SWTError: No more handles - The problem shows up in JOGL unit tests like com.jogamp.opengl.test.junit.jogl.swt.preAttach_NoAnimator() - The problem seems to be caused by a significant change to the way drawing works between GTK 2 and GTK 3. Somehow the NewtCanvasSWT is skipping a gdk_window_end_draw_frame() somewhere. But JOGL never directly calls gdk_window_begin_draw_frame(), gdk_window_end_draw_frame(), or gdk_drawing_context_get_cairo_context(), and it's never erroneously disposing a Cairo context, so I don't know how this could be happening. - The problem doesn't occur if you step through the code slowly in the debugger, seemingly because it can't switch frames fast enough to run out of contexts before the test ends. The gdk_window_begin_draw_frame()/gdk_window_end_draw_frame() calls are always properly paired when you set breakpoints on them. Next I'll try running the test for a longer time in the debugger, to see if I can make it fail after more cycles, but it's not looking promising. If anyone else wants to give this a try, I can give you the GTK 3 patch that I've written so far. |
Administrator
|
Please can you post the patch somewhere? I'd like to look at it. I appreciate your dedication, thank you for the excellent job :)
Julien Gouesse | Personal blog | Website
|
In reply to this post by Wade Walker
I think I found a solution for the problem.
Some of the methods have been moved to the GDK class. So I defined a new variable in the SWTAccessor class: private static final String str_OS_gdk_class = "org.eclipse.swt.internal.gtk.GDK"; Also on GTK 3 (now default on SWT) the following method is non existent anymore and has been replaced: OS.gdk_window_set_back_pixmap (window, 0, false) replace by OS.gdk_window_set_background_pattern(window, 0); which is now: GDK.gdk_window_set_background_pattern(window, 0); See: https://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=81b32128f07db650bc1cc9e0cc9f1272b6fa65f6 So I defined a new reflection access: d = ReflectionUtil.getClass(str_OS_gdk_class, false, SWTAccessor.class.getClassLoader()); I could now start the JOGL window. What I now get is a no handle exeception on Ubuntu 18.10 when I switch the view. But I also found a workaround here which should solve the problem, too: https://bugs.eclipse.org/bugs/show_bug.cgi?id=542675 If you have the time please test it. Here the complete SWTAccessor class (sorry for posting here): ---------------------------------------------------------------------------------------------------------------------------------------------- import com.jogamp.common.os.Platform; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; import org.eclipse.swt.graphics.GCData; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Control; import com.jogamp.nativewindow.AbstractGraphicsScreen; import com.jogamp.nativewindow.NativeWindowException; import com.jogamp.nativewindow.AbstractGraphicsDevice; import com.jogamp.nativewindow.NativeWindowFactory; import com.jogamp.nativewindow.VisualIDHolder; import com.jogamp.common.util.ReflectionUtil; import com.jogamp.common.util.VersionNumber; import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice; import com.jogamp.nativewindow.windows.WindowsGraphicsDevice; import com.jogamp.nativewindow.x11.X11GraphicsDevice; import jogamp.nativewindow.macosx.OSXUtil; import jogamp.nativewindow.x11.X11Lib; public class SWTAccessor { private static final boolean DEBUG = false; private static final Field swt_control_handle; private static final boolean swt_uses_long_handles; private static Object swt_osx_init = new Object(); private static Field swt_osx_control_view = null; private static Field swt_osx_view_id = null; private static final String nwt; public static final boolean isOSX; public static final boolean isWindows; public static final boolean isX11; public static final boolean isX11GTK; // X11/GTK, Windows/GDI, .. private static final String str_handle = "handle"; // OSX/Cocoa private static final String str_osx_view = "view"; // OSX private static final String str_osx_id = "id"; // OSX // static final String str_NSView = "org.eclipse.swt.internal.cocoa.NSView"; private static final Method swt_control_internal_new_GC; private static final Method swt_control_internal_dispose_GC; private static final String str_internal_new_GC = "internal_new_GC"; private static final String str_internal_dispose_GC = "internal_dispose_GC"; private static final String str_OS_gtk_class = "org.eclipse.swt.internal.gtk.GTK"; private static final String str_OS_gdk_class = "org.eclipse.swt.internal.gtk.GDK"; public static final Class<?> OS_gtk_class; private static final String str_OS_gtk_version = "GTK_VERSION"; public static final VersionNumber OS_gtk_version; private static final Method OS_gtk_widget_realize; private static final Method OS_gtk_widget_unrealize; // optional (removed in SWT 4.3) private static final Method OS_GTK_WIDGET_WINDOW; private static final Method OS_gtk_widget_get_window; private static final Method OS_gdk_x11_drawable_get_xdisplay; private static final Method OS_gdk_x11_display_get_xdisplay; private static final Method OS_gdk_window_get_display; private static final Method OS_gdk_x11_drawable_get_xid; private static final Method OS_gdk_x11_window_get_xid; private static final Method OS_gdk_window_set_back_pixmap; private static final String str_gtk_widget_realize = "gtk_widget_realize"; private static final String str_gtk_widget_unrealize = "gtk_widget_unrealize"; private static final String str_GTK_WIDGET_WINDOW = "GTK_WIDGET_WINDOW"; private static final String str_gtk_widget_get_window = "gtk_widget_get_window"; private static final String str_gdk_x11_drawable_get_xdisplay = "gdk_x11_drawable_get_xdisplay"; private static final String str_gdk_x11_display_get_xdisplay = "gdk_x11_display_get_xdisplay"; private static final String str_gdk_window_get_display = "gdk_window_get_display"; private static final String str_gdk_x11_drawable_get_xid = "gdk_x11_drawable_get_xid"; private static final String str_gdk_x11_window_get_xid = "gdk_x11_window_get_xid"; private static final String str_gdk_window_set_back_pixmap = "gdk_window_set_background_pattern"; private static final VersionNumber GTK_VERSION_2_14_0 = new VersionNumber(2, 14, 0); private static final VersionNumber GTK_VERSION_2_24_0 = new VersionNumber(2, 24, 0); private static final VersionNumber GTK_VERSION_3_0_0 = new VersionNumber(3, 0, 0); private static VersionNumber GTK_VERSION(final int version) { // return (major << 16) + (minor << 8) + micro; final int micro = ( version ) & 0xff; final int minor = ( version >> 8 ) & 0xff; final int major = ( version >> 16 ) & 0xff; return new VersionNumber(major, minor, micro); } static { AccessController.doPrivileged(new PrivilegedAction |
Free forum by Nabble | Edit this page |