aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-02-12 02:48:08 +0100
committerSven Gothel <[email protected]>2014-02-12 02:48:08 +0100
commitc5964bf2e3ebd6e05a7d551b033355c21ca9eea9 (patch)
treec010bbeffea78ac878b7aafe14f6a0a24fbc179e /src/jogl/classes
parentc3c204a2e374c1dc4c1fb51f15444e5b92850839 (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.java141
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextImpl.java12
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) {