|
@@ -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;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
}
|