Android: Added proper OpenGL ES version detection and a best EGL Config Chooser
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7594 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
8cbb0f210d
commit
5461d56ac6
@ -1,20 +0,0 @@
|
|||||||
/* AUTO-GENERATED FILE. DO NOT MODIFY.
|
|
||||||
*
|
|
||||||
* This class was automatically generated by the
|
|
||||||
* aapt tool from the resource data it found. It
|
|
||||||
* should not be modified by hand.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.jme3;
|
|
||||||
|
|
||||||
public final class R {
|
|
||||||
public static final class attr {
|
|
||||||
}
|
|
||||||
public static final class layout {
|
|
||||||
public static final int main=0x7f020000;
|
|
||||||
}
|
|
||||||
public static final class string {
|
|
||||||
public static final int app_name=0x7f030000;
|
|
||||||
public static final int jme3_appclass=0x7f030001;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -136,7 +136,7 @@ public class AndroidHarness extends Activity implements DialogInterface.OnClickL
|
|||||||
|
|
||||||
final String sTrace = s;
|
final String sTrace = s;
|
||||||
|
|
||||||
logger.severe(t != null ? t.toString() : "Failed");
|
logger.severe(t != null ? t.toString() : "OpenGL Exception");
|
||||||
logger.severe((errorMsg != null ? errorMsg + ": " : "") + sTrace);
|
logger.severe((errorMsg != null ? errorMsg + ": " : "") + sTrace);
|
||||||
|
|
||||||
this.runOnUiThread(new Runnable() {
|
this.runOnUiThread(new Runnable() {
|
||||||
@ -145,7 +145,7 @@ public class AndroidHarness extends Activity implements DialogInterface.OnClickL
|
|||||||
{
|
{
|
||||||
AlertDialog dialog = new AlertDialog.Builder(AndroidHarness.this)
|
AlertDialog dialog = new AlertDialog.Builder(AndroidHarness.this)
|
||||||
// .setIcon(R.drawable.alert_dialog_icon)
|
// .setIcon(R.drawable.alert_dialog_icon)
|
||||||
.setTitle(t != null ? t.toString() : "Failed")
|
.setTitle(t != null ? (t.getMessage() != null ? (t.getMessage() + ": " + t.getClass().getName()) : t.getClass().getName()) : "OpenGL Exception")
|
||||||
.setPositiveButton("Kill", AndroidHarness.this)
|
.setPositiveButton("Kill", AndroidHarness.this)
|
||||||
.setMessage((errorMsg != null ? errorMsg + ": " : "") + sTrace)
|
.setMessage((errorMsg != null ? errorMsg + ": " : "") + sTrace)
|
||||||
.create();
|
.create();
|
||||||
|
|||||||
@ -266,10 +266,10 @@ public abstract class AndroidApplication extends Application implements DialogIn
|
|||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
AlertDialog dialog = new AlertDialog.Builder(activity)
|
AlertDialog dialog = new AlertDialog.Builder(activity)
|
||||||
// .setIcon(R.drawable.alert_dialog_icon)
|
// .setIcon(R.drawable.alert_dialog_icon)
|
||||||
.setTitle(t != null ? t.toString() : "Failed")
|
.setTitle(t != null ? (t.getMessage() != null ? (t.getMessage() + ": " + t.getClass().getName()) : t.getClass().getName()) : "Exception")
|
||||||
.setPositiveButton("Kill", AndroidApplication.this)
|
.setPositiveButton("Kill", AndroidApplication.this)
|
||||||
.setMessage((errorMsg != null ? errorMsg + ": " : "") + sTrace)
|
.setMessage((errorMsg != null ? errorMsg + ": " : "") + sTrace)
|
||||||
.create();
|
.create();
|
||||||
|
|||||||
@ -34,6 +34,7 @@ package com.jme3.system.android;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.opengl.GLES20;
|
||||||
import android.opengl.GLSurfaceView;
|
import android.opengl.GLSurfaceView;
|
||||||
import android.view.SurfaceHolder;
|
import android.view.SurfaceHolder;
|
||||||
|
|
||||||
@ -52,7 +53,11 @@ import com.jme3.system.SystemListener;
|
|||||||
import com.jme3.system.Timer;
|
import com.jme3.system.Timer;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.microedition.khronos.egl.EGL10;
|
||||||
import javax.microedition.khronos.egl.EGLConfig;
|
import javax.microedition.khronos.egl.EGLConfig;
|
||||||
|
import javax.microedition.khronos.egl.EGLContext;
|
||||||
|
import javax.microedition.khronos.egl.EGLDisplay;
|
||||||
import javax.microedition.khronos.opengles.GL10;
|
import javax.microedition.khronos.opengles.GL10;
|
||||||
|
|
||||||
|
|
||||||
@ -84,7 +89,12 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
|
|||||||
protected int frameRate = 33;
|
protected int frameRate = 33;
|
||||||
//protected int minFrameDuration = 1000 / frameRate; // Set a max FPS of 33
|
//protected int minFrameDuration = 1000 / frameRate; // Set a max FPS of 33
|
||||||
protected int minFrameDuration = 0; // No FPS cap
|
protected int minFrameDuration = 0; // No FPS cap
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EGL_RENDERABLE_TYPE: EGL_OPENGL_ES_BIT = OpenGL ES 1.0 | EGL_OPENGL_ES2_BIT = OpenGL ES 2.0
|
||||||
|
*/
|
||||||
|
protected int clientOpenGLESVersion = 1;
|
||||||
|
|
||||||
public OGLESContext() { }
|
public OGLESContext() { }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -104,7 +114,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
|
|||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>createView</code>
|
* <code>createView</code>
|
||||||
* @param AndroidInput The Android input which must be bound to an activity
|
* @param view The Android input which will be used as the GLSurfaceView for this context
|
||||||
* @return GLSurfaceView The newly created view
|
* @return GLSurfaceView The newly created view
|
||||||
*/
|
*/
|
||||||
public GLSurfaceView createView(AndroidInput view)
|
public GLSurfaceView createView(AndroidInput view)
|
||||||
@ -114,30 +124,190 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>createView</code>
|
* <code>createView</code>
|
||||||
* @param AndroidInput The Android input which must be bound to an activity
|
* @param view The Android input which will be used as the GLSurfaceView for this context
|
||||||
* @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, int debugflags)
|
||||||
{
|
{
|
||||||
|
EGL10 egl = (EGL10) EGLContext.getEGL();
|
||||||
|
EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
|
||||||
|
|
||||||
|
int[] version = new int[2];
|
||||||
|
if (egl.eglInitialize(display, version) == true)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
// Loop over all configs to get the best
|
||||||
|
for(int i = 0; i < configurations; i++)
|
||||||
|
{
|
||||||
|
//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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clientOpenGLESVersion < 2)
|
||||||
|
{
|
||||||
|
logger.severe("OpenGL ES 2.0 is not supported on this device");
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("JME3 using best EGL configuration available here: ");
|
||||||
|
logEGLConfig(bestConfig, display, egl);
|
||||||
|
|
||||||
|
// Finished querying the configs
|
||||||
|
|
||||||
|
|
||||||
|
// Start to set up the view
|
||||||
this.view = view;
|
this.view = view;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Requesting client version from GLSurfaceView which is extended by
|
* Requesting client version from GLSurfaceView which is extended by
|
||||||
* AndroidInput.
|
* AndroidInput.
|
||||||
* This is required to get OpenGL ES 2.0
|
*/
|
||||||
*/
|
view.setEGLContextClientVersion(clientOpenGLESVersion);
|
||||||
view.setEGLContextClientVersion(2);
|
|
||||||
|
|
||||||
//RGB565, Depth16
|
//RGB565, Depth16
|
||||||
view.setEGLConfigChooser(5, 6, 5, 0, 16, 0);
|
//view.setEGLConfigChooser(5, 6, 5, 0, 16, 0);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
view.setFocusableInTouchMode(true);
|
view.setFocusableInTouchMode(true);
|
||||||
view.setFocusable(true);
|
view.setFocusable(true);
|
||||||
view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
|
view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
|
||||||
view.setDebugFlags(debugflags);
|
// view.setDebugFlags(GLSurfaceView.DEBUG_CHECK_GL_ERROR);
|
||||||
view.setRenderer(this);
|
// | GLSurfaceView.DEBUG_LOG_GL_CALLS);
|
||||||
|
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()
|
||||||
@ -152,7 +322,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
|
|||||||
{
|
{
|
||||||
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
||||||
public void uncaughtException(Thread thread, Throwable thrown) {
|
public void uncaughtException(Thread thread, Throwable thrown) {
|
||||||
((AndroidHarness)ctx).handleError("Uncaught exception thrown in "+thread.toString(), thrown);
|
((AndroidHarness)ctx).handleError("Exception thrown in " + thread.toString(), thrown);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -160,11 +330,16 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
|
|||||||
{
|
{
|
||||||
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
||||||
public void uncaughtException(Thread thread, Throwable thrown) {
|
public void uncaughtException(Thread thread, Throwable thrown) {
|
||||||
listener.handleError("Uncaught exception thrown in "+thread.toString(), thrown);
|
listener.handleError("Exception thrown in " + thread.toString(), thrown);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clientOpenGLESVersion < 2)
|
||||||
|
{
|
||||||
|
throw new UnsupportedOperationException("OpenGL ES 2.0 is not supported on this device");
|
||||||
|
}
|
||||||
|
|
||||||
timer = new AndroidTimer();
|
timer = new AndroidTimer();
|
||||||
|
|
||||||
renderer = new OGLESShaderRenderer();
|
renderer = new OGLESShaderRenderer();
|
||||||
@ -278,6 +453,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
|
|||||||
@Override
|
@Override
|
||||||
public void onSurfaceCreated(GL10 gl, EGLConfig cfg)
|
public void onSurfaceCreated(GL10 gl, EGLConfig cfg)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (created.get() && renderer != null)
|
if (created.get() && renderer != null)
|
||||||
{
|
{
|
||||||
renderer.resetGLObjects();
|
renderer.resetGLObjects();
|
||||||
@ -394,5 +570,9 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getClientOpenGLESVersion()
|
||||||
|
{
|
||||||
|
return clientOpenGLESVersion;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import android.opengl.GLSurfaceView;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import com.jme3.R;
|
|
||||||
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;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user