diff options
author | Sven Gothel <[email protected]> | 2010-10-14 21:26:43 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-10-14 21:26:43 +0200 |
commit | 774138544e1eec3330309ad682fa05154a07ab8d (patch) | |
tree | a9d612e98f1d16390763f54ab1888ff66f081a22 /src/jogl/classes/javax/media | |
parent | d7faeb8b96f5aba76967096006af4c420d964fef (diff) |
JOGL: Reenable Applet/Webstart/RCP support for JOGL + AWT + X11
Changed GLProfile/NativeWindowFactory/.. initialization methodology:
GLProfile:
public static synchronized void initSingleton(final boolean firstUIActionOnProcess);
NativeWindowFactory:
public static synchronized void initSingleton(final boolean firstUIActionOnProcess);
+++
Introducing NativeWindow ToolkitLock, implementations are
NullToolkitLock
JAWTToolkitLock
X11JAWTToolkitLock
X11ToolkitLock
AbstractGraphicsDevice provides generic global toolkit locking methods,
implemented by the ToolkitLock interface.
ToolkitLock's are aggregated in NativeWindow's DefaultGraphicsDevice
to implement it's superclass lock()/unlock() methods.
This enables a device specific locking strategy, ie on X11/AWT utilizing
JAWT && X11 locking, and maybe none for others (NEWT).
No locking is required for X11 / AWT, in case the above mentioned
initialization happened as a 'firstUIActionOnProcess'.
The ToolkitLock factory is currently a hardcoded part of NativeWindowFactory.
We may have to allow 3rd party NativeWindow implementations
to register custom ones.
+++
com.jogamp.opengl.impl.GLDrawableImpl cleanup:
Dealing with all locking code, providing all public methods. Exceptions are commented.
Specializations x11/windows/.. only contains platform code.
Pulled down access qualifiers if possible public -> protected.
com.jogamp.nativewindow.impl.x11.X11Util
Wrapping all X11Lib method with the new locking code.
com.jogamp.nativewindow.impl.jawt.JAWTUtil
Utilize global SunToolkit.awtLock() is available,
the fallback to global JAWT.lock().
The latter just invokes the first.
javax.media.nativewindow.awt.AWTGraphicsDevice
setHandle(long handle) -> setSubType(String type, long handle)
which also resets the ToolkitLock respecting the new type.
This ensures correct locking after the sub type has been determined,
ie AWT using an X11 peer.
+++
Misc Changes done on the way ..
GLCanvas:
Fixed inversed this.drawableHelper.isExternalAnimatorAnimating() condition,
which disabled normal repaint.
GLJPanel:
Removed drawableHelper.isExternalAnimatorAnimating() condition,
which disabled painting, since the animation thread just updates the source image.
NEWT WindowImpl:
When reparenting back to parent and 'refit' child if it's size exceeds it's parent.
More 'Fix: Memory consumption' commit 6ced17f0325d5719e992b246ffd156e5b39694b4.
NEWTEvent:
Removed code to evaluate the 'system event' attribute, need to find a better approach.
Diffstat (limited to 'src/jogl/classes/javax/media')
5 files changed, 97 insertions, 60 deletions
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java index a85993c8e..f9f5f8324 100644 --- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java +++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java @@ -127,7 +127,7 @@ public abstract class GLDrawableFactory { tmp = (GLDrawableFactory) ReflectionUtil.createInstance(factoryClassName, cl); } catch (JogampRuntimeException jre) { if (GLProfile.DEBUG) { - System.err.println("GLDrawableFactory.static - Native Platform: "+nativeOSType+" - not available: "+factoryClassName); + System.err.println("Info: GLDrawableFactory.static - Native Platform: "+nativeOSType+" - not available: "+factoryClassName); jre.printStackTrace(); } } @@ -139,7 +139,7 @@ public abstract class GLDrawableFactory { tmp = (GLDrawableFactory) ReflectionUtil.createInstance("com.jogamp.opengl.impl.egl.EGLDrawableFactory", cl); } catch (JogampRuntimeException jre) { if (GLProfile.DEBUG) { - System.err.println("GLDrawableFactory.static - EGLDrawableFactory - not available"); + System.err.println("Info: GLDrawableFactory.static - EGLDrawableFactory - not available"); jre.printStackTrace(); } } diff --git a/src/jogl/classes/javax/media/opengl/GLPipelineFactory.java b/src/jogl/classes/javax/media/opengl/GLPipelineFactory.java index 352545849..590e88ab7 100644 --- a/src/jogl/classes/javax/media/opengl/GLPipelineFactory.java +++ b/src/jogl/classes/javax/media/opengl/GLPipelineFactory.java @@ -152,11 +152,11 @@ public class GLPipelineFactory { instance = cstr.newInstance( cstrArgs ) ; } catch (Throwable t) { t.printStackTrace(); } if(null==instance) { - throw new GLException("Couldn't create instance of pipeline: "+upstreamClazz.getName()+ + throw new GLException("Error: Couldn't create instance of pipeline: "+upstreamClazz.getName()+ " ( "+getArgsClassNameList(downstreamClazz, additionalArgs) +" )"); } if( ! (instance instanceof GL) ) { - throw new GLException(upstreamClazz.getName()+" not an instance of GL"); + throw new GLException("Error: "+upstreamClazz.getName()+" not an instance of GL"); } return (GL) instance; } diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java index 287e7a5a9..be5968409 100644 --- a/src/jogl/classes/javax/media/opengl/GLProfile.java +++ b/src/jogl/classes/javax/media/opengl/GLProfile.java @@ -37,7 +37,9 @@ package javax.media.opengl; +import com.jogamp.common.jvm.JVMUtil; import com.jogamp.common.util.ReflectionUtil; +import com.jogamp.opengl.util.VersionInfo; import com.jogamp.opengl.impl.Debug; import com.jogamp.opengl.impl.GLDrawableFactoryImpl; import com.jogamp.opengl.impl.GLDynamicLookupHelper; @@ -281,6 +283,7 @@ public class GLProfile { * @see #GL_PROFILE_LIST_ALL */ public static final GLProfile getDefault() { + validateInitialization(); if(null==defaultGLProfile) { throw new GLException("No default profile available"); // should never be reached } @@ -349,6 +352,7 @@ public class GLProfile { public static final GLProfile get(String profile) throws GLException { + validateInitialization(); if(null==profile || profile.equals("GL")) return getDefault(); GLProfile glProfile = (GLProfile) mappedProfiles.get(profile); if(null==glProfile) { @@ -366,6 +370,7 @@ public class GLProfile { public static final GLProfile get(String[] profiles) throws GLException { + validateInitialization(); for(int i=0; i<profiles.length; i++) { String profile = profiles[i]; GLProfile glProfile = (GLProfile) mappedProfiles.get(profile); @@ -851,9 +856,9 @@ public class GLProfile { * Tries the profiles implementation and native libraries. * Throws an GLException if no profile could be found at all. */ - private static void initProfiles() { + private static void initProfiles(boolean firstUIActionOnProcess) { - NativeWindowFactory.initSingleton(); + NativeWindowFactory.initSingleton(firstUIActionOnProcess); ClassLoader classloader = GLProfile.class.getClassLoader(); @@ -898,13 +903,15 @@ public class GLProfile { t=le; } catch (RuntimeException re) { t=re; + } catch (Throwable tt) { + t=tt; } if(DEBUG) { if(null!=t) { t.printStackTrace(); } if(!hasNativeOSFactory) { - System.err.println("GLProfile.static - Native platform GLDrawable factory not available"); + System.err.println("Info: GLProfile.init - Native platform GLDrawable factory not available"); } } @@ -969,41 +976,80 @@ public class GLProfile { mappedProfiles = computeProfileMap(); if (DEBUG) { - System.err.println("GLProfile.static isAWTAvailable "+isAWTAvailable); - System.err.println("GLProfile.static hasNativeOSFactory "+hasNativeOSFactory); - System.err.println("GLProfile.static hasDesktopGL "+hasDesktopGL); - System.err.println("GLProfile.static hasDesktopGLES12 "+hasDesktopGLES12); - System.err.println("GLProfile.static hasGL234Impl "+hasGL234Impl); - System.err.println("GLProfile.static "+glAvailabilityToString()); + System.err.println(VersionInfo.getPackageInfo(null, "GLProfile.init", "javax.media.opengl", "GL")); + System.err.println(VersionInfo.getPlatformInfo(null, "GLProfile.init")); + System.err.println("GLProfile.init firstUIActionOnProcess "+firstUIActionOnProcess); + System.err.println("GLProfile.init isAWTAvailable "+isAWTAvailable); + System.err.println("GLProfile.init hasNativeOSFactory "+hasNativeOSFactory); + System.err.println("GLProfile.init hasDesktopGL "+hasDesktopGL); + System.err.println("GLProfile.init hasDesktopGLES12 "+hasDesktopGLES12); + System.err.println("GLProfile.init hasGL234Impl "+hasGL234Impl); + System.err.println("GLProfile.init "+glAvailabilityToString()); } + } + static { + JVMUtil.initSingleton(); } + static boolean initialized = false; + /** - * Initializes available profiles eagerly. + * Static one time initialization of JOGL. + * <p> + * Applications shall call this methods <b>ASAP</b>, before any other UI invocation.<br> + * You may issue the call in your main function.<br> + * In case applications are able to initialize JOGL before any other UI action,<br> + * they shall invoke this method with <code>firstUIActionOnProcess=true</code> and benefit from fast native multithreading support on all platforms if possible.</P> + * <P> + * RCP Application (Applet's, Webstart, Netbeans, ..) using JOGL may not be able to initialize JOGL + * before the first UI action.<br> + * In such case you shall invoke this method with <code>firstUIActionOnProcess=false</code>.<br> + * On some platforms, notably X11 with AWT usage, JOGL will utilize special locking mechanisms which may slow down your + * application.</P> + * <P> + * Remark: NEWT is currently not affected by this behavior, ie always uses native multithreading.</P> + * <P> + * However, in case this method is not invoked, hence GLProfile is not initialized explicitly by the user,<br> + * the first call to {@link #getDefault()}, {@link #get(java.lang.String)}, etc, will initialize with <code>firstUIActionOnProcess=false</code>,<br> + * hence without the possibility to enable native multithreading.<br> + * This is not the recommended way, since it may has a performance impact, but it allows you to run code without explicit initialization.</P> + * <P> + * In case no explicit initialization was invoked and the implicit initialization didn't happen,<br> + * you may encounter the following exception: + * <pre> + * javax.media.opengl.GLException: No default profile available + * </pre></P> + * + * @param firstUIActionOnProcess Should be <code>true</code> if called before the first UI action of the running program, + * otherwise <code>false</code>. */ - static { - // run the whole static initialization privileged to speed up, - // since this skips checking further access - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - initProfiles(); - return null; - } - }); + public static synchronized void initSingleton(final boolean firstUIActionOnProcess) { + if(!initialized) { + initialized = true; + // run the whole static initialization privileged to speed up, + // since this skips checking further access + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + initProfiles(firstUIActionOnProcess); + return null; + } + }); - if(null==defaultGLProfile) { - throw new GLException("No profile available: "+array2String(GL_PROFILE_LIST_ALL)+", "+glAvailabilityToString()); + if(null==defaultGLProfile) { + throw new GLException("No profile available: "+array2String(GL_PROFILE_LIST_ALL)+", "+glAvailabilityToString()); + } } } - /** - * It is mandatory to call this methods ASAP, before anything else.<br> - * You may issue the call in your main class static initializer block, or in the static main function.<br> - * This will kick off JOGL's static initialization.<br> - * It is essential to do this at the very beginning, so JOGL has a chance to initialize multithreading support.<br> - */ - public static void initSingleton() { + private static void validateInitialization() { + if(!initialized) { + synchronized(GLProfile.class) { + if(!initialized) { + initSingleton(false); + } + } + } } private static final String array2String(String[] list) { @@ -1028,17 +1074,17 @@ public class GLProfile { GLProfile glProfile = new GLProfile(profile, profileImpl); _mappedProfiles.put(profile, glProfile); if (DEBUG) { - System.err.println("GLProfile.static map "+glProfile); + System.err.println("GLProfile.init map "+glProfile); } if(null==defaultGLProfile) { defaultGLProfile=glProfile; if (DEBUG) { - System.err.println("GLProfile.static default "+glProfile); + System.err.println("GLProfile.init default "+glProfile); } } } else { if (DEBUG) { - System.err.println("GLProfile.static map *** no mapping for "+profile); + System.err.println("GLProfile.init map *** no mapping for "+profile); } } } diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index 60ed731f1..4ac21204f 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -45,7 +45,6 @@ import javax.media.nativewindow.*; import javax.media.nativewindow.awt.*; import com.jogamp.opengl.impl.*; -import com.jogamp.nativewindow.impl.jawt.JAWTUtil; import java.awt.Canvas; import java.awt.Color; @@ -54,7 +53,6 @@ import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; -import java.awt.Container; import java.awt.Window; import java.awt.event.WindowEvent; import java.awt.event.WindowAdapter; @@ -79,9 +77,8 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { private static final GLProfile defaultGLProfile; static { - NativeWindowFactory.initSingleton(); - defaultGLProfile = GLProfile.getDefault(); DEBUG = Debug.debug("GLCanvas"); + defaultGLProfile = GLProfile.getDefault(); } private GLProfile glProfile; @@ -234,7 +231,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { final GraphicsConfiguration compatible = (null!=config)?config.getGraphicsConfiguration():null; boolean equalCaps = config.getChosenCapabilities().equals(awtConfig.getChosenCapabilities()); if(DEBUG) { - Exception e = new Exception("Call Stack: "+Thread.currentThread().getName()); + Exception e = new Exception("Info: Call Stack: "+Thread.currentThread().getName()); e.printStackTrace(); System.err.println("!!! Created Config (n): HAVE GC "+chosen); System.err.println("!!! Created Config (n): THIS GC "+gc); @@ -313,7 +310,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { protected void dispose(boolean regenerate) { if(DEBUG) { - Exception ex1 = new Exception("dispose("+regenerate+") - start"); + Exception ex1 = new Exception("Info: dispose("+regenerate+") - start"); ex1.printStackTrace(); } @@ -381,7 +378,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { (int) ((getHeight() + bounds.getHeight()) / 2)); return; } - if( this.drawableHelper.isExternalAnimatorAnimating() ) { + if( ! this.drawableHelper.isExternalAnimatorAnimating() ) { display(); } } @@ -408,11 +405,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { /* * Save the chosen capabilities for use in getGraphicsConfiguration(). */ - JAWTUtil.lockToolkit(); + NativeWindowFactory.getDefaultToolkitLock().lock(); try { awtConfig = chooseGraphicsConfiguration(capabilities, chooser, device); if(DEBUG) { - Exception e = new Exception("Created Config: "+awtConfig); + Exception e = new Exception("Info: Created Config: "+awtConfig); e.printStackTrace(); } if(null!=awtConfig) { @@ -427,7 +424,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { context = (GLContextImpl) drawable.createContext(shareWith); context.setSynchronized(true); } finally { - JAWTUtil.unlockToolkit(); + NativeWindowFactory.getDefaultToolkitLock().unlock(); } if(DEBUG) { @@ -446,7 +443,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { <DL><DD><CODE>removeNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */ public void removeNotify() { if(DEBUG) { - Exception ex1 = new Exception("removeNotify - start"); + Exception ex1 = new Exception("Info: removeNotify - start"); ex1.printStackTrace(); } @@ -461,7 +458,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { } } if(DEBUG) { - System.out.println("removeNotify - end"); + System.err.println("Info: removeNotify - end"); } } @@ -580,7 +577,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { } public String toString() { - return "AWT-GLCanvas[ "+awtConfig+", "+((null!=drawable)?drawable.getClass().getName():"null-drawable")+", "+drawableHelper+"]"; + return "AWT-GLCanvas[ "+awtConfig+", "+((null!=drawable)?drawable.getClass().getName():"null-drawable")+"]"; } //---------------------------------------------------------------------- diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index e4a295ba3..192695955 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -138,8 +138,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { private int viewportY; static { - NativeWindowFactory.initSingleton(); - // Force eager initialization of part of the Java2D class since // otherwise it's likely it will try to be initialized while on // the Queue Flusher Thread, which is not allowed @@ -212,7 +210,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { protected void dispose(boolean regenerate) { if(DEBUG) { - Exception ex1 = new Exception("dispose("+regenerate+") - start"); + Exception ex1 = new Exception("Info: dispose("+regenerate+") - start"); ex1.printStackTrace(); } if (backend != null) { @@ -287,10 +285,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { return; } - if ( drawableHelper.isExternalAnimatorAnimating() ) { - return; - } - if (backend == null || !isInitialized) { createAndInitializeBackend(); } @@ -334,7 +328,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { <DL><DD><CODE>removeNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */ public void removeNotify() { if(DEBUG) { - Exception ex1 = new Exception("removeNotify - start"); + Exception ex1 = new Exception("Info: removeNotify - start"); ex1.printStackTrace(); } dispose(false); @@ -345,7 +339,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { isInitialized = false; super.removeNotify(); if(DEBUG) { - System.out.println("removeNotify - end"); + System.err.println("Info: removeNotify - end"); } } @@ -617,7 +611,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { } public String toString() { - return "AWT-GLJPanel[ "+((null!=backend)?backend.getDrawable().getClass().getName():"null-drawable")+", "+drawableHelper+"]"; + return "AWT-GLJPanel[ "+((null!=backend)?backend.getDrawable().getClass().getName():"null-drawable")+"]"; } private boolean disposeRegenerate; @@ -1034,7 +1028,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { } catch (GLException e) { if (DEBUG) { e.printStackTrace(); - System.err.println("GLJPanel: Falling back on software rendering because of problems creating pbuffer"); + System.err.println("Info: GLJPanel: Falling back on software rendering because of problems creating pbuffer"); } hardwareAccelerationDisabled = true; backend = null; @@ -1111,7 +1105,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { readBackWidthInPixels = Math.max(1, panelWidth); readBackHeightInPixels = Math.max(1, panelHeight); if (DEBUG) { - System.err.println("WARNING: falling back to software rendering due to bugs in OpenGL drivers"); + System.err.println("Warning: falling back to software rendering due to bugs in OpenGL drivers"); e.printStackTrace(); } createAndInitializeBackend(); |