From 8a4e964a88703bcab4a8888b25ea9e997953180a Mon Sep 17 00:00:00 2001
From: Kenneth Russel <kbrussel@alum.mit.edu>
Date: Sun, 10 Jul 2005 23:17:43 +0000
Subject: Initial set of context-related changes for the JSR-231 API. GLContext
 has been exposed in the public API. The GLEventListener callback mechanism
 has been removed from the core GLContext implementation and moved up to a
 higher level. GLAutoDrawable now contains the GLEventListener-related
 methods, and the GLEventListener's methods now receive a GLAutoDrawable as
 argument. All JOGL demos have been updated for the new APIs. Many FIXMEs and
 much unimplemented functionality remain. There is slightly different
 initialization behavior for the demos containing pbuffers, and the deferring
 of reshape callbacks needs to be rethought.

git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/branches/JSR-231@320 232f8b59-042b-4e1e-8c03-345bb8c30851
---
 src/net/java/games/jogl/impl/GLDrawableHelper.java | 80 ++++++++++++++++++++--
 1 file changed, 76 insertions(+), 4 deletions(-)

(limited to 'src/net/java/games/jogl/impl/GLDrawableHelper.java')

diff --git a/src/net/java/games/jogl/impl/GLDrawableHelper.java b/src/net/java/games/jogl/impl/GLDrawableHelper.java
index dd5d7c17f..da164088f 100644
--- a/src/net/java/games/jogl/impl/GLDrawableHelper.java
+++ b/src/net/java/games/jogl/impl/GLDrawableHelper.java
@@ -42,11 +42,13 @@ package net.java.games.jogl.impl;
 import java.util.*;
 import net.java.games.jogl.*;
 
-/** Encapsulates the implementation of most of the GLDrawable's
+/** Encapsulates the implementation of most of the GLAutoDrawable's
     methods to be able to share it between GLCanvas and GLJPanel. */
 
 public class GLDrawableHelper {
   private volatile List listeners = new ArrayList();
+  private static final boolean DEBUG = Debug.debug("GLDrawableHelper");
+  private static final boolean VERBOSE = Debug.verbose();
 
   public GLDrawableHelper() {
   }
@@ -63,22 +65,92 @@ public class GLDrawableHelper {
     listeners = newListeners;
   }
 
-  public void init(GLDrawable drawable) {
+  public void init(GLAutoDrawable drawable) {
     for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
       ((GLEventListener) iter.next()).init(drawable);
     }
   }
 
-  public void display(GLDrawable drawable) {
+  public void display(GLAutoDrawable drawable) {
     for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
       ((GLEventListener) iter.next()).display(drawable);
     }
   }
 
-  public void reshape(GLDrawable drawable,
+  public void reshape(GLAutoDrawable drawable,
                       int x, int y, int width, int height) {
     for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
       ((GLEventListener) iter.next()).reshape(drawable, x, y, width, height);
     }
   }
+
+  private static final ThreadLocal perThreadInitAction = new ThreadLocal();
+  private Runnable deferredReshapeAction;
+  /** Principal helper method which runs a Runnable with the context
+      made current. This could have been made part of GLContext, but a
+      desired goal is to be able to implement the GLCanvas in terms of
+      the GLContext's public APIs, and putting it into a separate
+      class helps ensure that we don't inadvertently use private
+      methods of the GLContext or its implementing classes. */
+  public void invokeGL(GLContext context,
+                       Runnable  runnable,
+                       boolean   isReshape,
+                       Runnable  initAction) {
+    // Support for recursive makeCurrent() calls as well as calling
+    // other drawables' display() methods from within another one's
+    GLContext lastContext    = GLContext.getCurrent();
+    Runnable  lastInitAction = (Runnable) perThreadInitAction.get();
+    if (lastContext != null) {
+      lastContext.release();
+    }
+    
+    int res = 0;
+    try {
+      res = context.makeCurrent();
+      if (res == GLContext.CONTEXT_NOT_CURRENT) {
+        if (isReshape) {
+          if (DEBUG) {
+            System.err.println("GLDrawableHelper " + this + ".invokeGL(): Deferring reshape action");
+          }
+          deferredReshapeAction = runnable;
+        }
+      } else {
+        if (res == GLContext.CONTEXT_CURRENT_NEW) {
+          if (DEBUG) {
+            System.err.println("GLDrawableHelper " + this + ".invokeGL(): Running initAction");
+          }
+          initAction.run();
+        }
+        if (deferredReshapeAction != null) {
+          if (DEBUG) {
+            System.err.println("GLDrawableHelper " + this + ".invokeGL(): Running deferred reshape action");
+          }
+          Runnable act = deferredReshapeAction;
+          deferredReshapeAction = null;
+          act.run();
+        }
+        if (DEBUG && VERBOSE) {
+          System.err.println("GLDrawableHelper " + this + ".invokeGL(): Running runnable");
+        }
+        runnable.run();
+        // FIXME: must phrase this in terms of new GLDrawable swap buffer functionality
+        if (((GLContextImpl) context).getAutoSwapBufferMode()) {
+          ((GLContextImpl) context).swapBuffers();
+        }
+      }
+    } finally {
+      try {
+        if (res != GLContext.CONTEXT_NOT_CURRENT) {
+          context.release();
+        }
+      } catch (Exception e) {
+      }
+      if (lastContext != null) {
+        int res2 = lastContext.makeCurrent();
+        if (res2 == GLContext.CONTEXT_CURRENT_NEW) {
+          lastInitAction.run();
+        }
+      }
+    }
+  }
 }
-- 
cgit v1.2.3