From 34fffab0bb25bbf8a4cd2bf372e018748982b9bc Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Thu, 23 Sep 2010 14:53:25 +0200 Subject: NEWT: Animator API Change - Changed Lifecycle of Display/Screen (part 4) Change GLAutoDrawable interface: setAnimator(Thread) -> setAnimator(GLAnimatorControl) to minimize the setAnimator(..) calls and to allow fine grained control over the animation, ie in case of reparenting where the animation shall pause while changing the window(s). Introducing GLAnimatorControl interface: - abstract class AnimatorBase implements GLAnimatorControl - class Animator extends AnimatorBase - class FPSAnimator extends AnimatorBase This also changes FPSAnimator, since it is no more derived from Animator, use it's superclass or superinterface instead. +++ - Fix GLJPanel.paintComponent(): Don't issue reshape/display in case an external animator thread is animating. - Fix: Documentation [API] --- .../com/jogamp/opengl/impl/GLDrawableHelper.java | 51 +++++++++++++--------- .../com/jogamp/opengl/impl/GLPbufferImpl.java | 6 +-- .../com/jogamp/opengl/impl/GLRunnableTask.java | 41 +++++++++++++---- 3 files changed, 67 insertions(+), 31 deletions(-) (limited to 'src/jogl/classes/com/jogamp/opengl/impl') diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java index 1e954af1d..1596f0baf 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -54,13 +55,14 @@ public class GLDrawableHelper { private boolean autoSwapBufferMode = true; private Object glRunnablesLock = new Object(); private ArrayList glRunnables = new ArrayList(); // one shot GL tasks - private Thread animatorThread = null; // default + private GLAnimatorControl animatorCtrl = null; // default public GLDrawableHelper() { } public String toString() { StringBuffer sb = new StringBuffer(); + sb.append("GLAnimatorControl: "+animatorCtrl+", "); synchronized(listenersLock) { sb.append("GLEventListeners num "+listeners.size()+" ["); for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { @@ -176,51 +178,60 @@ public class GLDrawableHelper { } } - public void setAnimator(Thread animator) throws GLException { + public void setAnimator(GLAnimatorControl animator) throws GLException { synchronized(glRunnablesLock) { - if(animator!=animatorThread && null!=animator && null!=animatorThread) { - throw new GLException("Trying to register animator thread "+animator+", where "+animatorThread+" is already registered. Unregister first."); + if(animatorCtrl!=animator && null!=animator && null!=animatorCtrl) { + throw new GLException("Trying to register GLAnimatorControl "+animator+", where "+animatorCtrl+" is already registered. Unregister first."); } - animatorThread = animator; + animatorCtrl = animator; } } - public Thread getAnimator() { + public GLAnimatorControl getAnimator() { synchronized(glRunnablesLock) { - return animatorThread; + return animatorCtrl; } } + public final boolean isExternalAnimatorAnimating() { + return ( null != animatorCtrl ) ? animatorCtrl.isAnimating() && animatorCtrl.getThread() != Thread.currentThread() : false ; + } + public void invoke(GLAutoDrawable drawable, boolean wait, GLRunnable glRunnable) { if( null == drawable || null == glRunnable ) { return; } Throwable throwable = null; - Object lock = new Object(); GLRunnableTask rTask = null; - synchronized(lock) { - boolean callDisplay; + Object rTaskLock = new Object(); + synchronized(rTaskLock) { + boolean deferred; synchronized(glRunnablesLock) { - callDisplay = null == animatorThread || animatorThread == Thread.currentThread() ; - rTask = new GLRunnableTask(glRunnable, ( !callDisplay && wait ) ? lock : null); + deferred = isExternalAnimatorAnimating(); + if(!deferred) { + wait = false; // don't wait if exec immediatly + } + rTask = new GLRunnableTask(glRunnable, + wait ? rTaskLock : null, + wait /* catch Exceptions if waiting for result */); glRunnables.add(rTask); } - if( callDisplay ) { + if( !deferred ) { drawable.display(); } else if( wait ) { try { - lock.wait(); + rTaskLock.wait(); // free lock, allow execution of rTask } catch (InterruptedException ie) { throwable = ie; } + if(null==throwable) { + throwable = rTask.getThrowable(); + } + if(null!=throwable) { + throw new RuntimeException(throwable); + } } } - if(null==throwable) { - throwable = rTask.getThrowable(); - } - if(null!=throwable) { - throw new RuntimeException(throwable); - } } public void setAutoSwapBufferMode(boolean onOrOff) { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java index c2efb3f4e..dcfb2e3f5 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java @@ -138,11 +138,11 @@ public class GLPbufferImpl implements GLPbuffer { drawableHelper.removeGLEventListener(listener); } - public void setAnimator(Thread animator) { - drawableHelper.setAnimator(animator); + public void setAnimator(GLAnimatorControl animatorControl) { + drawableHelper.setAnimator(animatorControl); } - public Thread getAnimator() { + public GLAnimatorControl getAnimator() { return drawableHelper.getAnimator(); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLRunnableTask.java b/src/jogl/classes/com/jogamp/opengl/impl/GLRunnableTask.java index ea1e63b8b..a2a6939cd 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLRunnableTask.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLRunnableTask.java @@ -38,27 +38,52 @@ import javax.media.opengl.GLAutoDrawable; public class GLRunnableTask implements GLRunnable { GLRunnable runnable; Object notifyObject; + boolean catchExceptions; + boolean isExecuted; Throwable runnableException; - public GLRunnableTask(GLRunnable runnable, Object notifyObject) { + public GLRunnableTask(GLRunnable runnable, Object notifyObject, boolean catchExceptions) { this.runnable = runnable ; this.notifyObject = notifyObject ; + this.catchExceptions = catchExceptions; + isExecuted = false; } public void run(GLAutoDrawable drawable) { - try { - runnable.run(drawable); - } catch (Throwable t) { - runnableException = t; - } - if(null != notifyObject) { + if(null == notifyObject) { + try { + runnable.run(drawable); + } catch (Throwable t) { + runnableException = t; + if(catchExceptions) { + runnableException.printStackTrace(); + } else { + throw new RuntimeException(runnableException); + } + } finally { + isExecuted=true; + } + } else { synchronized (notifyObject) { - notifyObject.notifyAll(); + try { + runnable.run(drawable); + } catch (Throwable t) { + runnableException = t; + if(catchExceptions) { + runnableException.printStackTrace(); + } else { + throw new RuntimeException(runnableException); + } + } finally { + isExecuted=true; + notifyObject.notifyAll(); + } } } } + public boolean isExecuted() { return isExecuted; } public Throwable getThrowable() { return runnableException; } } -- cgit v1.2.3