From 3ad03e41a0cda81119c23f350c00b064a4de70c2 Mon Sep 17 00:00:00 2001
From: Sven Gothel
+ * A GLEventListenerState instance can be created while components are {@link #moveFrom(GLAutoDrawable) moved from} a {@link GLAutoDrawable}
+ * to the new instance, which gains {@link #isOwner() ownership} of the moved components.
+ *
+ * A GLEventListenerState instance's components can be {@link #moveTo(GLAutoDrawable) moved to} a {@link GLAutoDrawable},
+ * while loosing {@link #isOwner() ownership} of the moved components.
+ *
+ */
+public class GLEventListenerState {
+ private static final boolean DEBUG = Debug.debug("GLDrawable");
+
+ private GLEventListenerState(AbstractGraphicsScreen upstreamScreen, boolean proxyOwnsUpstreamDevice, AbstractGraphicsScreen screen, GLCapabilitiesImmutable caps,
+ GLContext context, int count, GLAnimatorControl anim, boolean animStarted) {
+ this.upstreamScreen = upstreamScreen;
+ this.proxyOwnsUpstreamDevice = proxyOwnsUpstreamDevice;
+ this.screen = screen;
+ this.caps = caps;
+ this.context = context;
+ this.listeners = new GLEventListener[count];
+ this.listenersInit = new boolean[count];
+ this.anim = anim;
+ this.animStarted = animStarted;
+
+ this.owner = true;
+ }
+ /**
+ * Returns
+ * Ownership is lost if {@link #moveTo(GLAutoDrawable)} is being called successfully
+ * and all components are transferred to the new {@link GLAutoDrawable}.
+ *
+ *
+ * true
, if this instance is the current owner of the components,
+ * otherwise false
.
+ *
+ * If the {@link GLAutoDrawable} was added to a {@link GLAnimatorControl}, it is removed + * and the {@link GLAnimatorControl} added to the GLEventListenerState. + *
+ *+ * The returned GLEventListenerState instance is the {@link #isOwner() owner of the components}. + *
+ * + * @param a {@link GLAutoDrawable} source to move components from + * @return new GLEventListenerState instance {@link #isOwner() owning} moved components. + * + * @see #moveTo(GLAutoDrawable) + */ + public static GLEventListenerState moveFrom(GLAutoDrawable a) { + final int aSz = a.getGLEventListenerCount(); + + // Create new AbstractGraphicsScreen w/ cloned AbstractGraphicsDevice for future GLAutoDrawable + // allowing this AbstractGraphicsDevice to loose ownership -> not closing display/device! + final NativeSurface aSurface = a.getNativeSurface(); + final AbstractGraphicsConfiguration aCfg = aSurface.getGraphicsConfiguration(); + final AbstractGraphicsScreen aScreen1 = aCfg.getScreen(); + final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) aCfg.getChosenCapabilities(); + final AbstractGraphicsScreen aScreen2 = cloneScreen(aScreen1); + if( DEBUG ) { + System.err.println("GLEventListenerState.moveFrom.0: "+aSurface.getClass().getName()+", "+aSurface); + } + aScreen1.getDevice().clearHandleOwner(); // don't close device handle + + final AbstractGraphicsScreen aUpScreen2; + final boolean proxyOwnsUpstreamDevice; + { + AbstractGraphicsScreen _aUpScreen2=null; + if(aSurface instanceof ProxySurface) { + final ProxySurface aProxy = (ProxySurface)aSurface; + proxyOwnsUpstreamDevice = aProxy.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE ); + final NativeSurface aUpSurface = aProxy.getUpstreamSurface(); + if(DEBUG && null != aUpSurface) { + System.err.println("GLEventListenerState.moveFrom.1: "+aUpSurface.getClass().getName()+", "+aUpSurface); + } + if(null != aUpSurface) { + final AbstractGraphicsScreen aUpScreen1 = aUpSurface.getGraphicsConfiguration().getScreen(); + _aUpScreen2 = cloneScreen(aUpScreen1); + if(null != aUpScreen1) { + aUpScreen1.getDevice().clearHandleOwner(); // don't close device handle + } + if(DEBUG) { + System.err.println("GLEventListenerState.moveFrom.2: "+aSurface.getClass().getName()+", "+aSurface); + System.err.println("GLEventListenerState.moveFrom.3: "+aUpSurface.getClass().getName()+", "+aUpSurface); + } + } + } else { + proxyOwnsUpstreamDevice = false; + } + aUpScreen2=_aUpScreen2; + } + + final GLAnimatorControl aAnim = a.getAnimator(); + final boolean aAnimStarted; + if( null != aAnim ) { + aAnimStarted = aAnim.isStarted(); + aAnim.remove(a); // also handles ECT + } else { + aAnimStarted = false; + } + + final GLEventListenerState glls = new GLEventListenerState(aUpScreen2, proxyOwnsUpstreamDevice, aScreen2, caps, a.getContext(), aSz, aAnim, aAnimStarted); + + // + // remove and cache all GLEventListener and their init-state + // + for(int i=0; i+ * Note: After this operation, the GLEventListenerState reference should be released. + *
+ * + * @param a {@link GLAutoDrawable} destination to move GLEventListenerState components to + * + * @throws GLException if the {@link GLAutoDrawable}'s configuration is incompatible, i.e. different {@link GLCapabilitiesImmutable}. + * + * @see #moveFrom(GLAutoDrawable) + * @see #isOwner() + */ + public final void moveTo(GLAutoDrawable a) { + final Listtrue
if GL state preservation is supported in implementation and on current platform, false
otherwise.
+ * @see #preserveGLStateAtDestroy(boolean)
+ * @see #getPreservedGLState()
+ */
+ public boolean isGLStatePreservationSupported();
+
+ /**
+ * If set to true
, the next {@link GLAutoDrawable#destroy()} operation will
+ * {@link #pullGLEventListenerState() pull} to preserve the {@link GLEventListenerState}.
+ * + * This is a one-shot flag, i.e. after preserving the {@link GLEventListenerState}, + * the flag is cleared. + *
+ *+ * A preserved {@link GLEventListenerState} will be {@link #pushGLEventListenerState() pushed} + * if realized again. + *
+ * @returntrue
if supported and successful, false
otherwise.
+ * @see #isGLStatePreservationSupported()
+ * @see #getPreservedGLState()
+ */
+ public boolean preserveGLStateAtDestroy(boolean value);
+
+ /**
+ * Returns the preserved {@link GLEventListenerState} if preservation was performed,
+ * otherwise null
.
+ * @see #isGLStatePreservationSupported()
+ * @see #preserveGLStateAtDestroy(boolean)
+ */
+ public GLEventListenerState getPreservedGLState();
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLDrawableUtil.java b/src/jogl/classes/com/jogamp/opengl/util/GLDrawableUtil.java
index 1d68a402a..68d94d2e2 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLDrawableUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLDrawableUtil.java
@@ -33,6 +33,8 @@ import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLEventListener;
+import com.jogamp.opengl.GLEventListenerState;
+
import jogamp.opengl.Debug;
/**
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLEventListenerState.java b/src/jogl/classes/com/jogamp/opengl/util/GLEventListenerState.java
deleted file mode 100644
index 5b02e1fec..000000000
--- a/src/jogl/classes/com/jogamp/opengl/util/GLEventListenerState.java
+++ /dev/null
@@ -1,365 +0,0 @@
-/**
- * Copyright 2013 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice, this list
- * of conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of JogAmp Community.
- */
-package com.jogamp.opengl.util;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.media.nativewindow.AbstractGraphicsConfiguration;
-import javax.media.nativewindow.AbstractGraphicsDevice;
-import javax.media.nativewindow.AbstractGraphicsScreen;
-import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.NativeWindowFactory;
-import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.VisualIDHolder;
-import javax.media.opengl.GLAnimatorControl;
-import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLCapabilitiesImmutable;
-import javax.media.opengl.GLContext;
-import javax.media.opengl.GLEventListener;
-import javax.media.opengl.GLException;
-import javax.media.opengl.GLRunnable;
-
-import jogamp.opengl.Debug;
-
-import com.jogamp.nativewindow.MutableGraphicsConfiguration;
-
-/**
- * GLEventListenerState is holding {@link GLAutoDrawable} components crucial
- * to relocating all its {@link GLEventListener} w/ their operating {@link GLContext}, etc.
- * The components are:
- * - * A GLEventListenerState instance can be created while components are {@link #moveFrom(GLAutoDrawable) moved from} a {@link GLAutoDrawable} - * to the new instance, which gains {@link #isOwner() ownership} of the moved components. - *
- *- * A GLEventListenerState instance's components can be {@link #moveTo(GLAutoDrawable) moved to} a {@link GLAutoDrawable}, - * while loosing {@link #isOwner() ownership} of the moved components. - *
- *
- */
-public class GLEventListenerState {
- private static final boolean DEBUG = Debug.debug("GLDrawable");
-
- private GLEventListenerState(AbstractGraphicsScreen upstreamScreen, boolean proxyOwnsUpstreamDevice, AbstractGraphicsScreen screen, GLCapabilitiesImmutable caps,
- GLContext context, int count, GLAnimatorControl anim) {
- this.upstreamScreen = upstreamScreen;
- this.proxyOwnsUpstreamDevice = proxyOwnsUpstreamDevice;
- this.screen = screen;
- this.caps = caps;
- this.context = context;
- this.listeners = new GLEventListener[count];
- this.listenersInit = new boolean[count];
- this.anim = anim;
- this.owner = true;
- }
- /**
- * Returns true
, if this instance is the current owner of the components,
- * otherwise false
.
- *
- * Ownership is lost if {@link #moveTo(GLAutoDrawable)} is being called successfully - * and all components are transferred to the new {@link GLAutoDrawable}. - *
- */ - public final boolean isOwner() { return owner; } - - public final int listenerCount() { return listeners.length; } - - public final AbstractGraphicsScreen upstreamScreen; - public final boolean proxyOwnsUpstreamDevice; - public final AbstractGraphicsScreen screen; - public final GLCapabilitiesImmutable caps; - public final GLContext context; - public final GLEventListener[] listeners; - public final boolean[] listenersInit; - public final GLAnimatorControl anim; - - private boolean owner; - - /** - * Last resort to destroy and loose ownership - */ - public void destroy() { - if( owner ) { - final int aSz = listenerCount(); - for(int i=0; i- * If the {@link GLAutoDrawable} was added to a {@link GLAnimatorControl}, it is removed - * and the {@link GLAnimatorControl} added to the GLEventListenerState. - *
- *- * The returned GLEventListenerState instance is the {@link #isOwner() owner of the components}. - *
- * - * @param a {@link GLAutoDrawable} source to move components from - * @return new GLEventListenerState instance {@link #isOwner() owning} moved components. - * - * @see #moveTo(GLAutoDrawable) - */ - public static GLEventListenerState moveFrom(GLAutoDrawable a) { - final int aSz = a.getGLEventListenerCount(); - - // Create new AbstractGraphicsScreen w/ cloned AbstractGraphicsDevice for future GLAutoDrawable - // allowing this AbstractGraphicsDevice to loose ownership -> not closing display/device! - final NativeSurface aSurface = a.getNativeSurface(); - final AbstractGraphicsConfiguration aCfg = aSurface.getGraphicsConfiguration(); - final AbstractGraphicsScreen aScreen1 = aCfg.getScreen(); - final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) aCfg.getChosenCapabilities(); - final AbstractGraphicsScreen aScreen2 = cloneScreen(aScreen1); - if( DEBUG ) { - System.err.println("GLEventListenerState.moveFrom.0: "+aSurface.getClass().getName()+", "+aSurface); - } - aScreen1.getDevice().clearHandleOwner(); // don't close device handle - - final AbstractGraphicsScreen aUpScreen2; - final boolean proxyOwnsUpstreamDevice; - { - AbstractGraphicsScreen _aUpScreen2=null; - if(aSurface instanceof ProxySurface) { - final ProxySurface aProxy = (ProxySurface)aSurface; - proxyOwnsUpstreamDevice = aProxy.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE ); - final NativeSurface aUpSurface = aProxy.getUpstreamSurface(); - if(DEBUG && null != aUpSurface) { - System.err.println("GLEventListenerState.moveFrom.1: "+aUpSurface.getClass().getName()+", "+aUpSurface); - } - if(null != aUpSurface) { - final AbstractGraphicsScreen aUpScreen1 = aUpSurface.getGraphicsConfiguration().getScreen(); - _aUpScreen2 = cloneScreen(aUpScreen1); - if(null != aUpScreen1) { - aUpScreen1.getDevice().clearHandleOwner(); // don't close device handle - } - if(DEBUG) { - System.err.println("GLEventListenerState.moveFrom.2: "+aSurface.getClass().getName()+", "+aSurface); - System.err.println("GLEventListenerState.moveFrom.3: "+aUpSurface.getClass().getName()+", "+aUpSurface); - } - } - } else { - proxyOwnsUpstreamDevice = false; - } - aUpScreen2=_aUpScreen2; - } - - final GLAnimatorControl aAnim = a.getAnimator(); - if( null != aAnim ) { - aAnim.remove(a); // also handles ECT - } - - final GLEventListenerState glls = new GLEventListenerState(aUpScreen2, proxyOwnsUpstreamDevice, aScreen2, caps, a.getContext(), aSz, aAnim); - - // - // remove and cache all GLEventListener and their init-state - // - for(int i=0; i- * Note: After this operation, the GLEventListenerState reference should be released. - *
- * - * @param a {@link GLAutoDrawable} destination to move GLEventListenerState components to - * - * @throws GLException if the {@link GLAutoDrawable}'s configuration is incompatible, i.e. different {@link GLCapabilitiesImmutable}. - * - * @see #moveFrom(GLAutoDrawable) - * @see #isOwner() - */ - public final void moveTo(GLAutoDrawable a) { - final List