aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/games/jogl/impl/GLDrawableHelper.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/java/games/jogl/impl/GLDrawableHelper.java')
-rw-r--r--src/net/java/games/jogl/impl/GLDrawableHelper.java80
1 files changed, 76 insertions, 4 deletions
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();
+ }
+ }
+ }
+ }
}