summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java56
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java20
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java30
3 files changed, 89 insertions, 17 deletions
diff --git a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
index ad67f8281..cab768e3a 100644
--- a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
+++ b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
@@ -68,6 +68,8 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
protected volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
protected GLContextImpl context;
+ protected boolean preserveGLELSAtDestroy;
+ protected GLEventListenerState glels;
protected final boolean ownsDevice;
protected int additionalCtxCreationFlags = 0;
protected volatile boolean sendReshape = false; // volatile: maybe written by WindowManager thread w/o locking
@@ -88,6 +90,8 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
public GLAutoDrawableBase(GLDrawableImpl drawable, GLContextImpl context, boolean ownsDevice) {
this.drawable = drawable;
this.context = context;
+ this.preserveGLELSAtDestroy = false;
+ this.glels = null;
this.ownsDevice = ownsDevice;
if(null != context && null != drawable) {
context.setGLDrawable(drawable, false);
@@ -97,6 +101,54 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
/** Returns the recursive lock object of the upstream implementation, which synchronizes multithreaded access. */
protected abstract RecursiveLock getLock();
+
+
+ /**
+ * If set to <code>true</code>, the next {@link #destroy()} operation will
+ * {@link #pullGLEventListenerState() pull} to preserve the {@link GLEventListenerState}.
+ */
+ public final void setPreserveGLStateAtDestroy(boolean value) {
+ preserveGLELSAtDestroy = value;
+ }
+
+ /**
+ * Pulls the {@link GLEventListenerState} from this {@link GLAutoDrawable}.
+ *
+ * @return <code>true</code> if the {@link GLEventListenerState} is pulled successfully from this {@link GLAutoDrawable},
+ * otherwise <code>false</code>.
+ *
+ * @throws IllegalStateException if the {@link GLEventListenerState} is already pulled
+ *
+ * @see #pushGLEventListenerState()
+ */
+ protected final boolean pullGLEventListenerState() throws IllegalStateException {
+ if( null != glels ) {
+ throw new IllegalStateException("GLEventListenerState already pulled");
+ }
+ if( null != context && context.isCreated() ) {
+ glels = GLEventListenerState.moveFrom(this);
+ return null != glels;
+ }
+ return false;
+ }
+
+ /**
+ * Pushes a previously {@link #pullGLEventListenerState() pulled} {@link GLEventListenerState} to this {@link GLAutoDrawable}.
+ *
+ * @return <code>true</code> if the {@link GLEventListenerState} was previously {@link #pullGLEventListenerState() pulled}
+ * and is pushed successfully to this {@link GLAutoDrawable},
+ * otherwise <code>false</code>.
+ *
+ * @see #pullGLEventListenerState()
+ */
+ protected final boolean pushGLEventListenerState() {
+ if( null != glels ) {
+ glels.moveTo(this);
+ glels = null;
+ return true;
+ }
+ return false;
+ }
/** Default implementation to handle repaint events from the windowing system */
protected final void defaultWindowRepaintOp() {
@@ -229,6 +281,10 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
* In such case call <code>super.destroyImplInLock</code> first.</p>
*/
protected void destroyImplInLock() {
+ if( preserveGLELSAtDestroy ) {
+ preserveGLELSAtDestroy = false;
+ pullGLEventListenerState();
+ }
if( null != context ) {
if( context.isCreated() ) {
// Catch dispose GLExceptions by GLEventListener, just 'print' them
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index ce50d95dd..33f136460 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -421,6 +421,11 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
protected class GLLifecycleHook implements WindowImpl.LifecycleHook {
@Override
+ public void setPreserveResourcesAtDestroy() {
+ GLWindow.this.setPreserveGLStateAtDestroy(true);
+ }
+
+ @Override
public synchronized void destroyActionPreLock() {
// nop
}
@@ -433,7 +438,7 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
//Exception e1 = new Exception(msg);
//e1.printStackTrace();
}
-
+
destroyImplInLock();
if(Window.DEBUG_IMPLEMENTATION) {
@@ -479,8 +484,11 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
}
drawable = (GLDrawableImpl) factory.createGLDrawable(nw);
drawable.setRealized(true);
- context = (GLContextImpl) drawable.createContext(sharedContext);
- context.setContextCreationFlags(additionalCtxCreationFlags);
+
+ if( !GLWindow.this.pushGLEventListenerState() ) {
+ context = (GLContextImpl) drawable.createContext(sharedContext);
+ context.setContextCreationFlags(additionalCtxCreationFlags);
+ }
}
if(Window.DEBUG_IMPLEMENTATION) {
System.err.println("GLWindow.setVisibleActionPost("+visible+", "+nativeWindowCreated+") "+WindowImpl.getThreadName()+", fin: dt "+ (System.nanoTime()-t0)/1e6 +"ms");
@@ -512,7 +520,7 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
//
private GLContext sharedContext = null;
-
+
@Override
protected final RecursiveLock getLock() {
return window.getLock();
@@ -571,10 +579,6 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
}
@Override
- public final void setRealized(boolean realized) {
- }
-
- @Override
public final void swapBuffers() throws GLException {
defaultSwapBuffers();
}
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index af0bde179..dfaa55679 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -222,6 +222,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
*/
void setVisibleActionPost(boolean visible, boolean nativeWindowCreated);
+ /**
+ * Notifies the receiver to preserve resources (GL, ..)
+ * for the next destroy*() calls (only).
+ */
+ void setPreserveResourcesAtDestroy();
+
/**
* Invoked before Window destroy action,
* allows releasing of resources depending on the native Window.<br>
@@ -953,6 +959,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
runOnEDTIfAvail(true, destroyAction);
}
+ protected void destroy(boolean preserveResources) {
+ if( preserveResources && null != WindowImpl.this.lifecycleHook ) {
+ WindowImpl.this.lifecycleHook.setPreserveResourcesAtDestroy();
+ }
+ destroy();
+ }
+
/**
* @param cWin child window, must not be null
* @param pWin parent window, may be null
@@ -1053,9 +1066,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if(null==newParentWindowNEWT) {
throw new NativeWindowException("Reparenting with non NEWT Window type only available after it's realized: "+newParentWindow);
}
- // Destroy this window and use parent's Screen.
+ // Destroy this window and use parent's Screen, while trying to preserve resources.
// It may be created properly when the parent is made visible.
- destroy();
+ destroy(true);
setScreen( (ScreenImpl) newParentWindowNEWT.getScreen() );
operation = ReparentOperation.ACTION_NATIVE_CREATION_PENDING;
} else if(newParentWindow != getParent()) {
@@ -1078,9 +1091,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
operation = ReparentOperation.ACTION_NATIVE_CREATION_PENDING;
}
} else if ( forceDestroyCreate || !NewtFactory.isScreenCompatible(newParentWindow, screen) ) {
- // Destroy this window, may create a new compatible Screen/Display,
- // and mark it for creation.
- destroy();
+ // Destroy this window, may create a new compatible Screen/Display, while trying to preserve resources.
+ destroy(true);
if(null!=newParentWindowNEWT) {
setScreen( (ScreenImpl) newParentWindowNEWT.getScreen() );
} else {
@@ -1109,8 +1121,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// Already Top Window
operation = ReparentOperation.ACTION_NOP;
} else if( !isNativeValid() || forceDestroyCreate ) {
- // Destroy this window and mark it for [pending] creation.
- destroy();
+ // Destroy this window and mark it for [pending] creation, while trying to preserve resources.
+ destroy(true);
if( 0 < width && 0 < height ) {
operation = ReparentOperation.ACTION_NATIVE_CREATION;
} else {
@@ -1213,11 +1225,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
if(!ok) {
- // native reparent failed -> try creation
+ // native reparent failed -> try creation, while trying to preserve resources.
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window.reparent: native reparenting failed ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+" -> "+toHexString(newParentWindowHandle)+" - Trying recreation");
}
- destroy();
+ destroy(true);
operation = ReparentOperation.ACTION_NATIVE_CREATION ;
}
}