From 2711e729d0fce368b68bd778a36e48775b383f32 Mon Sep 17 00:00:00 2001 From: "iwg..ic" Date: Thu, 19 Sep 2013 21:25:38 +0000 Subject: [PATCH] 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 --- .../system/android/AndroidConfigChooser.java | 52 ++++----- .../com/jme3/system/android/OGLESContext.java | 101 ++++++------------ 2 files changed, 60 insertions(+), 93 deletions(-) diff --git a/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java b/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java index 202af4458..4c9de7a8c 100644 --- a/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java +++ b/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java @@ -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)) { @@ -100,18 +103,23 @@ public class AndroidConfigChooser implements EGLConfigChooser { } return value[0]; } - + /** * Gets called by the GLSurfaceView class to return the best config */ @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; } - logger.fine("GLSurfaceView asks for egl config, returning: "); - logEGLConfig(choosenConfig, display, egl, Level.FINE); - return choosenConfig; } /** @@ -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() { diff --git a/engine/src/android/com/jme3/system/android/OGLESContext.java b/engine/src/android/com/jme3/system/android/OGLESContext.java index 8e6961b69..aab8561fe 100644 --- a/engine/src/android/com/jme3/system/android/OGLESContext.java +++ b/engine/src/android/com/jme3/system/android/OGLESContext.java @@ -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 { @@ -93,7 +94,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex public Type getType() { return Type.Display; } - + /** * createView creates the GLSurfaceView that the renderer will * draw to.

The result GLSurfaceView will receive input events and @@ -106,27 +107,27 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex * ConfigType.BEST * @param eglConfigVerboseLogging if true show all found configs * @return GLSurfaceView The newly created view - * @deprecated AndroidGLSurfaceView createView() + * @deprecated AndroidGLSurfaceView createView() * and put the configType in the appSettigs with the key AndroidConfigChoose.SETTINGS_CONFIG_TYPE */ @Deprecated public AndroidGLSurfaceView createView(ConfigType configType, boolean eglConfigVerboseLogging) { settings.put(AndroidConfigChooser.SETTINGS_CONFIG_TYPE, configType); - return this.createView(); + return this.createView(); } /** * createView creates the GLSurfaceView that the renderer will * draw to.

The result GLSurfaceView will receive input events and * forward them to the Application. Any rendering will be done into the * GLSurfaceView. Only one GLSurfaceView can be created at this time. The - * given configType specifies how to determine the display configuration. + * given configType specifies how to determine the display configuration. + * * - * * @param eglConfigVerboseLogging if true show all found configs * @return GLSurfaceView The newly created view */ public AndroidGLSurfaceView createView() { - AndroidGLSurfaceView view; + AndroidGLSurfaceView view; ConfigType configType = (ConfigType)settings.get(AndroidConfigChooser.SETTINGS_CONFIG_TYPE); // Start to set up the view @@ -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. - view.setEGLContextClientVersion(clientOpenGLESVersion); - view.setEGLConfigChooser(configChooser); - view.getHolder().setFormat(configChooser.getPixelFormat()); - } finally { - if (display != null && display != EGL10.EGL_NO_DISPLAY) { - egl.eglTerminate(display); - } - } + clientOpenGLESVersion = 2; + view.setEGLContextClientVersion(clientOpenGLESVersion); } 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});