Sfoglia il codice sorgente

Android: fixed bug - EGL_SURFACE_TYPE is checked now. Added ConfigType.FASTEST and .BEST to AndroidHarness

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7685 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
kim..ng 14 anni fa
parent
commit
fef0820ca6

+ 20 - 13
engine/src/android/com/jme3/app/AndroidHarness.java

@@ -19,6 +19,7 @@ import com.jme3.input.event.TouchEvent;
 import com.jme3.system.AppSettings;
 import com.jme3.system.JmeSystem;
 import com.jme3.system.android.OGLESContext;
+import com.jme3.system.android.AndroidConfigChooser.ConfigType;
 
 
 /**
@@ -30,14 +31,27 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
 {
     protected final static Logger logger = Logger.getLogger(AndroidHarness.class.getName());
     
-    protected OGLESContext ctx;
-    protected GLSurfaceView view;
-    
+    /**
+     * The application class to start
+     */
     protected String appClass = "jme3test.android.Test";
+    
+    /**
+     * The jme3 application object
+     */
     protected Application app = null;
     
-    protected boolean debug = false;  
-    final private String ESCAPE_EVENT = "TouchEscape";
+    /**
+     * ConfigType.FASTEST is RGB565, GLSurfaceView default
+     * ConfigType.BEST is RGBA8888 or better if supported by the hardware
+     */
+    protected ConfigType eglConfigType = ConfigType.FASTEST;
+    
+          
+    protected OGLESContext ctx;
+    protected GLSurfaceView view;
+    
+    final private String ESCAPE_EVENT = "TouchEscape"; 
 
     @Override
     public void onCreate(Bundle savedInstanceState) 
@@ -65,14 +79,7 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
         app.setSettings(settings);
         app.start();    
         ctx = (OGLESContext) app.getContext();
-        if (debug)
-        {
-            view = ctx.createView(input, GLSurfaceView.DEBUG_CHECK_GL_ERROR | GLSurfaceView.DEBUG_LOG_GL_CALLS);
-        }
-        else
-        {
-            view = ctx.createView(input);
-        }
+        view = ctx.createView(input, eglConfigType);
    		setContentView(view);       		
     }
 

+ 359 - 0
engine/src/android/com/jme3/system/android/AndroidConfigChooser.java

@@ -0,0 +1,359 @@
+package com.jme3.system.android;
+
+import java.util.logging.Logger;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLDisplay;
+
+import android.graphics.PixelFormat;
+import android.opengl.GLSurfaceView.EGLConfigChooser;
+
+/**
+ * AndroidConfigChooser is used to determine the best suited EGL Config
+ * @author larynx
+ *
+ */
+public class AndroidConfigChooser implements EGLConfigChooser 
+{
+    private static final Logger logger = Logger.getLogger(AndroidConfigChooser.class.getName());
+    
+    protected int clientOpenGLESVersion = 0;
+    protected EGLConfig bestConfig = null;
+    protected EGLConfig fastestConfig = null;
+    protected EGLConfig choosenConfig = null;
+    protected ConfigType type;
+    protected int pixelFormat;
+    
+    private final static int EGL_OPENGL_ES2_BIT = 4;
+
+    public enum ConfigType 
+    {
+        /**
+         * RGB565, 0 alpha, 16 depth, 0 stencil
+         */
+        FASTEST,
+        /**
+         * RGB???, 0 alpha, 16 depth, 0 stencil
+         */
+        BEST
+    }
+    
+    public AndroidConfigChooser(ConfigType type)
+    {
+        this.type = type;
+    }
+        
+    /**
+     * Gets called by the GLSurfaceView class to return the best config
+     */    
+    @Override
+    public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display)
+    {
+        return choosenConfig;
+    }
+    
+    /**
+     * findConfig is used to locate the best config and init the chooser with
+     * @param egl
+     * @param display
+     * @return true if successfull, false if no config was found
+     */
+    public boolean findConfig(EGL10 egl, EGLDisplay display)
+    {        
+        //Querying number of configurations
+        int[] num_conf = new int[1];
+        egl.eglGetConfigs(display, null, 0, num_conf);  //if configuration array is null it still returns the number of configurations
+        int configurations = num_conf[0];
+
+        //Querying actual configurations
+        EGLConfig[] conf = new EGLConfig[configurations];
+        egl.eglGetConfigs(display, conf, configurations, num_conf);
+   
+       
+        int[] value = new int[1];        
+    
+        // Loop over all configs to get the best
+        for(int i = 0; i < configurations; i++)
+        {                    
+            if (conf[i] != null)
+            {                
+                egl.eglGetConfigAttrib(display, conf[i], EGL10.EGL_SURFACE_TYPE, value);
+                // check if conf is a valid gl window
+                if ((value[0] & EGL10.EGL_WINDOW_BIT) != 0)
+                {                    
+                    egl.eglGetConfigAttrib(display, conf[i], EGL10.EGL_DEPTH_SIZE, value);
+                    // check if conf has a depth of 16
+                    if (value[0] == 16)
+                    {
+                        egl.eglGetConfigAttrib(display, conf[i], EGL10.EGL_RENDERABLE_TYPE, value);
+                        // Check if conf is OpenGL ES 2.0
+                        if ((value[0] & EGL_OPENGL_ES2_BIT) != 0)
+                        {
+                            clientOpenGLESVersion = 2;  // OpenGL ES 2.0 detected
+                            bestConfig = better(bestConfig, conf[i], egl, display);
+                            fastestConfig = faster(fastestConfig, conf[i], egl, display);
+                            
+                            logger.info("Supported EGL Configuration #" + i );                            
+                            logEGLConfig(conf[i], display, egl);                                               
+                        }
+                    }
+                }
+            }
+            else
+            {
+                break;
+            }
+        }
+    
+        
+        if ((type == ConfigType.BEST) && (bestConfig != null))
+        {
+            logger.info("### JME3 ### using best EGL configuration available here: ");
+            choosenConfig = bestConfig;
+        }
+        else
+        {
+            logger.info("### JME3 ### using fastest EGL configuration available here: ");
+            choosenConfig = fastestConfig;            
+        }
+        
+        if (choosenConfig != null)
+        {
+            logEGLConfig(choosenConfig, display, egl);               
+            pixelFormat = getPixelFormat(choosenConfig, display, egl);
+            clientOpenGLESVersion = getOpenGLVersion(choosenConfig, display, egl);
+            return true;
+        }
+        else
+        {
+            logger.severe("Unable to get a valid OpenGL ES 2.0 config");
+            clientOpenGLESVersion = 1;
+            pixelFormat = PixelFormat.UNKNOWN;
+            return false;
+        }        
+    }
+
+    /**
+     * Returns the best of the two EGLConfig passed according to depth and colours
+     * @param a The first candidate
+     * @param b The second candidate
+     * @return The chosen candidate
+     */
+    private EGLConfig better(EGLConfig a, EGLConfig b, EGL10 egl, EGLDisplay display)
+    {
+        if(a == null) return b;
+    
+        EGLConfig result = null;
+    
+        int[] value = new int[1];
+    
+        // Choose highest color size
+        egl.eglGetConfigAttrib(display, a, EGL10.EGL_RED_SIZE, value);
+        int redA = value[0];
+    
+        egl.eglGetConfigAttrib(display, b, EGL10.EGL_RED_SIZE, value);
+        int redB = value[0];
+    
+        if (redA > redB)
+            result = a;
+        else if (redA < redB)
+            result = b;
+        else // red size is equal
+        {
+            // Choose lowest alpha size
+            egl.eglGetConfigAttrib(display, a, EGL10.EGL_ALPHA_SIZE, value);
+            int alphaA = value[0];
+    
+            egl.eglGetConfigAttrib(display, b, EGL10.EGL_ALPHA_SIZE, value);
+            int alphaB = value[0];
+    
+            if (alphaA < alphaB)
+                result = a;
+            else if (alphaA > alphaB)
+                result = b;
+            else // alpha is equal
+            {
+                // Choose lowest stencil size
+                egl.eglGetConfigAttrib(display, a, EGL10.EGL_STENCIL_SIZE, value);
+                int stencilA = value[0];
+        
+                egl.eglGetConfigAttrib(display, b, EGL10.EGL_STENCIL_SIZE, value);
+                int stencilB = value[0];
+        
+                if (stencilA < stencilB)
+                    result = a;
+                else
+                    result = b;
+            }
+        }
+        return result;
+    }
+    
+    /**
+     * Returns the fastest of the two EGLConfig passed according to depth and colours
+     * @param a The first candidate
+     * @param b The second candidate
+     * @return The chosen candidate
+     */
+    private EGLConfig faster(EGLConfig a, EGLConfig b, EGL10 egl, EGLDisplay display)
+    {
+        if(a == null) return b;
+    
+        EGLConfig result = null;
+    
+        int[] value = new int[1];
+    
+        // Choose highest color size
+        egl.eglGetConfigAttrib(display, a, EGL10.EGL_RED_SIZE, value);
+        int redA = value[0];
+    
+        egl.eglGetConfigAttrib(display, b, EGL10.EGL_RED_SIZE, value);
+        int redB = value[0];
+    
+        if ((redA == 5) && (redB != 5))
+            result = a;
+        else if ((redA != 5) && (redB == 5))
+            result = b;
+        else // red size is equal
+        {
+            // Choose lowest alpha size
+            egl.eglGetConfigAttrib(display, a, EGL10.EGL_ALPHA_SIZE, value);
+            int alphaA = value[0];
+    
+            egl.eglGetConfigAttrib(display, b, EGL10.EGL_ALPHA_SIZE, value);
+            int alphaB = value[0];
+    
+            if (alphaA < alphaB)
+                result = a;
+            else if (alphaA > alphaB)
+                result = b;
+            else // alpha is equal
+            {
+                // Choose lowest stencil size
+                egl.eglGetConfigAttrib(display, a, EGL10.EGL_STENCIL_SIZE, value);
+                int stencilA = value[0];
+        
+                egl.eglGetConfigAttrib(display, b, EGL10.EGL_STENCIL_SIZE, value);
+                int stencilB = value[0];
+        
+                if (stencilA < stencilB)
+                    result = a;
+                else
+                    result = b;
+            }
+        }
+        return result;
+    }
+    
+    private int getPixelFormat(EGLConfig conf, EGLDisplay display, EGL10 egl)
+    {
+        int[] value = new int[1];
+        int result = PixelFormat.RGB_565;
+
+        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RED_SIZE, value);
+        if (value[0] == 8)
+        {
+            egl.eglGetConfigAttrib(display, conf, EGL10.EGL_ALPHA_SIZE, value);
+            if (value[0] == 8)
+            {
+                result = PixelFormat.RGBA_8888;
+            }
+            else
+            {
+                result = PixelFormat.RGB_888;
+            }
+        }
+        return result;                    
+    }
+    
+    private int getOpenGLVersion(EGLConfig conf, EGLDisplay display, EGL10 egl)
+    {
+        int[] value = new int[1];
+        int result = 1;
+                        
+        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RENDERABLE_TYPE, value);
+        // Check if conf is OpenGL ES 2.0
+        if ((value[0] & EGL_OPENGL_ES2_BIT) != 0)
+        {
+            result = 2;
+        }
+
+        return result;                    
+    }
+    
+    /**
+     * log output with egl config details
+     * @param conf
+     * @param display
+     * @param egl
+     */
+    private void logEGLConfig(EGLConfig conf, EGLDisplay display, EGL10 egl)
+    {
+        int[] value = new int[1];
+
+        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RED_SIZE, value);
+        logger.info(String.format("EGL_RED_SIZE  = %d", value[0] ) );
+        
+        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_GREEN_SIZE, value);
+        logger.info(String.format("EGL_GREEN_SIZE  = %d", value[0] ) );
+        
+        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_BLUE_SIZE, value);
+        logger.info(String.format("EGL_BLUE_SIZE  = %d", value[0] ) );
+        
+        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_ALPHA_SIZE, value);
+        logger.info(String.format("EGL_ALPHA_SIZE  = %d", value[0] ) );
+        
+        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_DEPTH_SIZE, value);
+        logger.info(String.format("EGL_DEPTH_SIZE  = %d", value[0] ) );
+                
+        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_STENCIL_SIZE, value);
+        logger.info(String.format("EGL_STENCIL_SIZE  = %d", value[0] ) );
+
+        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RENDERABLE_TYPE, value);
+        logger.info(String.format("EGL_RENDERABLE_TYPE  = %d", value[0] ) );
+        
+        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SURFACE_TYPE, value);
+        logger.info(String.format("EGL_SURFACE_TYPE  = %d", value[0] ) );               
+    }
+    
+
+    
+    
+    // Getter - Setter
+    
+    public EGLConfig getBestConfig() 
+    {
+        return bestConfig;
+    }
+
+    public void setBestConfig(EGLConfig bestConfig) 
+    {
+        this.bestConfig = bestConfig;
+    }
+    public EGLConfig getFastestConfig() 
+    {
+        return fastestConfig;
+    }
+
+    public void setFastestConfig(EGLConfig fastestConfig) 
+    {
+        this.fastestConfig = fastestConfig;
+    }
+        
+    public int getClientOpenGLESVersion() 
+    {
+        return clientOpenGLESVersion;
+    }
+
+    public void setClientOpenGLESVersion(int clientOpenGLESVersion) 
+    {
+        this.clientOpenGLESVersion = clientOpenGLESVersion;
+    }
+    
+    public int getPixelFormat() 
+    {
+        return pixelFormat;
+    }
+    
+}

+ 20 - 158
engine/src/android/com/jme3/system/android/OGLESContext.java

@@ -34,8 +34,10 @@ package com.jme3.system.android;
 
 import android.app.Activity;
 import android.content.Context;
+import android.graphics.PixelFormat;
 import android.opengl.GLES20;
 import android.opengl.GLSurfaceView;
+import android.opengl.GLSurfaceView.EGLConfigChooser;
 import android.view.SurfaceHolder;
 
 import com.jme3.app.AndroidHarness;
@@ -53,6 +55,8 @@ import com.jme3.system.AppSettings;
 import com.jme3.system.JmeContext;
 import com.jme3.system.SystemListener;
 import com.jme3.system.Timer;
+import com.jme3.system.android.AndroidConfigChooser.ConfigType;
+
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.logging.Logger;
 
@@ -63,7 +67,7 @@ import javax.microedition.khronos.egl.EGLDisplay;
 import javax.microedition.khronos.opengles.GL10;
 
 
-public class OGLESContext implements JmeContext, GLSurfaceView.Renderer 
+public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
 {
 
     private static final Logger logger = Logger.getLogger(OGLESContext.class.getName());
@@ -123,7 +127,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
      */
     public GLSurfaceView createView(AndroidInput view)
     {
-        return createView(view, 0);
+        return createView(view, ConfigType.FASTEST);
     }
     
     /**
@@ -132,7 +136,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
      * @param debugflags 0, GLSurfaceView.DEBUG_CHECK_GL_ERROR | GLSurfaceView.DEBUG_LOG_GL_CALLS
      * @return GLSurfaceView The newly created view
      */    
-    public GLSurfaceView createView(AndroidInput view, int debugflags)
+    public GLSurfaceView createView(AndroidInput view, ConfigType configType)
     {                    
         EGL10 egl = (EGL10) EGLContext.getEGL();
         EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
@@ -143,179 +147,37 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
             logger.info("Display EGL Version: " + version[0] + "." + version[1]);
         }
         
-        //Querying number of configurations
-        int[] num_conf = new int[1];
-        egl.eglGetConfigs(display, null, 0, num_conf);  //if configuration array is null it still returns the number of configurations
-        int configurations = num_conf[0];
-
-        //Querying actual configurations
-        EGLConfig[] conf = new EGLConfig[configurations];
-        egl.eglGetConfigs(display, conf, configurations, num_conf);
-
-        EGLConfig bestConfig = null;
-        int[] value = new int[1];
-        int EGL_OPENGL_ES2_BIT = 4;
+        // Start to set up the view
+        this.view = view;    
 
-        // Loop over all configs to get the best
-        for(int i = 0; i < configurations; i++)
+        // Create a config chooser
+        AndroidConfigChooser configChooser = new AndroidConfigChooser(configType);
+        // Init chooser
+        if (!configChooser.findConfig(egl, display))
         {
-            //logger.info("Supported EGL Configuration #" + i );
-        
-            if (conf[i] != null)
-            {
-                //logger.info(String.format("conf[%d] = %s", i, conf[i].toString() ) );
-                //logEGLConfig(conf[i], display, egl);     
-                egl.eglGetConfigAttrib(display, conf[i], EGL10.EGL_RENDERABLE_TYPE, value);
-                if ((value[0] & EGL_OPENGL_ES2_BIT) != 0)
-                {
-                    clientOpenGLESVersion = 2;  // OpenGL ES 2.0 detected
-                    bestConfig = better(bestConfig, conf[i], egl, display);
-                }                                
-            }
-            else
-            {
-                break;
-            }
+            logger.severe("Unable to find suitable EGL config");
         }
-        
+                
+        clientOpenGLESVersion = configChooser.getClientOpenGLESVersion();
         if (clientOpenGLESVersion < 2)
         {
             logger.severe("OpenGL ES 2.0 is not supported on this device");
         }                
-        // Finished querying the configs
         
-        
-        // Start to set up the view
-        this.view = view;    
-
         /*
          * Requesting client version from GLSurfaceView which is extended by
          * AndroidInput.        
          */     
-        view.setEGLContextClientVersion(clientOpenGLESVersion);               
-
-        if (bestConfig != null)
-        {
-            logger.info("JME3 using best EGL configuration available here: ");        
-            logEGLConfig(bestConfig, display, egl);
-
-            // Choose best config        
-            egl.eglGetConfigAttrib(display, bestConfig, EGL10.EGL_RED_SIZE, value);
-            int redSize = value[0];
-            
-            egl.eglGetConfigAttrib(display, bestConfig, EGL10.EGL_GREEN_SIZE, value);
-            int greenSize = value[0];
-            
-            egl.eglGetConfigAttrib(display, bestConfig, EGL10.EGL_BLUE_SIZE, value);
-            int blueSize = value[0];
-    
-            egl.eglGetConfigAttrib(display, bestConfig, EGL10.EGL_ALPHA_SIZE, value);
-            int alphaSize = value[0];
-            
-            egl.eglGetConfigAttrib(display, bestConfig, EGL10.EGL_DEPTH_SIZE, value);
-            int depthSize = value[0];
-                    
-            egl.eglGetConfigAttrib(display, bestConfig, EGL10.EGL_STENCIL_SIZE, value);
-            int stencilSize = value[0];
-            
-            view.setEGLConfigChooser(redSize, greenSize, blueSize, alphaSize, depthSize, stencilSize);
-        }
-        else
-        {
-            //RGB565, Depth16            
-            logger.info("JME3 best EGL configuration not found using default: RGB565, Depth16, Alpha0, Stencil0");
-            view.setEGLConfigChooser(5, 6, 5, 0, 16, 0);
-        }
-    
+        view.setEGLContextClientVersion(clientOpenGLESVersion);
+        view.setEGLConfigChooser(configChooser);
         view.setFocusableInTouchMode(true);
         view.setFocusable(true);
+        view.setZOrderOnTop(true);
         view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
-//        view.setDebugFlags(GLSurfaceView.DEBUG_CHECK_GL_ERROR);
-//                         | GLSurfaceView.DEBUG_LOG_GL_CALLS);
+        view.getHolder().setFormat(configChooser.getPixelFormat());
         view.setRenderer(this);
         return view;
-
     }
-        
-    /**
-     * Returns the best of the two EGLConfig passed according to depth and colours
-     * @param a The first candidate
-     * @param b The second candidate
-     * @return The chosen candidate
-     */
-    private EGLConfig better(EGLConfig a, EGLConfig b, EGL10 egl, EGLDisplay display)
-    {
-        if(a == null) return b;
-    
-        EGLConfig result = null;
-    
-        int[] value = new int[1];
-    
-        egl.eglGetConfigAttrib(display, a, EGL10.EGL_DEPTH_SIZE, value);
-        int depthA = value[0];
-    
-        egl.eglGetConfigAttrib(display, b, EGL10.EGL_DEPTH_SIZE, value);
-        int depthB = value[0];
-    
-        if(depthA > depthB)
-            result = a;
-        else if(depthA < depthB)
-            result = b;
-        else //if depthA == depthB
-        {
-            egl.eglGetConfigAttrib(display, a, EGL10.EGL_RED_SIZE, value);
-            int redA = value[0];
-    
-            egl.eglGetConfigAttrib(display, b, EGL10.EGL_RED_SIZE, value);
-            int redB = value[0];
-    
-            if(redA > redB)
-                result = a;
-            else if(redA < redB)
-                result = b;
-            else //if redA == redB
-            {
-                // Don't care
-                result = a;
-            }
-        }
-        return result;
-    }
-
-    /**
-     * log output with egl config details
-     * @param conf
-     * @param display
-     * @param egl
-     */
-    private void logEGLConfig(EGLConfig conf, EGLDisplay display, EGL10 egl)
-    {
-        int[] value = new int[1];
-
-        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RED_SIZE, value);
-        logger.info(String.format("EGL_RED_SIZE  = %d", value[0] ) );
-        
-        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_BLUE_SIZE, value);
-        logger.info(String.format("EGL_BLUE_SIZE  = %d", value[0] ) );
-
-        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_GREEN_SIZE, value);
-        logger.info(String.format("EGL_GREEN_SIZE  = %d", value[0] ) );
-        
-        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_ALPHA_SIZE, value);
-        logger.info(String.format("EGL_ALPHA_SIZE  = %d", value[0] ) );
-        
-        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_DEPTH_SIZE, value);
-        logger.info(String.format("EGL_DEPTH_SIZE  = %d", value[0] ) );
-                
-        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_STENCIL_SIZE, value);
-        logger.info(String.format("EGL_STENCIL_SIZE  = %d", value[0] ) );
-
-        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RENDERABLE_TYPE, value);
-        logger.info(String.format("EGL_RENDERABLE_TYPE  = %d", value[0] ) );
-
-        
-    }
-    
     
 
     protected void initInThread()