From 6e599a2696f878786783e0fea17534e67655a5c9 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Fri, 21 May 2010 06:15:17 +0200 Subject: Changed NEWT NativeWindow creation contract - AWT/NEWT Parenting - Misc Fixes +++++ Changed NEWT NativeWindow creation contract Original contract: (1) A native window was created as soon as possible, ie when NEWTFactory.createWindow(..) was called - if possible. (2) A valid native window has to be created at least after setVisible(true) has been called. Problems: Not all implementation are able to create the native window that early, but at setVisible(true) only (e.g: KD and EGL). Due to window parenting especially the new AWT/NEWT parenting, the native window can only be created in case the parent native window is valid. New contract: (1) A native window is created at setVisible(true), if it's a top level window or the native parent window is valid. (2) A valid native window may not be created after setVisible(true) has been called. Subsequent setVisible(true) calls shall be made in case the creation has not been done yet. This is demonstrated in GLWindow.display() for example. The new contract implements a lazy native window creation. +++++ AWT/NEWT Parenting - HierarchyListener and ComponentListener ensure that the NEWT child window will be setVisible according to the AWT parent window. - Lazy native window creation relaxes requirements to the parent window's state. - Attachment of the child window and setVisible() may be called after NEWT child window creation. - GLWindow supports NEWT child window creation directly The test case TestParenting01AWT.java reflect this new contract and demonstrates more simplified and more flexible use cases. +++++ NEWT Fixes: - All NEWT implementation's native code method names end with 0. - GLWindow: don't issue the actual 'init'/'display' call to GLEventListeners in case the window is not visible. - NEWT setSize/setPosition: if native-window call native-window action and let the attributes being set by the feedback call, which issues more action, ie RESIZE. else set the attributes directly, no feedback call/action is necessary. +++++ X11 Fixes: - X11GLContext MakeContextCurrent: Use MakeCurrent in case write and read drawable are equal, otherwise SEGV happens on ATI with heavy multithreading involved! Even XLockDisplay and XSync didn't help here .. - X11GLXDrawableFactory shared resource: Removed the resource holder thread to simplify code, hence proper release is no more desired and it could become a cause for deadlock. - Moved XInitThreads() from NEWT X11Window -> NativeWindow X11Util, since NativeWindow is loaded first (essential for XInitThreads()) and it is the more basic lib. - Made call to XInitThreads() conditional, ie it's spared if AWT could be used - which causes SEGV .. (AWT bug). See X11Util.java +++++ JOGL Fixes: - GLProfile.isAWTAvailable() -> NativeWindowFactory.isAWTAvailable() - GLProfile.isAWTJOGLAvailable() -> GLProfile.isAWTAvailable() --- .../jogamp/opengl/impl/x11/glx/X11GLXContext.java | 8 +- .../opengl/impl/x11/glx/X11GLXDrawableFactory.java | 117 +++++---------------- .../classes/com/jogamp/opengl/util/Animator.java | 2 +- .../util/texture/TextureIO.java.javame_cdc_fp | 4 +- .../opengl/util/texture/TextureIO.java.javase | 4 +- src/jogl/classes/javax/media/opengl/GLProfile.java | 14 +-- 6 files changed, 44 insertions(+), 105 deletions(-) (limited to 'src/jogl') diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java index 9c3efea2e..76a6830d5 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java @@ -108,7 +108,13 @@ public abstract class X11GLXContext extends GLContextImpl { boolean res = false; try { - res = GLX.glXMakeContextCurrent(dpy, writeDrawable, readDrawable, ctx); + // at least on ATI we receive 'often' SEGV in case of + // highly multithreaded MakeContextCurrent calls with writeDrawable==readDrawable + if(writeDrawable==readDrawable) { + res = GLX.glXMakeCurrent(dpy, writeDrawable, ctx); + } else { + res = GLX.glXMakeContextCurrent(dpy, writeDrawable, readDrawable, ctx); + } } catch (RuntimeException re) { if(DEBUG) { System.err.println("X11GLXContext.glXMakeContextCurrent failed: "+re+", with "+ diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java index 823809f43..e2b24f9f0 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java @@ -67,16 +67,21 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna new Object[] {}); } catch (JogampRuntimeException jre) { /* n/a .. */ } - shareableResourceThread = new ShareableResourceThread(GLProfile.getDefault(), GLProfile.isAWTJOGLAvailable()); - shareableResourceThread.start(); - while (!shareableResourceThread.isInitialized()) { - synchronized(shareableResourceThread) { - try { - shareableResourceThread.wait(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } + // init shared resources .. + long tlsDisplay = X11Util.createThreadLocalDisplay(null); + X11GraphicsDevice sharedDevice = new X11GraphicsDevice(tlsDisplay); + vendorName = GLXUtil.getVendorName(sharedDevice.getHandle()); + isVendorATI = GLXUtil.isVendorATI(vendorName); + isVendorNVIDIA = GLXUtil.isVendorNVIDIA(vendorName); + sharedScreen = new X11GraphicsScreen(sharedDevice, 0); + X11Util.XLockDisplay(tlsDisplay); + try{ + sharedDrawable = new X11DummyGLXDrawable(sharedScreen, X11GLXDrawableFactory.this, GLProfile.getDefault()); + } finally { + X11Util.XUnlockDisplay(tlsDisplay); + } + if(isVendorATI() && GLProfile.isAWTAvailable()) { + X11Util.markThreadLocalDisplayUncloseable(tlsDisplay); // failure to close with ATI and AWT usage } if(null==sharedScreen || null==sharedDrawable) { throw new GLException("Couldn't init shared screen("+sharedScreen+")/drawable("+sharedDrawable+")"); @@ -104,73 +109,6 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna } } - ShareableResourceThread shareableResourceThread; - - class ShareableResourceThread extends Thread { - volatile boolean shutdown = false; - volatile boolean initialized = false; - GLProfile glp; - boolean mayUseAWT; - - final void shutdown() { shutdown = true; } - final boolean isInitialized() { return initialized; } - - public ShareableResourceThread(GLProfile glp, boolean mayUseAWT) { - super("ShareableResourceThread-"+Thread.currentThread().getName()); - this.glp = glp; - this.mayUseAWT = mayUseAWT; - } - - public void run() { - synchronized(this) { - long tlsDisplay = X11Util.createThreadLocalDisplay(null); - X11GraphicsDevice sharedDevice = new X11GraphicsDevice(tlsDisplay); - vendorName = GLXUtil.getVendorName(sharedDevice.getHandle()); - isVendorATI = GLXUtil.isVendorATI(vendorName); - isVendorNVIDIA = GLXUtil.isVendorNVIDIA(vendorName); - sharedScreen = new X11GraphicsScreen(sharedDevice, 0); - X11Util.XLockDisplay(sharedScreen.getDevice().getHandle()); - try{ - sharedDrawable = new X11DummyGLXDrawable(sharedScreen, X11GLXDrawableFactory.this, glp); - } finally { - X11Util.XUnlockDisplay(sharedScreen.getDevice().getHandle()); - } - if(isVendorATI() && mayUseAWT) { - X11Util.markThreadLocalDisplayUncloseable(tlsDisplay); // failure to close with ATI and AWT usage - } - initialized = true; - this.notifyAll(); - - while (!shutdown) { - synchronized(this) { - try { - this.wait(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - - // don't free native resources from this point on, - // since we might be in a critical shutdown hook sequence - if(null!=sharedDrawable) { - // may cause deadlock: sharedDrawable.destroy(); - sharedDrawable=null; - } - if(null!=sharedScreen) { - // may cause deadlock: X11Util.closeThreadLocalDisplay(null); - sharedScreen = null; - sharedDevice=null; - } - // don't close pending XDisplay, since they might be a different thread as the opener - X11Util.shutdown( false, DEBUG ); - - initialized = false; - this.notifyAll(); - } - } - } - private X11GraphicsScreen sharedScreen; private String vendorName; private boolean isVendorATI; @@ -202,20 +140,19 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna sharedContext.destroy(); // implies release, if current sharedContext=null; } - synchronized(shareableResourceThread) { - if (shareableResourceThread.isInitialized()) { - shareableResourceThread.shutdown(); - shareableResourceThread.notifyAll(); - while (shareableResourceThread.isInitialized()) { - try { - shareableResourceThread.wait(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } + + // don't free native resources from this point on, + // since we might be in a critical shutdown hook sequence + if(null!=sharedDrawable) { + // may cause deadlock: sharedDrawable.destroy(); + sharedDrawable=null; + } + if(null!=sharedScreen) { + // may cause deadlock: X11Util.closeThreadLocalDisplay(null); + sharedScreen = null; } - shareableResourceThread = null; + // don't close pending XDisplay, since they might be a different thread as the opener + X11Util.shutdown( false, DEBUG ); } public GLDrawableImpl createOnscreenDrawable(NativeWindow target) { diff --git a/src/jogl/classes/com/jogamp/opengl/util/Animator.java b/src/jogl/classes/com/jogamp/opengl/util/Animator.java index 9bef8e9c3..15b9d5eb9 100755 --- a/src/jogl/classes/com/jogamp/opengl/util/Animator.java +++ b/src/jogl/classes/com/jogamp/opengl/util/Animator.java @@ -70,7 +70,7 @@ public class Animator { /** Creates a new, empty Animator. */ public Animator(ThreadGroup tg) { - if(GLProfile.isAWTJOGLAvailable()) { + if(GLProfile.isAWTAvailable()) { try { impl = (AnimatorImpl) Class.forName("com.jogamp.opengl.util.awt.AWTAnimatorImpl").newInstance(); } catch (Exception e) { } diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java.javame_cdc_fp b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java.javame_cdc_fp index dbd194d21..3b694be68 100755 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java.javame_cdc_fp +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java.javame_cdc_fp @@ -729,7 +729,7 @@ public class TextureIO { static { /* - if(GLProfile.isAWTJOGLAvailable()) { + if(GLProfile.isAWTAvailable()) { // ImageIO provider, the fall-back, must be the first one added try { // Use reflection to avoid compile-time dependencies on AWT-related classes @@ -751,7 +751,7 @@ public class TextureIO { /* // ImageIO writer, the fall-back, must be the first one added - if(GLProfile.isAWTJOGLAvailable()) { + if(GLProfile.isAWTAvailable()) { try { // Use reflection to avoid compile-time dependencies on AWT-related classes TextureWriter writer = (TextureWriter) diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java.javase b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java.javase index 3e6f66f10..819a6acf5 100755 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java.javase +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java.javase @@ -729,7 +729,7 @@ public class TextureIO { static { // ImageIO provider, the fall-back, must be the first one added - if(GLProfile.isAWTJOGLAvailable()) { + if(GLProfile.isAWTAvailable()) { try { // Use reflection to avoid compile-time dependencies on AWT-related classes TextureProvider provider = (TextureProvider) @@ -748,7 +748,7 @@ public class TextureIO { addTextureProvider(new TGATextureProvider()); // ImageIO writer, the fall-back, must be the first one added - if(GLProfile.isAWTJOGLAvailable()) { + if(GLProfile.isAWTAvailable()) { try { // Use reflection to avoid compile-time dependencies on AWT-related classes TextureWriter writer = (TextureWriter) diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java index 6b49b24df..d746101ca 100644 --- a/src/jogl/classes/javax/media/opengl/GLProfile.java +++ b/src/jogl/classes/javax/media/opengl/GLProfile.java @@ -45,6 +45,7 @@ import java.util.HashMap; import java.util.Iterator; import java.security.*; import javax.media.opengl.fixedfunc.GLPointerFunc; +import javax.media.nativewindow.NativeWindowFactory; /** * Specifies the the OpenGL profile. @@ -830,7 +831,6 @@ public class GLProfile implements Cloneable { private static final String GL2ES12 = "GL2ES12"; private static /*final*/ boolean isAWTAvailable; - private static /*final*/ boolean isAWTJOGLAvailable; private static /*final*/ boolean hasGL234Impl; private static /*final*/ boolean hasGL4bcImpl; @@ -862,12 +862,8 @@ public class GLProfile implements Cloneable { AccessControlContext acc = AccessController.getContext(); - isAWTAvailable = !Debug.getBooleanProperty("java.awt.headless", true, acc) && - ReflectionUtil.isClassAvailable("java.awt.Component") ; - - isAWTJOGLAvailable = isAWTAvailable && - ReflectionUtil.isClassAvailable("javax.media.nativewindow.awt.AWTGraphicsDevice") && // NativeWindow - ReflectionUtil.isClassAvailable("javax.media.opengl.awt.GLCanvas") ; // JOGL + isAWTAvailable = NativeWindowFactory.isAWTAvailable() && + ReflectionUtil.isClassAvailable("javax.media.opengl.awt.GLCanvas") ; // JOGL boolean hasDesktopGL = false; boolean hasDesktopGLES12 = false; @@ -1040,7 +1036,6 @@ public class GLProfile implements Cloneable { if (DEBUG) { System.err.println("GLProfile.static isAWTAvailable "+isAWTAvailable); - System.err.println("GLProfile.static isAWTJOGLAvailable "+isAWTJOGLAvailable); System.err.println("GLProfile.static hasNativeOSFactory "+hasNativeOSFactory); System.err.println("GLProfile.static hasDesktopGL "+hasDesktopGL); System.err.println("GLProfile.static hasDesktopGLES12 "+hasDesktopGLES12); @@ -1156,8 +1151,9 @@ public class GLProfile implements Cloneable { return null; } + /** @return {@link javax.media.nativewindow.NativeWindowFactory#isAWTAvailable()} and + JOGL's AWT part */ public static boolean isAWTAvailable() { return isAWTAvailable; } - public static boolean isAWTJOGLAvailable() { return isAWTJOGLAvailable; } public static String getGLTypeName(int type) { switch (type) { -- cgit v1.2.3