diff --git a/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java b/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java index 82603f57e..c4cf581ed 100644 --- a/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java +++ b/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java @@ -71,97 +71,19 @@ public class AndroidConfigChooser implements EGLConfigChooser * @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]; - - - if (configurations <= 0) - { - logger.severe("###ERROR### ZERO EGL Configurations found, This Is a Problem"); - } + { - // 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 minimum 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); - - if (verbose) - { - logger.info("** Supported EGL Configuration #" + i ); - logEGLConfig(conf[i], display, egl); - } - } - else - { - if (verbose) - { - logger.info("NOT Supported EGL Configuration #" + i + " EGL_OPENGL_ES2_BIT not set"); - logEGLConfig(conf[i], display, egl); - } - } - } - else - { - if (verbose) - { - logger.info("NOT Supported EGL Configuration #" + i + " EGL_DEPTH_SIZE < 16"); - logEGLConfig(conf[i], display, egl); - } - } - } - else - { - if (verbose) - { - logger.info("NOT Supported EGL Configuration #" + i + " EGL_WINDOW_BIT not set"); - logEGLConfig(conf[i], display, egl); - } - } - } - else - { - logger.severe("###ERROR### EGL Configuration #" + i + " is NULL"); - } - } - - - if ((type == ConfigType.BEST) && (bestConfig != null)) - { + if (type == ConfigType.BEST) + { + ComponentSizeChooser compChooser = new ComponentSizeChooser(8, 8, 8, 8, 16, 0); + choosenConfig = compChooser.chooseConfig(egl, display); logger.info("JME3 using best EGL configuration available here: "); - choosenConfig = bestConfig; } else { - if (fastestConfig != null) - { - logger.info("JME3 using fastest EGL configuration available here: "); - } - choosenConfig = fastestConfig; + ComponentSizeChooser compChooser = new ComponentSizeChooser(5, 6, 5, 0, 16, 0); + choosenConfig = compChooser.chooseConfig(egl, display); + logger.info("JME3 using fastest EGL configuration available here: "); } if (choosenConfig != null) @@ -180,147 +102,6 @@ public class AndroidConfigChooser implements EGLConfigChooser 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 highest depth size - 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 // depth 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 565 color size - egl.eglGetConfigAttrib(display, a, EGL10.EGL_GREEN_SIZE, value); - int greenA = value[0]; - - egl.eglGetConfigAttrib(display, b, EGL10.EGL_GREEN_SIZE, value); - int greenB = value[0]; - - if ((greenA == 6) && (greenB != 6)) - result = a; - else if ((greenA != 6) && (greenB == 6)) - result = b; - else // green size is equal - { - // Choose lowest depth size - 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 // depth 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) { @@ -440,4 +221,141 @@ public class AndroidConfigChooser implements EGLConfigChooser return pixelFormat; } + + + private abstract class BaseConfigChooser implements EGLConfigChooser + { + public BaseConfigChooser(int[] configSpec) + { + mConfigSpec = filterConfigSpec(configSpec); + } + + public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) + { + int[] num_config = new int[1]; + if (!egl.eglChooseConfig(display, mConfigSpec, null, 0, + num_config)) { + throw new IllegalArgumentException("eglChooseConfig failed"); + } + + int numConfigs = num_config[0]; + + if (numConfigs <= 0) { + throw new IllegalArgumentException( + "No configs match configSpec"); + } + + EGLConfig[] configs = new EGLConfig[numConfigs]; + if (!egl.eglChooseConfig(display, mConfigSpec, configs, numConfigs, + num_config)) { + throw new IllegalArgumentException("eglChooseConfig#2 failed"); + } + EGLConfig config = chooseConfig(egl, display, configs); + if (config == null) { + throw new IllegalArgumentException("No config chosen"); + } + return config; + } + + abstract EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, + EGLConfig[] configs); + + protected int[] mConfigSpec; + + private int[] filterConfigSpec(int[] configSpec) + { + if (clientOpenGLESVersion != 2) { + return configSpec; + } + /* We know none of the subclasses define EGL_RENDERABLE_TYPE. + * And we know the configSpec is well formed. + */ + int len = configSpec.length; + int[] newConfigSpec = new int[len + 2]; + System.arraycopy(configSpec, 0, newConfigSpec, 0, len-1); + newConfigSpec[len-1] = EGL10.EGL_RENDERABLE_TYPE; + newConfigSpec[len] = 4; /* EGL_OPENGL_ES2_BIT */ + newConfigSpec[len+1] = EGL10.EGL_NONE; + return newConfigSpec; + } + } + + /** + * 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 + { + public ComponentSizeChooser(int redSize, int greenSize, int blueSize, + int alphaSize, int depthSize, int stencilSize) + { + super(new int[] { + EGL10.EGL_RED_SIZE, redSize, + EGL10.EGL_GREEN_SIZE, greenSize, + EGL10.EGL_BLUE_SIZE, blueSize, + EGL10.EGL_ALPHA_SIZE, alphaSize, + EGL10.EGL_DEPTH_SIZE, depthSize, + EGL10.EGL_STENCIL_SIZE, stencilSize, + EGL10.EGL_NONE}); + mValue = new int[1]; + mRedSize = redSize; + mGreenSize = greenSize; + mBlueSize = blueSize; + mAlphaSize = alphaSize; + mDepthSize = depthSize; + mStencilSize = stencilSize; + } + + @Override + public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs) + { + for (EGLConfig config : configs) + { + int d = findConfigAttrib(egl, display, config, + EGL10.EGL_DEPTH_SIZE, 0); + int s = findConfigAttrib(egl, display, config, + EGL10.EGL_STENCIL_SIZE, 0); + if ((d >= mDepthSize) && (s >= mStencilSize)) + { + int r = findConfigAttrib(egl, display, config, + EGL10.EGL_RED_SIZE, 0); + int g = findConfigAttrib(egl, display, config, + EGL10.EGL_GREEN_SIZE, 0); + int b = findConfigAttrib(egl, display, config, + EGL10.EGL_BLUE_SIZE, 0); + int a = findConfigAttrib(egl, display, config, + EGL10.EGL_ALPHA_SIZE, 0); + if ((r == mRedSize) && (g == mGreenSize) + && (b == mBlueSize) && (a == mAlphaSize)) { + return config; + } + } + } + return null; + } + + private int findConfigAttrib(EGL10 egl, EGLDisplay display, + EGLConfig config, int attribute, int defaultValue) + { + + if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) + { + return mValue[0]; + } + return defaultValue; + } + + private int[] mValue; + // Subclasses can adjust these values: + protected int mRedSize; + protected int mGreenSize; + protected int mBlueSize; + protected int mAlphaSize; + protected int mDepthSize; + protected int mStencilSize; + } + + + + } diff --git a/engine/src/android/com/jme3/system/android/OGLESContext.java b/engine/src/android/com/jme3/system/android/OGLESContext.java index 146e23ef3..e20cf6134 100644 --- a/engine/src/android/com/jme3/system/android/OGLESContext.java +++ b/engine/src/android/com/jme3/system/android/OGLESContext.java @@ -310,8 +310,8 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer } protected void applySettings(AppSettings settings) - { - setSettings(settings); + { + setSettings(settings); if (renderer != null) applySettingsToRenderer(renderer, this.settings); }