From 57a53fbe5280e5af1a7f01a9bdc9b6b091a73b23 Mon Sep 17 00:00:00 2001
From: marynate <mary.w.nate@gmail.com>
Date: Wed, 4 Jun 2014 11:32:49 +0800
Subject: [PATCH 1/2] Add RAW_ARRAY as valid paramter for java binding

---
 platform/android/java_glue.cpp | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp
index 4362b8f2c43..b11994eef0b 100644
--- a/platform/android/java_glue.cpp
+++ b/platform/android/java_glue.cpp
@@ -152,6 +152,14 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar
 			env->SetIntArrayRegion(arr,0,array.size(),r.ptr());
 			v.l=arr;
 
+		} break;
+		case Variant::RAW_ARRAY: {
+			DVector<uint8_t> array = *p_arg;
+			jbyteArray arr = env->NewByteArray(array.size());
+			DVector<uint8_t>::Read r = array.read();
+			env->SetByteArrayRegion(arr,0,array.size(),reinterpret_cast<const signed char*>(r.ptr()));
+			v.l=arr;
+
 		} break;
 		case Variant::REAL_ARRAY: {
 
@@ -244,6 +252,19 @@ Variant _jobject_to_variant(JNIEnv * env, jobject obj) {
 		return sarr;
 	};
 
+	if (name == "[B") {
+
+		jbyteArray arr = (jbyteArray)obj;
+		int fCount = env->GetArrayLength(arr);
+		DVector<uint8_t> sarr;
+		sarr.resize(fCount);
+
+		DVector<uint8_t>::Write w = sarr.write();
+		env->GetByteArrayRegion(arr,0,fCount,reinterpret_cast<signed char*>(w.ptr()));
+		w = DVector<uint8_t>::Write();
+		return sarr;
+	};
+
 	if (name == "java.lang.Float" || name == "java.lang.Double") {
 
 		jclass nclass = env->FindClass("java/lang/Number");
@@ -1346,6 +1367,7 @@ static Variant::Type get_jni_type(const String& p_type) {
 		{"double", Variant::REAL},
 		{"java.lang.String",Variant::STRING},
 		{"[I",Variant::INT_ARRAY},
+		{"[B",Variant::RAW_ARRAY},
 		{"[F",Variant::REAL_ARRAY},
 		{"[java.lang.String",Variant::STRING_ARRAY},
 		{"com.android.godot.Dictionary", Variant::DICTIONARY},
@@ -1381,6 +1403,7 @@ static const char* get_jni_sig(const String& p_type) {
 		{"java.lang.String","Ljava/lang/String;"},
 		{"com.android.godot.Dictionary", "Lcom/android/godot/Dictionary;"},
 		{"[I","[I"},
+		{"[B","[B"},
 		{"[F","[F"},
 		{"[java.lang.String","[Ljava/lang/String;"},
 		{NULL,"V"}

From ffe01a51cb7229e2648a5956c40ea04460c0b43e Mon Sep 17 00:00:00 2001
From: marynate <mary.w.nate@gmail.com>
Date: Wed, 4 Jun 2014 11:31:20 +0800
Subject: [PATCH 2/2] Add more callback for Godot.java

---
 .../java/src/com/android/godot/Godot.java     | 143 ++---
 .../java/src/com/android/godot/GodotView.java | 513 +++++++++---------
 2 files changed, 339 insertions(+), 317 deletions(-)

diff --git a/platform/android/java/src/com/android/godot/Godot.java b/platform/android/java/src/com/android/godot/Godot.java
index bd973ce49b0..9cadeb42318 100644
--- a/platform/android/java/src/com/android/godot/Godot.java
+++ b/platform/android/java/src/com/android/godot/Godot.java
@@ -62,6 +62,7 @@ import android.widget.FrameLayout;
 import com.android.godot.input.*;
 import java.io.InputStream;
 
+import javax.microedition.khronos.opengles.GL10;
 
 public class Godot extends Activity implements SensorEventListener
 {	
@@ -116,11 +117,13 @@ public class Godot extends Activity implements SensorEventListener
 
 		}
 
-		protected void onMainResume() {
-
-
-		}
+		protected void onMainPause() {}
+		protected void onMainResume() {}
+		protected void onMainDestroy() {}
 
+		protected void onGLDrawFrame(GL10 gl) {}
+		protected void onGLSurfaceChanged(GL10 gl, int width, int height) {} // singletons will always miss first onGLSurfaceChanged call
+		//protected void onGLSurfaceCreated(GL10 gl, EGLConfig config) {} // singletons won't be ready until first GodotLib.step()
 
 		public void registerMethods() {}
 	}
@@ -141,6 +144,7 @@ public class Godot extends Activity implements SensorEventListener
 	private Sensor mAccelerometer;
 
 	public FrameLayout layout;
+	public RelativeLayout adLayout;
 
 
 	static public GodotIO io;
@@ -154,7 +158,6 @@ public class Godot extends Activity implements SensorEventListener
 	static int singleton_count=0;
 
 
-
 	public interface ResultCallback {
 		public void callback(int requestCode, int resultCode, Intent data);
 	};
@@ -197,6 +200,12 @@ public class Godot extends Activity implements SensorEventListener
 		
         edittext.setView(mView);
         io.setEdit(edittext);
+		
+		// Ad layout
+		adLayout = new RelativeLayout(this);
+		adLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
+		layout.addView(adLayout);
+		
 	}
 
 	private static Godot _self;
@@ -206,46 +215,46 @@ public class Godot extends Activity implements SensorEventListener
 	}
 	
 
-        private String[] getCommandLine() {
+	private String[] getCommandLine() {
 
-            InputStream is;
-            try {
-                is = getAssets().open("/_cl_");
-                byte[] len = new byte[4];
-                int r = is.read(len);
-                if (r<4) {
-                    System.out.printf("**ERROR** Wrong cmdline length.\n");
-                    return new String[0];
-                }
-                int argc=((int)(len[3])<<24) | ((int)(len[2])<<16) | ((int)(len[1])<<8) | ((int)(len[0]));
-                String[] cmdline = new String[argc];
-                for(int i=0;i<argc;i++) {
-                    r = is.read(len);
-                    if (r<4) {
-                        System.out.printf("**ERROR** Wrong cmdline param lenght.\n");
-                        return new String[0];
-                    }
-                    int strlen=((int)(len[3])<<24) | ((int)(len[2])<<16) | ((int)(len[1])<<8) | ((int)(len[0]));
-                    if (strlen>65535) {
-                        System.out.printf("**ERROR** Wrong command len\n");
-                        return new String[0];
-                    }
-                    byte[] arg = new byte[strlen];
-                    r = is.read(arg);
-                    if (r!=strlen) {
-                        cmdline[i]=new String(arg,"UTF-8");
-                    }
+		InputStream is;
+		try {
+			is = getAssets().open("/_cl_");
+			byte[] len = new byte[4];
+			int r = is.read(len);
+			if (r<4) {
+				System.out.printf("**ERROR** Wrong cmdline length.\n");
+				return new String[0];
+			}
+			int argc=((int)(len[3])<<24) | ((int)(len[2])<<16) | ((int)(len[1])<<8) | ((int)(len[0]));
+			String[] cmdline = new String[argc];
+			for(int i=0;i<argc;i++) {
+				r = is.read(len);
+				if (r<4) {
+					System.out.printf("**ERROR** Wrong cmdline param lenght.\n");
+					return new String[0];
+				}
+				int strlen=((int)(len[3])<<24) | ((int)(len[2])<<16) | ((int)(len[1])<<8) | ((int)(len[0]));
+				if (strlen>65535) {
+					System.out.printf("**ERROR** Wrong command len\n");
+					return new String[0];
+				}
+				byte[] arg = new byte[strlen];
+				r = is.read(arg);
+				if (r!=strlen) {
+					cmdline[i]=new String(arg,"UTF-8");
+				}
 
-                }
+			}
 
-                return cmdline;
-            } catch (Exception e) {
+			return cmdline;
+		} catch (Exception e) {
 
-                return new String[0];
-            }
+			return new String[0];
+		}
 
 
-        }
+	}
 
 	@Override protected void onCreate(Bundle icicle) {
 
@@ -282,6 +291,9 @@ public class Godot extends Activity implements SensorEventListener
 	@Override protected void onDestroy(){
 		
 		if(mPaymentsManager != null ) mPaymentsManager.destroy();
+		for(int i=0;i<singleton_count;i++) {
+			singletons[i].onMainDestroy();
+		}
 		super.onDestroy();
 	}
 	
@@ -291,6 +303,9 @@ public class Godot extends Activity implements SensorEventListener
 		mSensorManager.unregisterListener(this);
 		GodotLib.focusout();
 
+		for(int i=0;i<singleton_count;i++) {
+			singletons[i].onMainPause();
+		}
 	}
 
 	@Override protected void onResume() {
@@ -396,31 +411,31 @@ public class Godot extends Activity implements SensorEventListener
 		return true;
 	}
 
-    @Override public boolean onKeyMultiple(final int inKeyCode, int repeatCount, KeyEvent event) {
-        String s = event.getCharacters();
-        if (s == null || s.length() == 0)
-        	return super.onKeyMultiple(inKeyCode, repeatCount, event);
-        
-        final char[] cc = s.toCharArray();
-        int cnt = 0;
-        for (int i = cc.length; --i >= 0; cnt += cc[i] != 0 ? 1 : 0);
-        if (cnt == 0) return super.onKeyMultiple(inKeyCode, repeatCount, event);
-        final Activity me = this;
-        queueEvent(new Runnable() {
-            // This method will be called on the rendering thread:
-            public void run() {
-                for (int i = 0, n = cc.length; i < n; i++) {
-                    int keyCode;
-                    if ((keyCode = cc[i]) != 0) {
-                        // Simulate key down and up...
-                		GodotLib.key(0, keyCode, true);
-                		GodotLib.key(0, keyCode, false);
-                    }
-                }
-            }
-        });
-        return true;
-    }	
+	@Override public boolean onKeyMultiple(final int inKeyCode, int repeatCount, KeyEvent event) {
+		String s = event.getCharacters();
+		if (s == null || s.length() == 0)
+			return super.onKeyMultiple(inKeyCode, repeatCount, event);
+
+		final char[] cc = s.toCharArray();
+		int cnt = 0;
+		for (int i = cc.length; --i >= 0; cnt += cc[i] != 0 ? 1 : 0);
+		if (cnt == 0) return super.onKeyMultiple(inKeyCode, repeatCount, event);
+		final Activity me = this;
+		queueEvent(new Runnable() {
+			// This method will be called on the rendering thread:
+			public void run() {
+				for (int i = 0, n = cc.length; i < n; i++) {
+					int keyCode;
+					if ((keyCode = cc[i]) != 0) {
+						// Simulate key down and up...
+						GodotLib.key(0, keyCode, true);
+						GodotLib.key(0, keyCode, false);
+					}
+				}
+			}
+		});
+		return true;
+	}
 
 	private void queueEvent(Runnable runnable) {
 		// TODO Auto-generated method stub
diff --git a/platform/android/java/src/com/android/godot/GodotView.java b/platform/android/java/src/com/android/godot/GodotView.java
index 1993be8d2c5..f02cc00c285 100644
--- a/platform/android/java/src/com/android/godot/GodotView.java
+++ b/platform/android/java/src/com/android/godot/GodotView.java
@@ -62,13 +62,14 @@ import javax.microedition.khronos.opengles.GL10;
  *   bit depths). Failure to do so would result in an EGL_BAD_MATCH error.
  */
 public class GodotView extends GLSurfaceView {
-    private static String TAG = "GodotView";
-    private static final boolean DEBUG = false;
-    private static Context ctx;
 
-    private static GodotIO io;
-    private static boolean firsttime=true;
-    private static boolean use_gl2=false;
+	private static String TAG = "GodotView";
+	private static final boolean DEBUG = false;
+	private static Context ctx;
+
+	private static GodotIO io;
+	private static boolean firsttime=true;
+	private static boolean use_gl2=false;
 
 	private Godot activity;
 
@@ -113,37 +114,37 @@ public class GodotView extends GLSurfaceView {
 		return super.onKeyDown(keyCode, event);
 	}
 
-    private void init(boolean translucent, int depth, int stencil) {
+	private void init(boolean translucent, int depth, int stencil) {
 
-	this.setFocusableInTouchMode(true);
-	/* By default, GLSurfaceView() creates a RGB_565 opaque surface.
-	 * If we want a translucent one, we should change the surface's
-	 * format here, using PixelFormat.TRANSLUCENT for GL Surfaces
-	 * is interpreted as any 32-bit surface with alpha by SurfaceFlinger.
-	 */
-	if (translucent) {
-	    this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
+		this.setFocusableInTouchMode(true);
+		/* By default, GLSurfaceView() creates a RGB_565 opaque surface.
+		 * If we want a translucent one, we should change the surface's
+		 * format here, using PixelFormat.TRANSLUCENT for GL Surfaces
+		 * is interpreted as any 32-bit surface with alpha by SurfaceFlinger.
+		 */
+		if (translucent) {
+			this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
+		}
+
+		/* Setup the context factory for 2.0 rendering.
+		 * See ContextFactory class definition below
+		 */
+		setEGLContextFactory(new ContextFactory());
+
+		/* We need to choose an EGLConfig that matches the format of
+		 * our surface exactly. This is going to be done in our
+		 * custom config chooser. See ConfigChooser class definition
+		 * below.
+		 */
+		setEGLConfigChooser( translucent ?
+					new ConfigChooser(8, 8, 8, 8, depth, stencil) :
+					new ConfigChooser(5, 6, 5, 0, depth, stencil) );
+
+		/* Set the renderer responsible for frame rendering */
+		setRenderer(new Renderer());
 	}
 
-	/* Setup the context factory for 2.0 rendering.
-	 * See ContextFactory class definition below
-	 */
-	setEGLContextFactory(new ContextFactory());
-
-	/* We need to choose an EGLConfig that matches the format of
-	 * our surface exactly. This is going to be done in our
-	 * custom config chooser. See ConfigChooser class definition
-	 * below.
-	 */
-	setEGLConfigChooser( translucent ?
-			     new ConfigChooser(8, 8, 8, 8, depth, stencil) :
-			     new ConfigChooser(5, 6, 5, 0, depth, stencil) );
-
-	/* Set the renderer responsible for frame rendering */
-	setRenderer(new Renderer());
-    }
-
-    private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
+	private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
 	private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
 	public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
 		if (use_gl2)
@@ -151,11 +152,11 @@ public class GodotView extends GLSurfaceView {
 		else
 			Log.w(TAG, "creating OpenGL ES 1.1 context :");
 
-	    checkEglError("Before eglCreateContext", egl);
-	    int[] attrib_list2 = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
-	    EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, use_gl2?attrib_list2:null);
-	    checkEglError("After eglCreateContext", egl);
-	    return context;
+		checkEglError("Before eglCreateContext", egl);
+		int[] attrib_list2 = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
+		EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, use_gl2?attrib_list2:null);
+		checkEglError("After eglCreateContext", egl);
+		return context;
 	}
 
 	public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
@@ -170,225 +171,231 @@ public class GodotView extends GLSurfaceView {
 	}
     }
 
-    private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
+	private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
 
-	public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) {
-	    mRedSize = r;
-	    mGreenSize = g;
-	    mBlueSize = b;
-	    mAlphaSize = a;
-	    mDepthSize = depth;
-	    mStencilSize = stencil;
-	}
-
-	/* This EGL config specification is used to specify 2.0 rendering.
-	 * We use a minimum size of 4 bits for red/green/blue, but will
-	 * perform actual matching in chooseConfig() below.
-	 */
-	private static int EGL_OPENGL_ES2_BIT = 4;
-	private static int[] s_configAttribs2 =
-	{
-	    EGL10.EGL_RED_SIZE, 4,
-	    EGL10.EGL_GREEN_SIZE, 4,
-	    EGL10.EGL_BLUE_SIZE, 4,
-	  //  EGL10.EGL_DEPTH_SIZE,     16,
-	   // EGL10.EGL_STENCIL_SIZE,   EGL10.EGL_DONT_CARE,
-	    EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-	    EGL10.EGL_NONE
-	};
-	private static int[] s_configAttribs =
-	{
-	    EGL10.EGL_RED_SIZE, 4,
-	    EGL10.EGL_GREEN_SIZE, 4,
-	    EGL10.EGL_BLUE_SIZE, 4,
-	   // EGL10.EGL_DEPTH_SIZE,     16,
-	  //  EGL10.EGL_STENCIL_SIZE,   EGL10.EGL_DONT_CARE,
-	    EGL10.EGL_NONE
-	};
-
-	public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
-
-	    /* Get the number of minimally matching EGL configurations
-	     */
-	    int[] num_config = new int[1];
-	    egl.eglChooseConfig(display, use_gl2?s_configAttribs2:s_configAttribs, null, 0, num_config);
-
-	    int numConfigs = num_config[0];
-
-	    if (numConfigs <= 0) {
-		throw new IllegalArgumentException("No configs match configSpec");
-	    }
-
-	    /* Allocate then read the array of minimally matching EGL configs
-	     */
-	    EGLConfig[] configs = new EGLConfig[numConfigs];
-	    egl.eglChooseConfig(display, use_gl2?s_configAttribs2:s_configAttribs, configs, numConfigs, num_config);
-
-	    if (DEBUG) {
-		 printConfigs(egl, display, configs);
-	    }
-	    /* Now return the "best" one
-	     */
-	    return chooseConfig(egl, display, configs);
-	}
-
-	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);
-
-		// We need at least mDepthSize and mStencilSize bits
-		if (d < mDepthSize || s < mStencilSize)
-		    continue;
-
-		// We want an *exact* match for red/green/blue/alpha
-		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 void printConfigs(EGL10 egl, EGLDisplay display,
-	    EGLConfig[] configs) {
-	    int numConfigs = configs.length;
-	    Log.w(TAG, String.format("%d configurations", numConfigs));
-	    for (int i = 0; i < numConfigs; i++) {
-		Log.w(TAG, String.format("Configuration %d:\n", i));
-		printConfig(egl, display, configs[i]);
-	    }
-	}
-
-	private void printConfig(EGL10 egl, EGLDisplay display,
-		EGLConfig config) {
-	    int[] attributes = {
-		    EGL10.EGL_BUFFER_SIZE,
-		    EGL10.EGL_ALPHA_SIZE,
-		    EGL10.EGL_BLUE_SIZE,
-		    EGL10.EGL_GREEN_SIZE,
-		    EGL10.EGL_RED_SIZE,
-		    EGL10.EGL_DEPTH_SIZE,
-		    EGL10.EGL_STENCIL_SIZE,
-		    EGL10.EGL_CONFIG_CAVEAT,
-		    EGL10.EGL_CONFIG_ID,
-		    EGL10.EGL_LEVEL,
-		    EGL10.EGL_MAX_PBUFFER_HEIGHT,
-		    EGL10.EGL_MAX_PBUFFER_PIXELS,
-		    EGL10.EGL_MAX_PBUFFER_WIDTH,
-		    EGL10.EGL_NATIVE_RENDERABLE,
-		    EGL10.EGL_NATIVE_VISUAL_ID,
-		    EGL10.EGL_NATIVE_VISUAL_TYPE,
-		    0x3030, // EGL10.EGL_PRESERVED_RESOURCES,
-		    EGL10.EGL_SAMPLES,
-		    EGL10.EGL_SAMPLE_BUFFERS,
-		    EGL10.EGL_SURFACE_TYPE,
-		    EGL10.EGL_TRANSPARENT_TYPE,
-		    EGL10.EGL_TRANSPARENT_RED_VALUE,
-		    EGL10.EGL_TRANSPARENT_GREEN_VALUE,
-		    EGL10.EGL_TRANSPARENT_BLUE_VALUE,
-		    0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,
-		    0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,
-		    0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,
-		    0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,
-		    EGL10.EGL_LUMINANCE_SIZE,
-		    EGL10.EGL_ALPHA_MASK_SIZE,
-		    EGL10.EGL_COLOR_BUFFER_TYPE,
-		    EGL10.EGL_RENDERABLE_TYPE,
-		    0x3042 // EGL10.EGL_CONFORMANT
-	    };
-	    String[] names = {
-		    "EGL_BUFFER_SIZE",
-		    "EGL_ALPHA_SIZE",
-		    "EGL_BLUE_SIZE",
-		    "EGL_GREEN_SIZE",
-		    "EGL_RED_SIZE",
-		    "EGL_DEPTH_SIZE",
-		    "EGL_STENCIL_SIZE",
-		    "EGL_CONFIG_CAVEAT",
-		    "EGL_CONFIG_ID",
-		    "EGL_LEVEL",
-		    "EGL_MAX_PBUFFER_HEIGHT",
-		    "EGL_MAX_PBUFFER_PIXELS",
-		    "EGL_MAX_PBUFFER_WIDTH",
-		    "EGL_NATIVE_RENDERABLE",
-		    "EGL_NATIVE_VISUAL_ID",
-		    "EGL_NATIVE_VISUAL_TYPE",
-		    "EGL_PRESERVED_RESOURCES",
-		    "EGL_SAMPLES",
-		    "EGL_SAMPLE_BUFFERS",
-		    "EGL_SURFACE_TYPE",
-		    "EGL_TRANSPARENT_TYPE",
-		    "EGL_TRANSPARENT_RED_VALUE",
-		    "EGL_TRANSPARENT_GREEN_VALUE",
-		    "EGL_TRANSPARENT_BLUE_VALUE",
-		    "EGL_BIND_TO_TEXTURE_RGB",
-		    "EGL_BIND_TO_TEXTURE_RGBA",
-		    "EGL_MIN_SWAP_INTERVAL",
-		    "EGL_MAX_SWAP_INTERVAL",
-		    "EGL_LUMINANCE_SIZE",
-		    "EGL_ALPHA_MASK_SIZE",
-		    "EGL_COLOR_BUFFER_TYPE",
-		    "EGL_RENDERABLE_TYPE",
-		    "EGL_CONFORMANT"
-	    };
-	    int[] value = new int[1];
-	    for (int i = 0; i < attributes.length; i++) {
-		int attribute = attributes[i];
-		String name = names[i];
-		if ( egl.eglGetConfigAttrib(display, config, attribute, value)) {
-		    Log.w(TAG, String.format("  %s: %d\n", name, value[0]));
-		} else {
-		    // Log.w(TAG, String.format("  %s: failed\n", name));
-		    while (egl.eglGetError() != EGL10.EGL_SUCCESS);
+		public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) {
+			mRedSize = r;
+			mGreenSize = g;
+			mBlueSize = b;
+			mAlphaSize = a;
+			mDepthSize = depth;
+			mStencilSize = stencil;
 		}
-	    }
+
+		/* This EGL config specification is used to specify 2.0 rendering.
+		 * We use a minimum size of 4 bits for red/green/blue, but will
+		 * perform actual matching in chooseConfig() below.
+		 */
+		private static int EGL_OPENGL_ES2_BIT = 4;
+		private static int[] s_configAttribs2 =
+		{
+			EGL10.EGL_RED_SIZE, 4,
+			EGL10.EGL_GREEN_SIZE, 4,
+			EGL10.EGL_BLUE_SIZE, 4,
+		  //  EGL10.EGL_DEPTH_SIZE,     16,
+		   // EGL10.EGL_STENCIL_SIZE,   EGL10.EGL_DONT_CARE,
+			EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+			EGL10.EGL_NONE
+		};
+		private static int[] s_configAttribs =
+		{
+			EGL10.EGL_RED_SIZE, 4,
+			EGL10.EGL_GREEN_SIZE, 4,
+			EGL10.EGL_BLUE_SIZE, 4,
+		   // EGL10.EGL_DEPTH_SIZE,     16,
+		  //  EGL10.EGL_STENCIL_SIZE,   EGL10.EGL_DONT_CARE,
+			EGL10.EGL_NONE
+		};
+
+		public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
+
+			/* Get the number of minimally matching EGL configurations
+			 */
+			int[] num_config = new int[1];
+			egl.eglChooseConfig(display, use_gl2?s_configAttribs2:s_configAttribs, null, 0, num_config);
+
+			int numConfigs = num_config[0];
+
+			if (numConfigs <= 0) {
+			throw new IllegalArgumentException("No configs match configSpec");
+			}
+
+			/* Allocate then read the array of minimally matching EGL configs
+			 */
+			EGLConfig[] configs = new EGLConfig[numConfigs];
+			egl.eglChooseConfig(display, use_gl2?s_configAttribs2:s_configAttribs, configs, numConfigs, num_config);
+
+			if (DEBUG) {
+			 printConfigs(egl, display, configs);
+			}
+			/* Now return the "best" one
+			 */
+			return chooseConfig(egl, display, configs);
+		}
+
+		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);
+
+			// We need at least mDepthSize and mStencilSize bits
+			if (d < mDepthSize || s < mStencilSize)
+				continue;
+
+			// We want an *exact* match for red/green/blue/alpha
+			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 void printConfigs(EGL10 egl, EGLDisplay display,
+			EGLConfig[] configs) {
+			int numConfigs = configs.length;
+			Log.w(TAG, String.format("%d configurations", numConfigs));
+			for (int i = 0; i < numConfigs; i++) {
+			Log.w(TAG, String.format("Configuration %d:\n", i));
+			printConfig(egl, display, configs[i]);
+			}
+		}
+
+		private void printConfig(EGL10 egl, EGLDisplay display,
+			EGLConfig config) {
+			int[] attributes = {
+				EGL10.EGL_BUFFER_SIZE,
+				EGL10.EGL_ALPHA_SIZE,
+				EGL10.EGL_BLUE_SIZE,
+				EGL10.EGL_GREEN_SIZE,
+				EGL10.EGL_RED_SIZE,
+				EGL10.EGL_DEPTH_SIZE,
+				EGL10.EGL_STENCIL_SIZE,
+				EGL10.EGL_CONFIG_CAVEAT,
+				EGL10.EGL_CONFIG_ID,
+				EGL10.EGL_LEVEL,
+				EGL10.EGL_MAX_PBUFFER_HEIGHT,
+				EGL10.EGL_MAX_PBUFFER_PIXELS,
+				EGL10.EGL_MAX_PBUFFER_WIDTH,
+				EGL10.EGL_NATIVE_RENDERABLE,
+				EGL10.EGL_NATIVE_VISUAL_ID,
+				EGL10.EGL_NATIVE_VISUAL_TYPE,
+				0x3030, // EGL10.EGL_PRESERVED_RESOURCES,
+				EGL10.EGL_SAMPLES,
+				EGL10.EGL_SAMPLE_BUFFERS,
+				EGL10.EGL_SURFACE_TYPE,
+				EGL10.EGL_TRANSPARENT_TYPE,
+				EGL10.EGL_TRANSPARENT_RED_VALUE,
+				EGL10.EGL_TRANSPARENT_GREEN_VALUE,
+				EGL10.EGL_TRANSPARENT_BLUE_VALUE,
+				0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,
+				0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,
+				0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,
+				0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,
+				EGL10.EGL_LUMINANCE_SIZE,
+				EGL10.EGL_ALPHA_MASK_SIZE,
+				EGL10.EGL_COLOR_BUFFER_TYPE,
+				EGL10.EGL_RENDERABLE_TYPE,
+				0x3042 // EGL10.EGL_CONFORMANT
+			};
+			String[] names = {
+				"EGL_BUFFER_SIZE",
+				"EGL_ALPHA_SIZE",
+				"EGL_BLUE_SIZE",
+				"EGL_GREEN_SIZE",
+				"EGL_RED_SIZE",
+				"EGL_DEPTH_SIZE",
+				"EGL_STENCIL_SIZE",
+				"EGL_CONFIG_CAVEAT",
+				"EGL_CONFIG_ID",
+				"EGL_LEVEL",
+				"EGL_MAX_PBUFFER_HEIGHT",
+				"EGL_MAX_PBUFFER_PIXELS",
+				"EGL_MAX_PBUFFER_WIDTH",
+				"EGL_NATIVE_RENDERABLE",
+				"EGL_NATIVE_VISUAL_ID",
+				"EGL_NATIVE_VISUAL_TYPE",
+				"EGL_PRESERVED_RESOURCES",
+				"EGL_SAMPLES",
+				"EGL_SAMPLE_BUFFERS",
+				"EGL_SURFACE_TYPE",
+				"EGL_TRANSPARENT_TYPE",
+				"EGL_TRANSPARENT_RED_VALUE",
+				"EGL_TRANSPARENT_GREEN_VALUE",
+				"EGL_TRANSPARENT_BLUE_VALUE",
+				"EGL_BIND_TO_TEXTURE_RGB",
+				"EGL_BIND_TO_TEXTURE_RGBA",
+				"EGL_MIN_SWAP_INTERVAL",
+				"EGL_MAX_SWAP_INTERVAL",
+				"EGL_LUMINANCE_SIZE",
+				"EGL_ALPHA_MASK_SIZE",
+				"EGL_COLOR_BUFFER_TYPE",
+				"EGL_RENDERABLE_TYPE",
+				"EGL_CONFORMANT"
+			};
+			int[] value = new int[1];
+			for (int i = 0; i < attributes.length; i++) {
+			int attribute = attributes[i];
+			String name = names[i];
+			if ( egl.eglGetConfigAttrib(display, config, attribute, value)) {
+				Log.w(TAG, String.format("  %s: %d\n", name, value[0]));
+			} else {
+				// Log.w(TAG, String.format("  %s: failed\n", name));
+				while (egl.eglGetError() != EGL10.EGL_SUCCESS);
+			}
+			}
+		}
+
+		// Subclasses can adjust these values:
+		protected int mRedSize;
+		protected int mGreenSize;
+		protected int mBlueSize;
+		protected int mAlphaSize;
+		protected int mDepthSize;
+		protected int mStencilSize;
+		private int[] mValue = new int[1];
 	}
 
-	// Subclasses can adjust these values:
-	protected int mRedSize;
-	protected int mGreenSize;
-	protected int mBlueSize;
-	protected int mAlphaSize;
-	protected int mDepthSize;
-	protected int mStencilSize;
-	private int[] mValue = new int[1];
-    }
-
-    private static class Renderer implements GLSurfaceView.Renderer {
+	private static class Renderer implements GLSurfaceView.Renderer {
 
 
-	public void onDrawFrame(GL10 gl) {
-	    GodotLib.step();
+		public void onDrawFrame(GL10 gl) {
+			GodotLib.step();
+			for(int i=0;i<Godot.singleton_count;i++) {
+				Godot.singletons[i].onGLDrawFrame(gl);
+			}
+		}
+
+		public void onSurfaceChanged(GL10 gl, int width, int height) {
+
+			GodotLib.resize(width, height,!firsttime);
+			firsttime=false;
+			for(int i=0;i<Godot.singleton_count;i++) {
+				Godot.singletons[i].onGLSurfaceChanged(gl, width, height);
+			}
+		}
+
+		public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+			GodotLib.newcontext();
+		}
 	}
-
-	public void onSurfaceChanged(GL10 gl, int width, int height) {
-
-	    GodotLib.resize(width, height,!firsttime);
-	    firsttime=false;
-	}
-
-	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
-	    GodotLib.newcontext();
-	}
-    }
 }