diff options
author | Sven Gothel <[email protected]> | 2011-08-11 17:56:28 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-08-11 17:56:28 +0200 |
commit | cc551ca89bf207cafc83e7c8d9b22fd866ec4a26 (patch) | |
tree | 4e92726244aa436c2d27a0a71f6ad37f0a026e0c /src | |
parent | b893ada668591187ac6866296439811036db2d95 (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
Diffstat (limited to 'src')
7 files changed, 124 insertions, 105 deletions
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"); } } |