Android: Rewrite of EGL config chooser. ConfigType is also now deprecated so that egl* protected parameters in AndroidHarness can be used. These new parameters are copied into AppSettings and then used in AndroidConfigChooser to define the minimum requirements for selecting an appropriate egl config. If a different config is choosen, the AppSettings are updated so users can detect the currently used values.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10810 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
experimental
iwg..ic 11 years ago
parent c1c9fc871a
commit 592303181e
  1. 82
      engine/src/android/com/jme3/app/AndroidHarness.java
  2. 421
      engine/src/android/com/jme3/system/android/AndroidConfigChooser.java
  3. 58
      engine/src/android/com/jme3/system/android/OGLESContext.java

@ -24,7 +24,6 @@ import com.jme3.input.event.TouchEvent;
import com.jme3.renderer.android.AndroidGLSurfaceView; import com.jme3.renderer.android.AndroidGLSurfaceView;
import com.jme3.system.AppSettings; import com.jme3.system.AppSettings;
import com.jme3.system.SystemListener; import com.jme3.system.SystemListener;
import com.jme3.system.android.AndroidConfigChooser;
import com.jme3.system.android.AndroidConfigChooser.ConfigType; import com.jme3.system.android.AndroidConfigChooser.ConfigType;
import com.jme3.system.android.JmeAndroidSystem; import com.jme3.system.android.JmeAndroidSystem;
import com.jme3.system.android.OGLESContext; import com.jme3.system.android.OGLESContext;
@ -58,8 +57,51 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
/** /**
* ConfigType.FASTEST is RGB565, GLSurfaceView default ConfigType.BEST is * ConfigType.FASTEST is RGB565, GLSurfaceView default ConfigType.BEST is
* RGBA8888 or better if supported by the hardware * RGBA8888 or better if supported by the hardware
* @deprecated ConfigType has been deprecated. AppSettings are now used
* to determine the desired configuration to match how LWJGL is implemented.
* Use eglBitsPerPixel, eglAlphaBits, eglDepthBits, eglStencilBits in MainActivity to
* override the default values
* (default values: RGB888, 0 alpha bits, 16 bit depth, 0 stencil bits)
*/ */
protected ConfigType eglConfigType = ConfigType.FASTEST; @Deprecated
protected ConfigType eglConfigType = null;
/**
* Sets the desired RGB size for the surfaceview. 16 = RGB565, 24 = RGB888.
* (default = 24)
*/
protected int eglBitsPerPixel = 24;
/**
* Sets the desired number of Alpha bits for the surfaceview. This affects
* how the surfaceview is able to display Android views that are located
* under the surfaceview jME uses to render the scenegraph.
* 0 = Opaque surfaceview background (fastest)
* 1->7 = Transparent surfaceview background
* 8 or higher = Translucent surfaceview background
* (default = 0)
*/
protected int eglAlphaBits = 0;
/**
* The number of depth bits specifies the precision of the depth buffer.
* (default = 16)
*/
protected int eglDepthBits = 16;
/**
* Sets the number of samples to use for multisampling.</br>
* Leave 0 (default) to disable multisampling.</br>
* Set to 2 or 4 to enable multisampling.
*/
protected int eglSamples = 0;
/**
* Set the number of stencil bits.
* (default = 0)
*/
protected int eglStencilBits = 0;
/** /**
* If true all valid and not valid egl configs are logged * If true all valid and not valid egl configs are logged
* @deprecated this has no use * @deprecated this has no use
@ -69,7 +111,9 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
/** /**
* set to 2, 4 to enable multisampling. * set to 2, 4 to enable multisampling.
* @deprecated Use eglSamples
*/ */
@Deprecated
protected int antiAliasingSamples = 0; protected int antiAliasingSamples = 0;
/** /**
@ -210,9 +254,41 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
settings.setEmulateMouse(mouseEventsEnabled); settings.setEmulateMouse(mouseEventsEnabled);
settings.setEmulateMouseFlipAxis(mouseEventsInvertX, mouseEventsInvertY); settings.setEmulateMouseFlipAxis(mouseEventsInvertX, mouseEventsInvertY);
settings.setUseJoysticks(joystickEventsEnabled); settings.setUseJoysticks(joystickEventsEnabled);
if (eglConfigType == null) {
logger.log(Level.FINE, "using new appsettings for eglConfig");
settings.setBitsPerPixel(eglBitsPerPixel);
settings.setAlphaBits(eglAlphaBits);
settings.setDepthBits(eglDepthBits);
settings.setSamples(eglSamples);
settings.setStencilBits(eglStencilBits);
} else {
logger.log(Level.FINE, "using old eglConfigType {0} for eglConfig", eglConfigType);
switch (eglConfigType) {
case BEST:
settings.setBitsPerPixel(24);
settings.setAlphaBits(0);
settings.setDepthBits(16);
settings.setStencilBits(0);
break;
case FASTEST:
case LEGACY:
settings.setBitsPerPixel(16);
settings.setAlphaBits(0);
settings.setDepthBits(16);
settings.setStencilBits(0);
break;
case BEST_TRANSLUCENT:
settings.setBitsPerPixel(24);
settings.setAlphaBits(8);
settings.setDepthBits(16);
settings.setStencilBits(0);
break;
default:
throw new IllegalArgumentException("Invalid eglConfigType");
}
settings.setSamples(antiAliasingSamples); settings.setSamples(antiAliasingSamples);
}
settings.setResolution(disp.getWidth(), disp.getHeight()); settings.setResolution(disp.getWidth(), disp.getHeight());
settings.put(AndroidConfigChooser.SETTINGS_CONFIG_TYPE, eglConfigType);
settings.setAudioRenderer(audioRendererType); settings.setAudioRenderer(audioRendererType);

@ -1,7 +1,5 @@
package com.jme3.system.android; package com.jme3.system.android;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.EGLConfigChooser; import android.opengl.GLSurfaceView.EGLConfigChooser;
import com.jme3.renderer.android.RendererUtil; import com.jme3.renderer.android.RendererUtil;
import com.jme3.system.AppSettings; import com.jme3.system.AppSettings;
@ -14,20 +12,16 @@ import javax.microedition.khronos.egl.EGLDisplay;
/** /**
* AndroidConfigChooser is used to determine the best suited EGL Config * AndroidConfigChooser is used to determine the best suited EGL Config
* *
* @author larynx * @author iwgeric
*/ */
public class AndroidConfigChooser implements EGLConfigChooser { public class AndroidConfigChooser implements EGLConfigChooser {
private static final Logger logger = Logger.getLogger(AndroidConfigChooser.class.getName()); private static final Logger logger = Logger.getLogger(AndroidConfigChooser.class.getName());
public final static String SETTINGS_CONFIG_TYPE = "configType";
protected EGLConfig choosenConfig = null;
protected EGLDisplay configForDisplay = null;
protected AppSettings settings; protected AppSettings settings;
protected GLSurfaceView view;
protected int pixelFormat;
protected boolean verbose = false;
private final static int EGL_OPENGL_ES2_BIT = 4; private final static int EGL_OPENGL_ES2_BIT = 4;
@Deprecated
public enum ConfigType { public enum ConfigType {
/** /**
@ -75,161 +69,123 @@ public class AndroidConfigChooser implements EGLConfigChooser {
} }
} }
/**
*
* @param type
* @deprecated use AndroidConfigChooser(AppSettings settings)
*/
@Deprecated
public AndroidConfigChooser(ConfigType type) {
this.settings = new AppSettings(true);
settings.put(SETTINGS_CONFIG_TYPE, type);
}
public AndroidConfigChooser(AppSettings settings) { public AndroidConfigChooser(AppSettings settings) {
this.settings = settings; 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)) {
RendererUtil.checkEGLError(egl);
throw new AssertionError();
}
return value[0];
}
/** /**
* Gets called by the GLSurfaceView class to return the best config * Gets called by the GLSurfaceView class to return the best config
*/ */
@Override @Override
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
logger.fine("GLSurfaceView asking for egl config"); logger.fine("GLSurfaceView asking for egl config");
boolean configFound = findConfig(egl, display); Config requestedConfig = getRequestedConfig();
if (configFound) { EGLConfig[] configs = getConfigs(egl, display);
logger.fine("GLSurfaceView asks for egl config, returning: ");
logEGLConfig(choosenConfig, display, egl, Level.FINE); // First try to find an exact match, but allowing a higher stencil
view.getHolder().setFormat(pixelFormat); EGLConfig choosenConfig = chooseConfig(egl, display, configs, requestedConfig, false, false, false, true);
return choosenConfig; if (choosenConfig == null && requestedConfig.d > 16) {
} else { logger.log(Level.INFO, "EGL configuration not found, reducing depth");
logger.fine("GLSurfaceView asks for egl config, No config found"); requestedConfig.d = 16;
return null; choosenConfig = chooseConfig(egl, display, configs, requestedConfig, false, false, false, true);
} }
if (choosenConfig == null) {
logger.log(Level.INFO, "EGL configuration not found, allowing higher RGB");
choosenConfig = chooseConfig(egl, display, configs, requestedConfig, true, false, false, true);
} }
/** if (choosenConfig == null && requestedConfig.a > 0) {
* findConfig is used to locate the best config and init the chooser with logger.log(Level.INFO, "EGL configuration not found, allowing higher alpha");
* choosenConfig = chooseConfig(egl, display, configs, requestedConfig, true, true, false, true);
* @param egl }
* @param display
* @return true if successfull, false if no config was found
*/
private boolean findConfig(EGL10 egl, EGLDisplay display) {
ConfigType type = (ConfigType) settings.get(SETTINGS_CONFIG_TYPE);
ComponentSizeChooser compChooser = new ComponentSizeChooser(type, settings.getSamples()); if (choosenConfig == null && requestedConfig.s > 0) {
choosenConfig = compChooser.chooseConfig(egl, display); logger.log(Level.INFO, "EGL configuration not found, allowing higher samples");
logger.log(Level.FINE, "JME3 using {0} EGL configuration available here: ", type.name()); choosenConfig = chooseConfig(egl, display, configs, requestedConfig, true, true, true, true);
}
if (choosenConfig != null) { if (choosenConfig == null && requestedConfig.a > 0) {
// Remember the display for which we have the EGLConfig for logger.log(Level.INFO, "EGL configuration not found, reducing alpha");
configForDisplay = display; requestedConfig.a = 1;
logger.info("JME3 using choosen config: "); choosenConfig = chooseConfig(egl, display, configs, requestedConfig, true, true, false, true);
logEGLConfig(choosenConfig, display, egl, Level.INFO); }
pixelFormat = getPixelFormat(choosenConfig, display, egl);
if (pixelFormat == PixelFormat.TRANSLUCENT) { if (choosenConfig == null && requestedConfig.s > 0) {
view.setZOrderOnTop(true); logger.log(Level.INFO, "EGL configuration not found, reducing samples");
} requestedConfig.s = 1;
return true; if (requestedConfig.a > 0) {
choosenConfig = chooseConfig(egl, display, configs, requestedConfig, true, true, true, true);
} else { } else {
logger.severe("ERROR: Unable to get a valid OpenGL ES 2.0 config, neither Fastest nor Best found! Bug. Please report this."); choosenConfig = chooseConfig(egl, display, configs, requestedConfig, true, false, true, true);
pixelFormat = PixelFormat.UNKNOWN;
return false;
} }
} }
private int getPixelFormat(EGLConfig conf, EGLDisplay display, EGL10 egl) { if (choosenConfig == null && requestedConfig.getBitsPerPixel() > 16) {
//Android Pixel format is not very well documented. logger.log(Level.INFO, "EGL configuration not found, setting to RGB565");
//From what i gathered, the format is chosen automatically except for the alpha channel requestedConfig.r = 5;
//if the alpha channel has 8 bit or more, e set the pixel format to Transluscent, as it allow transparent view background requestedConfig.g = 6;
//if it's 0 bit, the format is OPAQUE otherwise it's TRANSPARENT requestedConfig.b = 5;
int result = eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_ALPHA_SIZE); choosenConfig = chooseConfig(egl, display, configs, requestedConfig, true, false, false, true);
if (result >= 8) { if (choosenConfig == null) {
logger.log(Level.FINE, "Pixel Format: TRANSLUCENT"); logger.log(Level.INFO, "EGL configuration not found, allowing higher alpha");
return PixelFormat.TRANSLUCENT; choosenConfig = chooseConfig(egl, display, configs, requestedConfig, true, true, false, true);
} }
if (result >= 1) {
logger.log(Level.FINE, "Pixel Format: TRANSPARENT");
return PixelFormat.TRANSPARENT;
} }
logger.log(Level.FINE, "Pixel Format: OPAQUE"); if (choosenConfig == null) {
return PixelFormat.OPAQUE; logger.log(Level.INFO, "EGL configuration not found, looking for best config with >= 16 bit Depth");
//failsafe, should pick best config with at least 16 depth
requestedConfig = new Config(0, 0, 0, 0, 16, 0, 0);
choosenConfig = chooseConfig(egl, display, configs, requestedConfig, true, false, false, true);
} }
private int getOpenGLVersion(EGLConfig conf, EGLDisplay display, EGL10 egl) { if (choosenConfig != null) {
int val = eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_RENDERABLE_TYPE); logger.fine("GLSurfaceView asks for egl config, returning: ");
// Check if conf is OpenGL ES 2.0 logEGLConfig(choosenConfig, display, egl, Level.FINE);
if ((val & EGL_OPENGL_ES2_BIT) != 0) {
return 2; storeSelectedConfig(egl, display, choosenConfig);
return choosenConfig;
} else { } else {
return 1; logger.severe("No EGL Config found");
return null;
} }
} }
private Config getRequestedConfig() {
int r, g, b;
if (settings.getBitsPerPixel() == 24) {
r = g = b = 8;
} else {
if (settings.getBitsPerPixel() != 16) {
logger.log(Level.SEVERE, "Invalid bitsPerPixel setting: {0}, setting to RGB565 (16)", settings.getBitsPerPixel());
settings.setBitsPerPixel(16);
}
r = 5;
g = 6;
b = 5;
}
logger.log(Level.FINE, "Requested Display Config:");
logger.log(Level.FINE, "RGB: {0}, alpha: {1}, depth: {2}, samples: {3}, stencil: {4}",
new Object[]{settings.getBitsPerPixel(),
settings.getAlphaBits(), settings.getDepthBits(),
settings.getSamples(), settings.getStencilBits()});
return new Config(
r, g, b,
settings.getAlphaBits(),
settings.getDepthBits(),
settings.getSamples(),
settings.getStencilBits());
}
/** /**
* log output with egl config details * Query egl for the available configs
*
* @param conf
* @param display
* @param egl * @param egl
* @param display
* @return
*/ */
private void logEGLConfig(EGLConfig conf, EGLDisplay display, EGL10 egl, Level level) { private EGLConfig[] getConfigs(EGL10 egl, EGLDisplay display) {
logger.log(level, "EGL_RED_SIZE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_RED_SIZE));
logger.log(level, "EGL_GREEN_SIZE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_GREEN_SIZE));
logger.log(level, "EGL_BLUE_SIZE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_BLUE_SIZE));
logger.log(level, "EGL_ALPHA_SIZE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_ALPHA_SIZE));
logger.log(level, "EGL_DEPTH_SIZE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_DEPTH_SIZE));
logger.log(level, "EGL_STENCIL_SIZE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_STENCIL_SIZE));
logger.log(level, "EGL_RENDERABLE_TYPE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_RENDERABLE_TYPE));
logger.log(level, "EGL_SURFACE_TYPE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_SURFACE_TYPE));
logger.log(level, "EGL_SAMPLE_BUFFERS = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_SAMPLE_BUFFERS));
logger.log(level, "EGL_SAMPLES = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_SAMPLES));
}
private abstract class BaseConfigChooser implements EGLConfigChooser {
public BaseConfigChooser() {
}
@Override
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
int[] num_config = new int[1]; int[] num_config = new int[1];
int[] configSpec = new int[]{ int[] configSpec = new int[]{
@ -254,34 +210,22 @@ public class AndroidConfigChooser implements EGLConfigChooser {
logger.fine("----------------------------------------"); logger.fine("----------------------------------------");
} }
EGLConfig config = chooseConfig(egl, display, configs); return configs;
return config;
}
abstract EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
EGLConfig[] configs);
}
/**
* Choose a configuration with exactly the specified r,g,b,a sizes, and at
* least the specified depth and stencil sizes.
*/
private class ComponentSizeChooser extends BaseConfigChooser {
private ConfigType configType;
protected int mSamples;
public ComponentSizeChooser(ConfigType configType, int samples) {
mSamples = samples;
this.configType = configType;
} }
@Override private EGLConfig chooseConfig(
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs) { EGL10 egl, EGLDisplay display, EGLConfig[] configs, Config requestedConfig,
boolean higherRGB, boolean higherAlpha,
boolean higherSamples, boolean higherStencil) {
EGLConfig keptConfig = null; EGLConfig keptConfig = null;
int kr = 0;
int kg = 0;
int kb = 0;
int ka = 0;
int kd = 0; int kd = 0;
int knbMs = 0; int ks = 0;
int kst = 0;
// first pass through config list. Try to find an exact match. // first pass through config list. Try to find an exact match.
@ -297,87 +241,144 @@ public class AndroidConfigChooser implements EGLConfigChooser {
int d = eglGetConfigAttribSafe(egl, display, config, int d = eglGetConfigAttribSafe(egl, display, config,
EGL10.EGL_DEPTH_SIZE); EGL10.EGL_DEPTH_SIZE);
int s = eglGetConfigAttribSafe(egl, display, config, int s = eglGetConfigAttribSafe(egl, display, config,
EGL10.EGL_STENCIL_SIZE);
int isMs = eglGetConfigAttribSafe(egl, display, config,
EGL10.EGL_SAMPLE_BUFFERS);
int nbMs = eglGetConfigAttribSafe(egl, display, config,
EGL10.EGL_SAMPLES); EGL10.EGL_SAMPLES);
int st = eglGetConfigAttribSafe(egl, display, config,
EGL10.EGL_STENCIL_SIZE);
if (inRange(r, configType.mr, configType.r) logger.log(Level.FINE, "Checking Config r: {0}, g: {1}, b: {2}, alpha: {3}, depth: {4}, samples: {5}, stencil: {6}",
&& inRange(g, configType.mg, configType.g) new Object[]{r, g, b, a, d, s, st});
&& inRange(b, configType.mb, configType.b)
&& inRange(a, configType.ma, configType.a)
&& inRange(d, configType.md, configType.d)
&& inRange(s, configType.ms, configType.s)) {
if (mSamples == 0 && isMs != 0) {
continue;
}
boolean keep;
//we keep the config if the depth is better or if the AA setting is better
if (d >= kd) {
kd = d;
keep = true;
} else {
keep = false;
}
if (mSamples != 0) { if (higherRGB && r < requestedConfig.r) { continue; }
if (nbMs >= knbMs && nbMs <= mSamples) { if (!higherRGB && r != requestedConfig.r) { continue; }
knbMs = nbMs;
keep = true; if (higherRGB && g < requestedConfig.g) { continue; }
} else { if (!higherRGB && g != requestedConfig.g) { continue; }
keep = false;
} if (higherRGB && b < requestedConfig.b) { continue; }
} if (!higherRGB && b != requestedConfig.b) { continue; }
if (higherAlpha && a < requestedConfig.a) { continue; }
if (!higherAlpha && a != requestedConfig.a) { continue; }
if (d < requestedConfig.d) { continue; } // always allow higher depth
if (higherSamples && s < requestedConfig.s) { continue; }
if (!higherSamples && s != requestedConfig.s) { continue; }
if (keep) { if (higherStencil && st < requestedConfig.st) { continue; }
if (!higherStencil && !inRange(st, 0, requestedConfig.st)) { continue; }
//we keep the config if it is better
if ( r >= kr || g >= kg || b >= kb || a >= ka ||
d >= kd || s >= ks || st >= kst ) {
kr = r; kg = g; kb = b; ka = a;
kd = d; ks = s; kst = st;
keptConfig = config; keptConfig = config;
} logger.log(Level.FINE, "Keeping Config r: {0}, g: {1}, b: {2}, alpha: {3}, depth: {4}, samples: {5}, stencil: {6}",
} new Object[]{r, g, b, a, d, s, st});
} }
if (keptConfig != null) {
return keptConfig;
} }
if (configType == ConfigType.BEST) {
logger.log(Level.WARNING, "Failed to find a suitable display configuration for BEST, attempting BEST_TRANSLUCENT");
configType = ConfigType.BEST_TRANSLUCENT;
keptConfig = chooseConfig(egl, display, configs);
if (keptConfig != null) { if (keptConfig != null) {
return keptConfig; return keptConfig;
} }
}
if (configType == ConfigType.BEST_TRANSLUCENT) { //no match found
logger.log(Level.WARNING, "Failed to find a suitable display configuration for BEST_TRANSLUCENT, attempting FASTEST"); logger.log(Level.SEVERE, "No egl config match found");
configType = ConfigType.FASTEST; return null;
keptConfig = chooseConfig(egl, display, configs); }
if (keptConfig != null) { private static int eglGetConfigAttribSafe(EGL10 egl, EGLDisplay display, EGLConfig config, int attribute) {
return keptConfig; int[] value = new int[1];
if (!egl.eglGetConfigAttrib(display, config, attribute, value)) {
RendererUtil.checkEGLError(egl);
throw new AssertionError();
} }
return value[0];
} }
logger.log(Level.WARNING, "Failed to find a suitable display configuration for FASTEST, hoping for the best..."); private void storeSelectedConfig(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
int r = eglGetConfigAttribSafe(egl, display, eglConfig, EGL10.EGL_RED_SIZE);
int g = eglGetConfigAttribSafe(egl, display, eglConfig, EGL10.EGL_GREEN_SIZE);
int b = eglGetConfigAttribSafe(egl, display, eglConfig, EGL10.EGL_BLUE_SIZE);
settings.setBitsPerPixel(r+g+b);
// failsafe. pick the 1st config with a 16 bit depth buffer. settings.setAlphaBits(
for (EGLConfig config : configs) { eglGetConfigAttribSafe(egl, display, eglConfig, EGL10.EGL_ALPHA_SIZE));
int d = eglGetConfigAttribSafe(egl, display, config, settings.setDepthBits(
EGL10.EGL_DEPTH_SIZE); eglGetConfigAttribSafe(egl, display, eglConfig, EGL10.EGL_DEPTH_SIZE));
if (d >= 16) { settings.setSamples(
return config; eglGetConfigAttribSafe(egl, display, eglConfig, EGL10.EGL_SAMPLES));
} settings.setStencilBits(
eglGetConfigAttribSafe(egl, display, eglConfig, EGL10.EGL_STENCIL_SIZE));
} }
//nothing much we can do... /**
return null; * log output with egl config details
*
* @param conf
* @param display
* @param egl
*/
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));
logger.log(level, "EGL_GREEN_SIZE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_GREEN_SIZE));
logger.log(level, "EGL_BLUE_SIZE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_BLUE_SIZE));
logger.log(level, "EGL_ALPHA_SIZE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_ALPHA_SIZE));
logger.log(level, "EGL_DEPTH_SIZE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_DEPTH_SIZE));
logger.log(level, "EGL_STENCIL_SIZE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_STENCIL_SIZE));
logger.log(level, "EGL_RENDERABLE_TYPE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_RENDERABLE_TYPE));
logger.log(level, "EGL_SURFACE_TYPE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_SURFACE_TYPE));
logger.log(level, "EGL_SAMPLE_BUFFERS = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_SAMPLE_BUFFERS));
logger.log(level, "EGL_SAMPLES = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_SAMPLES));
} }
private boolean inRange(int val, int min, int max) { private boolean inRange(int val, int min, int max) {
return min <= val && val <= max; return min <= val && val <= max;
} }
private class Config {
/**
* red, green, blue, alpha, depth, samples, stencil
*/
int r, g, b, a, d, s, st;
private Config(int r, int g, int b, int a, int d, int s, int st) {
this.r = r;
this.g = g;
this.b = b;
this.a = a;
this.d = d;
this.s = s;
this.st = st;
}
private int getBitsPerPixel() {
return r+g+b;
} }
}
//DON'T REMOVE THIS, USED FOR UNIT TESTING FAILING CONFIGURATION LISTS. //DON'T REMOVE THIS, USED FOR UNIT TESTING FAILING CONFIGURATION LISTS.
// private static class Config { // private static class Config {
// //

@ -37,9 +37,9 @@ import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.pm.ConfigurationInfo; import android.content.pm.ConfigurationInfo;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView; import android.opengl.GLSurfaceView;
import android.text.InputType; import android.text.InputType;
import android.util.Log;
import android.view.Gravity; import android.view.Gravity;
import android.view.SurfaceHolder; import android.view.SurfaceHolder;
import android.view.ViewGroup.LayoutParams; import android.view.ViewGroup.LayoutParams;
@ -52,11 +52,8 @@ import com.jme3.input.controls.SoftTextDialogInputListener;
import com.jme3.input.dummy.DummyKeyInput; import com.jme3.input.dummy.DummyKeyInput;
import com.jme3.input.dummy.DummyMouseInput; import com.jme3.input.dummy.DummyMouseInput;
import com.jme3.renderer.android.AndroidGLSurfaceView; import com.jme3.renderer.android.AndroidGLSurfaceView;
import com.jme3.renderer.RendererException;
import com.jme3.renderer.android.OGLESShaderRenderer; import com.jme3.renderer.android.OGLESShaderRenderer;
import com.jme3.renderer.android.RendererUtil;
import com.jme3.system.*; import com.jme3.system.*;
import com.jme3.system.android.AndroidConfigChooser.ConfigType;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -102,33 +99,10 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
* GLSurfaceView. Only one GLSurfaceView can be created at this time. 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 configType ConfigType.FASTEST (Default) | ConfigType.LEGACY |
* ConfigType.BEST
* @param eglConfigVerboseLogging if true show all found configs
* @return GLSurfaceView The newly created view
* @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();
}
/**
* <code>createView</code> creates the GLSurfaceView that the renderer will
* draw to. <p> 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.
*
*
* @param eglConfigVerboseLogging if true show all found configs
* @return GLSurfaceView The newly created view * @return GLSurfaceView The newly created view
*/ */
public AndroidGLSurfaceView createView() { public AndroidGLSurfaceView createView() {
AndroidGLSurfaceView view; AndroidGLSurfaceView view;
ConfigType configType = (ConfigType)settings.get(AndroidConfigChooser.SETTINGS_CONFIG_TYPE);
// Start to set up the view // Start to set up the view
view = new AndroidGLSurfaceView(JmeAndroidSystem.getActivity().getApplication()); view = new AndroidGLSurfaceView(JmeAndroidSystem.getActivity().getApplication());
@ -138,9 +112,11 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
androidInput.setView(view); androidInput.setView(view);
androidInput.loadSettings(settings); androidInput.loadSettings(settings);
// setEGLContextClientVersion must be set before calling setRenderer
// this means it cannot be set in AndroidConfigChooser (too late)
int rawOpenGLESVersion = getOpenGLESVersion(); int rawOpenGLESVersion = getOpenGLESVersion();
logger.log(Level.FINE, "clientOpenGLESVersion {0}.{1}", // logger.log(Level.FINE, "clientOpenGLESVersion {0}.{1}",
new Object[]{clientOpenGLESVersion>>16, clientOpenGLESVersion<<16}); // new Object[]{clientOpenGLESVersion>>16, clientOpenGLESVersion<<16});
if (rawOpenGLESVersion < 0x20000) { if (rawOpenGLESVersion < 0x20000) {
throw new UnsupportedOperationException("OpenGL ES 2.0 is not supported on this device"); throw new UnsupportedOperationException("OpenGL ES 2.0 is not supported on this device");
} else { } else {
@ -152,9 +128,29 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
view.setFocusable(true); view.setFocusable(true);
view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU); view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
AndroidConfigChooser configChooser = new AndroidConfigChooser(settings, view); // setFormat must be set before AndroidConfigChooser is called by the surfaceview.
view.setEGLConfigChooser(configChooser); // if setFormat is called after ConfigChooser is called, then execution
// stops at the setFormat call without a crash.
// We look at the user setting for alpha bits and set the surfaceview
// PixelFormat to either Opaque, Transparent, or Translucent.
// ConfigChooser will do it's best to honor the alpha requested by the user
// For best rendering performance, use Opaque (alpha bits = 0).
int curAlphaBits = settings.getAlphaBits();
logger.log(Level.FINE, "curAlphaBits: {0}", curAlphaBits);
if (curAlphaBits >= 8) {
logger.log(Level.FINE, "Pixel Format: TRANSLUCENT");
view.getHolder().setFormat(PixelFormat.TRANSLUCENT);
view.setZOrderOnTop(true);
} else if (curAlphaBits >= 1) {
logger.log(Level.FINE, "Pixel Format: TRANSPARENT");
view.getHolder().setFormat(PixelFormat.TRANSPARENT);
} else {
logger.log(Level.FINE, "Pixel Format: OPAQUE");
view.getHolder().setFormat(PixelFormat.OPAQUE);
}
AndroidConfigChooser configChooser = new AndroidConfigChooser(settings);
view.setEGLConfigChooser(configChooser);
view.setRenderer(this); view.setRenderer(this);
return view; return view;

Loading…
Cancel
Save