29package com.jogamp.opengl.util;
31import jogamp.opengl.Debug;
32import jogamp.opengl.FPSCounterImpl;
34import java.io.PrintStream;
35import java.util.ArrayList;
36import java.util.Locale;
38import com.jogamp.opengl.GLAnimatorControl;
39import com.jogamp.opengl.GLAutoDrawable;
40import com.jogamp.opengl.GLException;
41import com.jogamp.opengl.GLProfile;
43import com.jogamp.common.ExceptionUtils;
44import com.jogamp.common.util.InterruptedRuntimeException;
56 protected static final boolean DEBUG = Debug.debug(
"Animator");
75 @SuppressWarnings(
"serial")
80 this.drawable = drawable;
96 private static int seqInstanceNumber = 0;
102 protected ArrayList<GLAutoDrawable>
drawables =
new ArrayList<GLAutoDrawable>();
112 private final static Class<?> awtAnimatorImplClazz;
118 clazz = Class.forName(
"com.jogamp.opengl.util.AWTAnimatorImpl");
119 }
catch (
final Exception e) {
122 awtAnimatorImplClazz = clazz;
124 awtAnimatorImplClazz =
null;
157 private static final boolean useAWTAnimatorImpl(
final int modeBits) {
171 protected final synchronized void initImpl(
final boolean force) {
172 if( force ||
null ==
impl ) {
173 final String seqSuffix = String.format((Locale)
null,
"#%02d", seqInstanceNumber++);
174 if( useAWTAnimatorImpl(
modeBits ) ) {
178 }
catch (
final Exception e) { e.printStackTrace(); }
181 impl =
new DefaultAnimatorImpl();
207 if( useAWTAnimatorImpl( _oldModeBits ) != useAWTAnimatorImpl(
modeBits ) ) {
220 System.err.println(
"Animator add: 0x"+Integer.toHexString(drawable.hashCode())+
" - "+
toString()+
" - "+
getThreadName());
223 throw new IllegalArgumentException(
"Drawable already added to animator: "+
this+
", "+drawable);
238 public boolean eval() {
252 System.err.println(
"Animator remove: 0x"+Integer.toHexString(drawable.hashCode())+
" - "+
toString()+
" - "+
getThreadName());
255 throw new IllegalArgumentException(
"Drawable not added to animator: "+
this+
", "+drawable);
259 drawable.setExclusiveContextThread(
null );
262 public boolean eval() {
263 return null != drawable.getExclusiveContextThread();
267 System.err.println(
"Animator remove: Wait for Null-ECT OK: "+res+
", "+
toString()+
", dect "+drawable.getExclusiveContextThread());
271 final boolean paused =
pause();
274 drawable.setAnimator(
null);
280 System.err.println(
"Animator remove: Wait for !Animating-if-empty OK: "+res+
", "+
toString());
284 private final Condition waitForNotAnimatingIfEmptyCondition =
new Condition() {
286 public boolean eval() {
314 final boolean enable =
null != t;
346 final boolean propagateState;
347 final boolean oldExclusiveContext;
348 final Thread _exclusiveContextThread;
355 System.err.println(
"AnimatorBase.setExclusiveContextThread: "+oldExclusiveContext+
" -> "+
exclusiveContext+
", propagateState "+propagateState+
", "+
this);
358 final Thread dECT = enable ? (
null != _exclusiveContextThread ? _exclusiveContextThread :
animThread ) :
null ;
360 if( propagateState ) {
363 if( Thread.currentThread() ==
getThread() || Thread.currentThread() == _exclusiveContextThread ) {
375 }
catch (
final InterruptedException e) { }
389 if(
null != displayCaught ) {
390 System.err.println(
"AnimatorBase.setExclusiveContextThread: caught: "+displayCaught.getMessage());
391 displayCaught.printStackTrace();
394 if(
null != displayCaught ) {
397 return oldExclusiveContext;
439 System.err.println(
"AnimatorBase.setExclusiveContextImpl exlusive "+
exclusiveContext+
": Enable "+enable+
" for "+
this+
" - "+Thread.currentThread());
445 drawables.get(i).setExclusiveContextThread( enable ? ect :
null );
446 }
catch (
final RuntimeException e) {
453 if( expected !=
drawables.get(i).getExclusiveContextThread() ) {
560 }
catch (
final Throwable t) { }
602 final boolean blocking;
609 if( 0 >= pollPeriod ) {
610 pollPeriod = remaining;
612 nok = waitCondition.
eval();
613 while ( nok && remaining>0 ) {
614 final long t1 = System.currentTimeMillis();
615 if( pollPeriod > remaining ) { pollPeriod = remaining; }
619 }
catch (
final InterruptedException ie) {
620 throw new InterruptedRuntimeException(ie);
622 remaining -= System.currentTimeMillis() - t1 ;
623 nok = waitCondition.
eval();
635 nok = waitCondition.
eval();
638 nok = waitCondition.
eval();
641 final boolean res = !nok || !blocking;
642 if(
DEBUG || blocking && nok) {
643 if( blocking && remaining<=0 && nok ) {
644 System.err.println(
"finishLifecycleAction(" + waitCondition.getClass().getName() +
"): ++++++ timeout reached ++++++ " +
getThreadName());
646 System.err.println(
"finishLifecycleAction(" + waitCondition.getClass().getName() +
"): OK "+(!nok)+
647 "- pollPeriod "+pollPeriod+
", blocking "+blocking+
" -> res "+res+
650 System.err.println(
" - "+
toString());
652 ExceptionUtils.dumpStack(System.err);
663 protected static String
getThreadName() {
return Thread.currentThread().getName(); }
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
Specifies the the OpenGL profile.
static void initSingleton()
Static initialization of JOGL.
UncaughtAnimatorException(final GLAutoDrawable drawable, final Throwable cause)
final GLAutoDrawable getGLAutoDrawable()
Base implementation of GLAnimatorControl
static String getThreadName()
final long getLastFPSPeriod()
final int getUpdateFPSFrames()
static final boolean DEBUG
AnimatorBase()
Creates a new, empty Animator instance while expecting an AWT rendering thread if AWT is available.
final void setUncaughtExceptionHandler(final UncaughtExceptionHandler handler)
Set the handler invoked when this animator abruptly stops due to an uncaught exception from one of it...
final long getTotalFPSDuration()
final synchronized boolean isExclusiveContextEnabled()
Returns true, if the exclusive context thread is enabled, otherwise false.
final boolean setExclusiveContext(final boolean enable)
Dedicate all GLAutoDrawable's context to this animator thread.
final synchronized void setDrawablesExclCtxState(final boolean enable)
Should be called at start() and stop() from within the animator thread.
AnimatorBase(final int modeBits)
Creates a new, empty Animator instance with given modeBits.
static final int MODE_EXPECT_AWT_RENDERING_THREAD
If present in modeBits field and AWT is available, implementation is aware of the AWT EDT,...
final void display()
Called every frame to cause redrawing of all of the GLAutoDrawables this Animator manages.
static final long TO_WAIT_FOR_FINISH_LIFECYCLE_ACTION
A 1s timeout while waiting for a native action response, limiting finishLifecycleAction(Condition,...
final int getTotalFPSFrames()
final void resetFPSCounter()
Reset all performance counter (startTime, currentTime, frame number)
final void flushGLRunnables()
Should be called in case of an uncaught exception from within the animator thread to flush all animat...
final synchronized boolean handleUncaughtException(final UncaughtAnimatorException ue)
Should be called in case of an uncaught exception from within the animator thread,...
abstract String getBaseName(String prefix)
ArrayList< GLAutoDrawable > drawables
UncaughtExceptionHandler uncaughtExceptionHandler
final float getTotalFPS()
final synchronized void setModeBits(final boolean enable, final int bitValues)
Enables or disables the given bitValues in this Animators modeBits.
final UncaughtExceptionHandler getUncaughtExceptionHandler()
Returns the UncaughtExceptionHandler invoked when this animator abruptly stops due to an uncaught exc...
final long getFPSStartTime()
Returns the time of the first display call in milliseconds after enabling this feature via setUpdateF...
final long getLastFPSUpdateTime()
Returns the time of the last update interval in milliseconds, if this feature is enabled via setUpdat...
Thread userExclusiveContextThread
final synchronized boolean finishLifecycleAction(final Condition waitCondition, long pollPeriod)
final synchronized void initImpl(final boolean force)
Initializes implementation details post setup, invoked at add(GLAutoDrawable), start(),...
final synchronized Thread getThread()
final synchronized Thread getExclusiveContextThread()
Returns the exclusive context thread if isExclusiveContextEnabled() and isStarted(),...
final synchronized void add(final GLAutoDrawable drawable)
Adds a drawable to this animator's list of rendering drawables.
FPSCounterImpl fpsCounter
static final long POLLP_WAIT_FOR_FINISH_LIFECYCLE_ACTION
final synchronized Thread setExclusiveContext(final Thread t)
Dedicate all GLAutoDrawable's context to the given exclusive context thread.
synchronized int getModeBits()
final void setPrintExceptions(final boolean printExceptions)
Sets a flag indicating that when exceptions are being ignored by this Animator (see setIgnoreExceptio...
final void setIgnoreExceptions(final boolean ignoreExceptions)
Sets a flag causing this Animator to ignore exceptions produced while redrawing the drawables.
final void setUpdateFPSFrames(final int frames, final PrintStream out)
final boolean validateDrawablesExclCtxState(final Thread expected)
synchronized boolean isStarted()
Indicates whether this animator has been started.
A registered UncaughtExceptionHandler instance is invoked when an animator abruptly stops due to an u...
void uncaughtException(final GLAnimatorControl animator, final GLAutoDrawable drawable, final Throwable cause)
Method invoked when the given GLAnimatorControl is stopped due to the given uncaught exception happen...
An animator control interface, which implementation may drive a com.jogamp.opengl....
boolean isPaused()
Indicates whether this animator is started and either manually paused or paused automatically due to ...
boolean resume()
Resumes animation if paused.
boolean isAnimating()
Indicates whether this animator is started and is not paused.
boolean pause()
Pauses this animator.
A higher-level abstraction than GLDrawable which supplies an event based mechanism (GLEventListener) ...
Thread setExclusiveContextThread(Thread t)
Dedicates this instance's GLContext to the given thread.
abstract void setAnimator(GLAnimatorControl animatorControl)
Registers the usage of an animator, an com.jogamp.opengl.GLAnimatorControl implementation.
Thread getExclusiveContextThread()
boolean blockUntilDone(final Thread thread)
void display(final ArrayList< GLAutoDrawable > drawables, final boolean ignoreExceptions, final boolean printExceptions)