diff options
author | Sven Gothel <[email protected]> | 2009-03-14 05:20:29 +0000 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2009-03-14 05:20:29 +0000 |
commit | 9517d52c18bfa93d78e03f4c212757eda421afb6 (patch) | |
tree | 8c1bc95802461520f3477c3c224d285debff4e2c /src/classes/javax/media | |
parent | 78ff34edd75db5cd7f3055466d992ca7be3a70a6 (diff) |
NEWT window closing:
- New WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY and
WindowListener.windowDestroyNotify() method.
- Removed windowClosed() method for JNI hook
- Added windowDestroyNotify() windowDestroyed(),
where windowDestroyNotify() shall be called by the native implementation
_before_ the window gets shutdown.
The Window.java then sends a WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY event,
and either Window.java or it's owner GLWindow.java issues the destroy()
procedure.
- Added GLEventListener.dispose(GLAutoDrawable),
to allow user application to release GL ressources.
Issued by GLWindow (-> see windowDestroyNotify())
- X11 impl intercepts WM_DELETE_WINDOW, using Atom,
MacosX impl already uses the _before_ method (VERIFY),
and Windows impl uses the WM_CLOSE event (VERIFY).
JOGL2 dispose/destroy ..
- Added GLEventListener.dispose() to GLCanvas and GLJpanel
- GL* toString() rearrangement, assumes it is issued by GLContext(),
which indeed is the core information node.
- Added proper destroy() methods and calls,
to achieve a proper resource release at destruction.
Instrumentizing almost all classes with a destroy() method,
so no release function lookup is necessary.
- misc changes ..
JOGL2 Demos
- Fixed in regards to the above changes
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/branches/JOGL_2_SANDBOX@1867 232f8b59-042b-4e1e-8c03-345bb8c30851
Diffstat (limited to 'src/classes/javax/media')
-rw-r--r-- | src/classes/javax/media/opengl/GLArrayData.java | 2 | ||||
-rw-r--r-- | src/classes/javax/media/opengl/GLArrayDataWrapper.java | 11 | ||||
-rw-r--r-- | src/classes/javax/media/opengl/GLAutoDrawable.java | 9 | ||||
-rw-r--r-- | src/classes/javax/media/opengl/GLContext.java | 8 | ||||
-rw-r--r-- | src/classes/javax/media/opengl/GLEventListener.java | 11 | ||||
-rw-r--r-- | src/classes/javax/media/opengl/awt/GLCanvas.java | 95 | ||||
-rw-r--r-- | src/classes/javax/media/opengl/awt/GLJPanel.java | 57 | ||||
-rwxr-xr-x | src/classes/javax/media/opengl/util/FBObject.java | 27 | ||||
-rwxr-xr-x | src/classes/javax/media/opengl/util/PMVMatrix.java | 53 |
9 files changed, 249 insertions, 24 deletions
diff --git a/src/classes/javax/media/opengl/GLArrayData.java b/src/classes/javax/media/opengl/GLArrayData.java index a51229cd6..d17ee6a06 100644 --- a/src/classes/javax/media/opengl/GLArrayData.java +++ b/src/classes/javax/media/opengl/GLArrayData.java @@ -108,5 +108,7 @@ public interface GLArrayData { public String toString(); + public void destroy(GL gl); + } diff --git a/src/classes/javax/media/opengl/GLArrayDataWrapper.java b/src/classes/javax/media/opengl/GLArrayDataWrapper.java index f5b5be6c6..24d0fb7e1 100644 --- a/src/classes/javax/media/opengl/GLArrayDataWrapper.java +++ b/src/classes/javax/media/opengl/GLArrayDataWrapper.java @@ -90,6 +90,17 @@ public class GLArrayDataWrapper implements GLArrayData { public final Class getBufferClass() { return clazz; } + public void destroy(GL gl) { + this.buffer = null; + this.components = 0; + this.stride=0; + this.strideB=0; + this.strideL=0; + this.vboName=0; + this.vboUsage=false; + this.bufferOffset=0; + } + public String toString() { return "GLArrayDataWrapper["+name+ ", index "+index+ diff --git a/src/classes/javax/media/opengl/GLAutoDrawable.java b/src/classes/javax/media/opengl/GLAutoDrawable.java index 743cbc143..629142f64 100644 --- a/src/classes/javax/media/opengl/GLAutoDrawable.java +++ b/src/classes/javax/media/opengl/GLAutoDrawable.java @@ -77,6 +77,15 @@ public interface GLAutoDrawable extends GLDrawable { during this update cycle. */ public void removeGLEventListener(GLEventListener listener); + /** Destroys all resources associated with this GLAutoDrawable. + If a window is attached to it's implementation, it shall be closed. + Causes disposing of all OpenGL resources + by calling {@link GLEventListener#dispose dispose} for all + registered {@link GLEventListener}s. Called automatically by the + window system toolkit upon receiving a destroy notification. This + routine may be called manually. */ + public void destroy(); + /** Causes OpenGL rendering to be performed for this GLAutoDrawable by calling {@link GLEventListener#display display} for all registered {@link GLEventListener}s. Called automatically by the diff --git a/src/classes/javax/media/opengl/GLContext.java b/src/classes/javax/media/opengl/GLContext.java index 57569af2a..78252b4e8 100644 --- a/src/classes/javax/media/opengl/GLContext.java +++ b/src/classes/javax/media/opengl/GLContext.java @@ -216,10 +216,12 @@ public abstract class GLContext { return attachedObjects.put(new Integer(name), obj); } + /** + * Classname, GL, GLDrawable + */ public final String toString() { - return "GLContext: "+getClass().getName()+ - "(GL: "+getGL().getClass().getName()+","+ - " Factory: "+ getGLDrawable().getFactory().getClass().getName()+")"; + return getClass().getName()+" ["+getGL()+","+ + " Drawable: "+ getGLDrawable()+"] "; } /** Returns a non-null (but possibly empty) string containing the diff --git a/src/classes/javax/media/opengl/GLEventListener.java b/src/classes/javax/media/opengl/GLEventListener.java index 2f4d3ac72..d2c851a69 100644 --- a/src/classes/javax/media/opengl/GLEventListener.java +++ b/src/classes/javax/media/opengl/GLEventListener.java @@ -57,6 +57,17 @@ public interface GLEventListener extends EventListener { */ public void init(GLAutoDrawable drawable); + /** Called by the drawable before the OpenGL context is + destroyed by an external event. + This happens through notification by the + native window manager, ie window close, but also + manually by calling {@link GLAutoDrawable#destroy destroy}. + Shall be used to perform final release of all OpenGL + resources, such as memory buffers and GLSL programs. + You might also want to exit your application after receiving this signal. + */ + public void dispose(GLAutoDrawable drawable); + /** Called by the drawable to initiate OpenGL rendering by the client. After all GLEventListeners have been notified of a display event, the drawable will swap its buffers if {@link diff --git a/src/classes/javax/media/opengl/awt/GLCanvas.java b/src/classes/javax/media/opengl/awt/GLCanvas.java index 42700b9e8..040e78733 100644 --- a/src/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/classes/javax/media/opengl/awt/GLCanvas.java @@ -50,6 +50,10 @@ import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; +import java.awt.Container; +import java.awt.Window; +import java.awt.event.WindowEvent; +import java.awt.event.WindowAdapter; import java.awt.geom.*; import java.beans.*; import java.lang.reflect.*; @@ -156,7 +160,34 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { context.setSynchronized(true); } } - + + protected interface DestroyMethod { + public void destroyMethod(); + } + + protected final static Object addClosingListener(Component c, final DestroyMethod d) { + WindowAdapter cl = null; + Window w = getWindow(c); + if(null!=w) { + cl = new WindowAdapter() { + public void windowClosing(WindowEvent e) { + // we have to issue this call rigth away, + // otherwise the window gets destroyed + d.destroyMethod(); + } + }; + w.addWindowListener(cl); + } + return cl; + } + + protected final static Window getWindow(Component c) { + while ( c!=null && ! ( c instanceof Window ) ) { + c = c.getParent(); + } + return (Window)c; + } + /** * Overridden to choose a GraphicsConfiguration on a parent container's * GraphicsDevice because both devices @@ -252,9 +283,27 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { public void setRealized(boolean realized) { } + private Object closingListener = null; + private Object closingListenerLock = new Object(); + public void display() { maybeDoSingleThreadedWorkaround(displayOnEventDispatchThreadAction, displayAction); + if(null==closingListener) { + synchronized(closingListenerLock) { + if(null==closingListener) { + closingListener=addClosingListener(this, new DestroyMethod() { + public void destroyMethod() { destroy(); } }); + } + } + } + } + + /** + * Just an alias for removeNotify + */ + public void destroy() { + removeNotify(); } /** Overridden to cause OpenGL rendering to be performed during @@ -302,9 +351,6 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { disableBackgroundErase(); drawable.setRealized(true); } - if (DEBUG) { - System.err.println("GLCanvas.addNotify()"); - } } /** Overridden to track when this component is removed from a @@ -315,6 +361,12 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { <B>Overrides:</B> <DL><DD><CODE>removeNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */ public void removeNotify() { + if(DEBUG) { + Exception ex1 = new Exception("removeNotify - start"); + ex1.printStackTrace(); + } + drawableHelper.invokeGL(drawable, context, disposeAction, null); + if (Beans.isDesignTime()) { super.removeNotify(); } else { @@ -337,13 +389,16 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { destroyAction.run(); } } finally { - drawable.setRealized(false); - super.removeNotify(); - if (DEBUG) { - System.err.println("GLCanvas.removeNotify()"); + if(null!=drawable) { + drawable.setRealized(false); } + drawable=null; + super.removeNotify(); } } + if(DEBUG) { + System.out.println("removeNotify - end"); + } } /** Overridden to cause {@link GLDrawableHelper#reshape} to be @@ -423,10 +478,21 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { return drawable.getFactory(); } + public String toString() { + return "AWT-GLCanvas[ "+((null!=drawable)?drawable.getClass().getName():"null-drawable")+", "+drawableHelper+"]"; + } + //---------------------------------------------------------------------- // Internals only below this point // + class DisposeAction implements Runnable { + public void run() { + drawableHelper.dispose(GLCanvas.this); + } + } + private DisposeAction disposeAction = new DisposeAction(); + private void maybeDoSingleThreadedWorkaround(Runnable eventDispatchThreadAction, Runnable invokeGLAction) { if (Threading.isSingleThreaded() && @@ -488,11 +554,18 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { class DestroyAction implements Runnable { public void run() { + if(DEBUG) { + Exception ex1 = new Exception("DestroyAction - start"); + ex1.printStackTrace(); + } GLContext current = GLContext.getCurrent(); - if (current == context) { - context.release(); + if(null!=current) { + context.destroy(); + context = null; + } + if(DEBUG) { + System.out.println("DestroyAction - end"); } - context.destroy(); } } private DestroyAction destroyAction = new DestroyAction(); diff --git a/src/classes/javax/media/opengl/awt/GLJPanel.java b/src/classes/javax/media/opengl/awt/GLJPanel.java index 6711a5ed2..2efae7e96 100644 --- a/src/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/classes/javax/media/opengl/awt/GLJPanel.java @@ -204,6 +204,13 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { } } + /** + * Just an alias for removeNotify + */ + public void destroy() { + removeNotify(); + } + /** Overridden to cause OpenGL rendering to be performed during repaint cycles. Subclasses which override this method must call super.paintComponent() in their paintComponent() method in order @@ -275,15 +282,20 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { <B>Overrides:</B> <DL><DD><CODE>removeNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */ public void removeNotify() { - if (DEBUG) { - System.err.println("GLJPanel.removeNotify()"); + if(DEBUG) { + Exception ex1 = new Exception("removeNotify - start"); + ex1.printStackTrace(); } if (backend != null) { + drawableHelper.invokeGL(backend.getDrawable(), backend.getContext(), disposeAction, null); backend.destroy(); backend = null; } isInitialized = false; super.removeNotify(); + if(DEBUG) { + System.out.println("removeNotify - end"); + } } /** Overridden to cause {@link GLDrawableHelper#reshape} to be @@ -448,7 +460,18 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { // The backend might set itself to null, indicating it punted to // a different implementation -- try again } while (backend == null); + + if(null==closingListener) { + synchronized(closingListenerLock) { + if(null==closingListener) { + closingListener=GLCanvas.addClosingListener(this, new GLCanvas.DestroyMethod() { + public void destroyMethod() { destroy(); } }); + } + } + } } + private Object closingListener = null; + private Object closingListenerLock = new Object(); private void handleReshape() { panelWidth = reshapeWidth; @@ -481,6 +504,10 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { backend.postGL(g, false); } + public void dispose(GLAutoDrawable drawable) { + drawableHelper.dispose(GLJPanel.this); + } + public void display(GLAutoDrawable drawable) { if (!backend.preGL(g)) { return; @@ -506,6 +533,17 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { } } + public String toString() { + return "AWT-GLJPanel[ "+((null!=backend)?backend.getDrawable().getClass().getName():"null-drawable")+", "+drawableHelper+"]"; + } + + class DisposeAction implements Runnable { + public void run() { + updater.dispose(GLJPanel.this); + } + } + private DisposeAction disposeAction = new DisposeAction(); + class InitAction implements Runnable { public void run() { updater.init(GLJPanel.this); @@ -579,6 +617,9 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { // Called to get the current backend's GLContext public GLContext getContext(); + // Called to get the current backend's GLDrawable + public GLDrawable getDrawable(); + // Called to fetch the "real" chosen NWCapabilities for the backend public NWCapabilities getChosenNWCapabilities(); @@ -816,6 +857,10 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { return offscreenContext; } + public GLDrawable getDrawable() { + return offscreenDrawable; + } + public NWCapabilities getChosenNWCapabilities() { if (offscreenDrawable == null) { return null; @@ -903,6 +948,10 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { return pbuffer.getContext(); } + public GLDrawable getDrawable() { + return pbuffer; + } + public NWCapabilities getChosenNWCapabilities() { if (pbuffer == null) { return null; @@ -1070,6 +1119,10 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { return joglContext; } + public GLDrawable getDrawable() { + return joglDrawable; + } + public NWCapabilities getChosenNWCapabilities() { // FIXME: should do better than this; is it possible to using only platform-independent code? return new NWCapabilities(); diff --git a/src/classes/javax/media/opengl/util/FBObject.java b/src/classes/javax/media/opengl/util/FBObject.java index 660c8c806..340655966 100755 --- a/src/classes/javax/media/opengl/util/FBObject.java +++ b/src/classes/javax/media/opengl/util/FBObject.java @@ -207,6 +207,33 @@ public class FBObject { unbind(gl); } + public void destroy(GL gl) { + unbind(gl); + + int name[] = new int[1]; + + if(0!=stencil_rb) { + name[0] = stencil_rb; + gl.glDeleteRenderbuffers(1, name, 0); + stencil_rb = 0; + } + if(0!=depth_rb) { + name[0] = depth_rb; + gl.glDeleteRenderbuffers(1, name, 0); + depth_rb=0; + } + if(0!=fbo_tex) { + name[0] = fbo_tex; + gl.glDeleteTextures(1, name, 0); + fbo_tex = 0; + } + if(0!=fb) { + name[0] = fb; + gl.glDeleteFramebuffers(1, name, 0); + fb = 0; + } + } + public void bind(GL gl) { gl.glBindTexture(GL.GL_TEXTURE_2D, fbo_tex); gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, fb); diff --git a/src/classes/javax/media/opengl/util/PMVMatrix.java b/src/classes/javax/media/opengl/util/PMVMatrix.java index 5a69b920c..649e9942a 100755 --- a/src/classes/javax/media/opengl/util/PMVMatrix.java +++ b/src/classes/javax/media/opengl/util/PMVMatrix.java @@ -43,23 +43,23 @@ public class PMVMatrix implements GLMatrixIf { matrixMvit3 = BufferUtil.newFloatBuffer(3*3); - FloatBuffer buf = BufferUtil.newFloatBuffer(6*16); + localBuf = BufferUtil.newFloatBuffer(6*16); - matrixMult=slice(buf, 0*16, 16); + matrixMult=slice(localBuf, 0*16, 16); - matrixTrans=slice(buf, 1*16, 16); + matrixTrans=slice(localBuf, 1*16, 16); projectFloat.gluMakeIdentityf(matrixTrans); - matrixRot=slice(buf, 2*16, 16); + matrixRot=slice(localBuf, 2*16, 16); projectFloat.gluMakeIdentityf(matrixRot); - matrixScale=slice(buf, 3*16, 16); + matrixScale=slice(localBuf, 3*16, 16); projectFloat.gluMakeIdentityf(matrixScale); - matrixOrtho=slice(buf, 4*16, 16); + matrixOrtho=slice(localBuf, 4*16, 16); projectFloat.gluMakeIdentityf(matrixOrtho); - matrixFrustum=slice(buf, 5*16, 16); + matrixFrustum=slice(localBuf, 5*16, 16); projectFloat.gluMakeZero(matrixFrustum); vec3f=new float[3]; @@ -77,6 +77,43 @@ public class PMVMatrix implements GLMatrixIf { setDirty(); } + public void destroy() { + if(null!=projectFloat) { + projectFloat.destroy(); projectFloat=null; + } + + if(null!=matrixIdent) { + matrixIdent.clear(); matrixIdent=null; + } + if(null!=matrixTPMvMvitPmv) { + matrixTPMvMvitPmv.clear(); matrixTPMvMvitPmv=null; + } + if(null!=matrixMvit3) { + matrixMvit3.clear(); matrixMvit3=null; + } + if(null!=localBuf) { + localBuf.clear(); localBuf=null; + } + + if(null!=matrixPStack) { + matrixPStack.clear(); matrixPStack=null; + } + vec3f=null; + if(null!=matrixMvStack) { + matrixMvStack.clear(); matrixMvStack=null; + } + if(null!=matrixPStack) { + matrixPStack.clear(); matrixPStack=null; + } + if(null!=matrixTStack) { + matrixTStack.clear(); matrixTStack=null; + } + + matrixTPMvMvitPmv=null; matrixPMvMvit=null; matrixPMvMvitPmv=null; matrixPMvMvi=null; matrixPMv=null; + matrixP=null; matrixT=null; matrixMv=null; matrixMvi=null; matrixMvit=null; matrixPmv=null; + matrixMult=null; matrixTrans=null; matrixRot=null; matrixScale=null; matrixOrtho=null; matrixFrustum=null; + } + private static FloatBuffer slice(FloatBuffer buf, int pos, int len) { buf.position(pos); buf.limit(pos + len); @@ -606,7 +643,7 @@ public class PMVMatrix implements GLMatrixIf { protected FloatBuffer matrixIdent; protected FloatBuffer matrixTPMvMvitPmv, matrixPMvMvit, matrixPMvMvitPmv, matrixPMvMvi, matrixPMv, matrixP, matrixT, matrixMv, matrixMvi, matrixMvit, matrixPmv; protected FloatBuffer matrixMvit3; - protected FloatBuffer matrixMult, matrixTrans, matrixRot, matrixScale, matrixOrtho, matrixFrustum; + protected FloatBuffer localBuf, matrixMult, matrixTrans, matrixRot, matrixScale, matrixOrtho, matrixFrustum; protected float[] vec3f; protected List/*FloatBuffer*/ matrixTStack, matrixPStack, matrixMvStack; protected int matrixMode = GL_MODELVIEW; |