diff options
author | Kenneth Russel <[email protected]> | 2004-04-08 19:04:23 +0000 |
---|---|---|
committer | Kenneth Russel <[email protected]> | 2004-04-08 19:04:23 +0000 |
commit | f90ab644c419486f7894fda3725a9c81de8bb283 (patch) | |
tree | fba6e3c693cbaf620f9be5d0dfb853cf7ae789d5 | |
parent | 0a2874e6d6a69e3f5c8392402ad1d520adf37b23 (diff) |
Fixed Issue 25: Expose swapBuffers(), please
Fixed Issue 31: Make it safe to remove listeners from a GLDrawable while handling an event
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/trunk@93 232f8b59-042b-4e1e-8c03-345bb8c30851
17 files changed, 84 insertions, 33 deletions
diff --git a/src/net/java/games/jogl/GLCanvas.java b/src/net/java/games/jogl/GLCanvas.java index 527289fdc..9d58930e4 100644 --- a/src/net/java/games/jogl/GLCanvas.java +++ b/src/net/java/games/jogl/GLCanvas.java @@ -160,6 +160,18 @@ public final class GLCanvas extends Canvas implements GLDrawable { return context.getNoAutoRedrawMode(); } + public void setAutoSwapBufferMode(boolean onOrOff) { + context.setAutoSwapBufferMode(onOrOff); + } + + public boolean getAutoSwapBufferMode() { + return context.getAutoSwapBufferMode(); + } + + public void swapBuffers() { + context.invokeGL(swapBuffersAction, false, initAction); + } + public boolean canCreateOffscreenDrawable() { return context.canCreatePbufferContext(); } @@ -195,4 +207,11 @@ public final class GLCanvas extends Canvas implements GLDrawable { } } private DisplayAction displayAction = new DisplayAction(); + + class SwapBuffersAction implements Runnable { + public void run() { + context.swapBuffers(); + } + } + private SwapBuffersAction swapBuffersAction = new SwapBuffersAction(); } diff --git a/src/net/java/games/jogl/GLDrawable.java b/src/net/java/games/jogl/GLDrawable.java index 26b7b0a06..bfa0c9c26 100644 --- a/src/net/java/games/jogl/GLDrawable.java +++ b/src/net/java/games/jogl/GLDrawable.java @@ -170,6 +170,24 @@ public interface GLDrawable extends ComponentEvents { drawable. Defaults to false. */ public boolean getNoAutoRedrawMode(); + /** Enables or disables automatic buffer swapping for this drawable. + By default this property is set to true; when true, after all + GLEventListeners have been called for a display() event, the + front and back buffers are swapped, displaying the results of + the render. When disabled, the user is responsible for calling + {@link #swapBuffers} manually. */ + public void setAutoSwapBufferMode(boolean onOrOff); + + /** Indicates whether automatic buffer swapping is enabled for this + drawable. See {@link #setAutoBufferSwapMode}. */ + public boolean getAutoSwapBufferMode(); + + /** Swaps the front and back buffers of this drawable. When + automatic buffer swapping is enabled (as is the default), it is + not necessary to call this method and doing so may have + undefined results. */ + public void swapBuffers(); + /** Indicates whether this drawable is capable of fabricating a subordinate offscreen drawable for advanced rendering techniques which require offscreen hardware-accelerated surfaces. */ diff --git a/src/net/java/games/jogl/impl/GLContext.java b/src/net/java/games/jogl/impl/GLContext.java index 82672b1c3..98e56a314 100644 --- a/src/net/java/games/jogl/impl/GLContext.java +++ b/src/net/java/games/jogl/impl/GLContext.java @@ -102,6 +102,10 @@ public abstract class GLContext { // GLCanvas protected boolean noAutoRedraw; + // Flag for enabling / disabling automatic swapping of the front and + // back buffers + protected boolean autoSwapBuffers = true; + // Offscreen context handling. Offscreen contexts should handle // these resize requests in makeCurrent and clear the // pendingOffscreenResize flag. @@ -233,7 +237,9 @@ public abstract class GLContext { deferredReshapeAction = null; } runnable.run(); - swapBuffers(); + if (autoSwapBuffers && !isReshape) { + swapBuffers(); + } } catch (RuntimeException e) { caughtException = true; throw(e); @@ -347,6 +353,18 @@ public abstract class GLContext { return noAutoRedraw; } + public void setAutoSwapBufferMode(boolean autoSwapBuffers) { + this.autoSwapBuffers = autoSwapBuffers; + } + + public boolean getAutoSwapBufferMode() { + return autoSwapBuffers; + } + + /** Swaps the buffers of the OpenGL context if necessary. All error + conditions cause a GLException to be thrown. */ + public abstract void swapBuffers() throws GLException; + /** Routine needed only for offscreen contexts in order to resize the underlying bitmap. Called by GLJPanel. */ public void resizeOffscreenContext(int newWidth, int newHeight) { @@ -492,10 +510,6 @@ public abstract class GLContext { GLException to be thrown. */ protected abstract void free() throws GLException; - /** Swaps the buffers of the OpenGL context if necessary. All error - conditions cause a GLException to be thrown. */ - protected abstract void swapBuffers() throws GLException; - /** Helper routine which resets a ProcAddressTable generated by the GLEmitter by looking up anew all of its function pointers. */ protected void resetProcAddressTable(Object table) { diff --git a/src/net/java/games/jogl/impl/GLDrawableHelper.java b/src/net/java/games/jogl/impl/GLDrawableHelper.java index 89800e684..775fffdd6 100644 --- a/src/net/java/games/jogl/impl/GLDrawableHelper.java +++ b/src/net/java/games/jogl/impl/GLDrawableHelper.java @@ -46,39 +46,39 @@ import net.java.games.jogl.*; methods to be able to share it between GLCanvas and GLJPanel. */ public class GLDrawableHelper { - private List listeners = new ArrayList(); + private volatile List listeners = new ArrayList(); public GLDrawableHelper() { } - public void addGLEventListener(GLEventListener listener) { - listeners.add(listener); + public synchronized void addGLEventListener(GLEventListener listener) { + List newListeners = (List) ((ArrayList) listeners).clone(); + newListeners.add(listener); + listeners = newListeners; } - public void removeGLEventListener(GLEventListener listener) { - listeners.remove(listener); + public synchronized void removeGLEventListener(GLEventListener listener) { + List newListeners = (List) ((ArrayList) listeners).clone(); + newListeners.remove(listener); + listeners = newListeners; } public void init(GLDrawable drawable) { - // Note that we don't use iterator() since listeners may - // add/remove other listeners during initialization. We don't - // guarantee that all listeners will be evaluated if - // removeGLEventListener is called. - for (int i = 0; i < listeners.size(); i++) { - ((GLEventListener) listeners.get(i)).init(drawable); + for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { + ((GLEventListener) iter.next()).init(drawable); } } public void display(GLDrawable drawable) { - for (int i = 0; i < listeners.size(); i++) { - ((GLEventListener) listeners.get(i)).display(drawable); + for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { + ((GLEventListener) iter.next()).display(drawable); } } public void reshape(GLDrawable drawable, int x, int y, int width, int height) { - for (int i = 0; i < listeners.size(); i++) { - ((GLEventListener) listeners.get(i)).reshape(drawable, x, y, width, height); + for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { + ((GLEventListener) iter.next()).reshape(drawable, x, y, width, height); } } } diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXDummyGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXDummyGLContext.java index 02ca808c9..b39900342 100644 --- a/src/net/java/games/jogl/impl/macosx/MacOSXDummyGLContext.java +++ b/src/net/java/games/jogl/impl/macosx/MacOSXDummyGLContext.java @@ -98,7 +98,7 @@ class MacOSXDummyGLContext extends MacOSXGLContext throw new GLException("Should not call this"); } - protected synchronized void swapBuffers() throws GLException { + public synchronized void swapBuffers() throws GLException { throw new GLException("Should not call this"); } diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java index 9b7779d7e..470fe631d 100644 --- a/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java +++ b/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java @@ -159,7 +159,7 @@ public abstract class MacOSXGLContext extends GLContext } } - protected abstract void swapBuffers() throws GLException; + public abstract void swapBuffers() throws GLException; protected long dynamicLookupFunction(String glFuncName) { return CGL.getProcAddress(glFuncName); diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXOffscreenGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXOffscreenGLContext.java index 1bbb32eda..3ba7b108a 100644 --- a/src/net/java/games/jogl/impl/macosx/MacOSXOffscreenGLContext.java +++ b/src/net/java/games/jogl/impl/macosx/MacOSXOffscreenGLContext.java @@ -100,6 +100,6 @@ public class MacOSXOffscreenGLContext extends MacOSXPbufferGLContext return super.makeCurrent(initAction); } - protected synchronized void swapBuffers() throws GLException { + public synchronized void swapBuffers() throws GLException { } } diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java index 27b8a67f7..f87aa5668 100644 --- a/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java +++ b/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java @@ -156,7 +156,7 @@ public class MacOSXOnscreenGLContext extends MacOSXGLContext { } } - protected synchronized void swapBuffers() throws GLException { + public synchronized void swapBuffers() throws GLException { if (!CGL.flushBuffer(nsContext, nsView)) { throw new GLException("Error swapping buffers"); } diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXPbufferGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXPbufferGLContext.java index 5e2662b47..1edd88238 100644 --- a/src/net/java/games/jogl/impl/macosx/MacOSXPbufferGLContext.java +++ b/src/net/java/games/jogl/impl/macosx/MacOSXPbufferGLContext.java @@ -100,7 +100,7 @@ public class MacOSXPbufferGLContext extends MacOSXGLContext { return false; } - protected void swapBuffers() throws GLException { + public void swapBuffers() throws GLException { // FIXME: do we need to do anything if the pbuffer is double-buffered? } diff --git a/src/net/java/games/jogl/impl/windows/WindowsGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsGLContext.java index ff61bbd52..87073e22d 100644 --- a/src/net/java/games/jogl/impl/windows/WindowsGLContext.java +++ b/src/net/java/games/jogl/impl/windows/WindowsGLContext.java @@ -164,7 +164,7 @@ public abstract class WindowsGLContext extends GLContext { } } - protected abstract void swapBuffers() throws GLException; + public abstract void swapBuffers() throws GLException; protected long dynamicLookupFunction(String glFuncName) { long res = WGL.wglGetProcAddress(glFuncName); diff --git a/src/net/java/games/jogl/impl/windows/WindowsOffscreenGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsOffscreenGLContext.java index 6185ae9fd..68a5655da 100644 --- a/src/net/java/games/jogl/impl/windows/WindowsOffscreenGLContext.java +++ b/src/net/java/games/jogl/impl/windows/WindowsOffscreenGLContext.java @@ -128,7 +128,7 @@ public class WindowsOffscreenGLContext extends WindowsGLContext { return super.makeCurrent(initAction); } - protected synchronized void swapBuffers() throws GLException { + public synchronized void swapBuffers() throws GLException { } protected void create() { diff --git a/src/net/java/games/jogl/impl/windows/WindowsOnscreenGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsOnscreenGLContext.java index d97cded65..868846079 100644 --- a/src/net/java/games/jogl/impl/windows/WindowsOnscreenGLContext.java +++ b/src/net/java/games/jogl/impl/windows/WindowsOnscreenGLContext.java @@ -135,7 +135,7 @@ public class WindowsOnscreenGLContext extends WindowsGLContext { } } - protected synchronized void swapBuffers() throws GLException { + public synchronized void swapBuffers() throws GLException { if (!WGL.SwapBuffers(hdc)) { throw new GLException("Error swapping buffers"); } diff --git a/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java index dad9cec84..d3795905f 100644 --- a/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java +++ b/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java @@ -396,7 +396,7 @@ public class WindowsPbufferGLContext extends WindowsGLContext { } } - protected void swapBuffers() throws GLException { + public void swapBuffers() throws GLException { // FIXME: do we need to do anything if the pbuffer is double-buffered? // For now, just grab the pixels for the render-to-texture support. if (rtt && !hasRTT) { diff --git a/src/net/java/games/jogl/impl/x11/X11GLContext.java b/src/net/java/games/jogl/impl/x11/X11GLContext.java index 39bae6f62..3f59b5314 100644 --- a/src/net/java/games/jogl/impl/x11/X11GLContext.java +++ b/src/net/java/games/jogl/impl/x11/X11GLContext.java @@ -166,7 +166,7 @@ public abstract class X11GLContext extends GLContext { } } - protected abstract void swapBuffers() throws GLException; + public abstract void swapBuffers() throws GLException; protected long dynamicLookupFunction(String glFuncName) { long res = GLX.glXGetProcAddressARB(glFuncName); diff --git a/src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java b/src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java index 10ffdc854..7890982f3 100644 --- a/src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java +++ b/src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java @@ -135,7 +135,7 @@ public class X11OffscreenGLContext extends X11GLContext { return super.makeCurrent(initAction); } - protected synchronized void swapBuffers() throws GLException { + public synchronized void swapBuffers() throws GLException { } protected synchronized void free() throws GLException { diff --git a/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java b/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java index 882e9b3f1..0a38e6fc7 100644 --- a/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java +++ b/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java @@ -136,7 +136,7 @@ public class X11OnscreenGLContext extends X11GLContext { } } - protected synchronized void swapBuffers() throws GLException { + public synchronized void swapBuffers() throws GLException { // FIXME: this cast to int would be wrong on 64-bit platforms // where the argument type to glXMakeCurrent would change (should // probably make GLXDrawable, and maybe XID, Opaque as long) diff --git a/src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java b/src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java index c92eba96f..454628734 100644 --- a/src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java +++ b/src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java @@ -313,7 +313,7 @@ public class X11PbufferGLContext extends X11GLContext { } } - protected void swapBuffers() throws GLException { + public void swapBuffers() throws GLException { // FIXME: do we need to do anything if the pbuffer is double-buffered? } |