aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2011-08-11 17:56:28 +0200
committerSven Gothel <[email protected]>2011-08-11 17:56:28 +0200
commitcc551ca89bf207cafc83e7c8d9b22fd866ec4a26 (patch)
tree4e92726244aa436c2d27a0a71f6ad37f0a026e0c
parentb893ada668591187ac6866296439811036db2d95 (diff)
NEWT/Android Fix: Display/Screen/Window creation ; ScreenMode Change
- Remove Application Context notion in Screen/Display, use 'jogamp.common.os.android.StaticContext' - Display, Screen and Window construction is Android agnostic allowing simple GLWindow creation. - Android ScreenMode Fix: - Use unrotated screen dimension - Intercept 'orientation' configChange, which keeps running the application in case of a rotation. - ScreenMode Add: getRotatedWidth() / getRotatedHeight(), used for Screen.setScreenSize(..) which reflects the rotates dimension. - ScreenMode: getCurrentMode() allows new, not yet detected, ScreenModes
-rw-r--r--make/resources/android/AndroidManifest-jogl.xml1
-rw-r--r--make/resources/android/AndroidManifest-launcher.xml2
-rw-r--r--src/newt/classes/com/jogamp/newt/ScreenMode.java27
-rw-r--r--src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java4
-rw-r--r--src/newt/classes/jogamp/newt/ScreenImpl.java23
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java21
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java97
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java16
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java41
9 files changed, 127 insertions, 105 deletions
diff --git a/make/resources/android/AndroidManifest-jogl.xml b/make/resources/android/AndroidManifest-jogl.xml
index 24e7a7b78..c2017d37c 100644
--- a/make/resources/android/AndroidManifest-jogl.xml
+++ b/make/resources/android/AndroidManifest-jogl.xml
@@ -14,6 +14,7 @@
<activity android:name="jogamp.newt.driver.android.NewtVersionActivity"
android:finishOnTaskLaunch="true"
android:launchMode="singleTop"
+ android:configChanges="keyboardHidden|orientation"
android:label="@string/activity_v_name"
android:description="@string/activity_v_descr"
>
diff --git a/make/resources/android/AndroidManifest-launcher.xml b/make/resources/android/AndroidManifest-launcher.xml
index 7ce9693f1..1dfec1cb7 100644
--- a/make/resources/android/AndroidManifest-launcher.xml
+++ b/make/resources/android/AndroidManifest-launcher.xml
@@ -15,6 +15,7 @@
<activity android:name="com.jogamp.android.launcher.NEWTLauncherVersionActivity"
android:finishOnTaskLaunch="true"
android:launchMode="singleTop"
+ android:configChanges="keyboardHidden|orientation"
android:label="@string/activity_v_name"
android:description="@string/activity_v_descr"
>
@@ -26,6 +27,7 @@
<activity android:name="com.jogamp.android.launcher.NEWTLauncherGearsActivity"
android:finishOnTaskLaunch="true"
android:launchMode="singleTop"
+ android:configChanges="keyboardHidden|orientation"
android:label="@string/activity_gears1_name"
android:description="@string/activity_gears1_descr"
>
diff --git a/src/newt/classes/com/jogamp/newt/ScreenMode.java b/src/newt/classes/com/jogamp/newt/ScreenMode.java
index 81ce70249..2a05d842e 100644
--- a/src/newt/classes/com/jogamp/newt/ScreenMode.java
+++ b/src/newt/classes/com/jogamp/newt/ScreenMode.java
@@ -28,6 +28,8 @@
package com.jogamp.newt;
+import javax.media.nativewindow.util.DimensionReadOnly;
+
import com.jogamp.newt.util.MonitorMode;
/** Immutable ScreenMode Class, consisting of it's read only components:<br>
@@ -149,6 +151,22 @@ public class ScreenMode implements Cloneable {
public final int getRotation() {
return rotation;
}
+
+ /** Returns the rotated screen width,
+ * derived from <code>getMonitorMode().getSurfaceSize().getResolution()</code>
+ * and <code>getRotation()</code>
+ */
+ public final int getRotatedWidth() {
+ return getRotatedWH(true);
+ }
+
+ /** Returns the rotated screen height,
+ * derived from <code>getMonitorMode().getSurfaceSize().getResolution()</code>
+ * and <code>getRotation()</code>
+ */
+ public final int getRotatedHeight() {
+ return getRotatedWH(false);
+ }
public final String toString() {
return "[ " + getMonitorMode() + ", " + rotation + " degr ]";
@@ -186,4 +204,13 @@ public class ScreenMode implements Cloneable {
hash = ((hash << 5) - hash) + getRotation();
return hash;
}
+
+ private final int getRotatedWH(boolean width) {
+ final DimensionReadOnly d = getMonitorMode().getSurfaceSize().getResolution();
+ final boolean swap = ScreenMode.ROTATE_90 == rotation || ScreenMode.ROTATE_270 == rotation ;
+ if ( ( width && swap ) || ( !width && !swap ) ) {
+ return d.getHeight();
+ }
+ return d.getWidth();
+ }
}
diff --git a/src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java b/src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java
index 3e0e3dac5..9c4993f1d 100644
--- a/src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java
+++ b/src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java
@@ -244,8 +244,8 @@ public class ScreenModeUtil {
*
* @param modeProperties the input data
* @param offset the offset to the input data
- * @return index of the identical (old or new) ScreenMode element in <code>screenModePool</code>,
- * matching the input <code>modeProperties</code>, or -1 if input could not be processed.
+ * @return ScreenMode element matching the input <code>modeProperties</code>,
+ * or null if input could not be processed.
*/
public static ScreenMode streamIn(int[] modeProperties, int offset) {
return streamInImpl(null, null, null, null, null, modeProperties, offset);
diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java
index 45899f08d..cc0d03e01 100644
--- a/src/newt/classes/jogamp/newt/ScreenImpl.java
+++ b/src/newt/classes/jogamp/newt/ScreenImpl.java
@@ -230,6 +230,11 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
return fqname;
}
+ /**
+ * Set the <b>rotated</b> ScreenSize.
+ * @see com.jogamp.newt.ScreenMode#getRotatedWidth()
+ * @see com.jogamp.newt.ScreenMode#getRotatedHeight()
+ */
protected void setScreenSize(int w, int h) {
System.err.println("Detected screen size "+w+"x"+h);
width=w; height=h;
@@ -251,10 +256,19 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
return null != aScreen;
}
+
+ /**
+ * @return the <b>rotated</b> width.
+ * @see com.jogamp.newt.ScreenMode#getRotatedWidth()
+ */
public final int getWidth() {
return (usrWidth>0) ? usrWidth : (width>0) ? width : 480;
}
+ /**
+ * @return the <b>rotated</b> height
+ * @see com.jogamp.newt.ScreenMode#getRotatedHeight()
+ */
public final int getHeight() {
return (usrHeight>0) ? usrHeight : (height>0) ? height : 480;
}
@@ -287,13 +301,11 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
}
sms.lock();
try {
- smU = (ScreenMode) sms.getScreenModes().get(sm0); // unify via value hash
- if(null == smU) {
- throw new RuntimeException(sm0+" could not be hashed from ScreenMode list");
- }
+ smU = (ScreenMode) sms.getScreenModes().getOrAdd(sm0); // unified instance, maybe new
// if mode has changed somehow, update it ..
if( sms.getCurrentScreenMode().hashCode() != smU.hashCode() ) {
+ setScreenSize(smU.getRotatedWidth(), smU.getRotatedHeight());
sms.fireScreenModeChanged(smU, true);
}
} finally {
@@ -321,8 +333,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
boolean success = setCurrentScreenModeImpl(smU);
if(success) {
- setScreenSize(screenMode.getMonitorMode().getSurfaceSize().getResolution().getWidth(),
- screenMode.getMonitorMode().getSurfaceSize().getResolution().getHeight());
+ setScreenSize(screenMode.getRotatedWidth(), screenMode.getRotatedHeight());
}
if(DEBUG) {
diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java b/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java
index 1ba40f189..34935e0f9 100644
--- a/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java
@@ -35,9 +35,6 @@ import javax.media.nativewindow.*;
import javax.media.nativewindow.egl.*;
import javax.media.opengl.GLException;
-import android.content.Context;
-import android.view.Surface;
-
public class AndroidDisplay extends jogamp.newt.DisplayImpl {
static {
NEWTJNILibLoader.loadNEWT();
@@ -57,7 +54,6 @@ public class AndroidDisplay extends jogamp.newt.DisplayImpl {
protected void createNativeImpl() {
// EGL Device
- // final long eglDisplay = EGL.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY);
final long eglDisplay = EGL.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY);
if (eglDisplay == EGL.EGL_NO_DISPLAY) {
throw new GLException("Failed to created EGL default display: error 0x"+Integer.toHexString(EGL.eglGetError()));
@@ -78,21 +74,6 @@ public class AndroidDisplay extends jogamp.newt.DisplayImpl {
protected void dispatchMessagesNative() {
// n/a .. DispatchMessages();
- }
-
- public synchronized boolean setAppContext(Context ctx) {
- if(null == appContext) {
- appContext = ctx;
- return true;
- } else if(appContext != ctx) {
- throw new RuntimeException("AppContext already set to "+appContext+", can't override w/ "+ctx);
- }
- return false;
- }
- public synchronized Context getAppContext() {
- return appContext;
- }
-
- private Context appContext;
+ }
}
diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java b/src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java
index 34092e885..ce6a9c594 100644
--- a/src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java
@@ -29,12 +29,9 @@
package jogamp.newt.driver.android;
import javax.media.nativewindow.*;
-import javax.media.nativewindow.util.Dimension;
-import javax.media.nativewindow.util.DimensionReadOnly;
-import javax.media.nativewindow.util.SurfaceSize;
import com.jogamp.newt.ScreenMode;
-import com.jogamp.newt.util.MonitorMode;
+import com.jogamp.newt.util.ScreenModeUtil;
import android.content.Context;
import android.graphics.PixelFormat;
@@ -57,33 +54,50 @@ public class AndroidScreen extends jogamp.newt.ScreenImpl {
protected void closeNativeImpl() { }
- public synchronized boolean setAppContext(Context ctx) {
- if(!((AndroidDisplay) getDisplay()).setAppContext(ctx)) {
- return false;
- }
- final WindowManager wmgr = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE);
- sm = getScreenMode(wmgr.getDefaultDisplay());
- setScreenSize(sm.getMonitorMode().getSurfaceSize().getResolution().getWidth(),
- sm.getMonitorMode().getSurfaceSize().getResolution().getHeight());
- return true;
- }
- public synchronized Context getAppContext() {
- return ((AndroidDisplay) getDisplay()).getAppContext();
- }
-
protected ScreenMode getCurrentScreenModeImpl() {
- return sm;
+ final Context ctx = jogamp.common.os.android.StaticContext.getContext();
+ final WindowManager wmgr = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE);
+ final DisplayMetrics outMetrics = new DisplayMetrics();
+ final android.view.Display aDisplay = wmgr.getDefaultDisplay();
+ aDisplay.getMetrics(outMetrics);
+
+ final int arot = aDisplay.getRotation();
+ final int nrot = androidRotation2NewtRotation(arot);
+ int[] props = new int[ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL];
+ int offset = 1; // set later for verification of iterator
+ offset = getScreenSize(outMetrics, nrot, props, offset);
+ offset = getBpp(aDisplay, props, offset);
+ offset = getScreenSizeMM(outMetrics, props, offset);
+ props[offset++] = (int) aDisplay.getRefreshRate();
+ props[offset++] = nrot;
+ props[offset - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = offset; // count
+ return ScreenModeUtil.streamIn(props, 0);
}
- ScreenMode sm = null;
-
//----------------------------------------------------------------------
// Internals only
//
- static DimensionReadOnly getScreenSize(DisplayMetrics outMetrics) {
- return new Dimension(outMetrics.widthPixels, outMetrics.heightPixels);
+ static int androidRotation2NewtRotation(int arot) {
+ switch(arot) {
+ case Surface.ROTATION_270: return ScreenMode.ROTATE_270;
+ case Surface.ROTATION_180: return ScreenMode.ROTATE_180;
+ case Surface.ROTATION_90: return ScreenMode.ROTATE_90;
+ case Surface.ROTATION_0:
+ }
+ return ScreenMode.ROTATE_0;
+ }
+ static int getScreenSize(DisplayMetrics outMetrics, int nrot, int[] props, int offset) {
+ // swap width and height, since Android reflects rotated dimension, we don't
+ if (ScreenMode.ROTATE_90 == nrot || ScreenMode.ROTATE_270 == nrot) {
+ props[offset++] = outMetrics.heightPixels;
+ props[offset++] = outMetrics.widthPixels;
+ } else {
+ props[offset++] = outMetrics.widthPixels;
+ props[offset++] = outMetrics.heightPixels;
+ }
+ return offset;
}
- static SurfaceSize getSurfaceSize(android.view.Display aDisplay, DimensionReadOnly dim) {
+ static int getBpp(android.view.Display aDisplay, int[] props, int offset) {
int bpp;
switch(aDisplay.getPixelFormat()) {
case PixelFormat.RGBA_8888: bpp=32; break;
@@ -95,39 +109,16 @@ public class AndroidScreen extends jogamp.newt.ScreenImpl {
case PixelFormat.RGB_332: bpp= 8; break;
default: bpp=32;
}
- return new SurfaceSize(dim, bpp);
+ props[offset++] = bpp;
+ return offset;
}
- static DimensionReadOnly getScreenSizeMM(DisplayMetrics outMetrics) {
+ static int getScreenSizeMM(DisplayMetrics outMetrics, int[] props, int offset) {
final float iw = (float) outMetrics.widthPixels / outMetrics.xdpi;
final float ih = (float) outMetrics.heightPixels / outMetrics.xdpi;
final float mmpi = 25.4f;
- return new Dimension((int) ((iw * mmpi)+0.5), (int) ((ih * mmpi)+0.5));
+ props[offset++] = (int) ((iw * mmpi)+0.5);
+ props[offset++] = (int) ((ih * mmpi)+0.5);
+ return offset;
}
- static int getRotation(int androidRotation) {
- int nrot;
- switch(androidRotation) {
- case Surface.ROTATION_270: nrot = ScreenMode.ROTATE_270; break;
- case Surface.ROTATION_180: nrot = ScreenMode.ROTATE_180; break;
- case Surface.ROTATION_90: nrot = ScreenMode.ROTATE_90; break;
- case Surface.ROTATION_0:
- default: nrot = ScreenMode.ROTATE_0;
- }
- return nrot;
- }
- static ScreenMode getScreenMode(android.view.Display aDisplay) {
- final DisplayMetrics outMetrics = new DisplayMetrics();
- aDisplay.getMetrics(outMetrics);
-
- final DimensionReadOnly screenSize = getScreenSize(outMetrics);
- final SurfaceSize surfaceSize = getSurfaceSize(aDisplay, screenSize);
- final DimensionReadOnly screenSizeMM = getScreenSizeMM(outMetrics);
- final int refreshRate = (int) aDisplay.getRefreshRate();
- final MonitorMode mm = new MonitorMode(surfaceSize, screenSizeMM, refreshRate);
-
- final int rotation = getRotation(aDisplay.getRotation());
- return new ScreenMode(mm, rotation);
- }
-
-
}
diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java b/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java
index 795426c9e..aaefae037 100644
--- a/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java
@@ -85,8 +85,8 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
return PixelFormat.RGBA_8888;
}
- public AndroidWindow(Context ctx) {
- nsv = new MSurfaceView(ctx);
+ public AndroidWindow() {
+ nsv = new MSurfaceView(jogamp.common.os.android.StaticContext.getContext());
nsv.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, android.view.MotionEvent aEvent) {
MouseEvent newtEvent = AndroidNewtEventFactory.createMouseEvent(aEvent, AndroidWindow.this);
@@ -101,10 +101,6 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
sh.addCallback(this);
}
- public static Class[] getCustomConstructorArgumentTypes() {
- return new Class[] { Context.class } ;
- }
-
public SurfaceView getView() { return nsv; }
protected boolean canCreateNativeImpl() {
@@ -234,6 +230,7 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Log.d(MD.TAG, "surfaceChanged: f "+Integer.toString(format)+", "+width+"x"+height);
+ getScreen().getCurrentScreenMode(); // if ScreenMode changed .. trigger ScreenMode event
sizeChanged(width, height, false);
}
@@ -258,13 +255,6 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
super(ctx);
}
- /**
- protected void dispatchDraw(Canvas canvas) {
- // n/a
- }
- public void draw(Canvas canvas) {
- // n/a
- } */
}
//----------------------------------------------------------------------
// Internals only
diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java b/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java
index 96ca8514f..79065897e 100644
--- a/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java
+++ b/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java
@@ -33,6 +33,8 @@ import javax.media.opengl.GLProfile;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.Display;
import com.jogamp.newt.Screen;
+import com.jogamp.newt.ScreenMode;
+import com.jogamp.newt.event.ScreenModeListener;
import com.jogamp.newt.opengl.GLWindow;
import jogamp.newt.driver.android.test.GearsGL2ES1;
import com.jogamp.opengl.util.Animator;
@@ -40,11 +42,12 @@ import com.jogamp.opengl.util.Animator;
import jogamp.newt.driver.android.AndroidWindow;
import android.app.Activity;
+import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
+import android.view.SurfaceView;
public class NewtVersionActivity extends Activity {
- AndroidWindow window = null;
GLWindow glWindow = null;
Animator animator = null;
@Override
@@ -59,22 +62,34 @@ public class NewtVersionActivity extends Activity {
System.setProperty("jogamp.debug.NativeLibrary", "true");
// System.setProperty("jogamp.debug.NativeLibrary.Lookup", "true");
+ // register application context
+ jogamp.common.os.android.StaticContext.setContext(getApplicationContext());
+
+ // init GLProfile
GLProfile.initSingleton(true);
+ // create GLWindow (-> incl. underlying NEWT Display, Screen & Window)
GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GLES1));
- // caps.setRedBits(5); caps.setGreenBits(6); caps.setBlueBits(5);
- AndroidDisplay display = (AndroidDisplay) NewtFactory.createDisplay(null);
- AndroidScreen screen = (AndroidScreen) NewtFactory.createScreen(display, 0);
- screen.setAppContext(this.getApplicationContext());
+ glWindow = GLWindow.create(caps);
- window = (AndroidWindow) NewtFactory.createWindow(new Object[] { this }, screen, caps);
- setContentView(window.getView());
+ {
+ // use AndroidWindow's inner SurfaceView for this content view
+ SurfaceView view = ((AndroidWindow) glWindow.getWindow()).getView();
+ setContentView(view);
+ }
- glWindow = GLWindow.create(window);
glWindow.addGLEventListener(new GearsGL2ES1(1));
+ glWindow.getWindow().getScreen().addScreenModeListener(new ScreenModeListener() {
+ public void screenModeChangeNotify(ScreenMode sm) {
+ }
+
+ public void screenModeChanged(ScreenMode sm, boolean success) {
+ System.err.println("ScreenMode Changed: "+sm);
+ }
+ });
glWindow.setVisible(true);
animator = new Animator(glWindow);
- animator.setUpdateFPSFrames(1, null);
+ animator.setUpdateFPSFrames(60, System.err);
Log.d(MD.TAG, "onCreate - X");
}
@@ -124,8 +139,12 @@ public class NewtVersionActivity extends Activity {
public void onDestroy() {
Log.d(MD.TAG, "onDestroy - S");
super.onDestroy();
- glWindow.destroy();
- window.destroy();
+ if(null != animator) {
+ animator.stop();
+ }
+ if(null != glWindow) {
+ glWindow.destroy();
+ }
Log.d(MD.TAG, "onDestroy - X");
}
}