aboutsummaryrefslogtreecommitdiff
path: root/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/android/com/jme3/system/android/AndroidConfigChooser.java')
-rw-r--r--engine/src/android/com/jme3/system/android/AndroidConfigChooser.java362
1 files changed, 362 insertions, 0 deletions
diff --git a/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java b/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java
new file mode 100644
index 0000000..e55fa55
--- /dev/null
+++ b/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java
@@ -0,0 +1,362 @@
+package com.jme3.system.android;
+
+import android.graphics.PixelFormat;
+import android.opengl.GLSurfaceView.EGLConfigChooser;
+import java.util.logging.Logger;
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLDisplay;
+
+/**
+ * AndroidConfigChooser is used to determine the best suited EGL Config
+ * @author larynx
+ *
+ */
+public class AndroidConfigChooser implements EGLConfigChooser
+{
+ private static final Logger logger = Logger.getLogger(AndroidConfigChooser.class.getName());
+
+ protected int clientOpenGLESVersion = 0;
+ protected EGLConfig bestConfig = null;
+ protected EGLConfig fastestConfig = null;
+ protected EGLConfig choosenConfig = null;
+ protected ConfigType type;
+ protected int pixelFormat;
+
+ protected boolean verbose = false;
+
+ private final static int EGL_OPENGL_ES2_BIT = 4;
+
+ public enum ConfigType
+ {
+ /**
+ * RGB565, 0 alpha, 16 depth, 0 stencil
+ */
+ FASTEST,
+ /**
+ * RGB???, 0 alpha, >=16 depth, 0 stencil
+ */
+ BEST,
+ /**
+ * Turn off config chooser and use hardcoded
+ * setEGLContextClientVersion(2);
+ * setEGLConfigChooser(5, 6, 5, 0, 16, 0);
+ */
+ LEGACY
+ }
+
+ public AndroidConfigChooser(ConfigType type, boolean verbose)
+ {
+ this.type = type;
+ this.verbose = verbose;
+ }
+
+ /**
+ * Gets called by the GLSurfaceView class to return the best config
+ */
+ @Override
+ public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display)
+ {
+ logger.info("GLSurfaceView asks for egl config, returning: ");
+ logEGLConfig(choosenConfig, display, egl);
+ return choosenConfig;
+ }
+
+ /**
+ * findConfig is used to locate the best config and init the chooser with
+ * @param egl
+ * @param display
+ * @return true if successfull, false if no config was found
+ */
+ public boolean findConfig(EGL10 egl, EGLDisplay display)
+ {
+
+ if (type == ConfigType.BEST)
+ {
+ ComponentSizeChooser compChooser = new ComponentSizeChooser(8, 8, 8, 8, 32, 0);
+ choosenConfig = compChooser.chooseConfig(egl, display);
+
+ if (choosenConfig == null)
+ {
+ compChooser = new ComponentSizeChooser(8, 8, 8, 0, 32, 0);
+ choosenConfig = compChooser.chooseConfig(egl, display);
+ if (choosenConfig == null)
+ {
+ compChooser = new ComponentSizeChooser(8, 8, 8, 8, 16, 0);
+ choosenConfig = compChooser.chooseConfig(egl, display);
+ if (choosenConfig == null)
+ {
+ compChooser = new ComponentSizeChooser(8, 8, 8, 0, 16, 0);
+ choosenConfig = compChooser.chooseConfig(egl, display);
+ }
+ }
+ }
+
+ logger.info("JME3 using best EGL configuration available here: ");
+ }
+ else
+ {
+ 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)
+ {
+ logger.info("JME3 using choosen config: ");
+ logEGLConfig(choosenConfig, display, egl);
+ pixelFormat = getPixelFormat(choosenConfig, display, egl);
+ clientOpenGLESVersion = getOpenGLVersion(choosenConfig, display, egl);
+ return true;
+ }
+ else
+ {
+ logger.severe("###ERROR### Unable to get a valid OpenGL ES 2.0 config, nether Fastest nor Best found! Bug. Please report this.");
+ clientOpenGLESVersion = 1;
+ pixelFormat = PixelFormat.UNKNOWN;
+ return false;
+ }
+ }
+
+
+ private int getPixelFormat(EGLConfig conf, EGLDisplay display, EGL10 egl)
+ {
+ int[] value = new int[1];
+ int result = PixelFormat.RGB_565;
+
+ egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RED_SIZE, value);
+ if (value[0] == 8)
+ {
+ result = PixelFormat.RGBA_8888;
+ /*
+ egl.eglGetConfigAttrib(display, conf, EGL10.EGL_ALPHA_SIZE, value);
+ if (value[0] == 8)
+ {
+ result = PixelFormat.RGBA_8888;
+ }
+ else
+ {
+ result = PixelFormat.RGB_888;
+ }*/
+ }
+
+ if (verbose)
+ {
+ logger.info("Using PixelFormat " + result);
+ }
+
+ //return result; TODO Test pixelformat
+ return PixelFormat.TRANSPARENT;
+ }
+
+ private int getOpenGLVersion(EGLConfig conf, EGLDisplay display, EGL10 egl)
+ {
+ int[] value = new int[1];
+ int result = 1;
+
+ egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RENDERABLE_TYPE, value);
+ // Check if conf is OpenGL ES 2.0
+ if ((value[0] & EGL_OPENGL_ES2_BIT) != 0)
+ {
+ result = 2;
+ }
+
+ return result;
+ }
+
+ /**
+ * log output with egl config details
+ * @param conf
+ * @param display
+ * @param egl
+ */
+ public 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_GREEN_SIZE, value);
+ logger.info(String.format("EGL_GREEN_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_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] ) );
+
+ egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SURFACE_TYPE, value);
+ logger.info(String.format("EGL_SURFACE_TYPE = %d", value[0] ) );
+ }
+
+ public int getClientOpenGLESVersion()
+ {
+ return clientOpenGLESVersion;
+ }
+
+ public void setClientOpenGLESVersion(int clientOpenGLESVersion)
+ {
+ this.clientOpenGLESVersion = clientOpenGLESVersion;
+ }
+
+ public int getPixelFormat()
+ {
+ return pixelFormat;
+ }
+
+
+
+ private abstract class BaseConfigChooser implements EGLConfigChooser
+ {
+ private boolean bClientOpenGLESVersionSet;
+
+ public BaseConfigChooser(int[] configSpec)
+ {
+ bClientOpenGLESVersionSet = false;
+ 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");
+
+ return null;
+ }
+
+ 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 (bClientOpenGLESVersionSet == true) {
+ 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;
+
+ bClientOpenGLESVersionSet = true;
+
+ 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;
+ }
+
+
+
+
+}