From c9faf1391d8ab972fb0f1b231c33a5bf02be5051 Mon Sep 17 00:00:00 2001
From: Kenneth Russel <kbrussel@alum.mit.edu>
Date: Tue, 21 Feb 2006 08:06:07 +0000
Subject: Added GLWorkerThread for moving OpenGL-related work onto a different
 thread than the EDT. Added option for it in Threading; needs testing on more
 platforms.

git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/trunk@625 232f8b59-042b-4e1e-8c03-345bb8c30851
---
 .../com/sun/opengl/impl/GLWorkerThread.java        | 155 +++++++++++++++++++++
 1 file changed, 155 insertions(+)
 create mode 100755 src/classes/com/sun/opengl/impl/GLWorkerThread.java

(limited to 'src/classes/com/sun/opengl/impl/GLWorkerThread.java')

diff --git a/src/classes/com/sun/opengl/impl/GLWorkerThread.java b/src/classes/com/sun/opengl/impl/GLWorkerThread.java
new file mode 100755
index 000000000..7c1d7413b
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/GLWorkerThread.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2006 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 com.sun.opengl.impl;
+
+/** Singleton thread upon which all OpenGL work is performed by
+    default. Unfortunately many vendors' OpenGL drivers are not really
+    thread-safe and stability is much improved by performing OpenGL
+    work on at most one thread. This is the default behavior of the
+    GLAutoDrawable implementations according to the {@link
+    javax.media.opengl.Threading Threading} class. The GLWorkerThread
+    replaces the original AWT event queue thread-based mechanism for
+    two reasons: first, more than one AWT event queue thread may be
+    spawned, for example if a dialog is being shown; second, it avoids
+    blocking the AWT event queue thread during OpenGL rendering. */
+
+public class GLWorkerThread {
+  private static volatile boolean started;
+  private static volatile Thread thread;
+  private static Object lock;
+  private static volatile boolean shouldTerminate;
+
+  // The Runnable to execute on the worker thread -- no need for a
+  // queue since we don't have an invokeLater() primitive
+  private static volatile Runnable work;
+  
+  /** Should only be called by Threading class if creation of the
+      GLWorkerThread was requested via the opengl.1thread system
+      property. */
+  public static void start() {
+    if (!started) {
+      synchronized (GLWorkerThread.class) {
+        if (!started) {
+          lock = new Object();
+          thread = new Thread(new WorkerRunnable(),
+                              "JOGL GLWorkerThread");
+          started = true;
+          synchronized (lock) {
+            thread.start();
+            try {
+              lock.wait();
+            } catch (InterruptedException e) {
+            }
+          }
+        } else {
+          throw new RuntimeException("Should not start GLWorkerThread twice");
+        }
+      }
+    }
+  }
+
+  public static void invokeAndWait(Runnable runnable) {
+    if (!started) {
+      throw new RuntimeException("May not invokeAndWait on worker thread without starting it first");
+    }
+
+    Object lockTemp = lock;
+    if (lockTemp == null) {
+      return; // Terminating
+    }
+
+    synchronized (lockTemp) {
+      if (thread == null) {
+        // Terminating
+        return;
+      }
+
+      work = runnable;
+      lock.notifyAll();
+      try {
+        lock.wait();
+      } catch (InterruptedException e) {
+        throw new RuntimeException(e);
+      }
+    }
+  }
+
+  /** Indicates whether the OpenGL worker thread was started, i.e.,
+      whether it is currently in use. */
+  public static boolean isStarted() {
+    return started;
+  }
+
+  /** Indicates whether the current thread is the OpenGL worker
+      thread. */
+  public static boolean isWorkerThread() {
+    return (Thread.currentThread() == thread);
+  }
+
+  static class WorkerRunnable implements Runnable {
+    public void run() {
+      // Notify starting thread that we're ready
+      synchronized (lock) {
+        lock.notifyAll();
+      }
+
+      while (!shouldTerminate) {
+        synchronized (lock) {
+          while ((work == null) && !shouldTerminate) {
+            try {
+              lock.wait();
+            } catch (InterruptedException e) {
+            }
+          }
+          
+          if (shouldTerminate) {
+            thread = null;
+            lock = null;
+            return;
+          }
+
+          work.run();
+          work = null;
+          lock.notifyAll();
+        }
+      }
+    }
+  }
+}
-- 
cgit v1.2.3