summaryrefslogtreecommitdiffstats
path: root/src/jogl
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java51
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java8
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLRunnableTask.java62
-rw-r--r--src/jogl/classes/javax/media/opengl/GLAutoDrawable.java54
-rw-r--r--src/jogl/classes/javax/media/opengl/GLRunnable.java41
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java8
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java8
7 files changed, 222 insertions, 10 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java
index fcd662048..8fefe149e 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java
@@ -51,6 +51,7 @@ public class GLDrawableHelper {
private static final boolean VERBOSE = Debug.verbose();
private static final boolean NVIDIA_CRASH_WORKAROUND = Debug.isPropertyDefined("jogl.nvidia.crash.workaround", true);
private boolean autoSwapBufferMode = true;
+ private ArrayList glRunnables = new ArrayList(); // one shot GL tasks
public GLDrawableHelper() {
}
@@ -100,6 +101,7 @@ public class GLDrawableHelper {
for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
((GLEventListener) iter.next()).display(drawable);
}
+ execGLRunnables(drawable);
}
public void reshape(GLAutoDrawable drawable,
@@ -109,6 +111,55 @@ public class GLDrawableHelper {
}
}
+ private void execGLRunnables(GLAutoDrawable drawable) {
+ if(glRunnables.size()>0) {
+ ArrayList _glRunnables = null;
+ synchronized(glRunnables) {
+ if(glRunnables.size()>0) {
+ _glRunnables = glRunnables;
+ glRunnables = new ArrayList();
+ }
+ }
+ if(null!=_glRunnables) {
+ for (Iterator iter = _glRunnables.iterator(); iter.hasNext(); ) {
+ ((GLRunnable) iter.next()).run(drawable);
+ }
+ }
+ }
+ }
+
+ private void invokeLater(GLRunnable glRunnable) {
+ synchronized(glRunnables) {
+ glRunnables.add(glRunnable);
+ glRunnables.notifyAll();
+ }
+ }
+
+ public void invoke(boolean wait, GLRunnable glRunnable) {
+ if(glRunnable == null) {
+ return;
+ }
+ Object lock = new Object();
+ GLRunnableTask rTask = new GLRunnableTask(glRunnable, wait?lock:null/*, true*/);
+ Throwable throwable = null;
+ synchronized(lock) {
+ invokeLater(rTask);
+ if( wait ) {
+ try {
+ lock.wait();
+ } catch (InterruptedException ie) {
+ throwable = ie;
+ }
+ }
+ }
+ if(null==throwable) {
+ throwable = rTask.getThrowable();
+ }
+ if(null!=throwable) {
+ throw new RuntimeException(throwable);
+ }
+ }
+
public void setAutoSwapBufferMode(boolean onOrOff) {
autoSwapBufferMode = onOrOff;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java
index eb5e09d2f..071ac1378 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java
@@ -130,10 +130,18 @@ public class GLPbufferImpl implements GLPbuffer {
drawableHelper.addGLEventListener(listener);
}
+ public void addGLEventListener(int index, GLEventListener listener) {
+ drawableHelper.addGLEventListener(index, listener);
+ }
+
public void removeGLEventListener(GLEventListener listener) {
drawableHelper.removeGLEventListener(listener);
}
+ public void invoke(boolean wait, GLRunnable glRunnable) {
+ drawableHelper.invoke(wait, glRunnable);
+ }
+
public void setContext(GLContext ctx) {
context=(GLContextImpl)ctx;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLRunnableTask.java b/src/jogl/classes/com/jogamp/opengl/impl/GLRunnableTask.java
new file mode 100644
index 000000000..a6a030c6b
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLRunnableTask.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010, Sven Gothel
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions 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 Sven Gothel nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Sven Gothel BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jogamp.opengl.impl;
+
+import javax.media.opengl.GLRunnable;
+import javax.media.opengl.GLAutoDrawable;
+
+/**
+ * Helper class to provide a Runnable queue implementation with a Runnable wrapper
+ * which notifies after execution for the <code>invokeAndWait()</code> semantics.
+ */
+public class GLRunnableTask implements GLRunnable {
+ GLRunnable runnable;
+ Object notifyObject;
+
+ Throwable runnableException;
+
+ public GLRunnableTask(GLRunnable runnable, Object notifyObject) {
+ this.runnable = runnable ;
+ this.notifyObject = notifyObject ;
+ }
+
+ public void run(GLAutoDrawable drawable) {
+ try {
+ runnable.run(drawable);
+ } catch (Throwable t) {
+ runnableException = t;
+ }
+ if(null != notifyObject) {
+ synchronized (notifyObject) {
+ notifyObject.notifyAll();
+ }
+ }
+ }
+
+ public Throwable getThrowable() { return runnableException; }
+}
+
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
index 7342369d9..7236aa533 100644
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
+++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
@@ -138,11 +138,22 @@ public interface GLAutoDrawable extends GLDrawable {
*/
public void setContext(GLContext context);
- /** Adds a {@link GLEventListener} to this drawable. If multiple
- listeners are added to a given drawable, they are notified of
- events in an arbitrary order. */
+ /** Adds a {@link GLEventListener} to the end of this drawable queue.
+ The listeners are notified of events in the order of the queue. */
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.
+ * 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;
+
/** 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
@@ -150,6 +161,19 @@ public interface GLAutoDrawable extends GLDrawable {
during this update cycle. */
public void removeGLEventListener(GLEventListener listener);
+ /**
+ * Enqueues the one-shot {@link javax.media.opengl.GLRunnable} into the queue,
+ * which will be executed at the next {@link #display()} call.
+ * <p>
+ * Warning: We cannot verify if the caller runs in the same thread
+ * as the display caller, hence we cannot avoid a deadlock
+ * in such case. You have to know what you are doing,
+ * ie call this only in a I/O event listener, or such.<br></p>
+ * @see #display()
+ * @see javax.media.opengl.GLRunnable
+ */
+ public void invoke(boolean wait, GLRunnable glRunnable);
+
/** FIXME: Returns the current state,
{@link #STATE_INVALID}, {@link #STATE_VALID} or {@link #STATE_DESTROYING}.
Tool to determine, e.g. if a {@link GLEventListener#dispose dispose(..)}
@@ -166,19 +190,28 @@ public interface GLAutoDrawable extends GLDrawable {
routine may be called manually. */
public void destroy();
- /** Causes OpenGL rendering to be performed for this GLAutoDrawable
- by calling {@link GLEventListener#display display(..)} for all
- registered {@link GLEventListener}s. Called automatically by the
- window system toolkit upon receiving a repaint() request. this
- routine may be called manually for better control over the
+ /** <p>Causes OpenGL rendering to be performed for this GLAutoDrawable
+ in the following order:
+ <ul>
+ <li> Calling {@link GLEventListener#display display(..)} for all
+ registered {@link GLEventListener}s. </li>
+ <li> Execute and dismiss all one-shot {@link javax.media.opengl.GLRunnable},
+ enqueued via {@link #invoke(boolean, GLRunnable)}.</li>
+ </ul></p>
+ <p>
+ Called automatically by the
+ window system toolkit upon receiving a repaint() request.</p>
+ <p>
+ This routine may 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>
+ display(..)} callback.</p>
+ <p>
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
actual {@link GLEventListener#display display(..)} calls,
- in case this has not been done yet.*/
+ in case this has not been done yet.</p> */
public void display();
/** Enables or disables automatic buffer swapping for this drawable.
@@ -211,4 +244,5 @@ public interface GLAutoDrawable extends GLDrawable {
demos for examples.
@return the set GL pipeline or null if not successful */
public GL setGL(GL gl);
+
}
diff --git a/src/jogl/classes/javax/media/opengl/GLRunnable.java b/src/jogl/classes/javax/media/opengl/GLRunnable.java
new file mode 100644
index 000000000..8d619273f
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLRunnable.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010, Sven Gothel
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions 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 Sven Gothel nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Sven Gothel BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package javax.media.opengl;
+
+/** <p> Declares one-shot OpenGL commands, which client code can use to manage OpenGL
+ commands into a {@link GLAutoDrawable}. At the time any of these
+ methods is called, the drawable has made its associated OpenGL
+ context current, so it is valid to make OpenGL calls.<br></p>
+ <p> A GLRunnable maybe used to inject OpenGL commands via I/O event listener,
+ via {@link GLAutoDrawable#invoke(boolean, GLRunnable)}.</p>
+ */
+public interface GLRunnable {
+ /** Called by the drawable to initiate one-shot OpenGL commands by the
+ client, like {@link GLEventListener#display(GLAutoDrawable)}. */
+ public void run(GLAutoDrawable drawable);
+}
+
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index 77b8e45d3..2dafd691a 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -484,10 +484,18 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
drawableHelper.addGLEventListener(listener);
}
+ public void addGLEventListener(int index, GLEventListener listener) {
+ drawableHelper.addGLEventListener(index, listener);
+ }
+
public void removeGLEventListener(GLEventListener listener) {
drawableHelper.removeGLEventListener(listener);
}
+ public void invoke(boolean wait, GLRunnable glRunnable) {
+ drawableHelper.invoke(wait, glRunnable);
+ }
+
public void setContext(GLContext ctx) {
context=(GLContextImpl)ctx;
}
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index 955949415..73962e979 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -372,10 +372,18 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable {
drawableHelper.addGLEventListener(listener);
}
+ public void addGLEventListener(int index, GLEventListener listener) {
+ drawableHelper.addGLEventListener(index, listener);
+ }
+
public void removeGLEventListener(GLEventListener listener) {
drawableHelper.removeGLEventListener(listener);
}
+ public void invoke(boolean wait, GLRunnable glRunnable) {
+ drawableHelper.invoke(wait, glRunnable);
+ }
+
public GLContext createContext(GLContext shareWith) {
return backend.createContext(shareWith);
}