diff options
9 files changed, 107 insertions, 29 deletions
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java index 90290d882..9484f0656 100644 --- a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java +++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java @@ -249,7 +249,7 @@ public interface GLAutoDrawable extends GLDrawable { front and back buffers are swapped, displaying the results of the render. When disabled, the user is responsible for calling {@link #swapBuffers(..)} manually. */ - public void setAutoSwapBufferMode(boolean onOrOff); + public void setAutoSwapBufferMode(boolean enable); /** Indicates whether automatic buffer swapping is enabled for this drawable. See {@link #setAutoSwapBufferMode}. */ diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java index 5d91a5ee2..722ab4e7f 100644 --- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java +++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java @@ -43,16 +43,18 @@ package jogamp.opengl; import java.util.*; import javax.media.opengl.*; +import com.jogamp.opengl.util.Animator; + /** Encapsulates the implementation of most of the GLAutoDrawable's methods to be able to share it between GLCanvas and GLJPanel. */ public class GLDrawableHelper { protected static final boolean DEBUG = GLDrawableImpl.DEBUG; - private static final boolean VERBOSE = Debug.verbose(); private Object listenersLock = new Object(); private ArrayList<GLEventListener> listeners; private HashSet<GLEventListener> listenersToBeInit; private boolean autoSwapBufferMode; + private Thread skipContextReleaseThread; private Object glRunnablesLock = new Object(); private ArrayList<GLRunnable> glRunnables; private GLAnimatorControl animatorCtrl; @@ -67,6 +69,7 @@ public class GLDrawableHelper { listenersToBeInit = new HashSet<GLEventListener>(); } autoSwapBufferMode = true; + skipContextReleaseThread = null; synchronized(glRunnablesLock) { glRunnables = new ArrayList<GLRunnable>(); } @@ -270,14 +273,31 @@ public class GLDrawableHelper { } } - public final void setAutoSwapBufferMode(boolean onOrOff) { - autoSwapBufferMode = onOrOff; + public final void setAutoSwapBufferMode(boolean enable) { + autoSwapBufferMode = enable; } public final boolean getAutoSwapBufferMode() { return autoSwapBufferMode; } + /** + * @param t the thread for which context release shall be skipped, usually the animation thread, + * ie. {@link Animator#getThread()}. + * @deprecated this is an experimental feature, + * intended for measuring performance in regards to GL context switch + */ + public final void setSkipContextReleaseThread(Thread t) { + skipContextReleaseThread = t; + } + + /** + * @deprecated see {@link #setSkipContextReleaseThread(Thread)} + */ + public final Thread getSkipContextReleaseThread() { + return skipContextReleaseThread; + } + private static final ThreadLocal<Runnable> perThreadInitAction = new ThreadLocal<Runnable>(); /** Principal helper method which runs a Runnable with the context @@ -316,16 +336,31 @@ public class GLDrawableHelper { // Support for recursive makeCurrent() calls as well as calling // other drawables' display() methods from within another one's - // FIXME: re-evaluate due to possible expensive TLS access ? - GLContext lastContext = GLContext.getCurrent(); - Runnable lastInitAction = perThreadInitAction.get(); + int res = GLContext.CONTEXT_NOT_CURRENT; + GLContext lastContext = GLContext.getCurrent(); + Runnable lastInitAction = null; if (lastContext != null) { - lastContext.release(); + if (lastContext == context) { + res = GLContext.CONTEXT_CURRENT; + lastContext = null; + } else { + lastInitAction = perThreadInitAction.get(); + lastContext.release(); + } } - int res = 0; + /** + long t0 = System.currentTimeMillis(); + long td1 = 0; // makeCurrent + long tdR = 0; // render time + long td2 = 0; // swapBuffers + long td3 = 0; // release + boolean scr = true; */ + try { - res = context.makeCurrent(); + if (res == GLContext.CONTEXT_NOT_CURRENT) { + res = context.makeCurrent(); + } if (res != GLContext.CONTEXT_NOT_CURRENT) { if(null!=initAction) { perThreadInitAction.set(initAction); @@ -336,32 +371,43 @@ public class GLDrawableHelper { initAction.run(); } } + // tdR = System.currentTimeMillis(); + // td1 = tdR - t0; // makeCurrent if(null!=runnable) { - if (DEBUG && VERBOSE) { + if (DEBUG) { System.err.println("GLDrawableHelper " + this + ".invokeGL(): Running runnable"); } runnable.run(); + // td2 = System.currentTimeMillis(); + // tdR = td2 - tdR; // render time if (autoSwapBufferMode && null != initAction) { if (drawable != null) { drawable.swapBuffers(); + // td3 = System.currentTimeMillis(); + // td2 = td3 - td2; // swapBuffers } } } } } finally { - try { - if (res != GLContext.CONTEXT_NOT_CURRENT) { - context.release(); - } - } catch (Exception e) { + if(res != GLContext.CONTEXT_NOT_CURRENT && + (null == skipContextReleaseThread || Thread.currentThread()!=skipContextReleaseThread) ) { + try { + context.release(); + // scr = false; + } catch (Exception e) { + } } + // td3 = System.currentTimeMillis() - td3; // release if (lastContext != null) { int res2 = lastContext.makeCurrent(); - if (res2 == GLContext.CONTEXT_CURRENT_NEW) { + if (null != lastInitAction && res2 == GLContext.CONTEXT_CURRENT_NEW) { lastInitAction.run(); } } } + // long td0 = System.currentTimeMillis() - t0; + // System.err.println("td0 "+td0+"ms, fps "+(1.0/(td0/1000.0))+", td-makeCurrent: "+td1+"ms, td-render "+tdR+"ms, td-swap "+td2+"ms, td-release "+td3+"ms, skip ctx release: "+scr); } } diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index 7712b4654..3a49c06f0 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -51,6 +51,7 @@ import javax.media.opengl.*; import jogamp.opengl.FPSCounterImpl; import jogamp.opengl.GLDrawableHelper; import com.jogamp.opengl.JoglVersion; +import com.jogamp.opengl.util.Animator; /** * An implementation of {@link javax.media.opengl.GLAutoDrawable} interface, @@ -539,14 +540,12 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC } } - /** This implementation uses a static value */ - public void setAutoSwapBufferMode(boolean onOrOff) { + public void setAutoSwapBufferMode(boolean enable) { if(null!=helper) { - helper.setAutoSwapBufferMode(onOrOff); + helper.setAutoSwapBufferMode(enable); } } - /** This implementation uses a static value */ public boolean getAutoSwapBufferMode() { if(null!=helper) { return helper.getAutoSwapBufferMode(); @@ -554,6 +553,28 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC return false; } + /** + * @param t the thread for which context release shall be skipped, usually the animation thread, + * ie. {@link Animator#getThread()}. + * @deprecated this is an experimental feature, + * intended for measuring performance in regards to GL context switch + */ + public void setSkipContextReleaseThread(Thread t) { + if(null!=helper) { + helper.setSkipContextReleaseThread(t); + } + } + + /** + * @deprecated see {@link #setSkipContextReleaseThread(Thread)} + */ + public Thread getSkipContextReleaseThread() { + if(null!=helper) { + return helper.getSkipContextReleaseThread(); + } + return null; + } + public void swapBuffers() { if(drawable!=null && context != null) { drawable.swapBuffers(); diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java index 5e5b90770..bb678935a 100644 --- a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java +++ b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java @@ -81,6 +81,10 @@ public class NewtBaseActivity extends Activity { public void setAnimator(Animator animator) { this.animator = animator; + if(!animator.isStarted()) { + animator.start(); + } + animator.pause(); } @Override @@ -127,7 +131,7 @@ public class NewtBaseActivity extends Activity { super.onResume(); } if(null != animator) { - animator.start(); + animator.resume(); } } diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java index 3e9869c95..6abb0b354 100644 --- a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java +++ b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java @@ -71,11 +71,13 @@ public class NEWTGearsES2Activity extends NewtBaseActivity { System.err.println("ScreenMode Changed: "+sm); } }); - glWindow.setVisible(true); Animator animator = new Animator(glWindow); animator.setUpdateFPSFrames(60, System.err); // animator.setRunAsFastAsPossible(true); setAnimator(animator); + // glWindow.setSkipContextReleaseThread(animator.getThread()); + + glWindow.setVisible(true); Log.d(TAG, "onCreate - X"); } diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2TransActivity.java b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2TransActivity.java index 84ff0a5a7..691151ef3 100644 --- a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2TransActivity.java +++ b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2TransActivity.java @@ -67,10 +67,12 @@ public class NEWTGearsES2TransActivity extends NewtBaseActivity { System.err.println("ScreenMode Changed: "+sm); } }); - glWindow.setVisible(true); Animator animator = new Animator(glWindow); animator.setUpdateFPSFrames(60, System.err); setAnimator(animator); + // glWindow.setSkipContextReleaseThread(animator.getThread()); + + glWindow.setVisible(true); Log.d(TAG, "onCreate - X"); } diff --git a/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES2Activity.java b/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES2Activity.java index 70d1c382d..51cddd523 100644 --- a/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES2Activity.java +++ b/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES2Activity.java @@ -70,11 +70,13 @@ public class NEWTRedSquareES2Activity extends NewtBaseActivity { System.err.println("ScreenMode Changed: "+sm); } }); - glWindow.setVisible(true); Animator animator = new Animator(glWindow); animator.setUpdateFPSFrames(60, System.err); // animator.setRunAsFastAsPossible(true); setAnimator(animator); + // glWindow.setSkipContextReleaseThread(animator.getThread()); + glWindow.setVisible(true); + Log.d(TAG, "onCreate - X"); } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java index 573d92ad9..a2e470617 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java @@ -111,7 +111,7 @@ public class GearsES2 implements GLEventListener { gl.glEnable(GL.GL_DEPTH_TEST); st = new ShaderState(); - st.setVerbose(true); + // st.setVerbose(true); final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, 1, this.getClass(), "shader", "shader/bin", "gears"); final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, 1, this.getClass(), diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java index 64eb518fb..04897eda5 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java @@ -152,14 +152,15 @@ public class TestGearsES2NEWT extends UITestCase { } }); + animator.setUpdateFPSFrames(60, System.err); + animator.start(); + // glWindow.setSkipContextReleaseThread(animator.getThread()); + glWindow.setVisible(true); System.err.println("size/pos: "+f_glWindow.getX()+"/"+f_glWindow.getY()+" "+f_glWindow.getWidth()+"x"+f_glWindow.getHeight()+", "+f_glWindow.getInsets()); System.err.println("chosen: "+glWindow.getChosenCapabilities()); - animator.setUpdateFPSFrames(60, System.err); - animator.start(); - while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) { Thread.sleep(100); } |