aboutsummaryrefslogtreecommitdiffstats
path: root/src/classes/javax/media
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2009-03-14 05:20:29 +0000
committerSven Gothel <[email protected]>2009-03-14 05:20:29 +0000
commit9517d52c18bfa93d78e03f4c212757eda421afb6 (patch)
tree8c1bc95802461520f3477c3c224d285debff4e2c /src/classes/javax/media
parent78ff34edd75db5cd7f3055466d992ca7be3a70a6 (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.java2
-rw-r--r--src/classes/javax/media/opengl/GLArrayDataWrapper.java11
-rw-r--r--src/classes/javax/media/opengl/GLAutoDrawable.java9
-rw-r--r--src/classes/javax/media/opengl/GLContext.java8
-rw-r--r--src/classes/javax/media/opengl/GLEventListener.java11
-rw-r--r--src/classes/javax/media/opengl/awt/GLCanvas.java95
-rw-r--r--src/classes/javax/media/opengl/awt/GLJPanel.java57
-rwxr-xr-xsrc/classes/javax/media/opengl/util/FBObject.java27
-rwxr-xr-xsrc/classes/javax/media/opengl/util/PMVMatrix.java53
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;