From d514ecbf052d013ea8c0982c490757678075a9ea Mon Sep 17 00:00:00 2001
From: Sven Gothel
Date: Fri, 22 Mar 2013 13:43:59 +0100
Subject: NEWT/Android (Bug 665): Add Support for GLStateKeeper ; onPause()
always destroys ; Recognizing all GLAutoDrawable's GLAnimatorControl for
pause/resume ; Use GLAnimatorControl instead of Animator
- Add Support for GLStateKeeper
If !isFinishing() (HOME button), preserve the GLEventListener if an GLStateKeeper instance
- onPause() always destroys
onDestroy() is too late, i.e. surfaceDestroyed() already called
- Recognizing all GLAutoDrawable's GLAnimatorControl for pause/resume
pause/resume the GLAnimatorControl of all GLAutoDrawable instances
- Use GLAnimatorControl instead of Animator
We used an Animator reference .. duh!
Note: The EGL native WindowDriver (Android and BCM.IV) must retain their own copy of EGLGraphicsDevice,
which preserves the EGLDisplay handle due to EGLDisplayUtil reference counting per nativeHandleID.
---
.../newt/driver/android/NewtBaseActivity.java | 167 ++++++++++++++++-----
.../jogamp/newt/driver/android/ScreenDriver.java | 8 +-
.../jogamp/newt/driver/android/WindowDriver.java | 25 ++-
.../jogamp/newt/driver/bcm/vc/iv/WindowDriver.java | 17 ++-
4 files changed, 165 insertions(+), 52 deletions(-)
(limited to 'src/newt/classes')
diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
index 726793768..2ea7a9d84 100644
--- a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
+++ b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
@@ -32,9 +32,12 @@ import java.util.List;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.opengl.FPSCounter;
+import javax.media.opengl.GLAnimatorControl;
+import javax.media.opengl.GLAutoDrawable;
import com.jogamp.newt.Window;
-import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.GLEventListenerState;
+import com.jogamp.opengl.GLStateKeeper;
import jogamp.newt.driver.android.WindowDriver;
@@ -46,12 +49,46 @@ import android.view.WindowManager;
public class NewtBaseActivity extends Activity {
List newtWindows = new ArrayList();
- Animator animator = null;
+ List glAutoDrawables = new ArrayList();
+
+ GLAnimatorControl animator = null;
boolean isDelegatedActivity;
Activity rootActivity;
boolean setThemeCalled = false;
+ protected void startAnimation(boolean start) {
+ if(null != animator) {
+ final boolean res;
+ if( start ) {
+ if( animator.isPaused() ) {
+ res = animator.resume();
+ } else {
+ res = animator.start();
+ }
+ } else {
+ res = animator.stop();
+ }
+ Log.d(MD.TAG, "Animator global: start "+start+", result "+res);
+ }
+ for(int i=0; i
* @param androidWindow
* @param newtWindow
+ * @throws IllegalArgumentException if the newtWindow
's {@link Window#getDelegatedWindow() delegate} is not an AndroidDriver.
+ * @see #registerNEWTWindow(Window)
* @see #addContentView(android.view.Window, Window, android.view.ViewGroup.LayoutParams)
*/
- public void setContentView(android.view.Window androidWindow, Window newtWindow) {
- newtWindow = newtWindow.getDelegatedWindow();
- if(newtWindow instanceof WindowDriver) {
- adaptTheme4Transparency(newtWindow.getRequestedCapabilities());
- layoutForNEWTWindow(androidWindow, newtWindow);
- WindowDriver newtAWindow = (WindowDriver)newtWindow;
+ public void setContentView(final android.view.Window androidWindow, final Window newtWindow) throws IllegalArgumentException {
+ final Window delegateWindow = newtWindow.getDelegatedWindow();
+ if(delegateWindow instanceof WindowDriver) {
+ adaptTheme4Transparency(delegateWindow.getRequestedCapabilities());
+ layoutForNEWTWindow(androidWindow, delegateWindow);
+ final WindowDriver newtAWindow = (WindowDriver)delegateWindow;
androidWindow.setContentView(newtAWindow.getAndroidView());
- registerNEWTWindow(newtAWindow);
} else {
- throw new IllegalArgumentException("Given NEWT Window is not an Android Window: "+newtWindow.getClass());
+ throw new IllegalArgumentException("Given NEWT Window is not an Android Window: "+newtWindow.getClass().getName());
}
+ registerNEWTWindow(newtWindow);
}
/**
* This is one of the three registration methods (see below).
@@ -102,35 +141,67 @@ public class NewtBaseActivity extends Activity {
* @param androidWindow
* @param newtWindow
* @param params
- * @see #setContentView(android.view.Window, Window)
+ * @throws IllegalArgumentException if the newtWindow
's {@link Window#getDelegatedWindow() delegate} is not an AndroidDriver.
* @see #registerNEWTWindow(Window)
+ * @see #setContentView(android.view.Window, Window)
*/
- public void addContentView(android.view.Window androidWindow, Window newtWindow, android.view.ViewGroup.LayoutParams params) {
- newtWindow = newtWindow.getDelegatedWindow();
- if(newtWindow instanceof WindowDriver) {
- WindowDriver newtAWindow = (WindowDriver)newtWindow;
+ public void addContentView(final android.view.Window androidWindow, final Window newtWindow, final android.view.ViewGroup.LayoutParams params) throws IllegalArgumentException {
+ final Window delegateWindow = newtWindow.getDelegatedWindow();
+ if(delegateWindow instanceof WindowDriver) {
+ final WindowDriver newtAWindow = (WindowDriver)delegateWindow;
androidWindow.addContentView(newtAWindow.getAndroidView(), params);
- registerNEWTWindow(newtAWindow);
} else {
- throw new IllegalArgumentException("Given NEWT Window is not an Android Window: "+newtWindow.getClass());
+ throw new IllegalArgumentException("Given NEWT Window's Delegate is not an Android Window: "+delegateWindow.getClass().getName());
}
+ registerNEWTWindow(newtWindow);
}
/**
* This is one of the three registration methods (see below).
*
- * This methods simply registers the given NEWT window to ensure it's destruction at {@link #onDestroy()}.
- *
+ * This methods registers the given NEWT window to ensure it's destruction at {@link #onDestroy()}.
+ *
+ *
+ * If adding a {@link GLAutoDrawable} implementation, the {@link GLAnimatorControl} retrieved by {@link GLAutoDrawable#getAnimator()}
+ * will be used for {@link #onPause()} and {@link #onResume()}.
+ *
+ *
+ * If adding a {@link GLAutoDrawable} implementation, the {@link GLEventListenerState} will preserve it's state
+ * when {@link #onPause()} is being called while not {@link #isFinishing()}. A later {@link #onResume()} will
+ * reinstate the {@link GLEventListenerState}.
+ *
*
* @param newtWindow
+ * @throws IllegalArgumentException if the newtWindow
's {@link Window#getDelegatedWindow() delegate} is not an AndroidDriver.
* @see #setContentView(android.view.Window, Window)
* @see #addContentView(android.view.Window, Window, android.view.ViewGroup.LayoutParams)
*/
- public void registerNEWTWindow(Window newtWindow) {
- newtWindow = newtWindow.getDelegatedWindow();
- WindowDriver newtAWindow = (WindowDriver)newtWindow;
- newtAWindow.registerActivity(getActivity());
+ public void registerNEWTWindow(final Window newtWindow) throws IllegalArgumentException {
+ final Window delegateWindow = newtWindow.getDelegatedWindow();
+ Log.d(MD.TAG, "registerNEWTWindow: Type "+newtWindow.getClass().getName()+", delegate "+delegateWindow.getClass().getName());
+ if(delegateWindow instanceof WindowDriver) {
+ final WindowDriver newtAWindow = (WindowDriver)delegateWindow;
+ newtAWindow.registerActivity(getActivity());
+ } else {
+ throw new IllegalArgumentException("Given NEWT Window's Delegate is not an Android Window: "+delegateWindow.getClass().getName());
+ }
newtWindows.add(newtWindow);
+ if(newtWindow instanceof GLAutoDrawable) {
+ glAutoDrawables.add((GLAutoDrawable)newtWindow);
+ }
+ if(newtWindow instanceof GLStateKeeper) {
+ ((GLStateKeeper)newtWindow).setGLStateKeeperListener(glStateKeeperListener);
+ }
}
+ private final GLStateKeeper.Listener glStateKeeperListener = new GLStateKeeper.Listener() {
+ @Override
+ public void glStatePreserveNotify(GLStateKeeper glsk) {
+ Log.d(MD.TAG, "GLStateKeeper Preserving: 0x"+Integer.toHexString(glsk.hashCode()));
+ }
+ @Override
+ public void glStateRestored(GLStateKeeper glsk) {
+ Log.d(MD.TAG, "GLStateKeeper Restored: 0x"+Integer.toHexString(glsk.hashCode()));
+ }
+ };
/**
* Convenient method to set the Android window's flags to fullscreen or size-layout depending on the given NEWT window.
@@ -224,7 +295,19 @@ public class NewtBaseActivity extends Activity {
}
}
- public void setAnimator(Animator animator) {
+ /**
+ * Setting up a global {@Link GLAnimatorControl} for {@link #onPause()} and {@link #onResume()}.
+ *
+ * Note that if adding a {@link GLAutoDrawable} implementation via {@link #registerNEWTWindow(Window)},
+ * {@link #setContentView(android.view.Window, Window)} or {@link #addContentView(android.view.Window, Window, android.view.ViewGroup.LayoutParams)}
+ * their {@link GLAnimatorControl} retrieved by {@link GLAutoDrawable#getAnimator()} will be used as well.
+ * In this case, using this global {@Link GLAnimatorControl} is redundant.
+ *
+ * @see #registerNEWTWindow(Window)
+ * @see #setContentView(android.view.Window, Window)
+ * @see #addContentView(android.view.Window, Window, android.view.ViewGroup.LayoutParams)
+ */
+ public void setAnimator(GLAnimatorControl animator) {
this.animator = animator;
if(!animator.isStarted()) {
animator.start();
@@ -279,23 +362,33 @@ public class NewtBaseActivity extends Activity {
((FPSCounter)win).resetFPSCounter();
}
}
- if(null != animator) {
- animator.resume();
- animator.resetFPSCounter();
- }
+ startAnimation(true);
}
@Override
public void onPause() {
Log.d(MD.TAG, "onPause");
- if(null != animator) {
- animator.pause();
+ if( !getActivity().isFinishing() ) {
+ int ok=0, fail=0;
+ for(int i=0; i0) {
- final Window win = newtWindows.remove(newtWindows.size()-1);
- win.destroy();
- }
+ newtWindows.clear();
+ glAutoDrawables.clear();
jogamp.common.os.android.StaticContext.clear();
if(!isDelegatedActivity()) {
super.onDestroy();
diff --git a/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java
index 795aac5fb..aee372f01 100644
--- a/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java
@@ -28,19 +28,19 @@
package jogamp.newt.driver.android;
-import javax.media.nativewindow.*;
+import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.util.Dimension;
import javax.media.nativewindow.util.Point;
-import com.jogamp.newt.ScreenMode;
-import com.jogamp.newt.util.ScreenModeUtil;
-
import android.content.Context;
import android.graphics.PixelFormat;
import android.util.DisplayMetrics;
import android.view.Surface;
import android.view.WindowManager;
+import com.jogamp.newt.ScreenMode;
+import com.jogamp.newt.util.ScreenModeUtil;
+
public class ScreenDriver extends jogamp.newt.ScreenImpl {
static {
diff --git a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
index 8f9ee1c0f..6f78a6f6b 100644
--- a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
@@ -33,8 +33,10 @@ import jogamp.newt.WindowImpl;
import jogamp.newt.driver.android.event.AndroidNewtEventFactory;
import jogamp.newt.driver.android.event.AndroidNewtEventTranslator;
+import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.Capabilities;
import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.VisualIDHolder;
import javax.media.nativewindow.util.Insets;
@@ -49,6 +51,7 @@ import com.jogamp.newt.Screen;
import com.jogamp.newt.ScreenMode;
import jogamp.opengl.egl.EGL;
+import jogamp.opengl.egl.EGLDisplayUtil;
import jogamp.opengl.egl.EGLGraphicsConfiguration;
import jogamp.opengl.egl.EGLGraphicsConfigurationFactory;
@@ -322,7 +325,14 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
@Override
protected final void createNativeImpl() {
- Log.d(MD.TAG, "createNativeImpl 0 - surfaceHandle 0x"+Long.toHexString(surfaceHandle)+
+ // Create own screen/device resource instance allowing independent ownership,
+ // while still utilizing shared EGL resources.
+ final AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
+ final EGLGraphicsDevice aDevice = (EGLGraphicsDevice) aScreen.getDevice();
+ final EGLGraphicsDevice eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(aDevice.getNativeDisplayID(), aDevice.getConnection(), aDevice.getUnitID());
+ final DefaultGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aScreen.getIndex());
+
+ Log.d(MD.TAG, "createNativeImpl 0 - eglDevice 0x"+Integer.toHexString(eglDevice.hashCode())+", "+eglDevice+", surfaceHandle 0x"+Long.toHexString(surfaceHandle)+
", format [a "+androidFormat+", n "+nativeFormat+"], "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()+" - on thread "+Thread.currentThread().getName());
if(0!=getParentWindowHandle()) {
@@ -332,11 +342,9 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
throw new InternalError("surfaceHandle null");
}
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) getScreen().getDisplay().getGraphicsDevice();
final EGLGraphicsConfiguration eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
capsByFormat, (GLCapabilitiesImmutable) getRequestedCapabilities(),
- (GLCapabilitiesChooser)capabilitiesChooser, getScreen().getGraphicsScreen(), nativeFormat,
- isAndroidFormatTransparent(androidFormat));
+ (GLCapabilitiesChooser)capabilitiesChooser, eglScreen, nativeFormat, isAndroidFormatTransparent(androidFormat));
if (eglConfig == null) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
@@ -361,12 +369,14 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
setupInputListener(true);
- Log.d(MD.TAG, "createNativeImpl X: eglSurfaceHandle 0x"+Long.toHexString(eglSurface));
+ Log.d(MD.TAG, "createNativeImpl X: eglDevice 0x"+Integer.toHexString(eglDevice.hashCode())+", "+eglDevice+", eglSurfaceHandle 0x"+Long.toHexString(eglSurface));
}
@Override
protected final void closeNativeImpl() {
- Log.d(MD.TAG, "closeNativeImpl 0 - surfaceHandle 0x"+Long.toHexString(surfaceHandle)+
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) getGraphicsConfiguration().getScreen().getDevice();
+
+ Log.d(MD.TAG, "closeNativeImpl 0 - eglDevice 0x"+Integer.toHexString(eglDevice.hashCode())+", "+eglDevice+", surfaceHandle 0x"+Long.toHexString(surfaceHandle)+
", eglSurfaceHandle 0x"+Long.toHexString(eglSurface)+
", format [a "+androidFormat+", n "+nativeFormat+"], "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()+" - on thread "+Thread.currentThread().getName());
if(WindowImpl.DEBUG_IMPLEMENTATION) {
@@ -377,7 +387,6 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
if(0 != eglSurface) {
try {
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) getScreen().getDisplay().getGraphicsDevice();
if (!EGL.eglDestroySurface(eglDevice.getHandle(), eglSurface)) {
throw new GLException("Error destroying window surface (eglDestroySurface)");
}
@@ -389,6 +398,8 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
}
}
release0(surfaceHandle);
+
+ eglDevice.close();
if( null != androidView ) {
if( added2StaticViewGroup ) {
diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java
index bdef8e6cd..e820439d0 100644
--- a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java
@@ -29,16 +29,21 @@
package jogamp.newt.driver.bcm.vc.iv;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.Capabilities;
+import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.VisualIDHolder;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+
import jogamp.newt.WindowImpl;
import jogamp.newt.driver.linux.LinuxEventDeviceTracker;
import jogamp.newt.driver.linux.LinuxMouseTracker;
+import jogamp.opengl.egl.EGLDisplayUtil;
public class WindowDriver extends WindowImpl {
private static final String WINDOW_CLASS_NAME = "NewtWindow";
@@ -54,9 +59,15 @@ public class WindowDriver extends WindowImpl {
if(0!=getParentWindowHandle()) {
throw new RuntimeException("Window parenting not supported (yet)");
}
+ // Create own screen/device resource instance allowing independent ownership,
+ // while still utilizing shared EGL resources.
+ final AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
+ final EGLGraphicsDevice aDevice = (EGLGraphicsDevice) aScreen.getDevice();
+ final EGLGraphicsDevice eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(aDevice.getNativeDisplayID(), aDevice.getConnection(), aDevice.getUnitID());
+ final DefaultGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aScreen.getIndex());
final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration(
- capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED);
+ capsRequested, capsRequested, capabilitiesChooser, eglScreen, VisualIDHolder.VID_UNDEFINED);
if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
@@ -82,6 +93,8 @@ public class WindowDriver extends WindowImpl {
}
protected void closeNativeImpl() {
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) getGraphicsConfiguration().getScreen().getDevice();
+
removeWindowListener(LinuxMouseTracker.getSingleton());
removeWindowListener(LinuxEventDeviceTracker.getSingleton());
@@ -89,6 +102,8 @@ public class WindowDriver extends WindowImpl {
CloseWindow(windowHandleClose, windowUserData);
windowUserData=0;
}
+
+ eglDevice.close();
}
protected void requestFocusImpl(boolean reparented) {
--
cgit v1.2.3