Android: Modify EGLConfigChooser to evaluate available configs when asked by the surface. More to come to clean up this area. Addresses issue: http://hub.jmonkeyengine.org/forum/topic/crash-nexus-10-android-4-3/
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10798 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
5a1e7dbd63
commit
2711e729d0
@ -1,8 +1,8 @@
|
||||
package com.jme3.system.android;
|
||||
|
||||
import android.graphics.PixelFormat;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.opengl.GLSurfaceView.EGLConfigChooser;
|
||||
import com.jme3.renderer.RendererException;
|
||||
import com.jme3.renderer.android.RendererUtil;
|
||||
import com.jme3.system.AppSettings;
|
||||
import java.util.logging.Level;
|
||||
@ -20,12 +20,10 @@ public class AndroidConfigChooser implements EGLConfigChooser {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(AndroidConfigChooser.class.getName());
|
||||
public final static String SETTINGS_CONFIG_TYPE = "configType";
|
||||
protected int clientOpenGLESVersion = 0;
|
||||
protected EGLConfig bestConfig = null;
|
||||
protected EGLConfig fastestConfig = null;
|
||||
protected EGLConfig choosenConfig = null;
|
||||
protected EGLDisplay configForDisplay = null;
|
||||
protected AppSettings settings;
|
||||
protected GLSurfaceView view;
|
||||
protected int pixelFormat;
|
||||
protected boolean verbose = false;
|
||||
private final static int EGL_OPENGL_ES2_BIT = 4;
|
||||
@ -92,6 +90,11 @@ public class AndroidConfigChooser implements EGLConfigChooser {
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public AndroidConfigChooser(AppSettings settings, GLSurfaceView view) {
|
||||
this(settings);
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
private static int eglGetConfigAttribSafe(EGL10 egl, EGLDisplay display, EGLConfig config, int attribute) {
|
||||
int[] value = new int[1];
|
||||
if (!egl.eglGetConfigAttrib(display, config, attribute, value)) {
|
||||
@ -106,12 +109,17 @@ public class AndroidConfigChooser implements EGLConfigChooser {
|
||||
*/
|
||||
@Override
|
||||
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
|
||||
if (configForDisplay != display) {
|
||||
throw new RendererException("The display used for finding config is not the same as the render display");
|
||||
}
|
||||
logger.fine("GLSurfaceView asking for egl config");
|
||||
boolean configFound = findConfig(egl, display);
|
||||
if (configFound) {
|
||||
logger.fine("GLSurfaceView asks for egl config, returning: ");
|
||||
logEGLConfig(choosenConfig, display, egl, Level.FINE);
|
||||
view.getHolder().setFormat(pixelFormat);
|
||||
return choosenConfig;
|
||||
} else {
|
||||
logger.fine("GLSurfaceView asks for egl config, No config found");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,7 +129,7 @@ public class AndroidConfigChooser implements EGLConfigChooser {
|
||||
* @param display
|
||||
* @return true if successfull, false if no config was found
|
||||
*/
|
||||
public boolean findConfig(EGL10 egl, EGLDisplay display) {
|
||||
private boolean findConfig(EGL10 egl, EGLDisplay display) {
|
||||
ConfigType type = (ConfigType) settings.get(SETTINGS_CONFIG_TYPE);
|
||||
|
||||
ComponentSizeChooser compChooser = new ComponentSizeChooser(type, settings.getSamples());
|
||||
@ -134,11 +142,12 @@ public class AndroidConfigChooser implements EGLConfigChooser {
|
||||
logger.info("JME3 using choosen config: ");
|
||||
logEGLConfig(choosenConfig, display, egl, Level.INFO);
|
||||
pixelFormat = getPixelFormat(choosenConfig, display, egl);
|
||||
clientOpenGLESVersion = getOpenGLVersion(choosenConfig, display, egl);
|
||||
if (pixelFormat == PixelFormat.TRANSLUCENT) {
|
||||
view.setZOrderOnTop(true);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
logger.severe("ERROR: Unable to get a valid OpenGL ES 2.0 config, neither Fastest nor Best found! Bug. Please report this.");
|
||||
clientOpenGLESVersion = 1;
|
||||
pixelFormat = PixelFormat.UNKNOWN;
|
||||
return false;
|
||||
}
|
||||
@ -152,12 +161,15 @@ public class AndroidConfigChooser implements EGLConfigChooser {
|
||||
int result = eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_ALPHA_SIZE);
|
||||
|
||||
if (result >= 8) {
|
||||
logger.log(Level.FINE, "Pixel Format: TRANSLUCENT");
|
||||
return PixelFormat.TRANSLUCENT;
|
||||
}
|
||||
if (result >= 1) {
|
||||
logger.log(Level.FINE, "Pixel Format: TRANSPARENT");
|
||||
return PixelFormat.TRANSPARENT;
|
||||
}
|
||||
|
||||
logger.log(Level.FINE, "Pixel Format: OPAQUE");
|
||||
return PixelFormat.OPAQUE;
|
||||
}
|
||||
|
||||
@ -178,7 +190,7 @@ public class AndroidConfigChooser implements EGLConfigChooser {
|
||||
* @param display
|
||||
* @param egl
|
||||
*/
|
||||
public void logEGLConfig(EGLConfig conf, EGLDisplay display, EGL10 egl, Level level) {
|
||||
private void logEGLConfig(EGLConfig conf, EGLDisplay display, EGL10 egl, Level level) {
|
||||
|
||||
logger.log(level, "EGL_RED_SIZE = {0}",
|
||||
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_RED_SIZE));
|
||||
@ -211,18 +223,6 @@ public class AndroidConfigChooser implements EGLConfigChooser {
|
||||
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_SAMPLES));
|
||||
}
|
||||
|
||||
public int getClientOpenGLESVersion() {
|
||||
return clientOpenGLESVersion;
|
||||
}
|
||||
|
||||
public void setClientOpenGLESVersion(int clientOpenGLESVersion) {
|
||||
this.clientOpenGLESVersion = clientOpenGLESVersion;
|
||||
}
|
||||
|
||||
public int getPixelFormat() {
|
||||
return pixelFormat;
|
||||
}
|
||||
|
||||
private abstract class BaseConfigChooser implements EGLConfigChooser {
|
||||
|
||||
public BaseConfigChooser() {
|
||||
|
@ -32,11 +32,14 @@
|
||||
package com.jme3.system.android;
|
||||
|
||||
import android.app.Activity;
|
||||
import com.jme3.renderer.android.AndroidGLSurfaceView;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.pm.ConfigurationInfo;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
@ -48,6 +51,7 @@ import com.jme3.input.android.AndroidSensorJoyInput;
|
||||
import com.jme3.input.controls.SoftTextDialogInputListener;
|
||||
import com.jme3.input.dummy.DummyKeyInput;
|
||||
import com.jme3.input.dummy.DummyMouseInput;
|
||||
import com.jme3.renderer.android.AndroidGLSurfaceView;
|
||||
import com.jme3.renderer.RendererException;
|
||||
import com.jme3.renderer.android.OGLESShaderRenderer;
|
||||
import com.jme3.renderer.android.RendererUtil;
|
||||
@ -56,10 +60,7 @@ import com.jme3.system.android.AndroidConfigChooser.ConfigType;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
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 javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTextDialogInput {
|
||||
@ -137,65 +138,39 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
|
||||
androidInput.setView(view);
|
||||
androidInput.loadSettings(settings);
|
||||
|
||||
if (configType == ConfigType.LEGACY) {
|
||||
// Hardcoded egl setup
|
||||
clientOpenGLESVersion = 2;
|
||||
view.setEGLContextClientVersion(2);
|
||||
// RGB565, Depth16
|
||||
view.setEGLConfigChooser(5, 6, 5, 0, 16, 0);
|
||||
logger.fine("ConfigType.LEGACY using RGB565");
|
||||
int rawOpenGLESVersion = getOpenGLESVersion();
|
||||
logger.log(Level.FINE, "clientOpenGLESVersion {0}.{1}",
|
||||
new Object[]{clientOpenGLESVersion>>16, clientOpenGLESVersion<<16});
|
||||
if (rawOpenGLESVersion < 0x20000) {
|
||||
throw new UnsupportedOperationException("OpenGL ES 2.0 is not supported on this device");
|
||||
} else {
|
||||
EGL10 egl = (EGL10) EGLContext.getEGL();
|
||||
EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
|
||||
if (display == EGL10.EGL_NO_DISPLAY) {
|
||||
throw new RendererException("No default EGL display is available");
|
||||
}
|
||||
|
||||
int[] version = new int[2];
|
||||
if (!egl.eglInitialize(display, version)) {
|
||||
RendererUtil.checkEGLError(egl);
|
||||
}
|
||||
|
||||
logger.log(Level.INFO, "Display EGL Version: {0}.{1}", new Object[]{version[0], version[1]});
|
||||
|
||||
try {
|
||||
// Create a config chooser
|
||||
AndroidConfigChooser configChooser = new AndroidConfigChooser(settings);
|
||||
// Init chooser
|
||||
if (!configChooser.findConfig(egl, display)) {
|
||||
listener.handleError("Unable to find suitable EGL config", null);
|
||||
return null;
|
||||
}
|
||||
|
||||
clientOpenGLESVersion = configChooser.getClientOpenGLESVersion();
|
||||
if (clientOpenGLESVersion < 2) {
|
||||
listener.handleError("OpenGL ES 2.0 is not supported on this device", null);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Requesting client version from GLSurfaceView which is extended by
|
||||
// AndroidInput.
|
||||
clientOpenGLESVersion = 2;
|
||||
view.setEGLContextClientVersion(clientOpenGLESVersion);
|
||||
view.setEGLConfigChooser(configChooser);
|
||||
view.getHolder().setFormat(configChooser.getPixelFormat());
|
||||
} finally {
|
||||
if (display != null && display != EGL10.EGL_NO_DISPLAY) {
|
||||
egl.eglTerminate(display);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
view.setFocusableInTouchMode(true);
|
||||
view.setFocusable(true);
|
||||
view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
|
||||
if (configType == ConfigType.BEST_TRANSLUCENT) {
|
||||
//This is important to allow the GL surface to have a translucent background
|
||||
view.setZOrderOnTop(true);
|
||||
}
|
||||
|
||||
AndroidConfigChooser configChooser = new AndroidConfigChooser(settings, view);
|
||||
view.setEGLConfigChooser(configChooser);
|
||||
|
||||
view.setRenderer(this);
|
||||
|
||||
return view;
|
||||
}
|
||||
/**
|
||||
* Get the OpenGL ES version
|
||||
* @return version returns the int value of the GLES version
|
||||
*/
|
||||
public int getOpenGLESVersion() {
|
||||
ActivityManager am =
|
||||
(ActivityManager) JmeAndroidSystem.getActivity().getApplication().getSystemService(Context.ACTIVITY_SERVICE);
|
||||
ConfigurationInfo info = am.getDeviceConfigurationInfo();
|
||||
logger.log(Level.FINE, "OpenGL Version {0}:", info.getGlEsVersion());
|
||||
return info.reqGlEsVersion;
|
||||
// return (info.reqGlEsVersion >= 0x20000);
|
||||
}
|
||||
|
||||
// renderer:initialize
|
||||
@Override
|
||||
@ -225,10 +200,6 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
|
||||
}
|
||||
});
|
||||
|
||||
if (clientOpenGLESVersion < 2) {
|
||||
throw new UnsupportedOperationException("OpenGL ES 2.0 is not supported on this device");
|
||||
}
|
||||
|
||||
timer = new AndroidTimer();
|
||||
renderer = new OGLESShaderRenderer();
|
||||
|
||||
@ -412,10 +383,6 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
|
||||
}
|
||||
}
|
||||
|
||||
public int getClientOpenGLESVersion() {
|
||||
return clientOpenGLESVersion;
|
||||
}
|
||||
|
||||
public void requestDialog(final int id, final String title, final String initialValue, final SoftTextDialogInputListener listener) {
|
||||
logger.log(Level.FINE, "requestDialog: title: {0}, initialValue: {1}",
|
||||
new Object[]{title, initialValue});
|
||||
|
Loading…
x
Reference in New Issue
Block a user