diff options
45 files changed, 648 insertions, 172 deletions
diff --git a/make/gl-impl-CustomJavaCode-gl2_es2.java b/make/gl-impl-CustomJavaCode-gl2_es2.java index 855d1577d..9ddbf06fb 100644 --- a/make/gl-impl-CustomJavaCode-gl2_es2.java +++ b/make/gl-impl-CustomJavaCode-gl2_es2.java @@ -294,9 +294,8 @@ public final String toString() { StringBuffer buf = new StringBuffer(); - buf.append("GL: "); buf.append(getClass().getName()); - buf.append(" (GLSL compiler: "); + buf.append(" [GLSL compiler: "); buf.append(glShaderCompilerAvailable()); Set bfs = glGetShaderBinaryFormats(); buf.append(", binary formats "); @@ -306,20 +305,7 @@ buf.append(" "); buf.append(((Integer)(iter.next())).intValue()); } - buf.append(") (GLContext: "); - GLContext context = getContext(); - buf.append(context.getClass().getName()); - buf.append(", GLDrawable: "); - GLDrawable drawable = context.getGLDrawable(); - if(null!=drawable) { - buf.append(drawable.getClass().getName()); - buf.append(", Factory: "); - GLDrawableFactory factory = drawable.getFactory(); - buf.append(factory.getClass().getName()); - } else { - buf.append("n/a"); - } - buf.append(")"); + buf.append("]"); return buf.toString(); } diff --git a/make/gl-impl-CustomJavaCode-gles1.java b/make/gl-impl-CustomJavaCode-gles1.java index 8057262f9..909fa7009 100755 --- a/make/gl-impl-CustomJavaCode-gles1.java +++ b/make/gl-impl-CustomJavaCode-gles1.java @@ -303,24 +303,7 @@ public java.nio.ByteBuffer glMapBuffer(int target, int access) { native private long dispatch_glMapBuffer(int target, int access, long glProcAddress); public final String toString() { - StringBuffer buf = new StringBuffer(); - buf.append("GL: "); - buf.append(getClass().getName()); - buf.append(" (GLContext: "); - GLContext context = getContext(); - buf.append(context.getClass().getName()); - buf.append(", GLDrawable: "); - GLDrawable drawable = context.getGLDrawable(); - if(null!=drawable) { - buf.append(drawable.getClass().getName()); - buf.append(", Factory: "); - GLDrawableFactory factory = drawable.getFactory(); - buf.append(factory.getClass().getName()); - } else { - buf.append("n/a"); - } - buf.append(")"); - return buf.toString(); + return getClass().getName(); } public void glVertexPointer(GLArrayData array) { diff --git a/make/glu-CustomJavaCode-base.java b/make/glu-CustomJavaCode-base.java index 272377ece..aca542eb7 100755 --- a/make/glu-CustomJavaCode-base.java +++ b/make/glu-CustomJavaCode-base.java @@ -113,6 +113,13 @@ public GLU() this.project = new ProjectFloat(); } +public void destroy() { + if(null!=this.project) { + this.project.destroy(); + this.project=null; + } +} + public static final GL getCurrentGL() throws GLException { GLContext curContext = GLContext.getCurrent(); if (curContext == null) { diff --git a/make/glu-CustomJavaCode-gl2.java b/make/glu-CustomJavaCode-gl2.java index bb01871d7..aedacf3dd 100644 --- a/make/glu-CustomJavaCode-gl2.java +++ b/make/glu-CustomJavaCode-gl2.java @@ -34,6 +34,14 @@ public GLUgl2() this.project = new ProjectDouble(); } +public void destroy() { + if(null!=this.project) { + this.project.destroy(); + this.project=null; + } + super.destroy(); +} + //---------------------------------------------------------------------- // Utility routines diff --git a/make/glu-CustomJavaCode-gl2es1.java b/make/glu-CustomJavaCode-gl2es1.java index 24f161985..95e96c2e2 100755 --- a/make/glu-CustomJavaCode-gl2es1.java +++ b/make/glu-CustomJavaCode-gl2es1.java @@ -36,6 +36,10 @@ public GLUgl2es1() super(); } +public void destroy() { + super.destroy(); +} + //---------------------------------------------------------------------- // Utility routines // diff --git a/make/make.jogl.all.linux-x86.sh b/make/make.jogl.all.linux-x86.sh index cb0b44771..a9e4e8d85 100644 --- a/make/make.jogl.all.linux-x86.sh +++ b/make/make.jogl.all.linux-x86.sh @@ -4,11 +4,12 @@ # -Dc.compiler.debug=true -ant -v \ +ant \ -Drootrel.build=build-x86 \ -Dgluegen.cpptasks.detected.os=true \ -DisUnix=true \ -DisLinux=true \ -DisLinuxX86=true \ -DisX11=true \ + -DuseKD=true \ $* 2>&1 | tee make.jogl.all.linux-x86.log diff --git a/make/make.jogl.all.linux-x86_64.sh b/make/make.jogl.all.linux-x86_64.sh index 4a9d780a7..1a33f6708 100644 --- a/make/make.jogl.all.linux-x86_64.sh +++ b/make/make.jogl.all.linux-x86_64.sh @@ -4,7 +4,7 @@ # -Dc.compiler.debug=true -ant -v \ +ant \ -Drootrel.build=build-x86_64 \ -Dgluegen.cpptasks.detected.os=true \ -DisUnix=true \ diff --git a/make/make.jogl.cdcfp.linux-x86.sh b/make/make.jogl.cdcfp.linux-x86.sh index 56296b529..6d216f65a 100644 --- a/make/make.jogl.cdcfp.linux-x86.sh +++ b/make/make.jogl.cdcfp.linux-x86.sh @@ -10,6 +10,7 @@ # -Djava.generate.skip=true \ ant -v \ + -Drootrel.build=build-cdcfp-x86 \ -Djogl.cdcfp=true \ -Dgluegen.cpptasks.detected.os=true \ -DisUnix=true \ diff --git a/make/make.jogl.doc.all.x86.sh b/make/make.jogl.doc.all.x86.sh new file mode 100644 index 000000000..ab86fefd0 --- /dev/null +++ b/make/make.jogl.doc.all.x86.sh @@ -0,0 +1,8 @@ +#! /bin/sh + +. ../../setenv-build-jogl-x86.sh + +ant -v \ + -Drootrel.build=build-x86\ + -DuseKD=true \ + javadoc.spec javadoc javadoc.dev.all $* 2>&1 | tee make.jogl.doc.all.x86.log 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; + } } } |