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
3.0
kim..ng 14 years ago
parent 697a02e7c5
commit fef0820ca6
  1. 31
      engine/src/android/com/jme3/app/AndroidHarness.java
  2. 359
      engine/src/android/com/jme3/system/android/AndroidConfigChooser.java
  3. 172
      engine/src/android/com/jme3/system/android/OGLESContext.java

@ -19,6 +19,7 @@ import com.jme3.input.event.TouchEvent;
import com.jme3.system.AppSettings; import com.jme3.system.AppSettings;
import com.jme3.system.JmeSystem; import com.jme3.system.JmeSystem;
import com.jme3.system.android.OGLESContext; import com.jme3.system.android.OGLESContext;
import com.jme3.system.android.AndroidConfigChooser.ConfigType;
/** /**
@ -30,13 +31,26 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
{ {
protected final static Logger logger = Logger.getLogger(AndroidHarness.class.getName()); 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"; protected String appClass = "jme3test.android.Test";
/**
* The jme3 application object
*/
protected Application app = null; protected Application app = null;
protected boolean debug = false; /**
* 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"; final private String ESCAPE_EVENT = "TouchEscape";
@Override @Override
@ -65,14 +79,7 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
app.setSettings(settings); app.setSettings(settings);
app.start(); app.start();
ctx = (OGLESContext) app.getContext(); ctx = (OGLESContext) app.getContext();
if (debug) view = ctx.createView(input, eglConfigType);
{
view = ctx.createView(input, GLSurfaceView.DEBUG_CHECK_GL_ERROR | GLSurfaceView.DEBUG_LOG_GL_CALLS);
}
else
{
view = ctx.createView(input);
}
setContentView(view); setContentView(view);
} }

@ -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;
}
}

@ -34,8 +34,10 @@ package com.jme3.system.android;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.graphics.PixelFormat;
import android.opengl.GLES20; import android.opengl.GLES20;
import android.opengl.GLSurfaceView; import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.EGLConfigChooser;
import android.view.SurfaceHolder; import android.view.SurfaceHolder;
import com.jme3.app.AndroidHarness; import com.jme3.app.AndroidHarness;
@ -53,6 +55,8 @@ import com.jme3.system.AppSettings;
import com.jme3.system.JmeContext; import com.jme3.system.JmeContext;
import com.jme3.system.SystemListener; import com.jme3.system.SystemListener;
import com.jme3.system.Timer; import com.jme3.system.Timer;
import com.jme3.system.android.AndroidConfigChooser.ConfigType;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -123,7 +127,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
*/ */
public GLSurfaceView createView(AndroidInput view) 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 * @param debugflags 0, GLSurfaceView.DEBUG_CHECK_GL_ERROR | GLSurfaceView.DEBUG_LOG_GL_CALLS
* @return GLSurfaceView The newly created view * @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(); EGL10 egl = (EGL10) EGLContext.getEGL();
EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
@ -143,180 +147,38 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
logger.info("Display EGL Version: " + version[0] + "." + version[1]); logger.info("Display EGL Version: " + version[0] + "." + version[1]);
} }
//Querying number of configurations // Start to set up the view
int[] num_conf = new int[1]; this.view = view;
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;
// Loop over all configs to get the best // Create a config chooser
for(int i = 0; i < configurations; i++) AndroidConfigChooser configChooser = new AndroidConfigChooser(configType);
// Init chooser
if (!configChooser.findConfig(egl, display))
{ {
//logger.info("Supported EGL Configuration #" + i ); logger.severe("Unable to find suitable EGL config");
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;
}
} }
clientOpenGLESVersion = configChooser.getClientOpenGLESVersion();
if (clientOpenGLESVersion < 2) if (clientOpenGLESVersion < 2)
{ {
logger.severe("OpenGL ES 2.0 is not supported on this device"); 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 * Requesting client version from GLSurfaceView which is extended by
* AndroidInput. * AndroidInput.
*/ */
view.setEGLContextClientVersion(clientOpenGLESVersion); view.setEGLContextClientVersion(clientOpenGLESVersion);
view.setEGLConfigChooser(configChooser);
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.setFocusableInTouchMode(true); view.setFocusableInTouchMode(true);
view.setFocusable(true); view.setFocusable(true);
view.setZOrderOnTop(true);
view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU); view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
// view.setDebugFlags(GLSurfaceView.DEBUG_CHECK_GL_ERROR); view.getHolder().setFormat(configChooser.getPixelFormat());
// | GLSurfaceView.DEBUG_LOG_GL_CALLS);
view.setRenderer(this); view.setRenderer(this);
return view; 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() protected void initInThread()
{ {

Loading…
Cancel
Save