aboutsummaryrefslogtreecommitdiffstats
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
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
-rwxr-xr-xmake/scripts/tests-win.bat4
-rwxr-xr-xmake/scripts/tests-x64-dbg.bat5
-rw-r--r--make/scripts/tests.sh10
-rw-r--r--src/jogl/classes/javax/media/opengl/GLProfile.java141
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextImpl.java12
-rw-r--r--src/newt/classes/jogamp/newt/DisplayImpl.java3
6 files changed, 129 insertions, 46 deletions
diff --git a/make/scripts/tests-win.bat b/make/scripts/tests-win.bat
index 5642cca6f..f4db03a15 100755
--- a/make/scripts/tests-win.bat
+++ b/make/scripts/tests-win.bat
@@ -38,7 +38,7 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintin
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingNIOImageSwingAWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLCapabilities01NEWT %*
-REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT %*
+scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteAWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen01GLPBufferNEWT -time 5000
@@ -50,7 +50,7 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedConte
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT0 %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT1 %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT2 %*
-scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT3 %*
+REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT3 %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2AWT3 %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2AWT3b %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextWithJTabbedPaneAWT %*
diff --git a/make/scripts/tests-x64-dbg.bat b/make/scripts/tests-x64-dbg.bat
index ce2df922c..b3ebc03c2 100755
--- a/make/scripts/tests-x64-dbg.bat
+++ b/make/scripts/tests-x64-dbg.bat
@@ -55,7 +55,7 @@ REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.Animator" "-Djogl.debug.GLC
REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.GLJPanel" "-Djogl.debug.TileRenderer" "-Djogl.debug.TileRenderer.PNG"
REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.GLJPanel" "-Djogl.debug.TileRenderer"
REM set D_ARGS="-Djogl.gljpanel.noverticalflip"
-set D_ARGS="-Dnewt.debug=all"
+REM set D_ARGS="-Dnewt.debug=all"
REM set D_ARGS="-Dnewt.debug.Window"
REM set D_ARGS="-Dnewt.debug.Window.KeyEvent"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Window.KeyEvent" "-Dnewt.debug.EDT"
@@ -74,6 +74,9 @@ REM set D_ARGS="-Dnewt.debug.Screen"
REM set D_ARGS="-Dnewt.debug.Screen" "-Dnewt.debug.Window"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display" "-Dnewt.test.Window.reparent.incompatible=true"
+REM set D_ARGS="-Djogamp.debug.ReflectionUtil" "-Djogamp.debug.ReflectionUtil.forNameStats"
+REM set D_ARGS="-Djogamp.debug.ReflectionUtil.forNameStats"
+
REM set X_ARGS="-Dsun.java2d.noddraw=true" "-Dsun.java2d.opengl=true" "-Dsun.awt.noerasebackground=true"
REM set X_ARGS="-Dsun.java2d.noddraw=true" "-Dsun.java2d.d3d=false" "-Dsun.java2d.ddoffscreen=false" "-Dsun.java2d.gdiblit=false" "-Dsun.java2d.opengl=false" "-Dsun.awt.noerasebackground=true" "-Xms512m" "-Xmx1024m"
REM set X_ARGS="-Dsun.java2d.noddraw=true" "-Dsun.java2d.d3d=false" "-Dsun.java2d.ddoffscreen=false" "-Dsun.java2d.gdiblit=false" "-Dsun.java2d.opengl=true" "-Dsun.awt.noerasebackground=true" "-Xms512m" "-Xmx1024m"
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index 85eb14252..cd9a2bb2e 100644
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -96,6 +96,9 @@ function jrun() {
#D_ARGS="-Dnativewindow.debug=all -Dnewt.debug.Window"
#D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all -Djogamp.debug.Lock"
+ #D_ARGS="-Djogamp.debug.ReflectionUtil -Djogamp.debug.ReflectionUtil.forNameStats"
+ #D_ARGS="-Djogamp.debug.ReflectionUtil.forNameStats"
+
#D_ARGS="-Dnativewindow.debug.X11Util.ATI_HAS_NO_XCLOSEDISPLAY_BUG"
#D_ARGS="-Dnativewindow.debug.X11Util.ATI_HAS_NO_MULTITHREADING_BUG"
#D_ARGS="-Djogl.disable.opengles"
@@ -242,7 +245,7 @@ function jrun() {
#D_ARGS="-Djogamp.debug.IOUtil -Djogl.debug.GLSLCode -Djogl.debug.GLMediaPlayer"
#D_ARGS="-Djogl.debug.GLMediaPlayer -Djogl.debug.AudioSink"
#D_ARGS="-Djogl.debug.GLMediaPlayer -Djogl.debug.GLMediaPlayer.Native"
- D_ARGS="-Djogl.debug.GLMediaPlayer"
+ #D_ARGS="-Djogl.debug.GLMediaPlayer"
#D_ARGS="-Djogl.debug.GLMediaPlayer.StreamWorker.delay=25 -Djogl.debug.GLMediaPlayer"
#D_ARGS="-Djogl.debug.GLMediaPlayer.Native"
@@ -355,7 +358,7 @@ function testawtswt() {
#
#testnoawt jogamp.opengl.openal.av.ALDummyUsage $*
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube $*
-testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple $*
#
# performance tests
@@ -389,7 +392,8 @@ testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple $*
#testnoawt com.jogamp.opengl.test.junit.jogl.math.TestFloatUtil01MatrixMatrixMultNOUI $*
#testnoawt com.jogamp.opengl.test.junit.jogl.math.TestBinary16NOUI $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT $*
+testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT $*
+
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrent01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrent02NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLContextSurfaceLockNEWT $*
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) {
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java
index b485a4763..952e611f2 100644
--- a/src/newt/classes/jogamp/newt/DisplayImpl.java
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -76,8 +76,7 @@ public abstract class DisplayImpl extends Display {
});
final ClassLoader cl = DisplayImpl.class.getClassLoader();
- pngUtilAvail = ReflectionUtil.isClassAvailable("jogamp.opengl.util.pngj.PngReader", cl) &&
- ReflectionUtil.isClassAvailable("com.jogamp.opengl.util.PNGPixelRect", cl);
+ pngUtilAvail = ReflectionUtil.isClassAvailable("com.jogamp.opengl.util.PNGPixelRect", cl);
}
public static final boolean isPNGUtilAvailable() { return pngUtilAvail; }