diff options
author | Sven Gothel <[email protected]> | 2014-02-12 02:48:08 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-02-12 02:48:08 +0100 |
commit | c5964bf2e3ebd6e05a7d551b033355c21ca9eea9 (patch) | |
tree | c010bbeffea78ac878b7aafe14f6a0a24fbc179e /src/jogl/classes | |
parent | c3c204a2e374c1dc4c1fb51f15444e5b92850839 (diff) |
Bug 972 - Reduce ClassLoader Lookup, i.e. Class.forName(..): GLProfile, GLContextImpl, DisplayImpl
GLProfile, GLContextImpl:
- ReflectionUtil.DEBUG_STATS_FORNAME: Dump forName stats if set
- Cache GL*Impl and GL*ProcAddressTable Constructor<?> for GLContextImpl's createInstance(..)
- Remove off-thread early classloading thread which only adds complications
DisplayImpl:
- Remove one redundant availability test
Diffstat (limited to 'src/jogl/classes')
-rw-r--r-- | src/jogl/classes/javax/media/opengl/GLProfile.java | 141 | ||||
-rw-r--r-- | src/jogl/classes/jogamp/opengl/GLContextImpl.java | 12 |
2 files changed, 115 insertions, 38 deletions
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java index a43ddee07..80f46955d 100644 --- a/src/jogl/classes/javax/media/opengl/GLProfile.java +++ b/src/jogl/classes/javax/media/opengl/GLProfile.java @@ -39,7 +39,6 @@ package javax.media.opengl; import jogamp.nativewindow.NWJNILibLoader; import jogamp.opengl.Debug; -import jogamp.opengl.GLContextImpl; import jogamp.opengl.GLDrawableFactoryImpl; import jogamp.opengl.DesktopGLDynamicLookupHelper; @@ -51,6 +50,7 @@ import com.jogamp.common.util.VersionUtil; import com.jogamp.common.util.cache.TempJarCache; import com.jogamp.common.util.locks.LockFactory; import com.jogamp.common.util.locks.RecursiveThreadGroupLock; +import com.jogamp.gluegen.runtime.FunctionAddressResolver; import com.jogamp.nativewindow.NativeWindowVersion; import com.jogamp.opengl.JoglVersion; @@ -58,6 +58,7 @@ import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeWindowFactory; import javax.media.opengl.fixedfunc.GLPointerFunc; +import java.lang.reflect.Constructor; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.HashMap; @@ -110,7 +111,7 @@ public class GLProfile { final boolean justInitialized; initLock.lock(); try { - if(!initialized) { // volatile: ok + if(!initialized) { initialized = true; justInitialized = true; if(DEBUG) { @@ -118,6 +119,10 @@ public class GLProfile { Thread.dumpStack(); } + if(ReflectionUtil.DEBUG_STATS_FORNAME) { + ReflectionUtil.resetForNameCount(); + } + // run the whole static initialization privileged to speed up, // since this skips checking further access AccessController.doPrivileged(new PrivilegedAction<Object>() { @@ -125,24 +130,6 @@ public class GLProfile { public Object run() { Platform.initSingleton(); - // Performance hack to trigger classloading of the GL classes impl, which makes up to 12%, 800ms down to 700ms - new Thread(new Runnable() { - @Override - public void run() { - final ClassLoader cl = GLProfile.class.getClassLoader(); - try { - ReflectionUtil.createInstance(getGLImplBaseClassName(GL4bc)+"Impl", new Class[] { GLProfile.class, GLContextImpl.class }, new Object[] { null, null }, cl); - } catch (Throwable t) {} - try { - ReflectionUtil.createInstance(getGLImplBaseClassName(GLES3)+"Impl", new Class[] { GLProfile.class, GLContextImpl.class }, new Object[] { null, null }, cl); - } catch (Throwable t) {} - try { - ReflectionUtil.createInstance(getGLImplBaseClassName(GLES1)+"Impl", new Class[] { GLProfile.class, GLContextImpl.class }, new Object[] { null, null }, cl); - } catch (Throwable t) {} - } - }, "GLProfile-GL_Bootstrapping").start(); - - if(TempJarCache.isInitialized()) { final ClassLoader cl = GLProfile.class.getClassLoader(); final String newtFactoryClassName = "com.jogamp.newt.NewtFactory"; @@ -156,6 +143,11 @@ public class GLProfile { return null; } }); + if( ReflectionUtil.DEBUG_STATS_FORNAME ) { + if( justInitialized ) { + System.err.println(ReflectionUtil.getForNameStats(null).toString()); + } + } } else { justInitialized = false; } @@ -191,7 +183,7 @@ public class GLProfile { public static void shutdown() { initLock.lock(); try { - if(initialized) { // volatile: ok + if(initialized) { initialized = false; if(DEBUG) { System.err.println("GLProfile.shutdown() - thread "+Thread.currentThread().getName()); @@ -1045,7 +1037,6 @@ public class GLProfile { public final String getGLImplBaseClassName() { return getGLImplBaseClassName(getImplName()); } - private static final String getGLImplBaseClassName(String profileImpl) { if( GLES2 == profileImpl || GLES3 == profileImpl ) { return "jogamp.opengl.es3.GLES3"; @@ -1062,6 +1053,25 @@ public class GLProfile { } } + public final Constructor<?> getGLCtor(boolean glObject) { + return getGLCtor(getImplName(), glObject); + } + private static final Constructor<?> getGLCtor(String profileImpl, boolean glObject) { + if( GLES2 == profileImpl || GLES3 == profileImpl ) { + return glObject ? ctorGLES3Impl : ctorGLES3ProcAddr; + } else if( GLES1 == profileImpl ) { + return glObject ? ctorGLES1Impl : ctorGLES1ProcAddr; + } else if ( GL4bc == profileImpl || + GL4 == profileImpl || + GL3bc == profileImpl || + GL3 == profileImpl || + GL2 == profileImpl ) { + return glObject ? ctorGL234Impl : ctorGL234ProcAddr; + } else { + throw new GLException("unsupported profile \"" + profileImpl + "\""); + } + } + /** * @param o GLProfile object to compare with * @return true if given Object is a GLProfile and @@ -1530,13 +1540,87 @@ public class GLProfile { private static /*final*/ boolean hasEGLFactory; private static /*final*/ boolean hasGLES3Impl; private static /*final*/ boolean hasGLES1Impl; + private static /*final*/ Constructor<?> ctorGL234Impl; + private static /*final*/ Constructor<?> ctorGLES3Impl; + private static /*final*/ Constructor<?> ctorGLES1Impl; + private static /*final*/ Constructor<?> ctorGL234ProcAddr; + private static /*final*/ Constructor<?> ctorGLES3ProcAddr; + private static /*final*/ Constructor<?> ctorGLES1ProcAddr; private static /*final*/ GLDrawableFactoryImpl eglFactory = null; private static /*final*/ GLDrawableFactoryImpl desktopFactory = null; private static /*final*/ AbstractGraphicsDevice defaultDevice = null; - private static volatile boolean initialized = false; - private static RecursiveThreadGroupLock initLock = LockFactory.createRecursiveThreadGroupLock(); + private static boolean initialized = false; + private static final RecursiveThreadGroupLock initLock = LockFactory.createRecursiveThreadGroupLock(); + + private static final Class<?>[] ctorGLArgs = new Class<?>[] { GLProfile.class, jogamp.opengl.GLContextImpl.class }; + private static final Class<?>[] ctorProcArgs = new Class<?>[] { FunctionAddressResolver.class }; + private static final String GL4bcImplClassName = "jogamp.opengl.gl4.GL4bcImpl"; + private static final String GL4bcProcClassName = "jogamp.opengl.gl4.GL4bcProcAddressTable"; + private static final String GLES1ImplClassName = "jogamp.opengl.es1.GLES1Impl"; + private static final String GLES1ProcClassName = "jogamp.opengl.es1.GLES1ProcAddressTable"; + private static final String GLES3ImplClassName = "jogamp.opengl.es3.GLES3Impl"; + private static final String GLES3ProcClassName = "jogamp.opengl.es3.GLES3ProcAddressTable"; + + private static final Constructor<?> getCtor(final String clazzName, final boolean glObject, final ClassLoader cl) { + try { + return ReflectionUtil.getConstructor(clazzName, glObject ? ctorGLArgs : ctorProcArgs, cl); + } catch (Throwable t) { + if( DEBUG ) { + System.err.println("Catched: "+t.getMessage()); + t.printStackTrace(); + } + return null; + } + } + + private static final void initGLCtorImpl() { + final ClassLoader classloader = GLProfile.class.getClassLoader(); + + // depends on hasDesktopGLFactory + { + final Constructor<?> ctorGL = getCtor(GL4bcImplClassName, true, classloader); + final Constructor<?> ctorProc = null != ctorGL ? getCtor(GL4bcProcClassName, false, classloader) : null; + if( null != ctorProc ) { + hasGL234Impl = true; + ctorGL234Impl = ctorGL; + ctorGL234ProcAddr = ctorProc; + } else { + hasGL234Impl = false; + ctorGL234Impl = null; + ctorGL234ProcAddr = null; + } + } + + // depends on hasEGLFactory + { + final Constructor<?> ctorGL = getCtor(GLES1ImplClassName, true, classloader); + final Constructor<?> ctorProc = null != ctorGL ? getCtor(GLES1ProcClassName, false, classloader) : null; + if( null != ctorProc ) { + hasGLES1Impl = true; + ctorGLES1Impl = ctorGL; + ctorGLES1ProcAddr = ctorProc; + } else { + hasGLES1Impl = false; + ctorGLES1Impl = null; + ctorGLES1ProcAddr = null; + } + } + { + final Constructor<?> ctorGL = getCtor(GLES3ImplClassName, true, classloader); + final Constructor<?> ctorProc = null != ctorGL ? getCtor(GLES3ProcClassName, false, classloader) : null; + if( null != ctorProc ) { + hasGLES3Impl = true; + ctorGLES3Impl = ctorGL; + ctorGLES3ProcAddr = ctorProc; + } else { + hasGLES3Impl = false; + ctorGLES3Impl = null; + ctorGLES3ProcAddr = null; + } + } + } /** * Tries the profiles implementation and native libraries. @@ -1551,17 +1635,12 @@ public class GLProfile { System.err.println(JoglVersion.getInstance()); } - ClassLoader classloader = GLProfile.class.getClassLoader(); + final ClassLoader classloader = GLProfile.class.getClassLoader(); isAWTAvailable = NativeWindowFactory.isAWTAvailable() && ReflectionUtil.isClassAvailable("javax.media.opengl.awt.GLCanvas", classloader) ; // JOGL - // depends on hasDesktopGLFactory - hasGL234Impl = ReflectionUtil.isClassAvailable("jogamp.opengl.gl4.GL4bcImpl", classloader); - - // depends on hasEGLFactory - hasGLES1Impl = ReflectionUtil.isClassAvailable("jogamp.opengl.es1.GLES1Impl", classloader); - hasGLES3Impl = ReflectionUtil.isClassAvailable("jogamp.opengl.es3.GLES3Impl", classloader); + initGLCtorImpl(); // // Iteration of desktop GL availability detection diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java index 431bba6de..b133fc017 100644 --- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java @@ -54,7 +54,6 @@ import com.jogamp.common.util.ReflectionUtil; import com.jogamp.common.util.VersionNumber; import com.jogamp.common.util.VersionNumberString; import com.jogamp.common.util.locks.RecursiveLock; -import com.jogamp.gluegen.runtime.FunctionAddressResolver; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLNameResolver; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; @@ -1127,17 +1126,17 @@ public abstract class GLContextImpl extends GLContext { // Helpers for various context implementations // - private Object createInstance(GLProfile glp, String suffix, Class<?>[] cstrArgTypes, Object[] cstrArgs) { - return ReflectionUtil.createInstance(glp.getGLImplBaseClassName()+suffix, cstrArgTypes, cstrArgs, getClass().getClassLoader()); + private Object createInstance(GLProfile glp, boolean glObject, Object[] cstrArgs) { + return ReflectionUtil.createInstance(glp.getGLCtor(glObject), cstrArgs); } private boolean verifyInstance(GLProfile glp, String suffix, Object instance) { - return ReflectionUtil.instanceOf(instance, glp.getGLImplBaseClassName()+suffix); + return ReflectionUtil.instanceOf(instance, glp.getGLImplBaseClassName()+suffix); } /** Create the GL for this context. */ protected GL createGL(GLProfile glp) { - final GL gl = (GL) createInstance(glp, "Impl", new Class[] { GLProfile.class, GLContextImpl.class }, new Object[] { glp, this } ); + final GL gl = (GL) createInstance(glp, true, new Object[] { glp, this } ); /* FIXME: refactor dependence on Java 2D / JOGL bridge if (tracker != null) { @@ -1585,8 +1584,7 @@ public abstract class GLContextImpl extends GLContext { System.err.println(getThreadName() + ": GLContext GL ProcAddressTable reusing key("+contextFQN+") -> "+toHexString(table.hashCode())); } } else { - glProcAddressTable = (ProcAddressTable) createInstance(gl.getGLProfile(), "ProcAddressTable", - new Class[] { FunctionAddressResolver.class } , + glProcAddressTable = (ProcAddressTable) createInstance(gl.getGLProfile(), false, new Object[] { new GLProcAddressResolver() } ); resetProcAddressTable(getGLProcAddressTable()); synchronized(mappedContextTypeObjectLock) { |