=== modified file 'android/src/org/linaro/glmark2/Glmark2SurfaceView.java'
--- android/src/org/linaro/glmark2/Glmark2SurfaceView.java	2012-02-14 15:29:48 +0000
+++ android/src/org/linaro/glmark2/Glmark2SurfaceView.java	2012-05-15 12:39:38 +0000
@@ -12,6 +12,29 @@
 import javax.microedition.khronos.egl.EGLConfig;
 import javax.microedition.khronos.opengles.GL10;
 
+/** 
+ * Class that holds a configuration of a GL visual.
+ */
+class GLVisualConfig {
+    public GLVisualConfig() {}
+    public GLVisualConfig(int r, int g, int b, int a, int d, int buf) {
+        red = r;
+        green = g;
+        blue = b;
+        alpha = a;
+        depth = d;
+        buffer = buf;
+    }
+
+    public int red;
+    public int green;
+    public int blue;
+    public int alpha;
+    public int depth;
+    public int buffer;
+}
+
+
 class Glmark2SurfaceView extends GLSurfaceView {
 
     public static final String LOG_TAG = "glmark2";
@@ -22,14 +45,55 @@
 
         setEGLContextClientVersion(2);
 
-        // Uncomment the commands below to get an RGBA8888 surface and config.
-        //this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
-        //setEGLConfigChooser(new Glmark2ConfigChooser(8, 8, 8, 8, 16, 0));
-        setEGLConfigChooser(new Glmark2ConfigChooser(5, 6, 5, 0, 16, 0));
+        setEGLConfigChooser(getConfigChooser());
 
         setRenderer(new Glmark2Renderer(this));
     }
 
+    private EGLConfigChooser getConfigChooser() {
+        String args = mActivity.getIntent().getStringExtra("args");
+
+        String[] argv = args.split(" ");
+
+        /* Find the visual-config option argument */
+        String configString = new String();
+        boolean keepNext = false;
+        for (String arg : argv) {
+            if (keepNext) {
+                configString = arg;
+                break;
+            }
+
+            if (arg.equals("--visual-config"))
+                keepNext = true;
+        }
+
+        /* Parse the config string parameters */
+        String[] configParams = configString.split(":");
+        GLVisualConfig targetConfig = new GLVisualConfig(5, 6, 5, 0, 16, 1);
+
+        for (String param : configParams) {
+            String[] paramKeyValue = param.split("=");
+            if (paramKeyValue.length < 2)
+                continue;
+
+            if (paramKeyValue[0].equals("red") || paramKeyValue[0].equals("r"))
+                targetConfig.red = Integer.parseInt(paramKeyValue[1]);
+            else if (paramKeyValue[0].equals("green") || paramKeyValue[0].equals("g"))
+                targetConfig.green = Integer.parseInt(paramKeyValue[1]);
+            else if (paramKeyValue[0].equals("blue") || paramKeyValue[0].equals("b"))
+                targetConfig.blue = Integer.parseInt(paramKeyValue[1]);
+            else if (paramKeyValue[0].equals("alpha") || paramKeyValue[0].equals("a"))
+                targetConfig.alpha = Integer.parseInt(paramKeyValue[1]);
+            else if (paramKeyValue[0].equals("depth") || paramKeyValue[0].equals("d"))
+                targetConfig.depth = Integer.parseInt(paramKeyValue[1]);
+            else if (paramKeyValue[0].equals("buffer") || paramKeyValue[0].equals("buf"))
+                targetConfig.buffer = Integer.parseInt(paramKeyValue[1]);
+        }
+
+        return new Glmark2ConfigChooser(targetConfig);
+    }
+
     /**
      * EGLConfigChooser that quits with an error dialog when a suitable config
      * cannot be found.
@@ -37,24 +101,19 @@
     private class Glmark2ConfigChooser implements EGLConfigChooser {
         private int[] mAttribList;
 
-        public Glmark2ConfigChooser(int redSize, int greenSize, int blueSize,
-                                    int alphaSize, int depthSize, int stencilSize)
+        public Glmark2ConfigChooser(GLVisualConfig targetConfig)
         {
             mAttribList = 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_RED_SIZE, targetConfig.red,
+                    EGL10.EGL_GREEN_SIZE, targetConfig.green,
+                    EGL10.EGL_BLUE_SIZE, targetConfig.blue,
+                    EGL10.EGL_ALPHA_SIZE, targetConfig.alpha,
+                    EGL10.EGL_DEPTH_SIZE, targetConfig.depth,
+                    EGL10.EGL_BUFFER_SIZE, targetConfig.buffer,
                     EGL10.EGL_RENDERABLE_TYPE, 4, /* 4 = EGL_OPENGL_ES2_BIT */
                     EGL10.EGL_NONE };
-            mRedSize = redSize;
-            mGreenSize = greenSize;
-            mBlueSize = blueSize;
-            mAlphaSize = alphaSize;
-            mDepthSize = depthSize;
-            mStencilSize = stencilSize;
+
+            mTargetConfig = targetConfig;
        }
 
         @Override
@@ -101,32 +160,34 @@
                 throw new IllegalArgumentException("eglChooseConfig#2 failed");
             }
 
-            /*
-             * Try to find a config that matches exactly the RGBA size
-             * specified by the user and is >= for depth and stencil.
-             */
+            /* Find the best matching config. */
+            int bestScore = Integer.MIN_VALUE;
+            EGLConfig bestConfig = configs[0];
+
             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);
-                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 &&
-                    d >= mDepthSize && s >= mStencilSize)
-                {
-                    return config;
+                GLVisualConfig vc = new GLVisualConfig();
+                vc.red = findConfigAttrib(egl, display, config,
+                                          EGL10.EGL_RED_SIZE, 0);
+                vc.green = findConfigAttrib(egl, display, config,
+                                            EGL10.EGL_GREEN_SIZE, 0);
+                vc.blue = findConfigAttrib(egl, display, config,
+                                           EGL10.EGL_BLUE_SIZE, 0);
+                vc.alpha = findConfigAttrib(egl, display, config,
+                                            EGL10.EGL_ALPHA_SIZE, 0);
+                vc.depth = findConfigAttrib(egl, display, config,
+                                            EGL10.EGL_DEPTH_SIZE, 0);
+                vc.buffer = findConfigAttrib(egl, display, config,
+                                             EGL10.EGL_BUFFER_SIZE, 0);
+
+                int score = Glmark2Native.scoreConfig(vc, mTargetConfig);
+
+                if (score > bestScore) {
+                    bestScore = score;
+                    bestConfig = config;
                 }
             }
 
-            throw new IllegalArgumentException("No configs match exactly");
+            return bestConfig;
         }
 
         private int findConfigAttrib(EGL10 egl, EGLDisplay display, EGLConfig config,
@@ -137,12 +198,7 @@
             return value[0];
         }
 
-        protected int mRedSize;
-        protected int mGreenSize;
-        protected int mBlueSize;
-        protected int mAlphaSize;
-        protected int mDepthSize;
-        protected int mStencilSize;
+        protected GLVisualConfig mTargetConfig;
     }
 
     public Activity getActivity() {
@@ -159,22 +215,26 @@
     }
 
     public void onDrawFrame(GL10 gl) {
-        if (!nativeRender())
+        if (!Glmark2Native.render())
             mView.getActivity().finish();
     }
 
     public void onSurfaceChanged(GL10 gl, int width, int height) {
-        nativeResize(width, height);
+        Glmark2Native.resize(width, height);
     }
 
     public void onSurfaceCreated(GL10 gl, EGLConfig config) {
         String args = mView.getActivity().getIntent().getStringExtra("args");
-        nativeInit(mView.getActivity().getAssets(), args);
+        Glmark2Native.init(mView.getActivity().getAssets(), args);
     }
 
     private Glmark2SurfaceView mView;
-    private static native void nativeInit(AssetManager assetManager, String args);
-    private static native void nativeResize(int w, int h);
-    private static native boolean nativeRender();
-    private static native void nativeDone();
+}
+
+class Glmark2Native {
+    public static native void init(AssetManager assetManager, String args);
+    public static native void resize(int w, int h);
+    public static native boolean render();
+    public static native void done();
+    public static native int scoreConfig(GLVisualConfig vc, GLVisualConfig target);
 }

=== modified file 'src/android.cpp'
--- src/android.cpp	2012-05-08 13:53:58 +0000
+++ src/android.cpp	2012-05-15 12:28:51 +0000
@@ -135,10 +135,43 @@
     delete[] argv;
 }
 
+/** 
+ * Converts a GLVisualConfig Java object to a GLVisualConfig C++ object.
+ * 
+ * @param env the JNIEnv
+ * @param jvc the Java VisualConfig object to convert
+ * @param vc the C++ VisualConfig object to fill
+ */
+static void
+gl_visual_config_from_jobject(JNIEnv *env, jobject jvc, GLVisualConfig &vc)
+{
+    jclass cls = env->GetObjectClass(jvc);
+    jfieldID fid;
+
+    fid = env->GetFieldID(cls, "red", "I");
+    vc.red = env->GetIntField(jvc, fid);
+
+    fid = env->GetFieldID(cls, "green", "I");
+    vc.green = env->GetIntField(jvc, fid);
+    
+    fid = env->GetFieldID(cls, "blue", "I");
+    vc.blue = env->GetIntField(jvc, fid);
+
+    fid = env->GetFieldID(cls, "alpha", "I");
+    vc.alpha = env->GetIntField(jvc, fid);
+
+    fid = env->GetFieldID(cls, "depth", "I");
+    vc.depth = env->GetIntField(jvc, fid);
+
+    fid = env->GetFieldID(cls, "buffer", "I");
+    vc.buffer = env->GetIntField(jvc, fid);
+}
+
+
 void
-Java_org_linaro_glmark2_Glmark2Renderer_nativeInit(JNIEnv* env, jclass clazz,
-                                                   jobject asset_manager,
-                                                   jstring args)
+Java_org_linaro_glmark2_native_init(JNIEnv* env, jclass clazz,
+                                    jobject asset_manager,
+                                    jstring args)
 {
     static_cast<void>(clazz);
     static const std::string arguments_file("/data/glmark2/args");
@@ -202,10 +235,10 @@
 }
 
 void
-Java_org_linaro_glmark2_Glmark2Renderer_nativeResize(JNIEnv* env,
-                                                     jclass clazz,
-                                                     jint w,
-                                                     jint h)
+Java_org_linaro_glmark2_native_resize(JNIEnv* env,
+                                      jclass clazz,
+                                      jint w,
+                                      jint h)
 {
     static_cast<void>(env);
     static_cast<void>(clazz);
@@ -215,7 +248,7 @@
 }
 
 void
-Java_org_linaro_glmark2_Glmark2Renderer_nativeDone(JNIEnv* env)
+Java_org_linaro_glmark2_native_done(JNIEnv* env)
 {
     static_cast<void>(env);
 
@@ -225,7 +258,7 @@
 }
 
 jboolean
-Java_org_linaro_glmark2_Glmark2Renderer_nativeRender(JNIEnv* env)
+Java_org_linaro_glmark2_native_render(JNIEnv* env)
 {
     static_cast<void>(env);
 
@@ -237,26 +270,46 @@
     return true;
 }
 
+jint
+Java_org_linaro_glmark2_native_scoreConfig(JNIEnv* env, jclass clazz,
+                                           jobject jvc, jobject jtarget)
+{
+    static_cast<void>(clazz);
+
+    GLVisualConfig vc;
+    GLVisualConfig target;
+
+    gl_visual_config_from_jobject(env, jvc, vc);
+    gl_visual_config_from_jobject(env, jtarget, target);
+
+    return vc.match_score(target);
+}
+
 static JNINativeMethod glmark2_native_methods[] = {
     {
-        "nativeInit",
+        "init",
         "(Landroid/content/res/AssetManager;Ljava/lang/String;)V",
-        reinterpret_cast<void*>(Java_org_linaro_glmark2_Glmark2Renderer_nativeInit)
+        reinterpret_cast<void*>(Java_org_linaro_glmark2_native_init)
     },
     {
-        "nativeResize",
+        "resize",
         "(II)V",
-        reinterpret_cast<void*>(Java_org_linaro_glmark2_Glmark2Renderer_nativeResize)
+        reinterpret_cast<void*>(Java_org_linaro_glmark2_native_resize)
     },
     {
-        "nativeDone",
+        "done",
         "()V",
-        reinterpret_cast<void*>(Java_org_linaro_glmark2_Glmark2Renderer_nativeDone)
+        reinterpret_cast<void*>(Java_org_linaro_glmark2_native_done)
     },
     {
-        "nativeRender",
+        "render",
         "()Z",
-        reinterpret_cast<void*>(Java_org_linaro_glmark2_Glmark2Renderer_nativeRender)
+        reinterpret_cast<void*>(Java_org_linaro_glmark2_native_render)
+    },
+    {
+        "scoreConfig",
+        "(Lorg/linaro/glmark2/GLVisualConfig;Lorg/linaro/glmark2/GLVisualConfig;)I",
+        reinterpret_cast<void*>(Java_org_linaro_glmark2_native_scoreConfig)
     }
 };
 
@@ -283,7 +336,7 @@
 static int
 register_natives(JNIEnv *env)
 {
-    const char* const class_path_name = "org/linaro/glmark2/Glmark2Renderer";
+    const char* const class_path_name = "org/linaro/glmark2/Glmark2Native";
     return register_native_methods(env, class_path_name,
                                    glmark2_native_methods,
                                    sizeof(glmark2_native_methods) /

=== modified file 'src/canvas-android.cpp'
--- src/canvas-android.cpp	2011-10-28 10:51:19 +0000
+++ src/canvas-android.cpp	2012-05-15 12:33:41 +0000
@@ -36,9 +36,24 @@
 bool
 CanvasAndroid::init()
 {
+    EGLint attribs[] = {
+        EGL_CONFIG_ID, 0,
+        EGL_NONE
+    };
+
+    /* Get the current EGL config */
+    EGLDisplay egl_display(eglGetCurrentDisplay());
+    EGLContext egl_context(eglGetCurrentContext());
+    EGLConfig egl_config(0);
+    EGLint num_configs;
+
+    eglQueryContext(egl_display, egl_context, EGL_CONFIG_ID, &(attribs[1]));
+
+    eglChooseConfig(egl_display, attribs, &egl_config, 1, &num_configs);
+
     resize(width_, height_);
 
-    if (!eglSwapInterval(eglGetCurrentDisplay(), 0))
+    if (!eglSwapInterval(egl_display, 0))
         Log::info("** Failed to set swap interval. Results may be bounded above by refresh rate.\n");
 
     init_gl_extensions();
@@ -50,6 +65,27 @@
 
     clear();
 
+    if (Options::show_debug) {
+        int buf, red, green, blue, alpha, depth, id, native_id;
+        eglGetConfigAttrib(egl_display, egl_config, EGL_CONFIG_ID, &id);
+        eglGetConfigAttrib(egl_display, egl_config, EGL_NATIVE_VISUAL_ID, &native_id);
+        eglGetConfigAttrib(egl_display, egl_config, EGL_BUFFER_SIZE, &buf);
+        eglGetConfigAttrib(egl_display, egl_config, EGL_RED_SIZE, &red);
+        eglGetConfigAttrib(egl_display, egl_config, EGL_GREEN_SIZE, &green);
+        eglGetConfigAttrib(egl_display, egl_config, EGL_BLUE_SIZE, &blue);
+        eglGetConfigAttrib(egl_display, egl_config, EGL_ALPHA_SIZE, &alpha);
+        eglGetConfigAttrib(egl_display, egl_config, EGL_DEPTH_SIZE, &depth);
+        Log::debug("EGL chosen config ID: 0x%x Native Visual ID: 0x%x\n"
+                   "  Buffer: %d bits\n"
+                   "     Red: %d bits\n"
+                   "   Green: %d bits\n"
+                   "    Blue: %d bits\n"
+                   "   Alpha: %d bits\n"
+                   "   Depth: %d bits\n",
+                   id, native_id,
+                   buf, red, green, blue, alpha, depth);
+    }
+
     return true;
 }
 

