aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/classes/com/sun/javafx/newt/GLWindow.java78
-rwxr-xr-xsrc/classes/com/sun/javafx/newt/Window.java69
-rw-r--r--src/classes/com/sun/javafx/newt/WindowEvent.java2
-rw-r--r--src/classes/com/sun/javafx/newt/WindowListener.java1
-rwxr-xr-xsrc/classes/com/sun/javafx/newt/kd/KDWindow.java3
-rwxr-xr-xsrc/classes/com/sun/javafx/newt/macosx/MacWindow.java5
-rwxr-xr-xsrc/classes/com/sun/javafx/newt/windows/WindowsWindow.java12
-rwxr-xr-xsrc/classes/com/sun/javafx/newt/x11/X11Window.java22
-rw-r--r--src/classes/com/sun/opengl/impl/GLContextImpl.java3
-rw-r--r--src/classes/com/sun/opengl/impl/GLDrawableHelper.java33
-rw-r--r--src/classes/com/sun/opengl/impl/GLDrawableImpl.java2
-rwxr-xr-xsrc/classes/com/sun/opengl/impl/ProjectFloat.java24
-rwxr-xr-xsrc/classes/com/sun/opengl/impl/gl2/ProjectDouble.java24
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/fixed/FixedFuncPipeline.java4
-rw-r--r--src/classes/com/sun/opengl/impl/jawt/JAWTWindow.java17
-rwxr-xr-xsrc/classes/com/sun/opengl/util/awt/TextRenderer.java6
-rw-r--r--src/classes/com/sun/opengl/util/glsl/ShaderCode.java14
-rw-r--r--src/classes/com/sun/opengl/util/glsl/ShaderProgram.java21
-rw-r--r--src/classes/com/sun/opengl/util/glsl/ShaderState.java21
-rwxr-xr-xsrc/classes/com/sun/opengl/util/glsl/fixed/FixedFuncHook.java4
-rwxr-xr-xsrc/classes/com/sun/opengl/util/texture/Texture.java13
-rwxr-xr-xsrc/classes/com/sun/opengl/util/texture/TextureData.java7
-rw-r--r--src/classes/com/sun/openmax/OMXInstance.java6
-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
-rwxr-xr-xsrc/native/newt/KDWindow.c18
-rw-r--r--src/native/newt/NewtMacWindow.m11
-rwxr-xr-xsrc/native/newt/WindowsWindow.c10
-rwxr-xr-xsrc/native/newt/X11Window.c47
36 files changed, 614 insertions, 136 deletions
diff --git a/src/classes/com/sun/javafx/newt/GLWindow.java b/src/classes/com/sun/javafx/newt/GLWindow.java
index 53943b087..3b35beae3 100644
--- a/src/classes/com/sun/javafx/newt/GLWindow.java
+++ b/src/classes/com/sun/javafx/newt/GLWindow.java
@@ -73,6 +73,7 @@ public class GLWindow extends Window implements GLAutoDrawable {
create()} instead. */
protected GLWindow(Window window) {
this.window = window;
+ this.window.setAutoDrawableMember(true);
window.addWindowListener(new WindowListener() {
public void windowResized(WindowEvent e) {
sendReshape = true;
@@ -80,13 +81,17 @@ public class GLWindow extends Window implements GLAutoDrawable {
public void windowMoved(WindowEvent e) {
}
+
+ public void windowDestroyNotify(WindowEvent e) {
+ sendDispose = true;
+ }
});
}
/** Creates a new GLWindow on the local display, screen 0, with a
dummy visual ID, and with the default NWCapabilities. */
public static GLWindow create() {
- return create(null, null);
+ return create(null, null, false);
}
public static GLWindow create(boolean undecorated) {
@@ -95,10 +100,10 @@ public class GLWindow extends Window implements GLAutoDrawable {
/** Creates a new GLWindow referring to the given window. */
public static GLWindow create(Window window) {
- return create(window, null);
+ return create(window, null, false);
}
public static GLWindow create(NWCapabilities caps) {
- return create(caps, false);
+ return create(null, caps, false);
}
/** Creates a new GLWindow on the local display, screen 0, with a
@@ -135,18 +140,32 @@ public class GLWindow extends Window implements GLAutoDrawable {
shouldNotCallThis();
}
- public void close() {
+ public synchronized void destroy() {
+ if(Window.DEBUG_WINDOW_EVENT) {
+ Exception e1 = new Exception("GLWindow.destroy 1: "+this);
+ e1.printStackTrace();
+ }
+
+ sendDisposeEvent();
+
if (context != null) {
- if (context == GLContext.getCurrent()) {
- context.release();
- }
context.destroy();
}
if (drawable != null) {
drawable.setRealized(false);
}
- window.close();
+ if(null!=window) {
+ window.destroy();
+ }
+
+ if(Window.DEBUG_WINDOW_EVENT) {
+ System.out.println("GLWindow.destroy fin: "+this);
+ }
+
+ drawable = null;
+ context = null;
+ window = null;
}
public boolean getPerfLogEnabled() { return perfLog; }
@@ -322,6 +341,10 @@ public class GLWindow extends Window implements GLAutoDrawable {
return window.getWindowListeners();
}
+ public String toString() {
+ return "NEWT-GLWindow[ "+drawable+", "+helper+", "+factory+"]";
+ }
+
//----------------------------------------------------------------------
// OpenGL-related methods and state
//
@@ -332,7 +355,8 @@ public class GLWindow extends Window implements GLAutoDrawable {
private GLContext context;
private GLDrawableHelper helper = new GLDrawableHelper();
// To make reshape events be sent immediately before a display event
- private boolean sendReshape;
+ private boolean sendReshape=false;
+ private boolean sendDispose=false;
private boolean perfLog = false;
public GLDrawableFactory getFactory() {
@@ -369,8 +393,21 @@ public class GLWindow extends Window implements GLAutoDrawable {
}
public void display() {
- pumpMessages();
- helper.invokeGL(drawable, context, displayAction, initAction);
+ if(window.getSurfaceHandle()!=0) {
+ pumpMessages();
+ if (sendDispose) {
+ destroy();
+ sendDispose=false;
+ } else {
+ helper.invokeGL(drawable, context, displayAction, initAction);
+ }
+ }
+ }
+
+ private void sendDisposeEvent() {
+ if(disposeAction!=null && drawable!=null && context != null && window!=null && window.getSurfaceHandle()!=0) {
+ helper.invokeGL(drawable, context, disposeAction, null);
+ }
}
public void setAutoSwapBufferMode(boolean onOrOff) {
@@ -382,11 +419,13 @@ public class GLWindow extends Window implements GLAutoDrawable {
}
public void swapBuffers() {
- if (context != null && context != GLContext.getCurrent()) {
- // Assume we should try to make the context current before swapping the buffers
- helper.invokeGL(drawable, context, swapBuffersAction, initAction);
- } else {
- drawable.swapBuffers();
+ if(window.getSurfaceHandle()!=0) {
+ if (context != null && context != GLContext.getCurrent()) {
+ // Assume we should try to make the context current before swapping the buffers
+ helper.invokeGL(drawable, context, swapBuffersAction, initAction);
+ } else {
+ drawable.swapBuffers();
+ }
}
}
@@ -403,6 +442,13 @@ public class GLWindow extends Window implements GLAutoDrawable {
}
private InitAction initAction = new InitAction();
+ class DisposeAction implements Runnable {
+ public void run() {
+ helper.dispose(GLWindow.this);
+ }
+ }
+ private DisposeAction disposeAction = new DisposeAction();
+
class DisplayAction implements Runnable {
public void run() {
if (sendReshape) {
diff --git a/src/classes/com/sun/javafx/newt/Window.java b/src/classes/com/sun/javafx/newt/Window.java
index a1e983c3c..8ba7610b3 100755
--- a/src/classes/com/sun/javafx/newt/Window.java
+++ b/src/classes/com/sun/javafx/newt/Window.java
@@ -162,7 +162,9 @@ public abstract class Window implements NativeWindow
protected abstract void dispatchMessages(int eventMask);
public String toString() {
- return "NEWT-Window[windowHandle "+getWindowHandle()+
+ StringBuffer sb = new StringBuffer();
+
+ sb.append("NEWT-Window[windowHandle "+getWindowHandle()+
", surfaceHandle "+getSurfaceHandle()+
", pos "+getX()+"/"+getY()+", size "+getWidth()+"x"+getHeight()+
", visible "+isVisible()+
@@ -170,7 +172,22 @@ public abstract class Window implements NativeWindow
", visualID "+visualID+
", "+chosenCaps+
", screen handle/index "+getScreenHandle()+"/"+getScreenIndex() +
- ", display handle "+getDisplayHandle()+ "]";
+ ", display handle "+getDisplayHandle());
+
+ sb.append(", WindowListeners num "+windowListeners.size()+" [");
+ for (Iterator iter = windowListeners.iterator(); iter.hasNext(); ) {
+ sb.append(iter.next()+", ");
+ }
+ sb.append("], MouseListeners num "+mouseListeners.size()+" [");
+ for (Iterator iter = mouseListeners.iterator(); iter.hasNext(); ) {
+ sb.append(iter.next()+", ");
+ }
+ sb.append("], KeyListeners num "+keyListeners.size()+" [");
+ for (Iterator iter = keyListeners.iterator(); iter.hasNext(); ) {
+ sb.append(iter.next()+", ");
+ }
+ sb.append("]");
+ return sb.toString();
}
protected Screen screen;
@@ -233,9 +250,18 @@ public abstract class Window implements NativeWindow
return locked;
}
- public void close() {
+ public synchronized void destroy() {
+ if(DEBUG_WINDOW_EVENT) {
+ System.out.println("Window.destroy() start");
+ }
+ windowListeners = new ArrayList();
+ mouseListeners = new ArrayList();
+ keyListeners = new ArrayList();
closeNative();
invalidate();
+ if(DEBUG_WINDOW_EVENT) {
+ System.out.println("Window.destroy() end");
+ }
}
public void invalidate() {
@@ -334,6 +360,40 @@ public abstract class Window implements NativeWindow
return fullscreen;
}
+ private boolean autoDrawableMember = false;
+
+ /**
+ * If set to true,
+ * certain action will be performed by the owning
+ * AutoDrawable, ie the destroy() call within windowDestroyNotify()
+ */
+ protected void setAutoDrawableMember(boolean b) {
+ autoDrawableMember = b;
+ }
+
+ protected void windowDestroyNotify() {
+ if(DEBUG_WINDOW_EVENT) {
+ System.out.println("Window.windowDestroyeNotify start");
+ }
+
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY);
+
+ if(!autoDrawableMember) {
+ destroy();
+ }
+
+ if(DEBUG_WINDOW_EVENT) {
+ System.out.println("Window.windowDestroyeNotify end");
+ }
+ }
+
+ protected void windowDestroyed() {
+ if(DEBUG_WINDOW_EVENT) {
+ System.out.println("Window.windowDestroyed");
+ }
+ invalidate();
+ }
+
public abstract void setVisible(boolean visible);
public abstract void setSize(int width, int height);
public abstract void setPosition(int x, int y);
@@ -562,6 +622,9 @@ public abstract class Window implements NativeWindow
case WindowEvent.EVENT_WINDOW_MOVED:
l.windowMoved(e);
break;
+ case WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY:
+ l.windowDestroyNotify(e);
+ break;
default:
throw new NativeWindowException("Unexpected window event type " + e.getEventType());
}
diff --git a/src/classes/com/sun/javafx/newt/WindowEvent.java b/src/classes/com/sun/javafx/newt/WindowEvent.java
index 49cdb5497..a502e912c 100644
--- a/src/classes/com/sun/javafx/newt/WindowEvent.java
+++ b/src/classes/com/sun/javafx/newt/WindowEvent.java
@@ -36,6 +36,7 @@ package com.sun.javafx.newt;
public class WindowEvent extends Event {
public static final int EVENT_WINDOW_RESIZED = 100;
public static final int EVENT_WINDOW_MOVED = 101;
+ public static final int EVENT_WINDOW_DESTROY_NOTIFY = 102;
public WindowEvent(int eventType, Window source, long when) {
this(false, eventType, source, when);
@@ -49,6 +50,7 @@ public class WindowEvent extends Event {
switch(type) {
case EVENT_WINDOW_RESIZED: return "WINDOW_RESIZED";
case EVENT_WINDOW_MOVED: return "WINDOW_MOVED";
+ case EVENT_WINDOW_DESTROY_NOTIFY: return "EVENT_WINDOW_DESTROY_NOTIFY";
default: return "unknown (" + type + ")";
}
}
diff --git a/src/classes/com/sun/javafx/newt/WindowListener.java b/src/classes/com/sun/javafx/newt/WindowListener.java
index b76202f01..e8423cbcc 100644
--- a/src/classes/com/sun/javafx/newt/WindowListener.java
+++ b/src/classes/com/sun/javafx/newt/WindowListener.java
@@ -36,4 +36,5 @@ package com.sun.javafx.newt;
public interface WindowListener extends EventListener {
public void windowResized(WindowEvent e);
public void windowMoved(WindowEvent e);
+ public void windowDestroyNotify(WindowEvent e);
}
diff --git a/src/classes/com/sun/javafx/newt/kd/KDWindow.java b/src/classes/com/sun/javafx/newt/kd/KDWindow.java
index 01570e1bb..276fc3ebd 100755
--- a/src/classes/com/sun/javafx/newt/kd/KDWindow.java
+++ b/src/classes/com/sun/javafx/newt/kd/KDWindow.java
@@ -156,9 +156,6 @@ public class KDWindow extends Window {
sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED);
}
- private void windowClosed() {
- }
-
private long eglWindowHandle;
private long windowHandleClose;
private int windowID;
diff --git a/src/classes/com/sun/javafx/newt/macosx/MacWindow.java b/src/classes/com/sun/javafx/newt/macosx/MacWindow.java
index f80f0b3ab..b465f505c 100755
--- a/src/classes/com/sun/javafx/newt/macosx/MacWindow.java
+++ b/src/classes/com/sun/javafx/newt/macosx/MacWindow.java
@@ -245,11 +245,6 @@ public class MacWindow extends Window {
}
}
- private void windowClosed() {
- nativeWindow = 0;
- visible = false;
- }
-
private char convertKeyChar(char keyChar) {
if (keyChar == '\r') {
// Turn these into \n
diff --git a/src/classes/com/sun/javafx/newt/windows/WindowsWindow.java b/src/classes/com/sun/javafx/newt/windows/WindowsWindow.java
index 8b9d635e8..a0cf1e7bc 100755
--- a/src/classes/com/sun/javafx/newt/windows/WindowsWindow.java
+++ b/src/classes/com/sun/javafx/newt/windows/WindowsWindow.java
@@ -83,9 +83,15 @@ public class WindowsWindow extends Window {
}
if(windowHandleClose != 0) {
DestroyWindow(windowHandleClose);
+ windowHandleClose = 0;
}
}
+ protected void windowDestroyed() {
+ windowHandleClose = 0;
+ super.windowDestroyed();
+ }
+
public void setVisible(boolean visible) {
if(this.visible!=visible) {
this.visible=visible;
@@ -166,10 +172,4 @@ public class WindowsWindow extends Window {
y = newY;
sendWindowEvent(WindowEvent.EVENT_WINDOW_MOVED);
}
-
- private void windowClosed() {
- }
-
- private void windowDestroyed() {
- }
}
diff --git a/src/classes/com/sun/javafx/newt/x11/X11Window.java b/src/classes/com/sun/javafx/newt/x11/X11Window.java
index 312cc161d..cd69b75ef 100755
--- a/src/classes/com/sun/javafx/newt/x11/X11Window.java
+++ b/src/classes/com/sun/javafx/newt/x11/X11Window.java
@@ -68,9 +68,17 @@ public class X11Window extends Window {
protected void closeNative() {
if(0!=displayHandleClose && 0!=windowHandleClose) {
CloseWindow(displayHandleClose, windowHandleClose);
+ windowHandleClose = 0;
+ displayHandleClose = 0;
}
}
+ protected void windowDestroyed() {
+ windowHandleClose = 0;
+ displayHandleClose = 0;
+ super.windowDestroyed();
+ }
+
public void setVisible(boolean visible) {
if(this.visible!=visible) {
this.visible=visible;
@@ -108,7 +116,7 @@ public class X11Window extends Window {
}
protected void dispatchMessages(int eventMask) {
- DispatchMessages(getDisplayHandle(), windowHandle, eventMask);
+ DispatchMessages(getDisplayHandle(), windowHandle, eventMask, windowDeleteAtom);
}
//----------------------------------------------------------------------
@@ -120,7 +128,7 @@ public class X11Window extends Window {
long visualID, int x, int y, int width, int height);
private native void CloseWindow(long display, long windowHandle);
private native void setVisible0(long display, long windowHandle, boolean visible);
- private native void DispatchMessages(long display, long windowHandle, int eventMask);
+ private native void DispatchMessages(long display, long windowHandle, int eventMask, long windowDeleteAtom);
private native void setSize0(long display, long windowHandle, int width, int height, int decorationToggle, boolean isVisible);
private native void setPosition0(long display, long windowHandle, int x, int y);
@@ -144,17 +152,13 @@ public class X11Window extends Window {
sendWindowEvent(WindowEvent.EVENT_WINDOW_MOVED);
}
- private void windowCreated(long visualID, long windowHandle) {
+ private void windowCreated(long visualID, long windowHandle, long windowDeleteAtom) {
this.visualID = visualID;
this.windowHandle = windowHandle;
- }
-
- private void windowClosed() {
- }
-
- private void windowDestroyed() {
+ this.windowDeleteAtom=windowDeleteAtom;
}
private long windowHandleClose;
private long displayHandleClose;
+ private long windowDeleteAtom;
}
diff --git a/src/classes/com/sun/opengl/impl/GLContextImpl.java b/src/classes/com/sun/opengl/impl/GLContextImpl.java
index d00afde4d..1d51ca9d6 100644
--- a/src/classes/com/sun/opengl/impl/GLContextImpl.java
+++ b/src/classes/com/sun/opengl/impl/GLContextImpl.java
@@ -165,7 +165,8 @@ public abstract class GLContextImpl extends GLContext {
public void destroy() {
if (lock.isHeld()) {
- throw new GLException("Can not destroy context while it is current");
+ // release current context
+ release();
}
/* FIXME: refactor dependence on Java 2D / JOGL bridge
diff --git a/src/classes/com/sun/opengl/impl/GLDrawableHelper.java b/src/classes/com/sun/opengl/impl/GLDrawableHelper.java
index 8c9568381..e7fea1cee 100644
--- a/src/classes/com/sun/opengl/impl/GLDrawableHelper.java
+++ b/src/classes/com/sun/opengl/impl/GLDrawableHelper.java
@@ -55,6 +55,16 @@ public class GLDrawableHelper {
public GLDrawableHelper() {
}
+ public synchronized String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("GLEventListeners num "+listeners.size()+" [");
+ for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
+ sb.append(iter.next()+", ");
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+
public synchronized void addGLEventListener(GLEventListener listener) {
List newListeners = (List) ((ArrayList) listeners).clone();
newListeners.add(listener);
@@ -67,6 +77,15 @@ public class GLDrawableHelper {
listeners = newListeners;
}
+ public synchronized void dispose(GLAutoDrawable drawable) {
+ List newListeners = (List) ((ArrayList) listeners).clone();
+ for (Iterator iter = newListeners.iterator(); iter.hasNext(); ) {
+ ((GLEventListener) iter.next()).dispose(drawable);
+ iter.remove();
+ }
+ listeners = newListeners;
+ }
+
public void init(GLAutoDrawable drawable) {
for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
((GLEventListener) iter.next()).init(drawable);
@@ -117,12 +136,14 @@ public class GLDrawableHelper {
try {
res = context.makeCurrent();
if (res != GLContext.CONTEXT_NOT_CURRENT) {
- perThreadInitAction.set(initAction);
- if (res == GLContext.CONTEXT_CURRENT_NEW) {
- if (DEBUG) {
- System.err.println("GLDrawableHelper " + this + ".invokeGL(): Running initAction");
- }
- initAction.run();
+ if(null!=initAction) {
+ perThreadInitAction.set(initAction);
+ if (res == GLContext.CONTEXT_CURRENT_NEW) {
+ if (DEBUG) {
+ System.err.println("GLDrawableHelper " + this + ".invokeGL(): Running initAction");
+ }
+ initAction.run();
+ }
}
if (DEBUG && VERBOSE) {
System.err.println("GLDrawableHelper " + this + ".invokeGL(): Running runnable");
diff --git a/src/classes/com/sun/opengl/impl/GLDrawableImpl.java b/src/classes/com/sun/opengl/impl/GLDrawableImpl.java
index 46c79cf2b..f01f8eeda 100644
--- a/src/classes/com/sun/opengl/impl/GLDrawableImpl.java
+++ b/src/classes/com/sun/opengl/impl/GLDrawableImpl.java
@@ -134,7 +134,7 @@ public abstract class GLDrawableImpl implements GLDrawable {
}
public String toString() {
- return "GLDrawable[realized "+getRealized()+
+ return getClass().getName()+"[realized "+getRealized()+
", window "+getNativeWindow()+
", factory "+getFactory()+"]";
}
diff --git a/src/classes/com/sun/opengl/impl/ProjectFloat.java b/src/classes/com/sun/opengl/impl/ProjectFloat.java
index 61c1bd8a1..fbeccc61f 100755
--- a/src/classes/com/sun/opengl/impl/ProjectFloat.java
+++ b/src/classes/com/sun/opengl/impl/ProjectFloat.java
@@ -164,6 +164,7 @@ public class ProjectFloat {
private final float[] up = new float[3];
// Buffer-based implementation
+ private FloatBuffer locbuf;
private final FloatBuffer matrixBuf;
private final FloatBuffer tempInvertMatrixBuf;
@@ -180,24 +181,31 @@ public class ProjectFloat {
// Slice up one big buffer because some NIO implementations
// allocate a huge amount of memory to back even the smallest of
// buffers.
- FloatBuffer buf = BufferUtil.newFloatBuffer(2*16+2*4+3*3);
+ locbuf = BufferUtil.newFloatBuffer(2*16+2*4+3*3);
int pos = 0;
int sz = 16;
- matrixBuf = slice(buf, pos, sz);
+ matrixBuf = slice(locbuf, pos, sz);
pos += sz;
- tempInvertMatrixBuf = slice(buf, pos, sz);
+ tempInvertMatrixBuf = slice(locbuf, pos, sz);
pos += sz;
sz = 4;
- inBuf = slice(buf, pos, sz);
+ inBuf = slice(locbuf, pos, sz);
pos += sz;
- outBuf = slice(buf, pos, sz);
+ outBuf = slice(locbuf, pos, sz);
pos += sz;
sz = 3;
- forwardBuf = slice(buf, pos, sz);
+ forwardBuf = slice(locbuf, pos, sz);
pos += sz;
- sideBuf = slice(buf, pos, sz);
+ sideBuf = slice(locbuf, pos, sz);
pos += sz;
- upBuf = slice(buf, pos, sz);
+ upBuf = slice(locbuf, pos, sz);
+ }
+
+ public void destroy() {
+ if(locbuf!=null) {
+ locbuf.clear();
+ locbuf=null;
+ }
}
private static FloatBuffer slice(FloatBuffer buf, int pos, int len) {
diff --git a/src/classes/com/sun/opengl/impl/gl2/ProjectDouble.java b/src/classes/com/sun/opengl/impl/gl2/ProjectDouble.java
index 760aba15d..4efbcfb1e 100755
--- a/src/classes/com/sun/opengl/impl/gl2/ProjectDouble.java
+++ b/src/classes/com/sun/opengl/impl/gl2/ProjectDouble.java
@@ -157,6 +157,7 @@ public class ProjectDouble {
private final double[] up = new double[3];
// Buffer-based implementation
+ private DoubleBuffer locbuf;
private final DoubleBuffer matrixBuf;
private final DoubleBuffer tempMatrixBuf;
@@ -173,24 +174,31 @@ public class ProjectDouble {
// Slice up one big buffer because some NIO implementations
// allocate a huge amount of memory to back even the smallest of
// buffers.
- DoubleBuffer buf = BufferUtil.newDoubleBuffer(128);
+ DoubleBuffer locbuf = BufferUtil.newDoubleBuffer(128);
int pos = 0;
int sz = 16;
- matrixBuf = slice(buf, pos, sz);
+ matrixBuf = slice(locbuf, pos, sz);
pos += sz;
- tempMatrixBuf = slice(buf, pos, sz);
+ tempMatrixBuf = slice(locbuf, pos, sz);
pos += sz;
sz = 4;
- inBuf = slice(buf, pos, sz);
+ inBuf = slice(locbuf, pos, sz);
pos += sz;
- outBuf = slice(buf, pos, sz);
+ outBuf = slice(locbuf, pos, sz);
pos += sz;
sz = 3;
- forwardBuf = slice(buf, pos, sz);
+ forwardBuf = slice(locbuf, pos, sz);
pos += sz;
- sideBuf = slice(buf, pos, sz);
+ sideBuf = slice(locbuf, pos, sz);
pos += sz;
- upBuf = slice(buf, pos, sz);
+ upBuf = slice(locbuf, pos, sz);
+ }
+
+ public void destroy() {
+ if(locbuf!=null) {
+ locbuf.clear();
+ locbuf=null;
+ }
}
private static DoubleBuffer slice(DoubleBuffer buf, int pos, int len) {
diff --git a/src/classes/com/sun/opengl/impl/glsl/fixed/FixedFuncPipeline.java b/src/classes/com/sun/opengl/impl/glsl/fixed/FixedFuncPipeline.java
index c5b85924d..1d33254c0 100644
--- a/src/classes/com/sun/opengl/impl/glsl/fixed/FixedFuncPipeline.java
+++ b/src/classes/com/sun/opengl/impl/glsl/fixed/FixedFuncPipeline.java
@@ -53,12 +53,12 @@ public class FixedFuncPipeline {
return name;
}
- public void release(GL2ES2 gl) {
- shaderState.release(gl);
+ public void destroy(GL2ES2 gl) {
shaderProgramColor.release(gl, true);
shaderProgramColorLight.release(gl, true);
shaderProgramColorTexture.release(gl, true);
shaderProgramColorTextureLight.release(gl, true);
+ shaderState.destroy(gl);
}
public void glEnableClientState(GL2ES2 gl, int glArrayIndex) {
diff --git a/src/classes/com/sun/opengl/impl/jawt/JAWTWindow.java b/src/classes/com/sun/opengl/impl/jawt/JAWTWindow.java
index ebbb7f666..b38df14ec 100644
--- a/src/classes/com/sun/opengl/impl/jawt/JAWTWindow.java
+++ b/src/classes/com/sun/opengl/impl/jawt/JAWTWindow.java
@@ -128,10 +128,6 @@ public abstract class JAWTWindow implements NativeWindow {
return component;
}
- public final boolean isTerminalObject() {
- return true;
- }
-
public void setSize(int width, int height) {
component.setSize(width, height);
}
@@ -145,10 +141,17 @@ public abstract class JAWTWindow implements NativeWindow {
}
public String toString() {
- return "JAWT-Window[windowHandle "+getWindowHandle()+
+ StringBuffer sb = new StringBuffer();
+
+ sb.append("JAWT-Window[windowHandle "+getWindowHandle()+
", surfaceHandle "+getSurfaceHandle()+
- ", size "+getWidth()+"x"+getHeight()+
+ ", pos "+component.getX()+"/"+component.getY()+", size "+getWidth()+"x"+getHeight()+
+ ", visible "+component.isVisible()+
", wrappedWindow "+getWrappedWindow()+
- ", terminalObject "+isTerminalObject()+"]";
+ ", visualID "+visualID+
+ ", screen handle/index "+getScreenHandle()+"/"+getScreenIndex() +
+ ", display handle "+getDisplayHandle()+"]");
+
+ return sb.toString();
}
}
diff --git a/src/classes/com/sun/opengl/util/awt/TextRenderer.java b/src/classes/com/sun/opengl/util/awt/TextRenderer.java
index 4e80dfaa4..b7616d879 100755
--- a/src/classes/com/sun/opengl/util/awt/TextRenderer.java
+++ b/src/classes/com/sun/opengl/util/awt/TextRenderer.java
@@ -1882,6 +1882,12 @@ public class TextRenderer {
}
}
+ public void dispose(GLAutoDrawable drawable) {
+ glu.destroy();
+ glu=null;
+ frame=null;
+ }
+
// Unused methods
public void init(GLAutoDrawable drawable) {
}
diff --git a/src/classes/com/sun/opengl/util/glsl/ShaderCode.java b/src/classes/com/sun/opengl/util/glsl/ShaderCode.java
index 288ef760b..f5ed88ff0 100644
--- a/src/classes/com/sun/opengl/util/glsl/ShaderCode.java
+++ b/src/classes/com/sun/opengl/util/glsl/ShaderCode.java
@@ -244,11 +244,21 @@ public class ShaderCode {
return valid;
}
- public void release(GL2ES2 gl) {
+ public void destroy(GL2ES2 gl) {
if(isValid()) {
- gl.glDeleteShader(shader());
+ if(null!=gl) {
+ gl.glDeleteShader(shader());
+ }
valid=false;
}
+ if(null!=shaderBinary) {
+ shaderBinary.clear();
+ shaderBinary=null;
+ }
+ shaderSource=null;
+ shaderBinaryFormat=-1;
+ shaderType=-1;
+ id=null;
}
public boolean equals(Object obj) {
diff --git a/src/classes/com/sun/opengl/util/glsl/ShaderProgram.java b/src/classes/com/sun/opengl/util/glsl/ShaderProgram.java
index 066244fa6..7973c471f 100644
--- a/src/classes/com/sun/opengl/util/glsl/ShaderProgram.java
+++ b/src/classes/com/sun/opengl/util/glsl/ShaderProgram.java
@@ -37,14 +37,29 @@ public class ShaderProgram {
public Integer key() { return id; }
/**
- * @see #glReleaseAllVertexAttributes
+ * Detaches all shader codes and deletes the program.
+ * Destroys the shader codes as well.
+ * Calls release(gl, true)
+ *
+ * @see #release(GL2ES2, boolean)
+ */
+ public synchronized void destroy(GL2ES2 gl) {
+ release(gl, true);
+ }
+
+ /**
+ * Detaches all shader codes and deletes the program.
+ * Calls release(gl, false)
+ *
+ * @see #release(GL2ES2, boolean)
*/
public synchronized void release(GL2ES2 gl) {
release(gl, false);
}
/**
- * @see #glReleaseAllVertexAttributes
+ * Detaches all shader codes and deletes the program.
+ * If releaseShaderToo is true, destroys the shader codes as well.
*/
public synchronized void release(GL2ES2 gl, boolean releaseShaderToo) {
glUseProgram(gl, false);
@@ -52,7 +67,7 @@ public class ShaderProgram {
ShaderCode shaderCode = (ShaderCode) iter.next();
gl.glDetachShader(shaderProgram, shaderCode.shader());
if(releaseShaderToo) {
- shaderCode.release(gl);
+ shaderCode.destroy(gl);
}
}
shaderMap.clear();
diff --git a/src/classes/com/sun/opengl/util/glsl/ShaderState.java b/src/classes/com/sun/opengl/util/glsl/ShaderState.java
index 6320f9c6a..52ae35d2d 100644
--- a/src/classes/com/sun/opengl/util/glsl/ShaderState.java
+++ b/src/classes/com/sun/opengl/util/glsl/ShaderState.java
@@ -105,13 +105,32 @@ public class ShaderState {
public ShaderProgram shaderProgram() { return shaderProgram; }
/**
+ * Calls release(gl, true, true)
+ *
+ * @see #glReleaseAllVertexAttributes
+ * @see #glReleaseAllUniforms
+ * @see #release(GL2ES2, boolean, boolean)
+ */
+ public synchronized void destroy(GL2ES2 gl) {
+ release(gl, true, true);
+ }
+
+ /**
+ * Calls release(gl, false, false)
+ *
* @see #glReleaseAllVertexAttributes
* @see #glReleaseAllUniforms
+ * @see #release(GL2ES2, boolean, boolean)
*/
- public synchronized void release(GL2ES2 gl) {
+ public synchronized void releaseAllData(GL2ES2 gl) {
release(gl, false, false);
}
+ /**
+ * @see #glReleaseAllVertexAttributes
+ * @see #glReleaseAllUniforms
+ * @see ShaderProgram#release(GL2ES2, boolean)
+ */
public synchronized void release(GL2ES2 gl, boolean releaseProgramToo, boolean releaseShaderToo) {
boolean prgInUse = false;
if(null!=shaderProgram) {
diff --git a/src/classes/com/sun/opengl/util/glsl/fixed/FixedFuncHook.java b/src/classes/com/sun/opengl/util/glsl/fixed/FixedFuncHook.java
index d4b3be046..8c4b539d5 100755
--- a/src/classes/com/sun/opengl/util/glsl/fixed/FixedFuncHook.java
+++ b/src/classes/com/sun/opengl/util/glsl/fixed/FixedFuncHook.java
@@ -46,8 +46,8 @@ public class FixedFuncHook implements GLFixedFuncHookIf {
vertexColorFile, vertexColorLightFile, fragmentColorFile, fragmentColorTextureFile);
}
- public void dispose() {
- fixedFunction.release(gl);
+ public void destroy() {
+ fixedFunction.destroy(gl);
fixedFunction = null;
}
diff --git a/src/classes/com/sun/opengl/util/texture/Texture.java b/src/classes/com/sun/opengl/util/texture/Texture.java
index 29f22e57a..e16b840fa 100755
--- a/src/classes/com/sun/opengl/util/texture/Texture.java
+++ b/src/classes/com/sun/opengl/util/texture/Texture.java
@@ -264,17 +264,28 @@ public class Texture {
*
* @throws GLException if no OpenGL context was current or if any
* OpenGL-related errors occurred
+ * @deprecated use destroy(GL)
*/
public void dispose() throws GLException {
- dispose(GLU.getCurrentGL());
+ destroy(GLU.getCurrentGL());
}
/**
* Disposes the native resources used by this texture object.
*
* @throws GLException if any OpenGL-related errors occurred
+ * @deprecated use destroy(GL)
*/
public void dispose(GL gl) throws GLException {
+ destroy(gl);
+ }
+
+ /**
+ * Destroys the native resources used by this texture object.
+ *
+ * @throws GLException if any OpenGL-related errors occurred
+ */
+ public void destroy(GL gl) throws GLException {
gl.glDeleteTextures(1, new int[] {texID}, 0);
texID = 0;
}
diff --git a/src/classes/com/sun/opengl/util/texture/TextureData.java b/src/classes/com/sun/opengl/util/texture/TextureData.java
index dcaee52f2..8dbd124af 100755
--- a/src/classes/com/sun/opengl/util/texture/TextureData.java
+++ b/src/classes/com/sun/opengl/util/texture/TextureData.java
@@ -310,6 +310,13 @@ public class TextureData {
}
}
+ /** Calls flush()
+ * @see #flush()
+ */
+ public void destroy() {
+ flush();
+ }
+
/** Defines a callback mechanism to allow the user to explicitly
deallocate native resources (memory-mapped files, etc.)
associated with a particular TextureData. */
diff --git a/src/classes/com/sun/openmax/OMXInstance.java b/src/classes/com/sun/openmax/OMXInstance.java
index abddee5a8..0af6901b8 100644
--- a/src/classes/com/sun/openmax/OMXInstance.java
+++ b/src/classes/com/sun/openmax/OMXInstance.java
@@ -329,7 +329,7 @@ public class OMXInstance {
}
native float _getCurrentPosition(long moviePtr);
- public synchronized void dispose(GL gl) {
+ public synchronized void destroy(GL gl) {
removeAllEGLImageTexture2D(gl);
if (moviePtr != 0) {
long ptr = moviePtr;
@@ -344,7 +344,7 @@ public class OMXInstance {
}
protected synchronized void finalize() {
if (moviePtr != 0) {
- dispose(null);
+ destroy(null);
}
}
native void _destroyInstance(long moviePtr);
@@ -453,7 +453,7 @@ public class OMXInstance {
eglExt.eglDestroySync(eglImgTexs[i].sync);
}
if(null!=gl) {
- eglImgTexs[i].texture.dispose(gl);
+ eglImgTexs[i].texture.destroy(gl);
}
eglImgTexs[i]=null;
}
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;
diff --git a/src/native/newt/KDWindow.c b/src/native/newt/KDWindow.c
index 2b9d6d737..a6756bf70 100755
--- a/src/native/newt/KDWindow.c
+++ b/src/native/newt/KDWindow.c
@@ -80,7 +80,8 @@
*/
static jmethodID sizeChangedID = NULL;
-static jmethodID windowClosedID = NULL;
+static jmethodID windowDestroyNotifyID = NULL;
+static jmethodID windowDestroyedID = NULL;
static jmethodID sendMouseEventID = NULL;
static jmethodID sendKeyEventID = NULL;
@@ -94,11 +95,13 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_kd_KDWindow_initIDs
#endif
#endif
sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V");
- windowClosedID = (*env)->GetMethodID(env, clazz, "windowClosed", "()V");
+ windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
+ windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V");
sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIII)V");
sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
if (sizeChangedID == NULL ||
- windowClosedID == NULL ||
+ windowDestroyNotifyID == NULL ||
+ windowDestroyedID == NULL ||
sendMouseEventID == NULL ||
sendKeyEventID == NULL) {
DBG_PRINT( "initIDs failed\n" );
@@ -240,7 +243,9 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_kd_KDWindow_DispatchMessages
case KD_EVENT_WINDOW_CLOSE:
{
DBG_PRINT( "event window close : src: %d\n", owner);
- (*env)->CallVoidMethod(env, obj, windowClosedID);
+ (*env)->CallVoidMethod(env, obj, windowDestroyNotifyID);
+ // Called by Window.java: DestroyWindow(wnd);
+ // (*env)->CallVoidMethod(env, obj, windowDestroyedID);
}
break;
case KD_EVENT_WINDOWPROPERTY_CHANGE:
@@ -304,8 +309,8 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_kd_KDWindow_setFullScreen0
KDboolean v = fullscreen;
int res = kdSetWindowPropertybv(w, KD_WINDOWPROPERTY_FULLSCREEN_NV, &v);
-
DBG_PRINT( "[setFullScreen] v=%d, res=%d\n", fullscreen, res);
+ (void)res;
}
JNIEXPORT void JNICALL Java_com_sun_javafx_newt_kd_KDWindow_setSize0
@@ -315,8 +320,9 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_kd_KDWindow_setSize0
KDint32 v[] = { width, height };
int res = kdSetWindowPropertyiv(w, KD_WINDOWPROPERTY_SIZE, v);
-
DBG_PRINT( "[setSize] v=%dx%d, res=%d\n", width, height, res);
+ (void)res;
+
(*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height);
}
diff --git a/src/native/newt/NewtMacWindow.m b/src/native/newt/NewtMacWindow.m
index 5809c16b0..43f9b271e 100644
--- a/src/native/newt/NewtMacWindow.m
+++ b/src/native/newt/NewtMacWindow.m
@@ -40,7 +40,8 @@ static jmethodID sendMouseEventID = NULL;
static jmethodID sendKeyEventID = NULL;
static jmethodID sizeChangedID = NULL;
static jmethodID positionChangedID = NULL;
-static jmethodID windowClosedID = NULL;
+static jmethodID windowDestroyNotifyID = NULL;
+static jmethodID windowDestroyedID = NULL;
// This is set while messages are being dispatched and cleared afterward
static JNIEnv* env = NULL;
@@ -53,8 +54,9 @@ static JNIEnv* env = NULL;
sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V");
positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V");
- windowClosedID = (*env)->GetMethodID(env, clazz, "windowClosed", "()V");
- if (sendMouseEventID && sendKeyEventID && sizeChangedID && positionChangedID && windowClosedID) {
+ windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
+ windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V");
+ if (sendMouseEventID && sendKeyEventID && sizeChangedID && positionChangedID && windowDestroyedID && windowDestroyNotifyID) {
return YES;
}
return NO;
@@ -287,7 +289,8 @@ static jint mods2JavaMods(NSUInteger mods)
return;
}
- (*env)->CallVoidMethod(env, javaWindowObject, windowClosedID);
+ (*env)->CallVoidMethod(env, javaWindowObject, windowDestroyNotifyID);
+ // Will be called by Window.java (*env)->CallVoidMethod(env, javaWindowObject, windowDestroyedID);
}
@end
diff --git a/src/native/newt/WindowsWindow.c b/src/native/newt/WindowsWindow.c
index 1e173372b..ca8fb68dc 100755
--- a/src/native/newt/WindowsWindow.c
+++ b/src/native/newt/WindowsWindow.c
@@ -57,7 +57,7 @@ typedef int intptr_t;
static jmethodID sizeChangedID = NULL;
static jmethodID positionChangedID = NULL;
-static jmethodID windowClosedID = NULL;
+static jmethodID windowDestroyNotifyID = NULL;
static jmethodID windowDestroyedID = NULL;
static jmethodID sendMouseEventID = NULL;
static jmethodID sendKeyEventID = NULL;
@@ -96,8 +96,8 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
switch (message) {
case WM_CLOSE:
- (*env)->CallVoidMethod(env, window, windowClosedID);
- DestroyWindow(wnd);
+ (*env)->CallVoidMethod(env, window, windowDestroyNotifyID);
+ // Called by Window.java: DestroyWindow(wnd);
break;
case WM_DESTROY:
@@ -203,13 +203,13 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_initID
{
sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V");
positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V");
- windowClosedID = (*env)->GetMethodID(env, clazz, "windowClosed", "()V");
+ windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V");
sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIII)V");
sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
if (sizeChangedID == NULL ||
positionChangedID == NULL ||
- windowClosedID == NULL ||
+ windowDestroyNotifyID == NULL ||
windowDestroyedID == NULL ||
sendMouseEventID == NULL ||
sendKeyEventID == NULL) {
diff --git a/src/native/newt/X11Window.c b/src/native/newt/X11Window.c
index 7789e11b1..f06ceda18 100755
--- a/src/native/newt/X11Window.c
+++ b/src/native/newt/X11Window.c
@@ -113,6 +113,10 @@ static jint X11KeySym2NewtVKey(KeySym keySym) {
case XK_Control_L:
case XK_Control_R:
return VK_CONTROL;
+ case XK_Escape:
+ return VK_ESCAPE;
+ case XK_Delete:
+ return VK_DELETE;
}
return keySym;
}
@@ -193,7 +197,7 @@ JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_x11_X11Screen_getHeight0
static jmethodID sizeChangedID = NULL;
static jmethodID positionChangedID = NULL;
-static jmethodID windowClosedID = NULL;
+static jmethodID windowDestroyNotifyID = NULL;
static jmethodID windowDestroyedID = NULL;
static jmethodID windowCreatedID = NULL;
static jmethodID sendMouseEventID = NULL;
@@ -209,14 +213,14 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_x11_X11Window_initIDs
{
sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V");
positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V");
- windowClosedID = (*env)->GetMethodID(env, clazz, "windowClosed", "()V");
+ windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V");
- windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(JJ)V");
+ windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(JJJ)V");
sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIII)V");
sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
if (sizeChangedID == NULL ||
positionChangedID == NULL ||
- windowClosedID == NULL ||
+ windowDestroyNotifyID == NULL ||
windowDestroyedID == NULL ||
windowCreatedID == NULL ||
sendMouseEventID == NULL ||
@@ -342,9 +346,11 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Window_CreateWindow
visual,
attrMask,
&xswa);
+ Atom wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
+ XSetWMProtocols(dpy, window, &wm_delete_window, 1);
XClearWindow(dpy, window);
- (*env)->CallVoidMethod(env, obj, windowCreatedID, visualID, (jlong) window);
+ (*env)->CallVoidMethod(env, obj, windowCreatedID, visualID, (jlong) window, (jlong)wm_delete_window);
return (jlong) window;
}
@@ -368,6 +374,7 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_CloseWindow
XUnmapWindow(dpy, w);
XSync(dpy, True);
XDestroyWindow(dpy, w);
+ (*env)->CallVoidMethod(env, obj, windowDestroyedID);
}
/*
@@ -403,10 +410,11 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_setVisible0
* Signature: (JJI)V
*/
JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_DispatchMessages
- (JNIEnv *env, jobject obj, jlong display, jlong window, jint eventMask)
+ (JNIEnv *env, jobject obj, jlong display, jlong window, jint eventMask, jlong wmDeleteAtom)
{
Display * dpy = (Display *) (intptr_t) display;
Window w = (Window)window;
+ Atom wm_delete_window = (Atom)wmDeleteAtom;
if(eventMask<0) {
long xevent_mask_key = 0;
@@ -420,7 +428,7 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_DispatchMessages
xevent_mask_key |= KeyPressMask|KeyReleaseMask;
}
if( 0 != ( eventMask & EVENT_WINDOW ) ) {
- xevent_mask_win |= ExposureMask;
+ xevent_mask_win |= ExposureMask | StructureNotifyMask | SubstructureNotifyMask | VisibilityNotify ;
}
XSelectInput(dpy, w, xevent_mask_win|xevent_mask_key|xevent_mask_ptr);
@@ -444,7 +452,7 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_DispatchMessages
char text[255];
XNextEvent(dpy, &evt);
-
+
switch(evt.type) {
case ButtonPress:
case ButtonRelease:
@@ -461,9 +469,12 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_DispatchMessages
break;
case FocusIn:
case FocusOut:
+ break;
case DestroyNotify:
case CreateNotify:
case VisibilityNotify:
+ case Expose:
+ case UnmapNotify:
if( ! ( eventMask & EVENT_WINDOW ) ) {
continue;
}
@@ -525,24 +536,40 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_DispatchMessages
break;
case DestroyNotify:
if(evt.xdestroywindow.window==w) {
+ DBG_PRINT( "event . DestroyNotify call 0x%X\n", evt.xdestroywindow.window);
(*env)->CallVoidMethod(env, obj, windowDestroyedID);
}
break;
case CreateNotify:
if(evt.xcreatewindow.window==w) {
+ DBG_PRINT( "event . DestroyNotify call 0x%X\n", evt.xcreatewindow.window);
(*env)->CallVoidMethod(env, obj, windowCreatedID);
}
break;
case VisibilityNotify:
if(evt.xvisibility.window==w) {
+ DBG_PRINT( "event . VisibilityNotify call 0x%X\n", evt.xvisibility.window);
}
break;
case Expose:
- if(evt.xvisibility.window==w) {
- DBG_PRINT( "event . sizeChangedID call\n");
+ if(evt.xexpose.window==w) {
+ DBG_PRINT( "event . Expose call 0x%X\n", evt.xexpose.window);
(*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) evt.xexpose.width, (jint) evt.xexpose.height);
}
break;
+ case UnmapNotify:
+ if(evt.xunmap.window==w) {
+ DBG_PRINT( "event . UnmapNotify call 0x%X\n", evt.xunmap.window);
+ }
+ break;
+ case ClientMessage:
+ if (evt.xclient.window==w && evt.xclient.send_event==True && evt.xclient.data.l[0]==wm_delete_window) {
+ DBG_PRINT( "event . ClientMessage call 0x%X type 0x%X !!!\n", evt.xclient.window, evt.xclient.message_type);
+ (*env)->CallVoidMethod(env, obj, windowDestroyNotifyID);
+ // Called by Window.java: CloseWindow();
+ }
+ break;
+
}
}
}