aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/javax/media/opengl/GLAutoDrawable.java')
-rw-r--r--src/jogl/classes/javax/media/opengl/GLAutoDrawable.java425
1 files changed, 343 insertions, 82 deletions
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
index c676535c8..bf8fe65ac 100644
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
+++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
@@ -1,22 +1,22 @@
/*
* 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
* met:
- *
+ *
* - Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- *
+ *
* - Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- *
+ *
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
- *
+ *
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
@@ -29,53 +29,62 @@
* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
+ *
* You acknowledge that this software is not designed or intended for use
* in the design, construction, operation or maintenance of any nuclear
* facility.
- *
+ *
* Sun gratefully acknowledges that this software was originally authored
* and developed by Kenneth Bradley Russell and Christopher John Kline.
*/
package javax.media.opengl;
+import java.util.List;
+
import jogamp.opengl.Debug;
/** A higher-level abstraction than {@link GLDrawable} which supplies
an event based mechanism ({@link GLEventListener}) for performing
OpenGL rendering. A GLAutoDrawable automatically creates a primary
rendering context which is associated with the GLAutoDrawable for
- the lifetime of the object. This context has the {@link
- GLContext#setSynchronized synchronized} property enabled so that
- calls to {@link GLContext#makeCurrent makeCurrent} will block if
- the context is current on another thread. This allows the internal
- GLContext for the GLAutoDrawable to be used both by the event
- based rendering mechanism as well by end users directly.<P>
-
+ the lifetime of the object.
+ <p>
+ Since the {@link GLContext} {@link GLContext#makeCurrent makeCurrent}
+ implementation is synchronized, i.e. blocks if the context
+ is current on another thread, the internal
+ {@link GLContext} for the GLAutoDrawable can be used for the event
+ based rendering mechanism and by end users directly.
+ </p>
+ <h5><a name="initialization">GLAutoDrawable Initialization</a></h5>
+ <p>
The implementation shall initialize itself as soon as possible,
- ie if the attached {@link javax.media.nativewindow.NativeSurface NativeSurface} becomes visible/realized.
- The following protocol shall be satisfied:
+ which is only possible <i>after</i> the attached {@link javax.media.nativewindow.NativeSurface NativeSurface} becomes visible and and is realized.<br>
+ The following initialization sequence should be implemented:
<ul>
<li> Create the {@link GLDrawable} with the requested {@link GLCapabilities}</li>
<li> Notify {@link GLDrawable} to validate the {@link GLCapabilities} by calling {@link GLDrawable#setRealized setRealized(true)}.</li>
<li> Create the new {@link GLContext}.</li>
<li> Initialize all OpenGL resources by calling {@link GLEventListener#init init(..)} for all
- registered {@link GLEventListener}s. This can be done immediatly, or with the followup {@link #display display(..)} call.</li>
+ registered {@link GLEventListener}s. This can be done immediately, or with the followup {@link #display display(..)} call.</li>
<li> Send a reshape event by calling {@link GLEventListener#reshape reshape(..)} for all
registered {@link GLEventListener}s. This shall be done after the {@link GLEventListener#init init(..)} calls.</li>
- </ul><P>
-
- Another implementation detail is the drawable reconfiguration. One use case is where a window is being
- dragged to another screen with a different pixel configuration, ie {@link GLCapabilities}. The implementation
- shall be able to detect such cases in conjunction with the associated {@link javax.media.nativewindow.NativeSurface NativeSurface}.<br>
+ </ul>
+ Note: The last to {@link GLEventListener} actions shall be also performed, when {@link #addGLEventListener(GLEventListener) adding}
+ a new one to an already initialized {@link GLAutoDrawable}.
+ </p>
+ <h5><a name="reconfiguration">GLAutoDrawable Reconfiguration</a></h5>
+ <p>
+ Another implementation detail is the {@link GLDrawable} reconfiguration. One use case is where a window is being
+ dragged to another screen with a different pixel configuration, ie {@link GLCapabilities}. The implementation
+ shall be able to detect such cases in conjunction with the associated {@link javax.media.nativewindow.NativeSurface NativeSurface}.<br/>
For example, AWT's {@link java.awt.Canvas} 's {@link java.awt.Canvas#getGraphicsConfiguration getGraphicsConfiguration()}
- is capable to determine a display device change. This is demonstrated within {@link javax.media.opengl.awt.GLCanvas}'s
- and NEWT's <code>AWTCanvas</code> {@link javax.media.opengl.awt.GLCanvas#getGraphicsConfiguration getGraphicsConfiguration()}
- specialization. Another demonstration is NEWT's {@link javax.media.nativewindow.NativeWindow NativeWindow}
- implementation on the Windows platform, which utilizes the native platform's <i>MonitorFromWindow(HWND)</i> function.<br>
- All OpenGL resources shall be regenerated, while the drawable's {@link GLCapabilities} has
- to be choosen again. The following protocol shall be satisfied.
+ is capable to determine a display device change. This is demonstrated within {@link javax.media.opengl.awt.GLCanvas}'s
+ and NEWT's <code>AWTCanvas</code> {@link javax.media.opengl.awt.GLCanvas#getGraphicsConfiguration getGraphicsConfiguration()}
+ specialization. Another demonstration is NEWT's {@link javax.media.nativewindow.NativeWindow NativeWindow}
+ implementation on the Windows platform, which utilizes the native platform's <i>MonitorFromWindow(HWND)</i> function.<br/>
+ All OpenGL resources shall be regenerated, while the drawable's {@link GLCapabilities} has
+ to be chosen again. The following protocol shall be satisfied.
<ul>
<li> Controlled disposal:</li>
<ul>
@@ -95,26 +104,32 @@ import jogamp.opengl.Debug;
registered {@link GLEventListener}s. This shall be done after the {@link GLEventListener#init init(..)} calls.</li>
</ul>
</ul>
- Note: Current graphics driver keep the surface configuration for a given window, even if the window is moved to
+ Note: Current graphics driver keep the surface configuration for a given window, even if the window is moved to
a monitor with a different pixel configuration, ie 32bpp to 16bpp. However, it is best to not assume such behavior
- and make your application comply with the above protocol.<P>
-
- However, to not introduce to much breakage with older applications and because of the situation
- mentioned above, the <code>boolean</code> system property <code>jogl.screenchange.action</code> will control the
- screen change action as follows:<br>
-
+ and make your application comply with the above protocol.
+ <p>
+ Avoiding breakage with older applications and because of the situation
+ mentioned above, the <code>boolean</code> system property <code>jogl.screenchange.action</code> will control the
+ screen change action as follows:<br/>
<PRE>
- -Djogl.screenchange.action=false Disable the drawable reconfiguration (the default)
- -Djogl.screenchange.action=true Enable the drawable reconfiguration
- </PRE>
+ -Djogl.screenchange.action=false Disable the {@link GLDrawable} reconfiguration (the default)
+ -Djogl.screenchange.action=true Enable the {@link GLDrawable} reconfiguration
+ </PRE>
+ </p>
*/
public interface GLAutoDrawable extends GLDrawable {
- /** Flag reflecting wheather the drawable reconfiguration will be issued in
- * case a screen device change occured, e.g. in a multihead environment,
+ /** Flag reflecting whether the {@link GLDrawable} reconfiguration will be issued in
+ * case a screen device change occurred, e.g. in a multihead environment,
* where you drag the window to another monitor. */
public static final boolean SCREEN_CHANGE_ACTION_ENABLED = Debug.getBooleanProperty("jogl.screenchange.action", true);
/**
+ * If the implementation uses delegation, return the delegated {@link GLDrawable} instance,
+ * otherwise return <code>this</code> instance.
+ */
+ public GLDrawable getDelegatedDrawable();
+
+ /**
* Returns the context associated with this drawable. The returned
* context will be synchronized.
* Don't rely on it's identity, the context may change.
@@ -122,53 +137,195 @@ public interface GLAutoDrawable extends GLDrawable {
public GLContext getContext();
/**
- * Associate a new context to this drawable.
+ * Associate the new context, <code>newtCtx</code>, to this auto-drawable.
+ * <p>
+ * The current context will be destroyed if <code>destroyPrevCtx</code> is <code>true</code>,
+ * otherwise it will be dis-associated from this auto-drawable
+ * via {@link GLContext#setGLDrawable(GLDrawable, boolean) setGLDrawable(null, true);} first.
+ * </p>
+ * <p>
+ * The new context will be associated with this auto-drawable
+ * via {@link GLContext#setGLDrawable(GLDrawable, boolean) newCtx.setGLDrawable(drawable, true);}.
+ * </p>
+ * <p>
+ * If the old or new context was current on this thread, it is being released before switching the association.
+ * The new context will be made current afterwards, if it was current before.
+ * However the user shall take extra care that no other thread
+ * attempts to make this context current.
+ * </p>
+ *
+ * @param newCtx the new context, maybe <code>null</code> for dis-association.
+ * @param destroyPrevCtx if <code>true</code>, destroy the previous context if exists
+ * @return the previous GLContext, maybe <code>null</code>
+ *
+ * @see GLContext#setGLDrawable(GLDrawable, boolean)
+ * @see GLContext#setGLReadDrawable(GLDrawable)
+ * @see jogamp.opengl.GLDrawableHelper#switchContext(GLDrawable, GLContext, boolean, GLContext, int)
*/
- public void setContext(GLContext context);
+ public GLContext setContext(GLContext newCtx, boolean destroyPrevCtx);
- /** Adds a {@link GLEventListener} to the end of this drawable queue.
- The listeners are notified of events in the order of the queue. */
+ /**
+ * Adds the given {@link GLEventListener listener} to the end of this drawable queue.
+ * The {@link GLEventListener listeners} are notified of events in the order of the queue.
+ * <p>
+ * The newly added listener's {@link GLEventListener#init(GLAutoDrawable) init(..)}
+ * method will be called once before any other of it's callback methods.
+ * See {@link #getGLEventListenerInitState(GLEventListener)} for details.
+ * </p>
+ * @param listener The GLEventListener object to be inserted
+ */
public void addGLEventListener(GLEventListener listener);
- /**
- * Adds a {@link GLEventListener} at the given index of this drawable queue.
- * The listeners are notified of events in the order of the queue.
- * @param index Position where the listener will be inserted.
+ /**
+ * Adds the given {@link GLEventListener listener} at the given index of this drawable queue.
+ * The {@link GLEventListener listeners} are notified of events in the order of the queue.
+ * <p>
+ * The newly added listener's {@link GLEventListener#init(GLAutoDrawable) init(..)}
+ * method will be called once before any other of it's callback methods.
+ * See {@link #getGLEventListenerInitState(GLEventListener)} for details.
+ * </p>
+ * @param index Position where the listener will be inserted.
* Should be within (0 <= index && index <= size()).
* An index value of -1 is interpreted as the end of the list, size().
* @param listener The GLEventListener object to be inserted
* @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
*/
- public void addGLEventListener(int index, GLEventListener listener)
- throws IndexOutOfBoundsException;
+ public void addGLEventListener(int index, GLEventListener listener) throws IndexOutOfBoundsException;
+
+ /**
+ * Returns the number of {@link GLEventListener} of this drawable queue.
+ * @return The number of GLEventListener objects of this drawable queue.
+ */
+ public int getGLEventListenerCount();
+
+ /**
+ * Returns the {@link GLEventListener} at the given index of this drawable queue.
+ * @param index Position of the listener to be returned.
+ * Should be within (0 <= index && index < size()).
+ * An index value of -1 is interpreted as last listener, size()-1.
+ * @return The GLEventListener object at the given index.
+ * @throws IndexOutOfBoundsException If the index is not within (0 <= index && index < size()), or -1
+ */
+ public GLEventListener getGLEventListener(int index) throws IndexOutOfBoundsException;
- /** Removes a {@link GLEventListener} from this drawable. Note that
- if this is done from within a particular drawable's {@link
- GLEventListener} handler (reshape, display, etc.) that it is not
- guaranteed that all other listeners will be evaluated properly
- during this update cycle. */
- public void removeGLEventListener(GLEventListener listener);
+ /**
+ * Retrieves whether the given {@link GLEventListener listener} is initialized or not.
+ * <p>
+ * After {@link #addGLEventListener(GLEventListener) adding} a {@link GLEventListener} it is
+ * marked <i>uninitialized</i> and added to a list of to be initialized {@link GLEventListener}.
+ * If such <i>uninitialized</i> {@link GLEventListener}'s handler methods (reshape, display)
+ * are about to be invoked, it's {@link GLEventListener#init(GLAutoDrawable) init(..)} method is invoked first.
+ * Afterwards the {@link GLEventListener} is marked <i>initialized</i>
+ * and removed from the list of to be initialized {@link GLEventListener}.
+ * </p>
+ * <p>
+ * This methods returns the {@link GLEventListener} initialized state,
+ * i.e. returns <code>false</code> if it is included in the list of to be initialized {@link GLEventListener},
+ * otherwise <code>true</code>.
+ * </p>
+ * @param listener the GLEventListener object to query it's initialized state.
+ */
+ public boolean getGLEventListenerInitState(GLEventListener listener);
+
+ /**
+ * Sets the given {@link GLEventListener listener's} initialized state.
+ * <p>
+ * This methods allows manually setting the {@link GLEventListener} initialized state,
+ * i.e. adding it to, or removing it from the list of to be initialized {@link GLEventListener}.
+ * See {@link #getGLEventListenerInitState(GLEventListener)} for details.
+ * </p>
+ * <p>
+ * <b>Warning:</b> This method does not validate whether the given {@link GLEventListener listener's}
+ * is member of this drawable queue, i.e. {@link #addGLEventListener(GLEventListener) added}.
+ * </p>
+ * <p>
+ * This method is only exposed to allow users full control over the {@link GLEventListener}'s state
+ * and is usually not recommended to change.
+ * </p>
+ * <p>
+ * One use case is moving a {@link GLContext} and their initialized {@link GLEventListener}
+ * from one {@link GLAutoDrawable} to another,
+ * where a subsequent {@link GLEventListener#init(GLAutoDrawable) init(..)} call after adding it
+ * to the new owner is neither required nor desired.
+ * See {@link com.jogamp.opengl.util.GLDrawableUtil#swapGLContextAndAllGLEventListener(GLAutoDrawable, GLAutoDrawable) swapGLContextAndAllGLEventListener(..)}.
+ * </p>
+ * @param listener the GLEventListener object to perform a state change.
+ * @param initialized if <code>true</code>, mark the listener initialized, otherwise uninitialized.
+ */
+ public void setGLEventListenerInitState(GLEventListener listener, boolean initialized);
+
+ /**
+ * Disposes the given {@link GLEventListener listener} via {@link GLEventListener#dispose(GLAutoDrawable) dispose(..)}
+ * if it has been initialized and added to this queue.
+ * <p>
+ * If <code>remove</code> is <code>true</code>, the {@link GLEventListener} is removed from this drawable queue before disposal,
+ * otherwise marked uninitialized.
+ * </p>
+ * <p>
+ * If an {@link GLAnimatorControl} is being attached and the current thread is different
+ * than {@link GLAnimatorControl#getThread() the animator's thread}, it is paused during the operation.
+ * </p>
+ * <p>
+ * Note that this is an expensive operation, since {@link GLEventListener#dispose(GLAutoDrawable) dispose(..)}
+ * is decorated by {@link GLContext#makeCurrent()} and {@link GLContext#release()}.
+ * </p>
+ * <p>
+ * Use {@link #removeGLEventListener(GLEventListener) removeGLEventListener(listener)} instead
+ * if you just want to remove the {@link GLEventListener listener} and <i>don't care</i> about the disposal of the it's (OpenGL) resources.
+ * </p>
+ * <p>
+ * Also note that this is done from within a particular drawable's
+ * {@link GLEventListener} handler (reshape, display, etc.), that it is not
+ * guaranteed that all other listeners will be evaluated properly
+ * during this update cycle.
+ * </p>
+ * @param listener The GLEventListener object to be disposed and removed if <code>remove</code> is <code>true</code>
+ * @param remove pass <code>true</code> to have the <code>listener</code> removed from this drawable queue, otherwise pass <code>false</code>
+ * @return the disposed and/or removed GLEventListener, or null if no action was performed, i.e. listener was not added
+ */
+ public GLEventListener disposeGLEventListener(GLEventListener listener, boolean remove);
/**
+ * Removes the given {@link GLEventListener listener} from this drawable queue.
* <p>
+ * This is an inexpensive operation, since the removed listener's
+ * {@link GLEventListener#dispose(GLAutoDrawable) dispose(..)} method will <i>not</i> be called.
+ * </p>
+ * <p>
+ * Use {@link #disposeGLEventListener(GLEventListener, boolean) disposeGLEventListener(listener, true)}
+ * instead to ensure disposal of the {@link GLEventListener listener}'s (OpenGL) resources.
+ * </p>
+ * <p>
+ * Note that if this is done from within a particular drawable's
+ * {@link GLEventListener} handler (reshape, display, etc.), that it is not
+ * guaranteed that all other listeners will be evaluated properly
+ * during this update cycle.
+ * </p>
+ * @param listener The GLEventListener object to be removed
+ * @return the removed GLEventListener, or null if listener was not added
+ */
+ public GLEventListener removeGLEventListener(GLEventListener listener);
+
+ /**
* Registers the usage of an animator, an {@link javax.media.opengl.GLAnimatorControl} implementation.
- * The animator will be queried whether it's animating, ie periodically issuing {@link #display()} calls or not.</p><br>
+ * The animator will be queried whether it's animating, ie periodically issuing {@link #display()} calls or not.
* <p>
* This method shall be called by an animator implementation only,<br>
* e.g. {@link com.jogamp.opengl.util.Animator#add(javax.media.opengl.GLAutoDrawable)}, passing it's control implementation,<br>
- * and {@link com.jogamp.opengl.util.Animator#remove(javax.media.opengl.GLAutoDrawable)}, passing <code>null</code>.</p><br>
+ * and {@link com.jogamp.opengl.util.Animator#remove(javax.media.opengl.GLAutoDrawable)}, passing <code>null</code>.
+ * </p>
* <p>
* Impacts {@link #display()} and {@link #invoke(boolean, GLRunnable)} semantics.</p><br>
*
- * @param animator <code>null</code> reference indicates no animator is using
- * this <code>GLAutoDrawable</code>,<br>
- * a valid reference indicates an animator is using this <code>GLAutoDrawable</code>.
+ * @param animatorControl <code>null</code> reference indicates no animator is using
+ * this <code>GLAutoDrawable</code>,<br>
+ * a valid reference indicates an animator is using this <code>GLAutoDrawable</code>.
*
* @throws GLException if an animator is already registered.
* @see #display()
* @see #invoke(boolean, GLRunnable)
* @see javax.media.opengl.GLAnimatorControl
- */
+ */
public abstract void setAnimator(GLAnimatorControl animatorControl) throws GLException;
/**
@@ -179,30 +336,96 @@ public interface GLAutoDrawable extends GLDrawable {
*/
public GLAnimatorControl getAnimator();
- /**
+ /**
+ * Dedicates this instance's {@link GLContext} to the given thread.<br/>
+ * The thread will exclusively claim the {@link GLContext} via {@link #display()} and not release it
+ * until {@link #destroy()} or <code>setExclusiveContextThread(null)</code> has been called.
+ * <p>
+ * Default non-exclusive behavior is <i>requested</i> via <code>setExclusiveContextThread(null)</code>,
+ * which will cause the next call of {@link #display()} on the exclusive thread to
+ * release the {@link GLContext}. Only after it's async release, {@link #getExclusiveContextThread()}
+ * will return <code>null</code>.
+ * </p>
+ * <p>
+ * To release a previous made exclusive thread, a user issues <code>setExclusiveContextThread(null)</code>
+ * and may poll {@link #getExclusiveContextThread()} until it returns <code>null</code>,
+ * <i>while</i> the exclusive thread is still running.
+ * </p>
* <p>
+ * Note: Setting a new exclusive thread without properly releasing a previous one
+ * will throw an GLException.
+ * </p>
+ * <p>
+ * Note: Utilizing this feature w/ AWT could lead to an AWT-EDT deadlock, depending on the AWT implementation.
+ * Hence it is advised not to use it with native AWT GLAutoDrawable like GLCanvas.
+ * </p>
+ * <p>
+ * One scenario could be to dedicate the context to the {@link GLAnimatorControl#getThread() animator thread}
+ * and spare redundant context switches, see {@link com.jogamp.opengl.util.AnimatorBase#setExclusiveContext(boolean)}.
+ * </p>
+ * @param t the exclusive thread to claim the context, or <code>null</code> for default operation.
+ * @return previous exclusive context thread
+ * @throws GLException If an exclusive thread is still active but a new one is attempted to be set
+ * @see com.jogamp.opengl.util.AnimatorBase#setExclusiveContext(boolean)
+ */
+ public Thread setExclusiveContextThread(Thread t) throws GLException;
+
+ /**
+ * @see #setExclusiveContextThread(Thread)
+ */
+ public Thread getExclusiveContextThread();
+
+ /**
* Enqueues a one-shot {@link GLRunnable},
* which will be executed within the next {@link #display()} call
- * after all registered {@link GLEventListener}s
- * {@link GLEventListener#display(GLAutoDrawable) display(GLAutoDrawable)}
- * methods has been called.
- * </p>
+ * after all registered {@link GLEventListener}s
+ * {@link GLEventListener#display(GLAutoDrawable) display(GLAutoDrawable)}
+ * methods have been called.
* <p>
* If no {@link GLAnimatorControl} is animating (default),<br>
* or if the current thread is the animator thread,<br>
- * a {@link #display()} call is issued after enqueue the <code>GLRunnable</code>.<br>
- * No extra synchronization is performed in case <code>wait</code> is true, since it is executed in the current thread.</p>
+ * a {@link #display()} call is issued after enqueue the <code>GLRunnable</code>,
+ * hence the {@link GLRunnable} will be executed right away.<br/>
+ * </p>
* <p>
- * If an {@link GLAnimatorControl} is animating,<br>
- * no {@link #display()} call is issued, since the animator thread performs it.<br>
- * If <code>wait</code> is true, the implementation waits until the <code>GLRunnable</code> is executed.<br>
- * </p><br>
+ * If an {@link GLAnimatorControl animator} is running,<br>
+ * no explicit {@link #display()} call is issued, allowing the {@link GLAnimatorControl animator} to perform at due time.<br>
+ * </p>
+ * <p>
+ * If <code>wait</code> is <code>true</code> the call blocks until the <code>glRunnable</code>
+ * has been executed by the {@link GLAnimatorControl animator}, otherwise the method returns immediately.
+ * </p>
+ * <p>
+ * If <code>wait</code> is <code>true</code> <b>and</b>
+ * {@link #isRealized()} returns <code>false</code> <i>or</i> {@link #getContext()} returns <code>null</code>,
+ * the call is ignored and returns <code>false</code>.<br>
+ * This helps avoiding deadlocking the caller.
+ * </p>
+ * <p>
+ * The internal queue of {@link GLRunnable}'s is being flushed with {@link #destroy()}
+ * where all blocked callers are being notified.
+ * </p>
+ *
+ * @param wait if <code>true</code> block until execution of <code>glRunnable</code> is finished, otherwise return immediately w/o waiting
+ * @param glRunnable the {@link GLRunnable} to execute within {@link #display()}
+ * @return <code>true</code> if the {@link GLRunnable} has been processed or queued, otherwise <code>false</code>.
*
* @see #setAnimator(GLAnimatorControl)
* @see #display()
* @see GLRunnable
- */
- public void invoke(boolean wait, GLRunnable glRunnable);
+ * @see #invoke(boolean, List)
+ */
+ public boolean invoke(boolean wait, GLRunnable glRunnable);
+
+ /**
+ * Extends {@link #invoke(boolean, GLRunnable)} functionality
+ * allowing to inject a list of {@link GLRunnable}s.
+ * @param wait if <code>true</code> block until execution of the last <code>glRunnable</code> is finished, otherwise return immediately w/o waiting
+ * @param glRunnables the {@link GLRunnable}s to execute within {@link #display()}
+ * @return <code>true</code> if the {@link GLRunnable}s has been processed or queued, otherwise <code>false</code>.
+ * @see #invoke(boolean, GLRunnable)
+ */
+ public boolean invoke(boolean wait, List<GLRunnable> glRunnables);
/** Destroys all resources associated with this GLAutoDrawable,
inclusive the GLContext.
@@ -214,7 +437,7 @@ public interface GLAutoDrawable extends GLDrawable {
routine may be called manually. */
public void destroy();
- /**
+ /**
* <p>
* Causes OpenGL rendering to be performed for this GLAutoDrawable
* in the following order:
@@ -224,21 +447,21 @@ public interface GLAutoDrawable extends GLDrawable {
* <li> Executes all one-shot {@link javax.media.opengl.GLRunnable GLRunnable},
* enqueued via {@link #invoke(boolean, GLRunnable)}.</li>
* </ul></p>
- * <p>
+ * <p>
* May be called periodically by a running {@link javax.media.opengl.GLAnimatorControl} implementation,<br>
* which must register itself with {@link #setAnimator(javax.media.opengl.GLAnimatorControl)}.</p>
* <p>
* Called automatically by the window system toolkit upon receiving a repaint() request, <br>
* except an {@link javax.media.opengl.GLAnimatorControl} implementation {@link javax.media.opengl.GLAnimatorControl#isAnimating()}.</p>
- * <p>
+ * <p>
* This routine may also be called manually for better control over the
* rendering process. It is legal to call another GLAutoDrawable's
* display method from within the {@link GLEventListener#display
* display(..)} callback.</p>
* <p>
- * In case of a new generated OpenGL context,
+ * In case of a new generated OpenGL context,
* the implementation shall call {@link GLEventListener#init init(..)} for all
- * registered {@link GLEventListener}s <i>before</i> making the
+ * registered {@link GLEventListener}s <i>before</i> making the
* actual {@link GLEventListener#display display(..)} calls,
* in case this has not been done yet.</p>
*
@@ -260,17 +483,32 @@ public interface GLAutoDrawable extends GLDrawable {
/**
* @param flags Additional context creation flags.
- *
+ *
* @see GLContext#setContextCreationFlags(int)
* @see GLContext#enableGLDebugMessage(boolean)
*/
public void setContextCreationFlags(int flags);
-
+
/**
* @return Additional context creation flags
*/
public int getContextCreationFlags();
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This GLAutoDrawable implementation holds it's own GLContext reference,
+ * thus created a GLContext using this methods won't replace it implicitly.
+ * To replace or set this GLAutoDrawable's GLContext you need to call {@link #setContext(GLContext, boolean)}.
+ * </p>
+ * <p>
+ * The GLAutoDrawable implementation shall also set the
+ * context creation flags as customized w/ {@link #setContextCreationFlags(int)}.
+ * </p>
+ */
+ @Override
+ public GLContext createContext(GLContext shareWith);
+
/** Returns the {@link GL} pipeline object this GLAutoDrawable uses.
If this method is called outside of the {@link
GLEventListener}'s callback methods (init, display, etc.) it may
@@ -290,4 +528,27 @@ public interface GLAutoDrawable extends GLDrawable {
@return the set GL pipeline or null if not successful */
public GL setGL(GL gl);
+ /**
+ * Method <i>may</i> return the upstream UI toolkit object
+ * holding this {@link GLAutoDrawable} instance, if exist.
+ * <p>
+ * Currently known Java UI toolkits and it's known return types are:
+ *
+ * <table border="1">
+ * <tr><td>Toolkit</td> <td>GLAutoDrawable Implementation</td> <td>~</td> <td>Return Type of getUpstreamWidget()</td</tr>
+ * <tr><td>NEWT</td> <td>{@link com.jogamp.newt.opengl.GLWindow}</td> <td>has a</td> <td>{@link com.jogamp.newt.Window}</td</tr>
+ * <tr><td>SWT</td> <td>{@link com.jogamp.opengl.swt.GLCanvas}</td> <td>is a</td> <td>{@link org.eclipse.swt.widgets.Canvas}</td</tr>
+ * <tr><td>AWT</td> <td>{@link javax.media.opengl.awt.GLCanvas}</td> <td>is a</td> <td>{@link java.awt.Canvas}</td</tr>
+ * <tr><td>AWT</td> <td>{@link javax.media.opengl.awt.GLJPanel}</td> <td>is a</td> <td>{@link javax.swing.JPanel}</td</tr>
+ * </table>
+ * However, the result may be other object types than the listed above
+ * due to new supported toolkits.
+ * </p>
+ * <p>
+ * This method may also return <code>null</code> if no UI toolkit is being used,
+ * as common for offscreen rendering.
+ * </p>
+ */
+ public Object getUpstreamWidget();
+
}