aboutsummaryrefslogtreecommitdiffstats
path: root/src/classes/javax/media/opengl/Threading.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/classes/javax/media/opengl/Threading.java')
-rwxr-xr-xsrc/classes/javax/media/opengl/Threading.java215
1 files changed, 215 insertions, 0 deletions
diff --git a/src/classes/javax/media/opengl/Threading.java b/src/classes/javax/media/opengl/Threading.java
new file mode 100755
index 000000000..28dc00b9c
--- /dev/null
+++ b/src/classes/javax/media/opengl/Threading.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. 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
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * 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.awt.EventQueue;
+import java.lang.reflect.InvocationTargetException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import com.sun.opengl.impl.*;
+
+/** Defines the threading model for the implementation of the classes
+ in this package.
+
+ <P>
+
+ OpenGL is specified as a thread-safe API, but in practice there
+ are multithreading-related issues on most, if not all, of the
+ platforms which support it. For example, some OpenGL
+ implementations do not behave well when one context is made
+ current first on one thread, released, and then made current on a
+ second thread, although this is legal according to the OpenGL
+ specification. On other platforms there are other problems.
+
+ <P>
+
+ Due to these limitations, and due to the inherent multithreading
+ in the Java platform (in particular, in the Abstract Window
+ Toolkit), it is necessary to limit the multithreading occurring in
+ the typical application using the JOGL API. This has been done by
+ forcing all OpenGL-related work for GLAutoDrawables on to a single
+ thread. In other words, if an application uses only the
+ GLAutoDrawable and GLEventListener callback mechanism, it is
+ guaranteed to have the most correct single-threaded behavior on
+ all platforms.
+
+ <P>
+
+ Applications using the GLContext makeCurrent/release API directly
+ will inherently break this single-threaded model, as these methods
+ require that the OpenGL context be made current on the current
+ thread immediately. For applications wishing to integrate better
+ with the single-threaded model, this class provides public access
+ to the mechanism used by the JOGL implementation. Users can
+ execute Runnables on the internal thread used for performing
+ OpenGL work, and query whether the current thread is already this
+ thread. Using these mechanisms the user can move work from the
+ current thread on to the internal OpenGL thread if desired.
+
+ <P>
+
+ This class also provides mechanisms for querying whether this
+ internal serialization of OpenGL work is in effect, and a
+ programmatic way of disabling it. Currently it is enabled by
+ default, although it could be disabled in the future if OpenGL
+ drivers become more robust on all platforms.
+
+ <P>
+
+ In addition to specifying programmatically whether the single
+ thread for OpenGL work is enabled, users may switch it on and off
+ using the system property <code>jogl.1thread</code>. Valid values
+ for this system property are:
+
+ <PRE>
+ -Djogl.1thread=false Disable single-threading of OpenGL work
+ -Djogl.1thread=true Enable single-threading of OpenGL work (default)
+ -Djogl.1thread=auto Select default single-threading behavior (currently on)
+ </PRE>
+*/
+
+public class Threading {
+ private static boolean singleThreaded = true;
+
+ static {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String workaround = System.getProperty("jogl.1thread");
+ if (workaround != null && (!workaround.equals("auto"))) {
+ singleThreaded = Boolean.valueOf(workaround).booleanValue();
+ }
+ printWorkaroundNotice();
+ return null;
+ }
+ });
+ }
+
+ /** No reason to ever instantiate this class */
+ private Threading() {}
+
+ /** Provides a mechanism for end users to disable the default
+ single-threading of the JOGL implementation. Users are strongly
+ discouraged from calling this method unless they are aware of
+ all of the consequences and are prepared to enforce some amount
+ of threading restrictions in their applications. Disabling this
+ single-threading, for example, will have unintended consequences
+ on GLAutoDrawable implementations such as GLCanvas, GLJPanel and
+ GLPbuffer. Currently there is no supported way to re-enable it
+ once disabled, partly to discourage careless use of this
+ method. */
+ public static void disableSingleThreading() {
+ singleThreaded = false;
+ if (Debug.verbose()) {
+ System.err.println("Application forced disabling of single-threading of JOGL implementation");
+ }
+ }
+
+ /** Indicates whether OpenGL work is being automatically forced to a
+ single thread by the JOGL implementation. */
+ public static boolean isSingleThreaded() {
+ return singleThreaded;
+ }
+
+ /** Indicates whether the current thread is the single thread on
+ which the JOGL implementation performs all of its OpenGL-related
+ work. This method should only be called if the single-thread
+ model is in effect. */
+ public static boolean isOpenGLThread() throws GLException {
+ if (!isSingleThreaded()) {
+ throw new GLException("Should only call this in single-threaded mode");
+ }
+
+ if (Java2D.isOGLPipelineActive()) {
+ // FIXME: ideally only the QFT would be considered to be the
+ // "OpenGL thread", but we can not currently run all of JOGL's
+ // OpenGL work on that thread. For now, run the GLJPanel's
+ // Java2D/JOGL bridge on the QFT but everything else on the
+ // EDT, except when we're already on the QFT.
+ return (Java2D.isQueueFlusherThread() ||
+ EventQueue.isDispatchThread());
+ } else {
+ return EventQueue.isDispatchThread();
+ }
+ }
+
+ /** Executes the passed Runnable on the single thread used for all
+ OpenGL work in the JOGL implementation. It is not specified
+ exactly which thread is used for this purpose. This method
+ should only be called if the single-thread model is in use and
+ if the current thread is not the OpenGL thread (i.e., if
+ <code>isOpenGLThread()</code> returns false). It is up to the
+ end user to check to see whether the current thread is the
+ OpenGL thread and either execute the Runnable directly or
+ perform the work inside it. */
+ public static void invokeOnOpenGLThread(Runnable r) throws GLException {
+ if (!isSingleThreaded()) {
+ throw new GLException ("Should only call this in single-threaded mode");
+ }
+
+ if (isOpenGLThread()) {
+ throw new GLException ("Should only call this from other threads than the OpenGL thread");
+ }
+
+ // FIXME: ideally should run all OpenGL work on the Java2D QFT
+ // thread when it's enabled, but there are issues with this when
+ // the GLJPanel is not using the Java2D bridge; would like to run
+ // its OpenGL work on the QFT, but do the image drawing from the
+ // EDT. Other issues still remain with the GLCanvas as well.
+
+ // if (Java2D.isOGLPipelineActive()) {
+ // Java2D.invokeWithOGLContextCurrent(null, r);
+ // } else {
+ try {
+ EventQueue.invokeAndWait(r);
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (InterruptedException e) {
+ throw new GLException(e);
+ }
+ // }
+ }
+
+ private static void printWorkaroundNotice() {
+ if (singleThreaded && Debug.verbose()) {
+ System.err.println("Using single thread for performing OpenGL work in JOGL implementation");
+ }
+ }
+}