OSDN Git Service

[added] ResolutionStrategy
authorchristoph.widulle <christoph.widulle@6c4fd544-2939-11df-bb46-9574ba5d0bfa>
Fri, 31 Dec 2010 04:08:42 +0000 (04:08 +0000)
committerchristoph.widulle <christoph.widulle@6c4fd544-2939-11df-bb46-9574ba5d0bfa>
Fri, 31 Dec 2010 04:08:42 +0000 (04:08 +0000)
backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/AndroidApplication.java
backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/AndroidGraphics.java
backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/surfaceview/DefaultGLSurfaceView.java [new file with mode: 0644]
backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/surfaceview/FillResolutionStrategy.java [new file with mode: 0644]
backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/surfaceview/FixedResolutionStrategy.java [new file with mode: 0644]
backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/surfaceview/GLSurfaceView20.java
backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/surfaceview/GLSurfaceViewCupcake.java
backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/surfaceview/RatioResolutionStrategy.java [new file with mode: 0644]
backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/surfaceview/ResolutionStrategy.java [new file with mode: 0644]

index 993def6..d30bdd5 100644 (file)
@@ -19,10 +19,12 @@ import android.os.Bundle;
 import android.os.Debug;\r
 import android.os.Handler;\r
 import android.util.Log;\r
+import android.view.Gravity;\r
 import android.view.View;\r
 import android.view.Window;\r
 import android.view.WindowManager;\r
 \r
+import android.widget.FrameLayout;\r
 import com.badlogic.gdx.Application;\r
 import com.badlogic.gdx.ApplicationListener;\r
 import com.badlogic.gdx.Audio;\r
@@ -31,206 +33,229 @@ import com.badlogic.gdx.Gdx;
 import com.badlogic.gdx.Graphics;\r
 import com.badlogic.gdx.Input;\r
 import com.badlogic.gdx.Version;\r
+import com.badlogic.gdx.backends.android.surfaceview.FillResolutionStrategy;\r
 import com.badlogic.gdx.backends.android.surfaceview.GLSurfaceViewCupcake;\r
+import com.badlogic.gdx.backends.android.surfaceview.ResolutionStrategy;\r
 import com.badlogic.gdx.graphics.GL10;\r
 import com.badlogic.gdx.graphics.GL11;\r
 \r
 /**\r
  * An implementation of the {@link Application} interface for Android. Create an {@link Activity} that derives from this class. In\r
- * the {@link Activity#onCreate(Bundle)} method call the {@link #initialize(ApplicationListener,boolean)} method specifying the\r
+ * the {@link Activity#onCreate(Bundle)} method call the {@link #initialize(ApplicationListener, boolean)} method specifying the\r
  * configuration for the GLSurfaceView.\r
- * \r
+ *\r
  * @author mzechner\r
  */\r
 public class AndroidApplication extends Activity implements Application {\r
 \r
-       static {\r
-               Version.loadLibrary();\r
-       }\r
-\r
-       protected AndroidGraphics graphics;\r
-       protected AndroidInput input;\r
-       protected AndroidAudio audio;\r
-       protected AndroidFiles files;\r
-       protected ApplicationListener listener;\r
-       protected Handler handler;\r
-       protected boolean firstResume = true;\r
-\r
-       /**\r
-        * This method has to be called in the {@link Activity#onCreate(Bundle)} method. It sets up all the things necessary to get\r
-        * input, render via OpenGL and so on. If useGL20IfAvailable is set the AndroidApplication will try to create an OpenGL ES 2.0\r
-        * context which can then be used via {@link Graphics#getGL20()}. The {@link GL10} and {@link GL11} interfaces should not be\r
-        * used when OpenGL ES 2.0 is enabled. To query whether enabling OpenGL ES 2.0 was successful use the\r
-        * {@link Graphics#isGL20Available()} method. Sleep time in touch event handler is 0, so no sleeping is performed.\r
-        * \r
-        * @param listener the {@link ApplicationListener} implementing the program logic\r
-        * @param useGL2IfAvailable whether to use OpenGL ES 2.0 if its available.\r
-        */\r
-       public void initialize (ApplicationListener listener, boolean useGL2IfAvailable) {\r
-               initialize(listener, useGL2IfAvailable, 0);\r
-       }\r
-\r
-       /**\r
-        * This method has to be called in the {@link Activity#onCreate(Bundle)} method. It sets up all the things necessary to get\r
-        * input, render via OpenGL and so on. If useGL20IfAvailable is set the AndroidApplication will try to create an OpenGL ES 2.0\r
-        * context which can then be used via {@link Graphics#getGL20()}. The {@link GL10} and {@link GL11} interfaces should not be\r
-        * used when OpenGL ES 2.0 is enabled. To query whether enabling OpenGL ES 2.0 was successful use the\r
-        * {@link Graphics#isGL20Available()} method. sleepTime specifies the number of milliseconds to sleep in the touch event\r
-        * handler. This may be used on <= 1.6 Android devices. Note that it will not solve the CPU usage problem of the event handler\r
-        * of the Android system. Things will still slow down.\r
-        * \r
-        * @param listener the {@link ApplicationListener} implementing the program logic\r
-        * @param useGL2IfAvailable whether to use OpenGL ES 2.0 if its available.\r
-        * @param sleepTime specifies the number of milliseconds to sleep in the touch event handler\r
-        */\r
-       public void initialize (ApplicationListener listener, boolean useGL2IfAvailable, int sleepTime) {\r
-               graphics = new AndroidGraphics(this, useGL2IfAvailable);\r
-               input = new AndroidInput(this, graphics.view, sleepTime);\r
-               audio = new AndroidAudio(this);\r
-               files = new AndroidFiles(this.getAssets());\r
-               this.listener = listener;\r
-               this.handler = new Handler();\r
-\r
-               Gdx.app = this;\r
-               Gdx.input = this.getInput();\r
-               Gdx.audio = this.getAudio();\r
-               Gdx.files = this.getFiles();\r
-               Gdx.graphics = this.getGraphics();\r
-\r
-               requestWindowFeature(Window.FEATURE_NO_TITLE);\r
-               getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);\r
-               setContentView(graphics.getView());\r
-       }\r
-\r
-       /**\r
-        * This method has to be called in the {@link Activity#onCreate(Bundle)} method. It sets up all the things necessary to get\r
-        * input, render via OpenGL and so on. If useGL20IfAvailable is set the AndroidApplication will try to create an OpenGL ES 2.0\r
-        * context which can then be used via {@link Graphics#getGL20()}. The {@link GL10} and {@link GL11} interfaces should not be\r
-        * used when OpenGL ES 2.0 is enabled. To query whether enabling OpenGL ES 2.0 was successful use the\r
-        * {@link Graphics#isGL20Available()} method. sleepTime specifies the number of milliseconds to sleep in the touch event\r
-        * handler. This may be used on <= 1.6 Android devices. Note that it will not solve the CPU usage problem of the event handler\r
-        * of the Android system. Things will still slow down.\r
-        * \r
-        * Note: you have to add the returned view to your layout!\r
-        * \r
-        * @param listener the {@link ApplicationListener} implementing the program logic\r
-        * @param useGL2IfAvailable whether to use OpenGL ES 2.0 if its available.\r
-        * @param sleepTime specifies the number of milliseconds to sleep in the touch event handler\r
-        * @return the GLSurfaceView of the application\r
-        */\r
-       public View initializeForView (ApplicationListener listener, boolean useGL2IfAvailable, int sleepTime) {\r
-               graphics = new AndroidGraphics(this, useGL2IfAvailable);\r
-               input = new AndroidInput(this, graphics.view, sleepTime);\r
-               audio = new AndroidAudio(this);\r
-               files = new AndroidFiles(this.getAssets());\r
-               this.listener = listener;\r
-               this.handler = new Handler();\r
-\r
-               Gdx.app = this;\r
-               Gdx.input = this.getInput();\r
-               Gdx.audio = this.getAudio();\r
-               Gdx.files = this.getFiles();\r
-               Gdx.graphics = this.getGraphics();\r
-\r
-               return graphics.getView();\r
-       }\r
-\r
-       @Override protected void onPause () {\r
-               graphics.pause();\r
-\r
-               if (isFinishing()) {\r
-                       graphics.clearManagedCaches();\r
-                       graphics.destroy();\r
-               }\r
-\r
-               if (graphics != null && graphics.view != null) {\r
-                       if (graphics.view instanceof GLSurfaceViewCupcake) ((GLSurfaceViewCupcake)graphics.view).onPause();\r
-                       if (graphics.view instanceof android.opengl.GLSurfaceView) ((android.opengl.GLSurfaceView)graphics.view).onPause();\r
-               }\r
-\r
-               if (audio != null) audio.pause();\r
-               super.onPause();\r
-       }\r
-\r
-       @Override protected void onResume () {\r
-               Gdx.app = this;\r
-               Gdx.input = this.getInput();\r
-               Gdx.audio = this.getAudio();\r
-               Gdx.files = this.getFiles();\r
-               Gdx.graphics = this.getGraphics();\r
-\r
-               if (graphics != null && graphics.view != null) {\r
-                       if (graphics.view instanceof GLSurfaceViewCupcake) ((GLSurfaceViewCupcake)graphics.view).onResume();\r
-                       if (graphics.view instanceof android.opengl.GLSurfaceView) ((android.opengl.GLSurfaceView)graphics.view).onResume();\r
-               }\r
-\r
-               if (audio != null) audio.resume();\r
-               if (!firstResume)\r
-                       graphics.resume();\r
-               else\r
-                       firstResume = false;\r
-               super.onResume();\r
-       }\r
-\r
-       @Override protected void onDestroy () {\r
-               audio.dispose();\r
-               super.onDestroy();\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public Audio getAudio () {\r
-               return audio;\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public Files getFiles () {\r
-               return files;\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public Graphics getGraphics () {\r
-               return graphics;\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public Input getInput () {\r
-               return input;\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public void log (String tag, String message) {\r
-               Log.d(tag, message);\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public ApplicationType getType () {\r
-               return ApplicationType.Android;\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public int getVersion () {\r
-               return Build.VERSION.SDK.charAt(0) - '0';\r
-       }\r
-\r
-       @Override public long getJavaHeap () {\r
-               return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();\r
-       }\r
-\r
-       @Override public long getNativeHeap () {\r
-               return Debug.getNativeHeapAllocatedSize();\r
-       }\r
+    static {\r
+        Version.loadLibrary();\r
+    }\r
+\r
+    protected AndroidGraphics graphics;\r
+    protected AndroidInput input;\r
+    protected AndroidAudio audio;\r
+    protected AndroidFiles files;\r
+    protected ApplicationListener listener;\r
+    protected Handler handler;\r
+    protected boolean firstResume = true;\r
+\r
+    /**\r
+     * This method has to be called in the {@link Activity#onCreate(Bundle)} method. It sets up all the things necessary to get\r
+     * input, render via OpenGL and so on. If useGL20IfAvailable is set the AndroidApplication will try to create an OpenGL ES 2.0\r
+     * context which can then be used via {@link Graphics#getGL20()}. The {@link GL10} and {@link GL11} interfaces should not be\r
+     * used when OpenGL ES 2.0 is enabled. To query whether enabling OpenGL ES 2.0 was successful use the\r
+     * {@link Graphics#isGL20Available()} method. Sleep time in touch event handler is 0, so no sleeping is performed.\r
+     *\r
+     * @param listener          the {@link ApplicationListener} implementing the program logic\r
+     * @param useGL2IfAvailable whether to use OpenGL ES 2.0 if its available.\r
+     */\r
+    public void initialize(ApplicationListener listener, boolean useGL2IfAvailable) {\r
+        initialize(listener, useGL2IfAvailable, new FillResolutionStrategy(), 0);\r
+    }\r
+\r
+    /**\r
+     * This method has to be called in the {@link Activity#onCreate(Bundle)} method. It sets up all the things necessary to get\r
+     * input, render via OpenGL and so on. If useGL20IfAvailable is set the AndroidApplication will try to create an OpenGL ES 2.0\r
+     * context which can then be used via {@link Graphics#getGL20()}. The {@link GL10} and {@link GL11} interfaces should not be\r
+     * used when OpenGL ES 2.0 is enabled. To query whether enabling OpenGL ES 2.0 was successful use the\r
+     * {@link Graphics#isGL20Available()} method. sleepTime specifies the number of milliseconds to sleep in the touch event\r
+     * handler. This may be used on <= 1.6 Android devices. Note that it will not solve the CPU usage problem of the event handler\r
+     * of the Android system. Things will still slow down.\r
+     *\r
+     * @param listener          the {@link ApplicationListener} implementing the program logic\r
+     * @param useGL2IfAvailable whether to use OpenGL ES 2.0 if its available.\r
+     * @param sleepTime         specifies the number of milliseconds to sleep in the touch event handler\r
+     */\r
+    public void initialize(ApplicationListener listener, boolean useGL2IfAvailable, ResolutionStrategy resolutionStrategy, int sleepTime) {\r
+        graphics = new AndroidGraphics(this, useGL2IfAvailable, resolutionStrategy);\r
+        input = new AndroidInput(this, graphics.view, sleepTime);\r
+        audio = new AndroidAudio(this);\r
+        files = new AndroidFiles(this.getAssets());\r
+        this.listener = listener;\r
+        this.handler = new Handler();\r
+\r
+        Gdx.app = this;\r
+        Gdx.input = this.getInput();\r
+        Gdx.audio = this.getAudio();\r
+        Gdx.files = this.getFiles();\r
+        Gdx.graphics = this.getGraphics();\r
+\r
+        requestWindowFeature(Window.FEATURE_NO_TITLE);\r
+        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);\r
+        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);\r
+        setContentView(graphics.getView(), createLayoutParams());\r
+    }\r
+\r
+    protected FrameLayout.LayoutParams createLayoutParams() {\r
+        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(android.view.ViewGroup.LayoutParams.FILL_PARENT, android.view.ViewGroup.LayoutParams.FILL_PARENT);\r
+        layoutParams.gravity = Gravity.CENTER;\r
+        return layoutParams;\r
+    }\r
+\r
+    /**\r
+     * This method has to be called in the {@link Activity#onCreate(Bundle)} method. It sets up all the things necessary to get\r
+     * input, render via OpenGL and so on. If useGL20IfAvailable is set the AndroidApplication will try to create an OpenGL ES 2.0\r
+     * context which can then be used via {@link Graphics#getGL20()}. The {@link GL10} and {@link GL11} interfaces should not be\r
+     * used when OpenGL ES 2.0 is enabled. To query whether enabling OpenGL ES 2.0 was successful use the\r
+     * {@link Graphics#isGL20Available()} method. sleepTime specifies the number of milliseconds to sleep in the touch event\r
+     * handler. This may be used on <= 1.6 Android devices. Note that it will not solve the CPU usage problem of the event handler\r
+     * of the Android system. Things will still slow down.\r
+     * <p/>\r
+     * Note: you have to add the returned view to your layout!\r
+     *\r
+     * @param listener          the {@link ApplicationListener} implementing the program logic\r
+     * @param useGL2IfAvailable whether to use OpenGL ES 2.0 if its available.\r
+     * @param sleepTime         specifies the number of milliseconds to sleep in the touch event handler\r
+     * @return the GLSurfaceView of the application\r
+     */\r
+    public View initializeForView(ApplicationListener listener, boolean useGL2IfAvailable, ResolutionStrategy resolutionStrategy, int sleepTime) {\r
+        graphics = new AndroidGraphics(this, useGL2IfAvailable, resolutionStrategy);\r
+        input = new AndroidInput(this, graphics.view, sleepTime);\r
+        audio = new AndroidAudio(this);\r
+        files = new AndroidFiles(this.getAssets());\r
+        this.listener = listener;\r
+        this.handler = new Handler();\r
+\r
+        Gdx.app = this;\r
+        Gdx.input = this.getInput();\r
+        Gdx.audio = this.getAudio();\r
+        Gdx.files = this.getFiles();\r
+        Gdx.graphics = this.getGraphics();\r
+\r
+        return graphics.getView();\r
+    }\r
+\r
+    @Override\r
+    protected void onPause() {\r
+        graphics.pause();\r
+\r
+        if (isFinishing()) {\r
+            graphics.clearManagedCaches();\r
+            graphics.destroy();\r
+        }\r
+\r
+        if (graphics != null && graphics.view != null) {\r
+            if (graphics.view instanceof GLSurfaceViewCupcake) ((GLSurfaceViewCupcake) graphics.view).onPause();\r
+            if (graphics.view instanceof android.opengl.GLSurfaceView)\r
+                ((android.opengl.GLSurfaceView) graphics.view).onPause();\r
+        }\r
+\r
+        if (audio != null) audio.pause();\r
+        super.onPause();\r
+    }\r
+\r
+    @Override\r
+    protected void onResume() {\r
+        Gdx.app = this;\r
+        Gdx.input = this.getInput();\r
+        Gdx.audio = this.getAudio();\r
+        Gdx.files = this.getFiles();\r
+        Gdx.graphics = this.getGraphics();\r
+\r
+        if (graphics != null && graphics.view != null) {\r
+            if (graphics.view instanceof GLSurfaceViewCupcake) ((GLSurfaceViewCupcake) graphics.view).onResume();\r
+            if (graphics.view instanceof android.opengl.GLSurfaceView)\r
+                ((android.opengl.GLSurfaceView) graphics.view).onResume();\r
+        }\r
+\r
+        if (audio != null) audio.resume();\r
+        if (!firstResume)\r
+            graphics.resume();\r
+        else\r
+            firstResume = false;\r
+        super.onResume();\r
+    }\r
+\r
+    @Override\r
+    protected void onDestroy() {\r
+        audio.dispose();\r
+        super.onDestroy();\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public Audio getAudio() {\r
+        return audio;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public Files getFiles() {\r
+        return files;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public Graphics getGraphics() {\r
+        return graphics;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public Input getInput() {\r
+        return input;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public void log(String tag, String message) {\r
+        Log.d(tag, message);\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public ApplicationType getType() {\r
+        return ApplicationType.Android;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public int getVersion() {\r
+        return Build.VERSION.SDK.charAt(0) - '0';\r
+    }\r
+\r
+    @Override\r
+    public long getJavaHeap() {\r
+        return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();\r
+    }\r
+\r
+    @Override\r
+    public long getNativeHeap() {\r
+        return Debug.getNativeHeapAllocatedSize();\r
+    }\r
 }\r
index 9585ee8..0fe57ee 100644 (file)
 \r
 package com.badlogic.gdx.backends.android;\r
 \r
-import java.io.InputStream;\r
-\r
-import javax.microedition.khronos.egl.EGL10;\r
-import javax.microedition.khronos.egl.EGLConfig;\r
-import javax.microedition.khronos.egl.EGLContext;\r
-import javax.microedition.khronos.egl.EGLDisplay;\r
-\r
 import android.app.Activity;\r
 import android.graphics.Bitmap;\r
 import android.graphics.BitmapFactory;\r
@@ -29,496 +22,519 @@ import android.os.Build;
 import android.util.DisplayMetrics;\r
 import android.view.Display;\r
 import android.view.View;\r
-\r
 import com.badlogic.gdx.Gdx;\r
 import com.badlogic.gdx.Graphics;\r
-import com.badlogic.gdx.backends.android.surfaceview.GLSurfaceView20;\r
-import com.badlogic.gdx.backends.android.surfaceview.GLSurfaceViewCupcake;\r
+import com.badlogic.gdx.backends.android.surfaceview.*;\r
 import com.badlogic.gdx.files.FileHandle;\r
-import com.badlogic.gdx.graphics.GL10;\r
-import com.badlogic.gdx.graphics.GL11;\r
-import com.badlogic.gdx.graphics.GL20;\r
-import com.badlogic.gdx.graphics.GLCommon;\r
-import com.badlogic.gdx.graphics.Mesh;\r
-import com.badlogic.gdx.graphics.Pixmap;\r
+import com.badlogic.gdx.graphics.*;\r
 import com.badlogic.gdx.graphics.Pixmap.Format;\r
-import com.badlogic.gdx.graphics.Texture;\r
 import com.badlogic.gdx.graphics.Texture.TextureFilter;\r
 import com.badlogic.gdx.graphics.Texture.TextureWrap;\r
-import com.badlogic.gdx.graphics.TextureData;\r
 import com.badlogic.gdx.graphics.glutils.FrameBuffer;\r
 import com.badlogic.gdx.graphics.glutils.ShaderProgram;\r
 import com.badlogic.gdx.math.WindowedMean;\r
 import com.badlogic.gdx.utils.GdxRuntimeException;\r
 import com.badlogic.gdx.utils.MathUtils;\r
 \r
+import javax.microedition.khronos.egl.EGL10;\r
+import javax.microedition.khronos.egl.EGLConfig;\r
+import javax.microedition.khronos.egl.EGLContext;\r
+import javax.microedition.khronos.egl.EGLDisplay;\r
+import java.io.InputStream;\r
+\r
 /**\r
  * An implementation of {@link Graphics} for Android.\r
- * \r
+ *\r
  * @author mzechner\r
  */\r
 public final class AndroidGraphics implements Graphics, Renderer {\r
-       final View view;\r
-       int width;\r
-       int height;\r
-       AndroidApplication app;\r
-       GLCommon gl;\r
-       GL10 gl10;\r
-       GL11 gl11;\r
-       GL20 gl20;\r
-\r
-       private long lastFrameTime = System.nanoTime();\r
-       private float deltaTime = 0;\r
-       private long frameStart = System.nanoTime();\r
-       private int frames = 0;\r
-       private int fps;\r
-       private WindowedMean mean = new WindowedMean(5);\r
-\r
-       volatile boolean created = false;\r
-       volatile boolean running = false;\r
-       volatile boolean pause = false;\r
-       volatile boolean resume = false;\r
-       volatile boolean destroy = false;\r
-\r
-       private float ppiX = 0;\r
-       private float ppiY = 0;\r
-       private float ppcX = 0;\r
-       private float ppcY = 0;\r
-\r
-       public AndroidGraphics (AndroidApplication activity, boolean useGL2IfAvailable) {\r
-               view = createGLSurfaceView(activity, useGL2IfAvailable);\r
-               this.app = activity;\r
-       }\r
-\r
-       private View createGLSurfaceView (Activity activity, boolean useGL2) {\r
-               EGLConfigChooser configChooser = getEglConfigChooser();\r
-\r
-               if (useGL2 && checkGL20()) {\r
-                       GLSurfaceView20 view = new GLSurfaceView20(activity);\r
-                       if (configChooser != null) view.setEGLConfigChooser(configChooser);\r
-                       view.setRenderer(this);                 \r
-                       return view;\r
-               } else {\r
-                       if (Integer.parseInt(android.os.Build.VERSION.SDK) <= 4) {\r
-                               GLSurfaceViewCupcake view = new GLSurfaceViewCupcake(activity);\r
-                               if (configChooser != null) view.setEGLConfigChooser(configChooser);\r
-                               view.setRenderer(this);\r
-                               return view;\r
-                       } else {\r
-                               android.opengl.GLSurfaceView view = new android.opengl.GLSurfaceView(activity);\r
-                               if (configChooser != null) view.setEGLConfigChooser(configChooser);\r
-                               view.setRenderer(this);                         \r
-                               return view;\r
-                       }\r
-               }\r
-       }\r
-\r
-       private EGLConfigChooser getEglConfigChooser () {\r
-               if (!Build.DEVICE.equalsIgnoreCase("GT-I7500"))\r
-                       return null;\r
-               else\r
-                       return new android.opengl.GLSurfaceView.EGLConfigChooser() {\r
-\r
-                               public EGLConfig chooseConfig (EGL10 egl, EGLDisplay display) {\r
-\r
-                                       // Ensure that we get a 16bit depth-buffer. Otherwise, we'll fall\r
-                                       // back to Pixelflinger on some device (read: Samsung I7500)\r
-                                       int[] attributes = new int[] {EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE};\r
-                                       EGLConfig[] configs = new EGLConfig[1];\r
-                                       int[] result = new int[1];\r
-                                       egl.eglChooseConfig(display, attributes, configs, 1, result);\r
-                                       return configs[0];\r
-                               }\r
-                       };\r
-       }\r
-\r
-       private void updatePpi () {\r
-               DisplayMetrics metrics = new DisplayMetrics();\r
-               app.getWindowManager().getDefaultDisplay().getMetrics(metrics);\r
-\r
-               ppiX = metrics.xdpi;\r
-               ppiY = metrics.ydpi;\r
-               ppcX = metrics.xdpi / 2.54f;\r
-               ppcY = metrics.ydpi / 2.54f;\r
-       }\r
-\r
-       private boolean checkGL20 () {\r
-               EGL10 egl = (EGL10)EGLContext.getEGL();\r
-               EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);\r
-\r
-               int[] version = new int[2];\r
-               egl.eglInitialize(display, version);\r
-\r
-               int EGL_OPENGL_ES2_BIT = 4;\r
-               int[] configAttribs = {EGL10.EGL_RED_SIZE, 4, EGL10.EGL_GREEN_SIZE, 4, EGL10.EGL_BLUE_SIZE, 4, EGL10.EGL_RENDERABLE_TYPE,\r
-                       EGL_OPENGL_ES2_BIT, EGL10.EGL_NONE};\r
-\r
-               EGLConfig[] configs = new EGLConfig[10];\r
-               int[] num_config = new int[1];\r
-               egl.eglChooseConfig(display, configAttribs, configs, 10, num_config);\r
-               egl.eglTerminate(display);\r
-               return num_config[0] > 0;\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public GL10 getGL10 () {\r
-               return gl10;\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public GL11 getGL11 () {\r
-               return gl11;\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public GL20 getGL20 () {\r
-               return gl20;\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public int getHeight () {\r
-               return height;\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public int getWidth () {\r
-               return width;\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public boolean isGL11Available () {\r
-               return gl11 != null;\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public boolean isGL20Available () {\r
-               return gl20 != null;\r
-       }\r
-\r
-       private static boolean isPowerOfTwo (int value) {\r
-               return ((value != 0) && (value & (value - 1)) == 0);\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public Pixmap newPixmap (int width, int height, Format format) {\r
-               return new AndroidPixmap(width, height, format);\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public Pixmap newPixmap (InputStream in) {\r
-               Bitmap bitmap = BitmapFactory.decodeStream(in);\r
-               if (bitmap == null) throw new GdxRuntimeException("Couldn't load Pixmap from InputStream");\r
-               return new AndroidPixmap(bitmap);\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public Pixmap newPixmap (FileHandle file) {\r
-               return newPixmap(file.read());\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public Pixmap newPixmap (Object nativePixmap) {\r
-               return new AndroidPixmap((Bitmap)nativePixmap);\r
-       }\r
-\r
-       /**\r
-        * This instantiates the GL10, GL11 and GL20 instances. Includes the check for certain devices that pretend to support GL11 but\r
-        * fuck up vertex buffer objects. This includes the pixelflinger which segfaults when buffers are deleted as well as the\r
-        * Motorola CLIQ and the Samsung Behold II.\r
-        * \r
-        * @param gl\r
-        */\r
-       private void setupGL (javax.microedition.khronos.opengles.GL10 gl) {\r
-               if (gl10 != null || gl20 != null) return;\r
-\r
-               if (view instanceof GLSurfaceView20) {\r
-                       gl20 = new AndroidGL20();\r
-                       this.gl = gl20;\r
-               } else {\r
-                       gl10 = new AndroidGL10(gl);\r
-                       this.gl = gl10;\r
-                       if (gl instanceof javax.microedition.khronos.opengles.GL11) {\r
-                               String renderer = gl.glGetString(GL10.GL_RENDERER);\r
-                               if (!renderer.toLowerCase().contains("pixelflinger")\r
-                                       && !(android.os.Build.MODEL.equals("MB200") || android.os.Build.MODEL.equals("MB220") || android.os.Build.MODEL\r
-                                               .contains("Behold"))) {\r
-                                       gl11 = new AndroidGL11((javax.microedition.khronos.opengles.GL11)gl);\r
-                                       gl10 = gl11;\r
-                               }\r
-                       }\r
-               }\r
-\r
-               Gdx.gl = this.gl;\r
-               Gdx.gl10 = gl10;\r
-               Gdx.gl11 = gl11;\r
-               Gdx.gl20 = gl20;\r
-\r
-               Gdx.app.log("AndroidGraphics", "OGL renderer: " + gl.glGetString(GL10.GL_RENDERER));\r
-               Gdx.app.log("AndroidGraphics", "OGL vendor: " + gl.glGetString(GL10.GL_VENDOR));\r
-               Gdx.app.log("AndroidGraphics", "OGL version: " + gl.glGetString(GL10.GL_VERSION));\r
-               Gdx.app.log("AndroidGraphics", "OGL extensions: " + gl.glGetString(GL10.GL_EXTENSIONS));\r
-       }\r
-\r
-       @Override public void onSurfaceChanged (javax.microedition.khronos.opengles.GL10 gl, int width, int height) {\r
-               this.width = width;\r
-               this.height = height;\r
-               updatePpi();\r
-               app.listener.resize(width, height);\r
-       }\r
-\r
-       @Override public void onSurfaceCreated (javax.microedition.khronos.opengles.GL10 gl, EGLConfig config) {\r
-               setupGL(gl);\r
-               logConfig(config);\r
-               updatePpi();\r
-\r
-               Mesh.invalidateAllMeshes();\r
-               AndroidTexture.invalidateAllTextures();\r
-               ShaderProgram.invalidateAllShaderPrograms();\r
-               FrameBuffer.invalidateAllFrameBuffers();\r
-\r
-               Display display = app.getWindowManager().getDefaultDisplay();\r
-               this.width = display.getWidth();\r
-               this.height = display.getHeight();\r
-               mean = new WindowedMean(5);\r
-               this.lastFrameTime = System.nanoTime();\r
-\r
-               gl.glViewport(0, 0, this.width, this.height);\r
-\r
-               if (created == false) {\r
-                       app.listener.create();\r
-                       created = true;\r
-                       synchronized (this) {\r
-                               running = true;\r
-                       }\r
-               }\r
-       }\r
-\r
-       private void logConfig (EGLConfig config) {\r
-               EGL10 egl = (EGL10)EGLContext.getEGL();\r
-               EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);\r
-               int r = getAttrib(egl, display, config, EGL10.EGL_RED_SIZE, 0);\r
-               int g = getAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE, 0);\r
-               int b = getAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0);\r
-               int a = getAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0);\r
-               int d = getAttrib(egl, display, config, EGL10.EGL_DEPTH_SIZE, 0);\r
-               int s = getAttrib(egl, display, config, EGL10.EGL_STENCIL_SIZE, 0);\r
-\r
-               Gdx.app.log("AndroidGraphics", "framebuffer: (" + r + ", " + g + ", " + b + ", " + a + ")");\r
-               Gdx.app.log("AndroidGraphics", "depthbuffer: (" + d + ")");\r
-               Gdx.app.log("AndroidGraphics", "stencilbuffer: (" + s + ")");\r
-       }\r
-\r
-       int[] value = new int[1];\r
-\r
-       private int getAttrib (EGL10 egl, EGLDisplay display, EGLConfig config, int attrib, int defValue) {\r
-               if (egl.eglGetConfigAttrib(display, config, attrib, value)) {\r
-                       return value[0];\r
-               }\r
-               return defValue;\r
-       }\r
-\r
-       Object synch = new Object();\r
-\r
-       void resume () {\r
-               synchronized (synch) {\r
-                       running = true;\r
-                       resume = true;\r
-               }\r
-       }\r
-\r
-       void pause () {\r
-               synchronized (synch) {\r
-                       running = false;\r
-                       pause = true;\r
-                       while (pause) {\r
-                               try {\r
-                                       synch.wait();\r
-                               } catch (InterruptedException ignored) {\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-\r
-       void destroy () {\r
-               synchronized (synch) {\r
-                       running = false;\r
-                       destroy = true;\r
-\r
-                       while (destroy) {\r
-                               try {\r
-                                       synch.wait();\r
-                               } catch (InterruptedException ex) {\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-\r
-       @Override public void onDrawFrame (javax.microedition.khronos.opengles.GL10 gl) {\r
-               long time = System.nanoTime();\r
-               deltaTime = (time - lastFrameTime) / 1000000000.0f;\r
-               lastFrameTime = time;\r
-               mean.addValue(deltaTime);\r
-\r
-               boolean lrunning = false;\r
-               boolean lpause = false;\r
-               boolean ldestroy = false;\r
-               boolean lresume = false;\r
-\r
-               synchronized (synch) {\r
-                       lrunning = running;\r
-                       lpause = pause;\r
-                       ldestroy = destroy;\r
-                       lresume = resume;\r
-\r
-                       if (resume) {\r
-                               resume = false;\r
-                       }\r
-\r
-                       if (pause) {\r
-                               pause = false;\r
-                               synch.notifyAll();\r
-                       }\r
-\r
-                       if (destroy) {\r
-                               destroy = false;\r
-                               synch.notifyAll();\r
-                       }\r
-               }\r
-\r
-               if (lresume) {\r
-                       app.listener.resume();\r
-                       Gdx.app.log("AndroidGraphics", "resumed");\r
-               }\r
-\r
-               if (lrunning) {\r
-                       app.input.processEvents();\r
-                       app.listener.render();\r
-               }\r
-\r
-               if (lpause) {\r
-                       app.listener.pause();\r
-                       Gdx.app.log("AndroidGraphics", "paused");\r
-               }\r
-\r
-               if (ldestroy) {\r
-                       app.listener.dispose();\r
-                       Gdx.app.log("AndroidGraphics", "destroyed");\r
-               }\r
-\r
-               if (time - frameStart > 1000000000) {\r
-                       fps = frames;\r
-                       frames = 0;\r
-                       frameStart = time;\r
-               }\r
-               frames++;\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public float getDeltaTime () {\r
-               return mean.getMean() == 0 ? deltaTime : mean.getMean();\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public GraphicsType getType () {\r
-               return GraphicsType.AndroidGL;\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public int getFramesPerSecond () {\r
-               return fps;\r
-       }\r
-\r
-       @Override public Texture newUnmanagedTexture (int width, int height, Format format, TextureFilter minFilter,\r
-               TextureFilter magFilter, TextureWrap uWrap, TextureWrap vWrap) {\r
-               if (gl != gl20 && (!MathUtils.isPowerOfTwo(width) || !MathUtils.isPowerOfTwo(height)))\r
-                       throw new GdxRuntimeException("Dimensions have to be a power of two");\r
-\r
-               Bitmap.Config config = AndroidPixmap.getInternalFormat(format);\r
-               Bitmap bitmap = Bitmap.createBitmap(width, height, config);\r
-               Texture texture = null;\r
-               texture = new AndroidTexture(this, bitmap, minFilter, magFilter, uWrap, vWrap, false, null);\r
-               bitmap.recycle();\r
-               return texture;\r
-       }\r
-\r
-       @Override public Texture newUnmanagedTexture (Pixmap pixmap, TextureFilter minFilter, TextureFilter magFilter,\r
-               TextureWrap uWrap, TextureWrap vWrap) {\r
-\r
-               if (gl != gl20 && (!MathUtils.isPowerOfTwo(pixmap.getWidth()) || !MathUtils.isPowerOfTwo(pixmap.getHeight())))\r
-                       throw new GdxRuntimeException("Dimensions have to be a power of two");\r
-\r
-               return new AndroidTexture(this, (Bitmap)pixmap.getNativePixmap(), minFilter, magFilter, uWrap, vWrap, false, null);\r
-       }\r
-\r
-       @Override public Texture newTexture (FileHandle file, TextureFilter minFilter, TextureFilter magFilter, TextureWrap uWrap,\r
-               TextureWrap vWrap) {\r
-               return new AndroidTexture(this, (Bitmap)null, minFilter, magFilter, uWrap, vWrap, true, file);\r
-       }\r
-\r
-       @Override public Texture newTexture (TextureData textureData, TextureFilter minFilter, TextureFilter magFilter,\r
-               TextureWrap uWrap, TextureWrap vWrap) {\r
-               return new AndroidTexture(this, textureData, minFilter, magFilter, uWrap, vWrap);\r
-       }\r
-\r
-       public void clearManagedCaches () {\r
-               Mesh.clearAllMeshes();\r
-               AndroidTexture.clearAllTextures();\r
-               ShaderProgram.clearAllShaderPrograms();\r
-               FrameBuffer.clearAllFrameBuffers();\r
-       }\r
-\r
-       public View getView () {\r
-               return view;\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public GLCommon getGLCommon () {\r
-               return gl;\r
-       }\r
-\r
-       @Override public float getPpiX () {\r
-               return ppiX;\r
-       }\r
-\r
-       @Override public float getPpiY () {\r
-               return ppiY;\r
-       }\r
-\r
-       @Override public float getPpcX () {\r
-               return ppcX;\r
-       }\r
-\r
-       @Override public float getPpcY () {\r
-               return ppcY;\r
-       }\r
+    final View view;\r
+    int width;\r
+    int height;\r
+    AndroidApplication app;\r
+    GLCommon gl;\r
+    GL10 gl10;\r
+    GL11 gl11;\r
+    GL20 gl20;\r
+\r
+    private long lastFrameTime = System.nanoTime();\r
+    private float deltaTime = 0;\r
+    private long frameStart = System.nanoTime();\r
+    private int frames = 0;\r
+    private int fps;\r
+    private WindowedMean mean = new WindowedMean(5);\r
+\r
+    volatile boolean created = false;\r
+    volatile boolean running = false;\r
+    volatile boolean pause = false;\r
+    volatile boolean resume = false;\r
+    volatile boolean destroy = false;\r
+\r
+    private float ppiX = 0;\r
+    private float ppiY = 0;\r
+    private float ppcX = 0;\r
+    private float ppcY = 0;\r
+\r
+    public AndroidGraphics(AndroidApplication activity, boolean useGL2IfAvailable, ResolutionStrategy resolutionStrategy) {\r
+        view = createGLSurfaceView(activity, useGL2IfAvailable, resolutionStrategy);\r
+        this.app = activity;\r
+    }\r
+\r
+    private View createGLSurfaceView(Activity activity, boolean useGL2, ResolutionStrategy resolutionStrategy) {\r
+        EGLConfigChooser configChooser = getEglConfigChooser();\r
+\r
+        if (useGL2 && checkGL20()) {\r
+            GLSurfaceView20 view = new GLSurfaceView20(activity, resolutionStrategy);\r
+            if (configChooser != null) view.setEGLConfigChooser(configChooser);\r
+            view.setRenderer(this);\r
+            return view;\r
+        } else {\r
+            if (Integer.parseInt(android.os.Build.VERSION.SDK) <= 4) {\r
+                GLSurfaceViewCupcake view = new GLSurfaceViewCupcake(activity, resolutionStrategy);\r
+                if (configChooser != null) view.setEGLConfigChooser(configChooser);\r
+                view.setRenderer(this);\r
+                return view;\r
+            } else {\r
+                android.opengl.GLSurfaceView view = new DefaultGLSurfaceView(activity, resolutionStrategy);\r
+                if (configChooser != null) view.setEGLConfigChooser(configChooser);\r
+                view.setRenderer(this);\r
+                return view;\r
+            }\r
+        }\r
+    }\r
+\r
+    private EGLConfigChooser getEglConfigChooser() {\r
+        if (!Build.DEVICE.equalsIgnoreCase("GT-I7500"))\r
+            return null;\r
+        else\r
+            return new android.opengl.GLSurfaceView.EGLConfigChooser() {\r
+\r
+                public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {\r
+\r
+                    // Ensure that we get a 16bit depth-buffer. Otherwise, we'll fall\r
+                    // back to Pixelflinger on some device (read: Samsung I7500)\r
+                    int[] attributes = new int[]{EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE};\r
+                    EGLConfig[] configs = new EGLConfig[1];\r
+                    int[] result = new int[1];\r
+                    egl.eglChooseConfig(display, attributes, configs, 1, result);\r
+                    return configs[0];\r
+                }\r
+            };\r
+    }\r
+\r
+    private void updatePpi() {\r
+        DisplayMetrics metrics = new DisplayMetrics();\r
+        app.getWindowManager().getDefaultDisplay().getMetrics(metrics);\r
+\r
+        ppiX = metrics.xdpi;\r
+        ppiY = metrics.ydpi;\r
+        ppcX = metrics.xdpi / 2.54f;\r
+        ppcY = metrics.ydpi / 2.54f;\r
+    }\r
+\r
+    private boolean checkGL20() {\r
+        EGL10 egl = (EGL10) EGLContext.getEGL();\r
+        EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);\r
+\r
+        int[] version = new int[2];\r
+        egl.eglInitialize(display, version);\r
+\r
+        int EGL_OPENGL_ES2_BIT = 4;\r
+        int[] configAttribs = {EGL10.EGL_RED_SIZE, 4, EGL10.EGL_GREEN_SIZE, 4, EGL10.EGL_BLUE_SIZE, 4, EGL10.EGL_RENDERABLE_TYPE,\r
+                EGL_OPENGL_ES2_BIT, EGL10.EGL_NONE};\r
+\r
+        EGLConfig[] configs = new EGLConfig[10];\r
+        int[] num_config = new int[1];\r
+        egl.eglChooseConfig(display, configAttribs, configs, 10, num_config);\r
+        egl.eglTerminate(display);\r
+        return num_config[0] > 0;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public GL10 getGL10() {\r
+        return gl10;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public GL11 getGL11() {\r
+        return gl11;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public GL20 getGL20() {\r
+        return gl20;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public int getHeight() {\r
+        return height;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public int getWidth() {\r
+        return width;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public boolean isGL11Available() {\r
+        return gl11 != null;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public boolean isGL20Available() {\r
+        return gl20 != null;\r
+    }\r
+\r
+    private static boolean isPowerOfTwo(int value) {\r
+        return ((value != 0) && (value & (value - 1)) == 0);\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public Pixmap newPixmap(int width, int height, Format format) {\r
+        return new AndroidPixmap(width, height, format);\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public Pixmap newPixmap(InputStream in) {\r
+        Bitmap bitmap = BitmapFactory.decodeStream(in);\r
+        if (bitmap == null) throw new GdxRuntimeException("Couldn't load Pixmap from InputStream");\r
+        return new AndroidPixmap(bitmap);\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public Pixmap newPixmap(FileHandle file) {\r
+        return newPixmap(file.read());\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public Pixmap newPixmap(Object nativePixmap) {\r
+        return new AndroidPixmap((Bitmap) nativePixmap);\r
+    }\r
+\r
+    /**\r
+     * This instantiates the GL10, GL11 and GL20 instances. Includes the check for certain devices that pretend to support GL11 but\r
+     * fuck up vertex buffer objects. This includes the pixelflinger which segfaults when buffers are deleted as well as the\r
+     * Motorola CLIQ and the Samsung Behold II.\r
+     *\r
+     * @param gl\r
+     */\r
+    private void setupGL(javax.microedition.khronos.opengles.GL10 gl) {\r
+        if (gl10 != null || gl20 != null) return;\r
+\r
+        if (view instanceof GLSurfaceView20) {\r
+            gl20 = new AndroidGL20();\r
+            this.gl = gl20;\r
+        } else {\r
+            gl10 = new AndroidGL10(gl);\r
+            this.gl = gl10;\r
+            if (gl instanceof javax.microedition.khronos.opengles.GL11) {\r
+                String renderer = gl.glGetString(GL10.GL_RENDERER);\r
+                if (!renderer.toLowerCase().contains("pixelflinger")\r
+                        && !(android.os.Build.MODEL.equals("MB200") || android.os.Build.MODEL.equals("MB220") || android.os.Build.MODEL\r
+                        .contains("Behold"))) {\r
+                    gl11 = new AndroidGL11((javax.microedition.khronos.opengles.GL11) gl);\r
+                    gl10 = gl11;\r
+                }\r
+            }\r
+        }\r
+\r
+        Gdx.gl = this.gl;\r
+        Gdx.gl10 = gl10;\r
+        Gdx.gl11 = gl11;\r
+        Gdx.gl20 = gl20;\r
+\r
+        Gdx.app.log("AndroidGraphics", "OGL renderer: " + gl.glGetString(GL10.GL_RENDERER));\r
+        Gdx.app.log("AndroidGraphics", "OGL vendor: " + gl.glGetString(GL10.GL_VENDOR));\r
+        Gdx.app.log("AndroidGraphics", "OGL version: " + gl.glGetString(GL10.GL_VERSION));\r
+        Gdx.app.log("AndroidGraphics", "OGL extensions: " + gl.glGetString(GL10.GL_EXTENSIONS));\r
+    }\r
+\r
+    @Override\r
+    public void onSurfaceChanged(javax.microedition.khronos.opengles.GL10 gl, int width, int height) {\r
+        this.width = width;\r
+        this.height = height;\r
+        updatePpi();\r
+        app.listener.resize(width, height);\r
+    }\r
+\r
+    @Override\r
+    public void onSurfaceCreated(javax.microedition.khronos.opengles.GL10 gl, EGLConfig config) {\r
+        setupGL(gl);\r
+        logConfig(config);\r
+        updatePpi();\r
+\r
+        Mesh.invalidateAllMeshes();\r
+        AndroidTexture.invalidateAllTextures();\r
+        ShaderProgram.invalidateAllShaderPrograms();\r
+        FrameBuffer.invalidateAllFrameBuffers();\r
+\r
+        Display display = app.getWindowManager().getDefaultDisplay();\r
+        this.width = display.getWidth();\r
+        this.height = display.getHeight();\r
+        mean = new WindowedMean(5);\r
+        this.lastFrameTime = System.nanoTime();\r
+\r
+        gl.glViewport(0, 0, this.width, this.height);\r
+\r
+        if (created == false) {\r
+            app.listener.create();\r
+            created = true;\r
+            synchronized (this) {\r
+                running = true;\r
+            }\r
+        }\r
+    }\r
+\r
+    private void logConfig(EGLConfig config) {\r
+        EGL10 egl = (EGL10) EGLContext.getEGL();\r
+        EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);\r
+        int r = getAttrib(egl, display, config, EGL10.EGL_RED_SIZE, 0);\r
+        int g = getAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE, 0);\r
+        int b = getAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0);\r
+        int a = getAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0);\r
+        int d = getAttrib(egl, display, config, EGL10.EGL_DEPTH_SIZE, 0);\r
+        int s = getAttrib(egl, display, config, EGL10.EGL_STENCIL_SIZE, 0);\r
+\r
+        Gdx.app.log("AndroidGraphics", "framebuffer: (" + r + ", " + g + ", " + b + ", " + a + ")");\r
+        Gdx.app.log("AndroidGraphics", "depthbuffer: (" + d + ")");\r
+        Gdx.app.log("AndroidGraphics", "stencilbuffer: (" + s + ")");\r
+    }\r
+\r
+    int[] value = new int[1];\r
+\r
+    private int getAttrib(EGL10 egl, EGLDisplay display, EGLConfig config, int attrib, int defValue) {\r
+        if (egl.eglGetConfigAttrib(display, config, attrib, value)) {\r
+            return value[0];\r
+        }\r
+        return defValue;\r
+    }\r
+\r
+    Object synch = new Object();\r
+\r
+    void resume() {\r
+        synchronized (synch) {\r
+            running = true;\r
+            resume = true;\r
+        }\r
+    }\r
+\r
+    void pause() {\r
+        synchronized (synch) {\r
+            running = false;\r
+            pause = true;\r
+            while (pause) {\r
+                try {\r
+                    synch.wait();\r
+                } catch (InterruptedException ignored) {\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    void destroy() {\r
+        synchronized (synch) {\r
+            running = false;\r
+            destroy = true;\r
+\r
+            while (destroy) {\r
+                try {\r
+                    synch.wait();\r
+                } catch (InterruptedException ex) {\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void onDrawFrame(javax.microedition.khronos.opengles.GL10 gl) {\r
+        long time = System.nanoTime();\r
+        deltaTime = (time - lastFrameTime) / 1000000000.0f;\r
+        lastFrameTime = time;\r
+        mean.addValue(deltaTime);\r
+\r
+        boolean lrunning = false;\r
+        boolean lpause = false;\r
+        boolean ldestroy = false;\r
+        boolean lresume = false;\r
+\r
+        synchronized (synch) {\r
+            lrunning = running;\r
+            lpause = pause;\r
+            ldestroy = destroy;\r
+            lresume = resume;\r
+\r
+            if (resume) {\r
+                resume = false;\r
+            }\r
+\r
+            if (pause) {\r
+                pause = false;\r
+                synch.notifyAll();\r
+            }\r
+\r
+            if (destroy) {\r
+                destroy = false;\r
+                synch.notifyAll();\r
+            }\r
+        }\r
+\r
+        if (lresume) {\r
+            app.listener.resume();\r
+            Gdx.app.log("AndroidGraphics", "resumed");\r
+        }\r
+\r
+        if (lrunning) {\r
+            app.input.processEvents();\r
+            app.listener.render();\r
+        }\r
+\r
+        if (lpause) {\r
+            app.listener.pause();\r
+            Gdx.app.log("AndroidGraphics", "paused");\r
+        }\r
+\r
+        if (ldestroy) {\r
+            app.listener.dispose();\r
+            Gdx.app.log("AndroidGraphics", "destroyed");\r
+        }\r
+\r
+        if (time - frameStart > 1000000000) {\r
+            fps = frames;\r
+            frames = 0;\r
+            frameStart = time;\r
+        }\r
+        frames++;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public float getDeltaTime() {\r
+        return mean.getMean() == 0 ? deltaTime : mean.getMean();\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public GraphicsType getType() {\r
+        return GraphicsType.AndroidGL;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public int getFramesPerSecond() {\r
+        return fps;\r
+    }\r
+\r
+    @Override\r
+    public Texture newUnmanagedTexture(int width, int height, Format format, TextureFilter minFilter,\r
+                                       TextureFilter magFilter, TextureWrap uWrap, TextureWrap vWrap) {\r
+        if (gl != gl20 && (!MathUtils.isPowerOfTwo(width) || !MathUtils.isPowerOfTwo(height)))\r
+            throw new GdxRuntimeException("Dimensions have to be a power of two");\r
+\r
+        Bitmap.Config config = AndroidPixmap.getInternalFormat(format);\r
+        Bitmap bitmap = Bitmap.createBitmap(width, height, config);\r
+        Texture texture = null;\r
+        texture = new AndroidTexture(this, bitmap, minFilter, magFilter, uWrap, vWrap, false, null);\r
+        bitmap.recycle();\r
+        return texture;\r
+    }\r
+\r
+    @Override\r
+    public Texture newUnmanagedTexture(Pixmap pixmap, TextureFilter minFilter, TextureFilter magFilter,\r
+                                       TextureWrap uWrap, TextureWrap vWrap) {\r
+\r
+        if (gl != gl20 && (!MathUtils.isPowerOfTwo(pixmap.getWidth()) || !MathUtils.isPowerOfTwo(pixmap.getHeight())))\r
+            throw new GdxRuntimeException("Dimensions have to be a power of two");\r
+\r
+        return new AndroidTexture(this, (Bitmap) pixmap.getNativePixmap(), minFilter, magFilter, uWrap, vWrap, false, null);\r
+    }\r
+\r
+    @Override\r
+    public Texture newTexture(FileHandle file, TextureFilter minFilter, TextureFilter magFilter, TextureWrap uWrap,\r
+                              TextureWrap vWrap) {\r
+        return new AndroidTexture(this, (Bitmap) null, minFilter, magFilter, uWrap, vWrap, true, file);\r
+    }\r
+\r
+    @Override\r
+    public Texture newTexture(TextureData textureData, TextureFilter minFilter, TextureFilter magFilter,\r
+                              TextureWrap uWrap, TextureWrap vWrap) {\r
+        return new AndroidTexture(this, textureData, minFilter, magFilter, uWrap, vWrap);\r
+    }\r
+\r
+    public void clearManagedCaches() {\r
+        Mesh.clearAllMeshes();\r
+        AndroidTexture.clearAllTextures();\r
+        ShaderProgram.clearAllShaderPrograms();\r
+        FrameBuffer.clearAllFrameBuffers();\r
+    }\r
+\r
+    public View getView() {\r
+        return view;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public GLCommon getGLCommon() {\r
+        return gl;\r
+    }\r
+\r
+    @Override\r
+    public float getPpiX() {\r
+        return ppiX;\r
+    }\r
+\r
+    @Override\r
+    public float getPpiY() {\r
+        return ppiY;\r
+    }\r
+\r
+    @Override\r
+    public float getPpcX() {\r
+        return ppcX;\r
+    }\r
+\r
+    @Override\r
+    public float getPpcY() {\r
+        return ppcY;\r
+    }\r
 }\r
diff --git a/backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/surfaceview/DefaultGLSurfaceView.java b/backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/surfaceview/DefaultGLSurfaceView.java
new file mode 100644 (file)
index 0000000..973ac72
--- /dev/null
@@ -0,0 +1,27 @@
+package com.badlogic.gdx.backends.android.surfaceview;\r
+\r
+import android.content.Context;\r
+import android.opengl.GLSurfaceView;\r
+import android.util.AttributeSet;\r
+\r
+public class DefaultGLSurfaceView extends GLSurfaceView {\r
+\r
+\r
+    final ResolutionStrategy resolutionStrategy;\r
+\r
+    public DefaultGLSurfaceView(Context context, ResolutionStrategy resolutionStrategy) {\r
+        super(context);\r
+        this.resolutionStrategy = resolutionStrategy;\r
+    }\r
+\r
+    public DefaultGLSurfaceView(Context context, AttributeSet attrs, ResolutionStrategy resolutionStrategy) {\r
+        super(context, attrs);\r
+        this.resolutionStrategy = resolutionStrategy;\r
+    }\r
+\r
+    @Override\r
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {\r
+        ResolutionStrategy.MeasuredDimension measures = resolutionStrategy.calcMeasures(widthMeasureSpec, heightMeasureSpec);\r
+        setMeasuredDimension(measures.width, measures.height);\r
+    }\r
+}\r
diff --git a/backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/surfaceview/FillResolutionStrategy.java b/backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/surfaceview/FillResolutionStrategy.java
new file mode 100644 (file)
index 0000000..e64e56b
--- /dev/null
@@ -0,0 +1,16 @@
+package com.badlogic.gdx.backends.android.surfaceview;\r
+\r
+import android.view.View;\r
+\r
+public class FillResolutionStrategy implements ResolutionStrategy {\r
+\r
+\r
+    @Override\r
+    public MeasuredDimension calcMeasures(int widthMeasureSpec, int heightMeasureSpec) {\r
+\r
+        final int width = View.MeasureSpec.getSize(widthMeasureSpec);\r
+        final int height = View.MeasureSpec.getSize(heightMeasureSpec);\r
+\r
+        return new MeasuredDimension(width, height);\r
+    }\r
+}\r
diff --git a/backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/surfaceview/FixedResolutionStrategy.java b/backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/surfaceview/FixedResolutionStrategy.java
new file mode 100644 (file)
index 0000000..ef0a7a5
--- /dev/null
@@ -0,0 +1,17 @@
+package com.badlogic.gdx.backends.android.surfaceview;\r
+\r
+public class FixedResolutionStrategy implements ResolutionStrategy {\r
+\r
+    private final int width;\r
+    private final int height;\r
+\r
+    public FixedResolutionStrategy(int width, int height) {\r
+        this.width = width;\r
+        this.height = height;\r
+    }\r
+\r
+    @Override\r
+    public MeasuredDimension calcMeasures(int widthMeasureSpec, int heightMeasureSpec) {\r
+        return new MeasuredDimension(width, height);\r
+    }\r
+}\r
index 236de45..0fc1777 100644 (file)
@@ -26,218 +26,230 @@ package com.badlogic.gdx.backends.android.surfaceview;
  * governing permissions and limitations under the License.
  */
 
-import javax.microedition.khronos.egl.EGL10;
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.egl.EGLContext;
-import javax.microedition.khronos.egl.EGLDisplay;
-
 import android.content.Context;
 import android.graphics.PixelFormat;
 import android.opengl.GLSurfaceView;
 import android.util.Log;
 
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+
 /**
  * A simple GLSurfaceView sub-class that demonstrate how to perform OpenGL ES 2.0 rendering into a GL Surface. Note the following
  * important details:
- * 
+ * <p/>
  * - The class must use a custom context factory to enable 2.0 rendering. See ContextFactory class definition below.
- * 
+ * <p/>
  * - The class must use a custom EGLConfigChooser to be able to select an EGLConfig that supports 2.0. This is done by providing a
  * config specification to eglChooseConfig() that has the attribute EGL10.ELG_RENDERABLE_TYPE containing the EGL_OPENGL_ES2_BIT
  * flag set. See ConfigChooser class definition below.
- * 
+ * <p/>
  * - The class must select the surface's format, then choose an EGLConfig that matches it exactly (with regards to
  * red/green/blue/alpha channels bit depths). Failure to do so would result in an EGL_BAD_MATCH error.
  */
 public class GLSurfaceView20 extends GLSurfaceView {
-       static String TAG = "GL2JNIView";
-       private static final boolean DEBUG = false;
-
-       public GLSurfaceView20 (Context context) {
-               super(context);
-               init(false, 16, 0);
-       }
-
-       public GLSurfaceView20 (Context context, boolean translucent, int depth, int stencil) {
-               super(context);
-               init(translucent, depth, stencil);
-       }
-
-       private void init (boolean translucent, int depth, int stencil) {
-
-               /*
-                * By default, GLSurfaceView() creates a RGB_565 opaque surface. If we want a translucent one, we should change the
-                * surface's format here, using PixelFormat.TRANSLUCENT for GL Surfaces is interpreted as any 32-bit surface with alpha by
-                * SurfaceFlinger.
-                */
-               if (translucent) {
-                       this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
-               }
-
-               /*
-                * Setup the context factory for 2.0 rendering. See ContextFactory class definition below
-                */
-               setEGLContextFactory(new ContextFactory());
-
-               /*
-                * We need to choose an EGLConfig that matches the format of our surface exactly. This is going to be done in our custom
-                * config chooser. See ConfigChooser class definition below.
-                */
-               setEGLConfigChooser(translucent ? new ConfigChooser(8, 8, 8, 8, depth, stencil) : new ConfigChooser(5, 6, 5, 0, depth,
-                       stencil));
-
-               /* Set the renderer responsible for frame rendering */
-       }
-
-       static class ContextFactory implements GLSurfaceView.EGLContextFactory {
-               private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
-
-               public EGLContext createContext (EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
-                       Log.w(TAG, "creating OpenGL ES 2.0 context");
-                       checkEglError("Before eglCreateContext", egl);
-                       int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE};
-                       EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
-                       checkEglError("After eglCreateContext", egl);
-                       return context;
-               }
-
-               public void destroyContext (EGL10 egl, EGLDisplay display, EGLContext context) {
-                       egl.eglDestroyContext(display, context);
-               }
-       }
-
-       static void checkEglError (String prompt, EGL10 egl) {
-               int error;
-               while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
-                       Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
-               }
-       }
-
-       private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
-
-               public ConfigChooser (int r, int g, int b, int a, int depth, int stencil) {
-                       mRedSize = r;
-                       mGreenSize = g;
-                       mBlueSize = b;
-                       mAlphaSize = a;
-                       mDepthSize = depth;
-                       mStencilSize = stencil;
-               }
-
-               /*
-                * This EGL config specification is used to specify 2.0 rendering. We use a minimum size of 4 bits for red/green/blue, but
-                * will perform actual matching in chooseConfig() below.
-                */
-               private static int EGL_OPENGL_ES2_BIT = 4;
-               private static int[] s_configAttribs2 = {EGL10.EGL_RED_SIZE, 4, EGL10.EGL_GREEN_SIZE, 4, EGL10.EGL_BLUE_SIZE, 4,
-                       EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL10.EGL_NONE};
-
-               public EGLConfig chooseConfig (EGL10 egl, EGLDisplay display) {
-
-                       /*
-                        * Get the number of minimally matching EGL configurations
-                        */
-                       int[] num_config = new int[1];
-                       egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config);
-
-                       int numConfigs = num_config[0];
-
-                       if (numConfigs <= 0) {
-                               throw new IllegalArgumentException("No configs match configSpec");
-                       }
-
-                       /*
-                        * Allocate then read the array of minimally matching EGL configs
-                        */
-                       EGLConfig[] configs = new EGLConfig[numConfigs];
-                       egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config);
-
-                       if (DEBUG) {
-                               printConfigs(egl, display, configs);
-                       }
-                       /*
-                        * Now return the "best" one
-                        */
-                       return chooseConfig(egl, display, configs);
-               }
-
-               public EGLConfig chooseConfig (EGL10 egl, EGLDisplay display, EGLConfig[] configs) {
-                       for (EGLConfig config : configs) {
-                               int d = findConfigAttrib(egl, display, config, EGL10.EGL_DEPTH_SIZE, 0);
-                               int s = findConfigAttrib(egl, display, config, EGL10.EGL_STENCIL_SIZE, 0);
-
-                               // We need at least mDepthSize and mStencilSize bits
-                               if (d < mDepthSize || s < mStencilSize) continue;
-
-                               // We want an *exact* match for red/green/blue/alpha
-                               int r = findConfigAttrib(egl, display, config, EGL10.EGL_RED_SIZE, 0);
-                               int g = findConfigAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE, 0);
-                               int b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0);
-                               int a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0);
-
-                               if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize) return config;
-                       }
-                       return null;
-               }
-
-               private int findConfigAttrib (EGL10 egl, EGLDisplay display, EGLConfig config, int attribute, int defaultValue) {
-
-                       if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
-                               return mValue[0];
-                       }
-                       return defaultValue;
-               }
-
-               private void printConfigs (EGL10 egl, EGLDisplay display, EGLConfig[] configs) {
-                       int numConfigs = configs.length;
-                       Log.w(TAG, String.format("%d configurations", numConfigs));
-                       for (int i = 0; i < numConfigs; i++) {
-                               Log.w(TAG, String.format("Configuration %d:\n", i));
-                               printConfig(egl, display, configs[i]);
-                       }
-               }
-
-               private void printConfig (EGL10 egl, EGLDisplay display, EGLConfig config) {
-                       int[] attributes = {EGL10.EGL_BUFFER_SIZE, EGL10.EGL_ALPHA_SIZE, EGL10.EGL_BLUE_SIZE, EGL10.EGL_GREEN_SIZE,
-                               EGL10.EGL_RED_SIZE, EGL10.EGL_DEPTH_SIZE, EGL10.EGL_STENCIL_SIZE, EGL10.EGL_CONFIG_CAVEAT, EGL10.EGL_CONFIG_ID,
-                               EGL10.EGL_LEVEL, EGL10.EGL_MAX_PBUFFER_HEIGHT, EGL10.EGL_MAX_PBUFFER_PIXELS, EGL10.EGL_MAX_PBUFFER_WIDTH,
-                               EGL10.EGL_NATIVE_RENDERABLE, EGL10.EGL_NATIVE_VISUAL_ID, EGL10.EGL_NATIVE_VISUAL_TYPE,
-                               0x3030, // EGL10.EGL_PRESERVED_RESOURCES,
-                               EGL10.EGL_SAMPLES, EGL10.EGL_SAMPLE_BUFFERS, EGL10.EGL_SURFACE_TYPE, EGL10.EGL_TRANSPARENT_TYPE,
-                               EGL10.EGL_TRANSPARENT_RED_VALUE, EGL10.EGL_TRANSPARENT_GREEN_VALUE, EGL10.EGL_TRANSPARENT_BLUE_VALUE, 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,
-                               0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,
-                               0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,
-                               0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,
-                               EGL10.EGL_LUMINANCE_SIZE, EGL10.EGL_ALPHA_MASK_SIZE, EGL10.EGL_COLOR_BUFFER_TYPE, EGL10.EGL_RENDERABLE_TYPE, 0x3042 // EGL10.EGL_CONFORMANT
-                       };
-                       String[] names = {"EGL_BUFFER_SIZE", "EGL_ALPHA_SIZE", "EGL_BLUE_SIZE", "EGL_GREEN_SIZE", "EGL_RED_SIZE",
-                               "EGL_DEPTH_SIZE", "EGL_STENCIL_SIZE", "EGL_CONFIG_CAVEAT", "EGL_CONFIG_ID", "EGL_LEVEL", "EGL_MAX_PBUFFER_HEIGHT",
-                               "EGL_MAX_PBUFFER_PIXELS", "EGL_MAX_PBUFFER_WIDTH", "EGL_NATIVE_RENDERABLE", "EGL_NATIVE_VISUAL_ID",
-                               "EGL_NATIVE_VISUAL_TYPE", "EGL_PRESERVED_RESOURCES", "EGL_SAMPLES", "EGL_SAMPLE_BUFFERS", "EGL_SURFACE_TYPE",
-                               "EGL_TRANSPARENT_TYPE", "EGL_TRANSPARENT_RED_VALUE", "EGL_TRANSPARENT_GREEN_VALUE", "EGL_TRANSPARENT_BLUE_VALUE",
-                               "EGL_BIND_TO_TEXTURE_RGB", "EGL_BIND_TO_TEXTURE_RGBA", "EGL_MIN_SWAP_INTERVAL", "EGL_MAX_SWAP_INTERVAL",
-                               "EGL_LUMINANCE_SIZE", "EGL_ALPHA_MASK_SIZE", "EGL_COLOR_BUFFER_TYPE", "EGL_RENDERABLE_TYPE", "EGL_CONFORMANT"};
-                       int[] value = new int[1];
-                       for (int i = 0; i < attributes.length; i++) {
-                               int attribute = attributes[i];
-                               String name = names[i];
-                               if (egl.eglGetConfigAttrib(display, config, attribute, value)) {
-                                       Log.w(TAG, String.format("  %s: %d\n", name, value[0]));
-                               } else {
-                                       // Log.w(TAG, String.format("  %s: failed\n", name));
-                                       while (egl.eglGetError() != EGL10.EGL_SUCCESS)
-                                               ;
-                               }
-                       }
-               }
-
-               // Subclasses can adjust these values:
-               protected int mRedSize;
-               protected int mGreenSize;
-               protected int mBlueSize;
-               protected int mAlphaSize;
-               protected int mDepthSize;
-               protected int mStencilSize;
-               private int[] mValue = new int[1];
-       }
+    static String TAG = "GL2JNIView";
+    private static final boolean DEBUG = false;
+
+    final ResolutionStrategy resolutionStrategy;
+
+    public GLSurfaceView20(Context context, ResolutionStrategy resolutionStrategy) {
+        super(context);
+         this.resolutionStrategy = resolutionStrategy;
+        init(false, 16, 0);
+    }
+
+    public GLSurfaceView20(Context context, boolean translucent, int depth, int stencil, ResolutionStrategy resolutionStrategy) {
+        super(context);
+        this.resolutionStrategy = resolutionStrategy;
+        init(translucent, depth, stencil);
+
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        ResolutionStrategy.MeasuredDimension measures = resolutionStrategy.calcMeasures(widthMeasureSpec, heightMeasureSpec);
+        setMeasuredDimension(measures.width, measures.height);
+    }
+
+    private void init(boolean translucent, int depth, int stencil) {
+
+        /*
+           * By default, GLSurfaceView() creates a RGB_565 opaque surface. If we want a translucent one, we should change the
+           * surface's format here, using PixelFormat.TRANSLUCENT for GL Surfaces is interpreted as any 32-bit surface with alpha by
+           * SurfaceFlinger.
+           */
+        if (translucent) {
+            this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
+        }
+
+        /*
+           * Setup the context factory for 2.0 rendering. See ContextFactory class definition below
+           */
+        setEGLContextFactory(new ContextFactory());
+
+        /*
+           * We need to choose an EGLConfig that matches the format of our surface exactly. This is going to be done in our custom
+           * config chooser. See ConfigChooser class definition below.
+           */
+        setEGLConfigChooser(translucent ? new ConfigChooser(8, 8, 8, 8, depth, stencil) : new ConfigChooser(5, 6, 5, 0, depth,
+                stencil));
+
+        /* Set the renderer responsible for frame rendering */
+    }
+
+
+    static class ContextFactory implements GLSurfaceView.EGLContextFactory {
+        private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+
+        public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
+            Log.w(TAG, "creating OpenGL ES 2.0 context");
+            checkEglError("Before eglCreateContext", egl);
+            int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE};
+            EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
+            checkEglError("After eglCreateContext", egl);
+            return context;
+        }
+
+        public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
+            egl.eglDestroyContext(display, context);
+        }
+    }
+
+    static void checkEglError(String prompt, EGL10 egl) {
+        int error;
+        while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
+            Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
+        }
+    }
+
+    private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
+
+        public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) {
+            mRedSize = r;
+            mGreenSize = g;
+            mBlueSize = b;
+            mAlphaSize = a;
+            mDepthSize = depth;
+            mStencilSize = stencil;
+        }
+
+        /*
+           * This EGL config specification is used to specify 2.0 rendering. We use a minimum size of 4 bits for red/green/blue, but
+           * will perform actual matching in chooseConfig() below.
+           */
+        private static int EGL_OPENGL_ES2_BIT = 4;
+        private static int[] s_configAttribs2 = {EGL10.EGL_RED_SIZE, 4, EGL10.EGL_GREEN_SIZE, 4, EGL10.EGL_BLUE_SIZE, 4,
+                EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL10.EGL_NONE};
+
+        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
+
+            /*
+                * Get the number of minimally matching EGL configurations
+                */
+            int[] num_config = new int[1];
+            egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config);
+
+            int numConfigs = num_config[0];
+
+            if (numConfigs <= 0) {
+                throw new IllegalArgumentException("No configs match configSpec");
+            }
+
+            /*
+                * Allocate then read the array of minimally matching EGL configs
+                */
+            EGLConfig[] configs = new EGLConfig[numConfigs];
+            egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config);
+
+            if (DEBUG) {
+                printConfigs(egl, display, configs);
+            }
+            /*
+                * Now return the "best" one
+                */
+            return chooseConfig(egl, display, configs);
+        }
+
+        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs) {
+            for (EGLConfig config : configs) {
+                int d = findConfigAttrib(egl, display, config, EGL10.EGL_DEPTH_SIZE, 0);
+                int s = findConfigAttrib(egl, display, config, EGL10.EGL_STENCIL_SIZE, 0);
+
+                // We need at least mDepthSize and mStencilSize bits
+                if (d < mDepthSize || s < mStencilSize) continue;
+
+                // We want an *exact* match for red/green/blue/alpha
+                int r = findConfigAttrib(egl, display, config, EGL10.EGL_RED_SIZE, 0);
+                int g = findConfigAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE, 0);
+                int b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0);
+                int a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0);
+
+                if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize) return config;
+            }
+            return null;
+        }
+
+        private int findConfigAttrib(EGL10 egl, EGLDisplay display, EGLConfig config, int attribute, int defaultValue) {
+
+            if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
+                return mValue[0];
+            }
+            return defaultValue;
+        }
+
+        private void printConfigs(EGL10 egl, EGLDisplay display, EGLConfig[] configs) {
+            int numConfigs = configs.length;
+            Log.w(TAG, String.format("%d configurations", numConfigs));
+            for (int i = 0; i < numConfigs; i++) {
+                Log.w(TAG, String.format("Configuration %d:\n", i));
+                printConfig(egl, display, configs[i]);
+            }
+        }
+
+        private void printConfig(EGL10 egl, EGLDisplay display, EGLConfig config) {
+            int[] attributes = {EGL10.EGL_BUFFER_SIZE, EGL10.EGL_ALPHA_SIZE, EGL10.EGL_BLUE_SIZE, EGL10.EGL_GREEN_SIZE,
+                    EGL10.EGL_RED_SIZE, EGL10.EGL_DEPTH_SIZE, EGL10.EGL_STENCIL_SIZE, EGL10.EGL_CONFIG_CAVEAT, EGL10.EGL_CONFIG_ID,
+                    EGL10.EGL_LEVEL, EGL10.EGL_MAX_PBUFFER_HEIGHT, EGL10.EGL_MAX_PBUFFER_PIXELS, EGL10.EGL_MAX_PBUFFER_WIDTH,
+                    EGL10.EGL_NATIVE_RENDERABLE, EGL10.EGL_NATIVE_VISUAL_ID, EGL10.EGL_NATIVE_VISUAL_TYPE,
+                    0x3030, // EGL10.EGL_PRESERVED_RESOURCES,
+                    EGL10.EGL_SAMPLES, EGL10.EGL_SAMPLE_BUFFERS, EGL10.EGL_SURFACE_TYPE, EGL10.EGL_TRANSPARENT_TYPE,
+                    EGL10.EGL_TRANSPARENT_RED_VALUE, EGL10.EGL_TRANSPARENT_GREEN_VALUE, EGL10.EGL_TRANSPARENT_BLUE_VALUE, 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,
+                    0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,
+                    0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,
+                    0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,
+                    EGL10.EGL_LUMINANCE_SIZE, EGL10.EGL_ALPHA_MASK_SIZE, EGL10.EGL_COLOR_BUFFER_TYPE, EGL10.EGL_RENDERABLE_TYPE, 0x3042 // EGL10.EGL_CONFORMANT
+            };
+            String[] names = {"EGL_BUFFER_SIZE", "EGL_ALPHA_SIZE", "EGL_BLUE_SIZE", "EGL_GREEN_SIZE", "EGL_RED_SIZE",
+                    "EGL_DEPTH_SIZE", "EGL_STENCIL_SIZE", "EGL_CONFIG_CAVEAT", "EGL_CONFIG_ID", "EGL_LEVEL", "EGL_MAX_PBUFFER_HEIGHT",
+                    "EGL_MAX_PBUFFER_PIXELS", "EGL_MAX_PBUFFER_WIDTH", "EGL_NATIVE_RENDERABLE", "EGL_NATIVE_VISUAL_ID",
+                    "EGL_NATIVE_VISUAL_TYPE", "EGL_PRESERVED_RESOURCES", "EGL_SAMPLES", "EGL_SAMPLE_BUFFERS", "EGL_SURFACE_TYPE",
+                    "EGL_TRANSPARENT_TYPE", "EGL_TRANSPARENT_RED_VALUE", "EGL_TRANSPARENT_GREEN_VALUE", "EGL_TRANSPARENT_BLUE_VALUE",
+                    "EGL_BIND_TO_TEXTURE_RGB", "EGL_BIND_TO_TEXTURE_RGBA", "EGL_MIN_SWAP_INTERVAL", "EGL_MAX_SWAP_INTERVAL",
+                    "EGL_LUMINANCE_SIZE", "EGL_ALPHA_MASK_SIZE", "EGL_COLOR_BUFFER_TYPE", "EGL_RENDERABLE_TYPE", "EGL_CONFORMANT"};
+            int[] value = new int[1];
+            for (int i = 0; i < attributes.length; i++) {
+                int attribute = attributes[i];
+                String name = names[i];
+                if (egl.eglGetConfigAttrib(display, config, attribute, value)) {
+                    Log.w(TAG, String.format("  %s: %d\n", name, value[0]));
+                } else {
+                    // Log.w(TAG, String.format("  %s: failed\n", name));
+                    while (egl.eglGetError() != EGL10.EGL_SUCCESS)
+                        ;
+                }
+            }
+        }
+
+        // Subclasses can adjust these values:
+        protected int mRedSize;
+        protected int mGreenSize;
+        protected int mBlueSize;
+        protected int mAlphaSize;
+        protected int mDepthSize;
+        protected int mStencilSize;
+        private int[] mValue = new int[1];
+    }
 }
index fda6e95..e9f183b 100644 (file)
@@ -165,22 +165,33 @@ public class GLSurfaceViewCupcake extends SurfaceView implements SurfaceHolder.C
         */\r
        public final static int DEBUG_LOG_GL_CALLS = 2;\r
 \r
+     final ResolutionStrategy resolutionStrategy;\r
+\r
        /**\r
         * Standard View constructor. In order to render something, you must call {@link #setRenderer} to register a renderer.\r
         */\r
-       public GLSurfaceViewCupcake (Context context) {\r
+       public GLSurfaceViewCupcake (Context context, ResolutionStrategy resolutionStrategy) {\r
                super(context);\r
+        this.resolutionStrategy = resolutionStrategy;\r
                init();\r
        }\r
 \r
        /**\r
         * Standard View constructor. In order to render something, you must call {@link #setRenderer} to register a renderer.\r
         */\r
-       public GLSurfaceViewCupcake (Context context, AttributeSet attrs) {\r
+       public GLSurfaceViewCupcake (Context context, AttributeSet attrs, ResolutionStrategy resolutionStrategy) {\r
                super(context, attrs);\r
+         this.resolutionStrategy = resolutionStrategy;\r
                init();\r
        }\r
 \r
+\r
+    @Override\r
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {\r
+        ResolutionStrategy.MeasuredDimension measures = resolutionStrategy.calcMeasures(widthMeasureSpec, heightMeasureSpec);\r
+        setMeasuredDimension(measures.width, measures.height);\r
+    }\r
+\r
        private void init () {\r
                // Install a SurfaceHolder.Callback so we get notified when the\r
                // underlying surface is created and destroyed\r
diff --git a/backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/surfaceview/RatioResolutionStrategy.java b/backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/surfaceview/RatioResolutionStrategy.java
new file mode 100644 (file)
index 0000000..802231a
--- /dev/null
@@ -0,0 +1,38 @@
+package com.badlogic.gdx.backends.android.surfaceview;\r
+\r
+import android.view.View;\r
+\r
+public class RatioResolutionStrategy implements ResolutionStrategy {\r
+\r
+    private final float ratio;\r
+\r
+    public RatioResolutionStrategy(float ratio) {\r
+        this.ratio = ratio;\r
+    }\r
+\r
+    public RatioResolutionStrategy(final float width, final float height) {\r
+        this.ratio = width / height;\r
+    }\r
+\r
+    @Override\r
+    public MeasuredDimension calcMeasures(int widthMeasureSpec, int heightMeasureSpec) {\r
+\r
+        final int specWidth = View.MeasureSpec.getSize(widthMeasureSpec);\r
+        final int specHeight = View.MeasureSpec.getSize(heightMeasureSpec);\r
+\r
+        final float desiredRatio = ratio;\r
+        final float realRatio = (float) specWidth / specHeight;\r
+\r
+        int width;\r
+        int height;\r
+        if (realRatio < desiredRatio) {\r
+            width = specWidth;\r
+            height = Math.round(width / desiredRatio);\r
+        } else {\r
+            height = specHeight;\r
+            width = Math.round(height * desiredRatio);\r
+        }\r
+\r
+        return new MeasuredDimension(width, height);\r
+    }\r
+}\r
diff --git a/backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/surfaceview/ResolutionStrategy.java b/backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/surfaceview/ResolutionStrategy.java
new file mode 100644 (file)
index 0000000..cc67851
--- /dev/null
@@ -0,0 +1,23 @@
+package com.badlogic.gdx.backends.android.surfaceview;\r
+\r
+public interface ResolutionStrategy {\r
+\r
+\r
+    public MeasuredDimension calcMeasures( final int widthMeasureSpec, final int heightMeasureSpec);\r
+\r
+\r
+    public static class MeasuredDimension {\r
+        public final int width;\r
+        public final int height;\r
+\r
+        public MeasuredDimension(int width, int height) {\r
+            this.width = width;\r
+            this.height = height;\r
+        }\r
+\r
+    }\r
+\r
+\r
+\r
+\r
+}\r