Fixed bug 1242 - PATCH: Improve support for OpenGL ES under X11
authorSam Lantinga <slouken@libsdl.org>
Sun, 08 Jan 2012 02:23:37 -0500
changeset 6188 e82023802002
parent 6187 6b1932e5a36b
child 6189 b5a665fbaedc
Fixed bug 1242 - PATCH: Improve support for OpenGL ES under X11 Scott Percival 2011-07-03 06:41:51 PDT This submission is aimed at making life easier for OpenGL ES capable devices running a X11 stack (e.g. Maemo, Meego, TrimSlice, other ARM SoC boards not running Android). SDL's Pandora support already has the neccesary GLES-to-X11 glue code, however it's all ghetto'd off in Makefile.pandora and not very flexible. The patch: - adds an awesome --enable-video-opengles option to configure - re-modifies the opengles and opengles2 SDL_renderers to use function pointers - no idea why this was removed? - for SDL_Renderers, links in libGLESv1_CM, libGLES_CM (for PowerVR fans) or libGLESv2 at runtime - links in libEGL.so at runtime - the old code made an assumption that eglFunctions could be pulled from the active GLES library, PowerVR for one doesn't let you do that with their libGLESv2 - allows you to pick which of GLES v1 or v2 to load via SDL_GL_CONTEXT_MAJOR_VERSION So far I've tested this on a Nokia N900 (OMAP 3430/SGX 530 running Maemo 5) and a Toshiba AC100 (Tegra 2 running Ubuntu 10.10). I haven't tested it on... well, everything that isn't those two, such as a Pandora, iOS or Android device. The Pandora specific code should be kept intact (fingers crossed), and nothing painfully drastic has been added to the SDL_renderers. The library loading sequence in SDL_x11opengles has been updated to accomodate both NVIDIA's propensity to let developers get away with murder and PowerVR's alternative of punishing every missed step. The test apps work okay with GLES or GLES2 as the renderer. For some reason alpha blending doesn't seem to work on the Tegra 2; last week NVIDIA pushed out a new set of X11 GLES drivers, so I'll try and investigate once I upgrade those. Also, this patch adds things to configure.in, include/SDL_config.h.in and test/configure.in. I didn't know what the policy was re. committing generated spaghetti from autotools, so ./autogen.sh has to be run again. Sorry. I think that's about everything, let me know if there's anything I've overlooked.
configure
configure.in
include/SDL_config.h.in
src/render/opengles/SDL_glesfuncs.h
src/render/opengles/SDL_render_gles.c
src/render/opengles2/SDL_gles2funcs.h
src/render/opengles2/SDL_render_gles2.c
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/x11/SDL_x11opengles.c
src/video/x11/SDL_x11opengles.h
src/video/x11/SDL_x11video.c
src/video/x11/SDL_x11window.c
test/configure
test/configure.in
--- a/configure	Sun Jan 08 01:15:20 2012 -0500
+++ b/configure	Sun Jan 08 02:23:37 2012 -0500
@@ -1562,6 +1562,7 @@
                           [default=yes]
   --enable-video-dummy    use dummy video driver [default=yes]
   --enable-video-opengl   include OpenGL support [default=yes]
+  --enable-video-opengles include OpenGL ES support [default=yes]
   --enable-input-events   use Linux 2.4 unified input interface
                           [default=yes]
   --enable-input-tslib    use the Touchscreen library for input
@@ -3772,13 +3773,13 @@
 else
   lt_cv_nm_interface="BSD nm"
   echo "int some_variable = 0;" > conftest.$ac_ext
-  (eval echo "\"\$as_me:3775: $ac_compile\"" >&5)
+  (eval echo "\"\$as_me:3776: $ac_compile\"" >&5)
   (eval "$ac_compile" 2>conftest.err)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:3778: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval echo "\"\$as_me:3779: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
   (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:3781: output\"" >&5)
+  (eval echo "\"\$as_me:3782: output\"" >&5)
   cat conftest.out >&5
   if $GREP 'External.*some_variable' conftest.out > /dev/null; then
     lt_cv_nm_interface="MS dumpbin"
@@ -5005,7 +5006,7 @@
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 5008 "configure"' > conftest.$ac_ext
+  echo '#line 5009 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -7166,11 +7167,11 @@
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7169: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7170: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:7173: \$? = $ac_status" >&5
+   echo "$as_me:7174: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -7505,11 +7506,11 @@
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7508: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7509: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:7512: \$? = $ac_status" >&5
+   echo "$as_me:7513: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -7610,11 +7611,11 @@
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7613: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7614: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:7617: \$? = $ac_status" >&5
+   echo "$as_me:7618: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -7665,11 +7666,11 @@
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7668: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7669: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:7672: \$? = $ac_status" >&5
+   echo "$as_me:7673: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -10423,7 +10424,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 10426 "configure"
+#line 10427 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -10519,7 +10520,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 10522 "configure"
+#line 10523 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -14201,11 +14202,11 @@
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:14204: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:14205: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:14208: \$? = $ac_status" >&5
+   echo "$as_me:14209: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -14300,11 +14301,11 @@
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:14303: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:14304: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:14307: \$? = $ac_status" >&5
+   echo "$as_me:14308: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -14352,11 +14353,11 @@
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:14355: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:14356: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:14359: \$? = $ac_status" >&5
+   echo "$as_me:14360: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -23752,6 +23753,201 @@
     fi
 }
 
+# Check whether --enable-video-opengles was given.
+if test "${enable_video_opengles+set}" = set; then
+  enableval=$enable_video_opengles;
+else
+  enable_video_opengles=yes
+fi
+
+
+CheckOpenGLESX11()
+{
+    if test x$enable_video = xyes -a x$enable_video_opengles = xyes; then
+        { echo "$as_me:$LINENO: checking for OpenGL ES (EGL) support" >&5
+echo $ECHO_N "checking for OpenGL ES (EGL) support... $ECHO_C" >&6; }
+        video_opengles=no
+        cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+         #include <EGL/egl.h>
+
+int
+main ()
+{
+
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+
+        video_opengles=yes
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+        { echo "$as_me:$LINENO: result: $video_opengles" >&5
+echo "${ECHO_T}$video_opengles" >&6; }
+        if test x$video_opengles = xyes; then
+            { echo "$as_me:$LINENO: checking for OpenGL ES v1 headers" >&5
+echo $ECHO_N "checking for OpenGL ES v1 headers... $ECHO_C" >&6; }
+            video_opengles_v1=no
+            cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+             #include <GLES/gl.h>
+             #include <GLES/glext.h>
+
+int
+main ()
+{
+
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+
+            video_opengles_v1=yes
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+            { echo "$as_me:$LINENO: result: $video_opengles_v1" >&5
+echo "${ECHO_T}$video_opengles_v1" >&6; }
+            if test x$video_opengles_v1 = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define SDL_VIDEO_OPENGL_ES 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define SDL_VIDEO_RENDER_OGL_ES 1
+_ACEOF
+
+            fi
+            { echo "$as_me:$LINENO: checking for OpenGL ES v2 headers" >&5
+echo $ECHO_N "checking for OpenGL ES v2 headers... $ECHO_C" >&6; }
+            video_opengles_v2=no
+            cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+             #include <GLES2/gl2.h>
+             #include <GLES2/gl2ext.h>
+
+int
+main ()
+{
+
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+
+            video_opengles_v2=yes
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+            { echo "$as_me:$LINENO: result: $video_opengles_v2" >&5
+echo "${ECHO_T}$video_opengles_v2" >&6; }
+            if test x$video_opengles_v2 = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define SDL_VIDEO_OPENGL_ES2 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define SDL_VIDEO_RENDER_OGL_ES2 1
+_ACEOF
+
+            fi
+        fi
+    fi
+}
+
 CheckWINDOWSGL()
 {
     if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then
@@ -27000,6 +27196,7 @@
         CheckDirectFB
         CheckFusionSound
         CheckOpenGLX11
+        CheckOpenGLESX11
         CheckInputEvents
         CheckTslib
         CheckUSBHID
--- a/configure.in	Sun Jan 08 01:15:20 2012 -0500
+++ b/configure.in	Sun Jan 08 02:23:37 2012 -0500
@@ -1474,6 +1474,57 @@
     fi
 }
 
+dnl Check to see if OpenGL ES support is desired
+AC_ARG_ENABLE(video-opengles,
+AC_HELP_STRING([--enable-video-opengles], [include OpenGL ES support [[default=yes]]]),
+              , enable_video_opengles=yes)
+
+dnl Find OpenGL ES
+CheckOpenGLESX11()
+{
+    if test x$enable_video = xyes -a x$enable_video_opengles = xyes; then
+        AC_MSG_CHECKING(for OpenGL ES (EGL) support)
+        video_opengles=no
+        AC_TRY_COMPILE([
+         #include <EGL/egl.h>
+        ],[
+        ],[
+        video_opengles=yes
+        ])
+        AC_MSG_RESULT($video_opengles)
+        if test x$video_opengles = xyes; then
+            AC_MSG_CHECKING(for OpenGL ES v1 headers)
+            video_opengles_v1=no
+            AC_TRY_COMPILE([
+             #include <GLES/gl.h>
+             #include <GLES/glext.h>
+            ],[
+            ],[
+            video_opengles_v1=yes
+            ])
+            AC_MSG_RESULT($video_opengles_v1)
+            if test x$video_opengles_v1 = xyes; then
+                AC_DEFINE(SDL_VIDEO_OPENGL_ES, 1, [ ])
+                AC_DEFINE(SDL_VIDEO_RENDER_OGL_ES, 1, [ ])
+            fi
+            AC_MSG_CHECKING(for OpenGL ES v2 headers)
+            video_opengles_v2=no
+            AC_TRY_COMPILE([
+             #include <GLES2/gl2.h>
+             #include <GLES2/gl2ext.h>
+            ],[
+            ],[
+            video_opengles_v2=yes
+            ])
+            AC_MSG_RESULT($video_opengles_v2)
+            if test x$video_opengles_v2 = xyes; then
+                AC_DEFINE(SDL_VIDEO_OPENGL_ES2, 1, [ ])
+                AC_DEFINE(SDL_VIDEO_RENDER_OGL_ES2, 1, [ ])
+            fi
+        fi
+    fi
+}
+
 dnl Check for Windows OpenGL
 CheckWINDOWSGL()
 {
@@ -2043,6 +2094,7 @@
         CheckDirectFB
         CheckFusionSound
         CheckOpenGLX11
+        CheckOpenGLESX11
         CheckInputEvents
         CheckTslib
         CheckUSBHID
--- a/include/SDL_config.h.in	Sun Jan 08 01:15:20 2012 -0500
+++ b/include/SDL_config.h.in	Sun Jan 08 02:23:37 2012 -0500
@@ -271,6 +271,7 @@
 #undef SDL_VIDEO_RENDER_D3D
 #undef SDL_VIDEO_RENDER_OGL
 #undef SDL_VIDEO_RENDER_OGL_ES
+#undef SDL_VIDEO_RENDER_OGL_ES2
 #undef SDL_VIDEO_RENDER_DIRECTFB
 
 /* Enable OpenGL support */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/render/opengles/SDL_glesfuncs.h	Sun Jan 08 02:23:37 2012 -0500
@@ -0,0 +1,30 @@
+SDL_PROC(void, glBindTexture, (GLenum, GLuint))
+SDL_PROC(void, glBlendFunc, (GLenum, GLenum))
+SDL_PROC(void, glClear, (GLbitfield))
+SDL_PROC(void, glClearColor, (GLclampf, GLclampf, GLclampf, GLclampf))
+SDL_PROC(void, glColor4f, (GLfloat, GLfloat, GLfloat, GLfloat))
+SDL_PROC(void, glDeleteTextures, (GLsizei, const GLuint *))
+SDL_PROC(void, glDisable, (GLenum))
+SDL_PROC(void, glDisableClientState, (GLenum array))
+SDL_PROC(void, glDrawArrays, (GLenum, GLint, GLsizei))
+SDL_PROC(void, glDrawTexiOES, (GLint, GLint, GLint, GLint, GLint))
+SDL_PROC(void, glEnable, (GLenum))
+SDL_PROC(void, glEnableClientState, (GLenum))
+SDL_PROC(void, glGenTextures, (GLsizei, GLuint *))
+SDL_PROC(GLenum, glGetError, (void))
+SDL_PROC(void, glGetIntegerv, (GLenum, GLint *))
+SDL_PROC(void, glLoadIdentity, (void))
+SDL_PROC(void, glMatrixMode, (GLenum))
+SDL_PROC(void, glOrthof, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat))
+SDL_PROC(void, glPixelStorei, (GLenum, GLint))
+SDL_PROC(void, glReadPixels, (GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid*))
+SDL_PROC(void, glTexCoordPointer, (GLint, GLenum, GLsizei, const GLvoid *))
+SDL_PROC(void, glTexEnvf, (GLenum, GLenum, GLfloat))
+SDL_PROC(void, glTexImage2D, (GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *))
+SDL_PROC(void, glTexParameteri, (GLenum, GLenum, GLint))
+SDL_PROC(void, glTexParameteriv, (GLenum, GLenum, const GLint *))
+SDL_PROC(void, glTexSubImage2D, (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *))
+SDL_PROC(void, glVertexPointer, (GLint, GLenum, GLsizei, const GLvoid *))
+SDL_PROC(void, glViewport, (GLint, GLint, GLsizei, GLsizei))
+
+/* vi: set ts=4 sw=4 expandtab: */
--- a/src/render/opengles/SDL_render_gles.c	Sun Jan 08 01:15:20 2012 -0500
+++ b/src/render/opengles/SDL_render_gles.c	Sun Jan 08 02:23:37 2012 -0500
@@ -40,6 +40,9 @@
 
 /* OpenGL ES 1.1 renderer implementation, based on the OpenGL renderer */
 
+/* Used to re-create the window with OpenGL capability */
+extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);
+
 static const float inv255f = 1.0f / 255.0f;
 
 static SDL_Renderer *GLES_CreateRenderer(SDL_Window * window, Uint32 flags);
@@ -92,6 +95,10 @@
         SDL_bool tex_coords;
     } current;
 
+#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
+#include "SDL_glesfuncs.h"
+#undef SDL_PROC
+
     SDL_bool useDrawTexture;
     SDL_bool GL_OES_draw_texture_supported;
 } GLES_RenderData;
@@ -142,6 +149,26 @@
     SDL_SetError("%s: %s", prefix, error);
 }
 
+static int GLES_LoadFunctions(GLES_RenderData * data)
+{
+#ifdef __SDL_NOGETPROCADDR__
+#define SDL_PROC(ret,func,params) data->func=func;
+#else
+#define SDL_PROC(ret,func,params) \
+    do { \
+        data->func = SDL_GL_GetProcAddress(#func); \
+        if ( ! data->func ) { \
+            SDL_SetError("Couldn't load GLES function %s: %s\n", #func, SDL_GetError()); \
+            return -1; \
+        } \
+    } while ( 0 );  
+#endif /* _SDL_NOGETPROCADDR_ */
+
+#include "SDL_glesfuncs.h"
+#undef SDL_PROC
+    return 0;
+}
+
 static SDL_GLContext SDL_CurrentContext = NULL;
 
 static int
@@ -176,14 +203,14 @@
     data->current.blendMode = -1;
     data->current.tex_coords = SDL_FALSE;
 
-    glDisable(GL_DEPTH_TEST);
-    glDisable(GL_CULL_FACE);
+    data->glDisable(GL_DEPTH_TEST);
+    data->glDisable(GL_CULL_FACE);
 
-    glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity();
+    data->glMatrixMode(GL_MODELVIEW);
+    data->glLoadIdentity();
 
-    glEnableClientState(GL_VERTEX_ARRAY);
-    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    data->glEnableClientState(GL_VERTEX_ARRAY);
+    data->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 }
 
 SDL_Renderer *
@@ -193,6 +220,19 @@
     SDL_Renderer *renderer;
     GLES_RenderData *data;
     GLint value;
+    Uint32 windowFlags;
+    
+    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
+    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
+    
+    windowFlags = SDL_GetWindowFlags(window);
+    if (!(windowFlags & SDL_WINDOW_OPENGL)) {
+        if (SDL_RecreateWindow(window, windowFlags | SDL_WINDOW_OPENGL) < 0) {
+            /* Uh oh, better try to put it back... */
+            SDL_RecreateWindow(window, windowFlags);
+            return NULL;
+        }
+    }
 
     renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
     if (!renderer) {
@@ -227,9 +267,6 @@
     renderer->driverdata = data;
     renderer->window = window;
 
-    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
-    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
-
     data->context = SDL_GL_CreateContext(window);
     if (!data->context) {
         GLES_DestroyRenderer(renderer);
@@ -240,6 +277,11 @@
         return NULL;
     }
 
+    if (GLES_LoadFunctions(data) < 0) {
+        GLES_DestroyRenderer(renderer);
+        return NULL;
+    }
+
     if (flags & SDL_RENDERER_PRESENTVSYNC) {
         SDL_GL_SetSwapInterval(1);
     } else {
@@ -262,9 +304,9 @@
     }
 #endif
 
-    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
+    data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
     renderer->info.max_texture_width = value;
-    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
+    data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
     renderer->info.max_texture_height = value;
 
     /* Set up parameters for rendering */
@@ -313,6 +355,7 @@
 static int
 GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
 {
+    GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
     GLES_TextureData *data;
     GLint internalFormat;
     GLenum format, type;
@@ -351,9 +394,9 @@
 
     texture->driverdata = data;
 
-    glGetError();
-    glEnable(GL_TEXTURE_2D);
-    glGenTextures(1, &data->texture);
+    renderdata->glGetError();
+    renderdata->glEnable(GL_TEXTURE_2D);
+    renderdata->glGenTextures(1, &data->texture);
 
     data->type = GL_TEXTURE_2D;
     /* no NPOV textures allowed in OpenGL ES (yet) */
@@ -365,17 +408,17 @@
     data->format = format;
     data->formattype = type;
     scaleMode = GetScaleQuality();
-    glBindTexture(data->type, data->texture);
-    glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, scaleMode);
-    glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER, scaleMode);
-    glTexParameteri(data->type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameteri(data->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    renderdata->glBindTexture(data->type, data->texture);
+    renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, scaleMode);
+    renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER, scaleMode);
+    renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
-    glTexImage2D(data->type, 0, internalFormat, texture_w,
+    renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
                              texture_h, 0, format, type, NULL);
-    glDisable(GL_TEXTURE_2D);
+    renderdata->glDisable(GL_TEXTURE_2D);
 
-    result = glGetError();
+    result = renderdata->glGetError();
     if (result != GL_NO_ERROR) {
         GLES_SetError("glTexImage2D()", result);
         return -1;
@@ -387,6 +430,7 @@
 GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
                    const SDL_Rect * rect, const void *pixels, int pitch)
 {
+    GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
     GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
     Uint8 *blob = NULL;
     Uint8 *src;
@@ -421,11 +465,11 @@
     }
 
     /* Create a texture subimage with the supplied data */
-    glGetError();
-    glEnable(data->type);
-    glBindTexture(data->type, data->texture);
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    glTexSubImage2D(data->type,
+    renderdata->glGetError();
+    renderdata->glEnable(data->type);
+    renderdata->glBindTexture(data->type, data->texture);
+    renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    renderdata->glTexSubImage2D(data->type,
                     0,
                     rect->x,
                     rect->y,
@@ -438,7 +482,7 @@
         SDL_free(blob);
     }
 
-    if (glGetError() != GL_NO_ERROR)
+    if (renderdata->glGetError() != GL_NO_ERROR)
     {
         SDL_SetError("Failed to update texture");
         return -1;
@@ -483,12 +527,12 @@
         return 0;
     }
 
-    glViewport(renderer->viewport.x, renderer->viewport.y,
+    data->glViewport(renderer->viewport.x, renderer->viewport.y,
                renderer->viewport.w, renderer->viewport.h);
 
-    glMatrixMode(GL_PROJECTION);
-    glLoadIdentity();
-    glOrthof((GLfloat) 0,
+    data->glMatrixMode(GL_PROJECTION);
+    data->glLoadIdentity();
+    data->glOrthof((GLfloat) 0,
              (GLfloat) renderer->viewport.w,
              (GLfloat) renderer->viewport.h,
              (GLfloat) 0, 0.0, 1.0);
@@ -501,7 +545,7 @@
     Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
 
     if (color != data->current.color) {
-        glColor4f((GLfloat) r * inv255f,
+        data->glColor4f((GLfloat) r * inv255f,
                         (GLfloat) g * inv255f,
                         (GLfloat) b * inv255f,
                         (GLfloat) a * inv255f);
@@ -515,23 +559,23 @@
     if (blendMode != data->current.blendMode) {
         switch (blendMode) {
         case SDL_BLENDMODE_NONE:
-            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-            glDisable(GL_BLEND);
+            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+            data->glDisable(GL_BLEND);
             break;
         case SDL_BLENDMODE_BLEND:
-            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-            glEnable(GL_BLEND);
-            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+            data->glEnable(GL_BLEND);
+            data->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
             break;
         case SDL_BLENDMODE_ADD:
-            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-            glEnable(GL_BLEND);
-            glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+            data->glEnable(GL_BLEND);
+            data->glBlendFunc(GL_SRC_ALPHA, GL_ONE);
             break;
         case SDL_BLENDMODE_MOD:
-            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-            glEnable(GL_BLEND);
-            glBlendFunc(GL_ZERO, GL_SRC_COLOR);
+            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+            data->glEnable(GL_BLEND);
+            data->glBlendFunc(GL_ZERO, GL_SRC_COLOR);
             break;
         }
         data->current.blendMode = blendMode;
@@ -543,9 +587,9 @@
 {
     if (enabled != data->current.tex_coords) {
         if (enabled) {
-            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+            data->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
         } else {
-            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+            data->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
         }
         data->current.tex_coords = enabled;
     }
@@ -571,14 +615,16 @@
 static int
 GLES_RenderClear(SDL_Renderer * renderer)
 {
+    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
+
     GLES_ActivateRenderer(renderer);
 
-    glClearColor((GLfloat) renderer->r * inv255f,
+    data->glClearColor((GLfloat) renderer->r * inv255f,
                  (GLfloat) renderer->g * inv255f,
                  (GLfloat) renderer->b * inv255f,
                  (GLfloat) renderer->a * inv255f);
 
-    glClear(GL_COLOR_BUFFER_BIT);
+    data->glClear(GL_COLOR_BUFFER_BIT);
 
     return 0;
 }
@@ -587,6 +633,7 @@
 GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
                       int count)
 {
+    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
     int i;
     GLshort *vertices;
 
@@ -597,8 +644,8 @@
         vertices[2*i+0] = (GLshort)points[i].x;
         vertices[2*i+1] = (GLshort)points[i].y;
     }
-    glVertexPointer(2, GL_SHORT, 0, vertices);
-    glDrawArrays(GL_POINTS, 0, count);
+    data->glVertexPointer(2, GL_SHORT, 0, vertices);
+    data->glDrawArrays(GL_POINTS, 0, count);
     SDL_stack_free(vertices);
 
     return 0;
@@ -608,6 +655,7 @@
 GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
                      int count)
 {
+    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
     int i;
     GLshort *vertices;
 
@@ -618,16 +666,16 @@
         vertices[2*i+0] = (GLshort)points[i].x;
         vertices[2*i+1] = (GLshort)points[i].y;
     }
-    glVertexPointer(2, GL_SHORT, 0, vertices);
+    data->glVertexPointer(2, GL_SHORT, 0, vertices);
     if (count > 2 && 
         points[0].x == points[count-1].x && points[0].y == points[count-1].y) {
         /* GL_LINE_LOOP takes care of the final segment */
         --count;
-        glDrawArrays(GL_LINE_LOOP, 0, count);
+        data->glDrawArrays(GL_LINE_LOOP, 0, count);
     } else {
-        glDrawArrays(GL_LINE_STRIP, 0, count);
+        data->glDrawArrays(GL_LINE_STRIP, 0, count);
         /* We need to close the endpoint of the line */
-        glDrawArrays(GL_POINTS, count-1, 1);
+        data->glDrawArrays(GL_POINTS, count-1, 1);
     }
     SDL_stack_free(vertices);
 
@@ -638,6 +686,7 @@
 GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects,
                      int count)
 {
+    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
     int i;
 
     GLES_SetDrawingState(renderer);
@@ -658,8 +707,8 @@
         vertices[6] = maxx;
         vertices[7] = maxy;
 
-        glVertexPointer(2, GL_SHORT, 0, vertices);
-        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+        data->glVertexPointer(2, GL_SHORT, 0, vertices);
+        data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
     }
 
     return 0;
@@ -677,9 +726,9 @@
 
     GLES_ActivateRenderer(renderer);
 
-    glEnable(GL_TEXTURE_2D);
+    data->glEnable(GL_TEXTURE_2D);
 
-    glBindTexture(texturedata->type, texturedata->texture);
+    data->glBindTexture(texturedata->type, texturedata->texture);
 
     if (texture->modMode) {
         GLES_SetColor(data, texture->r, texture->g, texture->b, texture->a);
@@ -702,9 +751,9 @@
         cropRect[1] = srcrect->y + srcrect->h;
         cropRect[2] = srcrect->w;
         cropRect[3] = -srcrect->h;
-        glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES,
+        data->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES,
                                cropRect);
-        glDrawTexiOES(renderer->viewport.x + dstrect->x,
+        data->glDrawTexiOES(renderer->viewport.x + dstrect->x,
 	              h - (renderer->viewport.y + dstrect->y) - dstrect->h, 0,
                             dstrect->w, dstrect->h);
     } else {
@@ -744,11 +793,11 @@
         texCoords[6] = maxu;
         texCoords[7] = maxv;
 
-        glVertexPointer(2, GL_SHORT, 0, vertices);
-        glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
-        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+        data->glVertexPointer(2, GL_SHORT, 0, vertices);
+        data->glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
+        data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
     }
-    glDisable(GL_TEXTURE_2D);
+    data->glDisable(GL_TEXTURE_2D);
 
     return 0;
 }
@@ -757,6 +806,7 @@
 GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
                     Uint32 pixel_format, void * pixels, int pitch)
 {
+    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
     SDL_Window *window = renderer->window;
     Uint32 temp_format = SDL_PIXELFORMAT_ABGR8888;
     void *temp_pixels;
@@ -776,9 +826,9 @@
 
     SDL_GetWindowSize(window, &w, &h);
 
-    glPixelStorei(GL_PACK_ALIGNMENT, 1);
+    data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
 
-    glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h,
+    data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h,
                        GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels);
 
     /* Flip the rows to be top-down */
@@ -815,6 +865,8 @@
 static void
 GLES_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
 {
+    GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
+
     GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
 
     GLES_ActivateRenderer(renderer);
@@ -823,7 +875,7 @@
         return;
     }
     if (data->texture) {
-        glDeleteTextures(1, &data->texture);
+        renderdata->glDeleteTextures(1, &data->texture);
     }
     if (data->pixels) {
         SDL_free(data->pixels);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/render/opengles2/SDL_gles2funcs.h	Sun Jan 08 02:23:37 2012 -0500
@@ -0,0 +1,42 @@
+SDL_PROC(void, glActiveTexture, (GLenum))
+SDL_PROC(void, glAttachShader, (GLuint, GLuint))
+SDL_PROC(void, glBindAttribLocation, (GLuint, GLuint, const char *))
+SDL_PROC(void, glBindTexture, (GLenum, GLuint))
+SDL_PROC(void, glBlendFunc, (GLenum, GLenum))
+SDL_PROC(void, glClear, (GLbitfield))
+SDL_PROC(void, glClearColor, (GLclampf, GLclampf, GLclampf, GLclampf))
+SDL_PROC(void, glCompileShader, (GLuint))
+SDL_PROC(GLuint, glCreateProgram, (void))
+SDL_PROC(GLuint, glCreateShader, (GLenum))
+SDL_PROC(void, glDeleteProgram, (GLuint))
+SDL_PROC(void, glDeleteShader, (GLuint))
+SDL_PROC(void, glDeleteTextures, (GLsizei, const GLuint *))
+SDL_PROC(void, glDisable, (GLenum))
+SDL_PROC(void, glDisableVertexAttribArray, (GLuint))
+SDL_PROC(void, glDrawArrays, (GLenum, GLint, GLsizei))
+SDL_PROC(void, glEnable, (GLenum))
+SDL_PROC(void, glEnableVertexAttribArray, (GLuint))
+SDL_PROC(void, glFinish, (void))
+SDL_PROC(void, glGenTextures, (GLsizei, GLuint *))
+SDL_PROC(void, glGetBooleanv, (GLenum, GLboolean *))
+SDL_PROC(const GLubyte *, glGetString, (GLenum))
+SDL_PROC(GLenum, glGetError, (void))
+SDL_PROC(void, glGetIntegerv, (GLenum, GLint *))
+SDL_PROC(void, glGetProgramiv, (GLuint, GLenum, GLint *))
+SDL_PROC(void, glGetShaderInfoLog, (GLuint, GLsizei, GLsizei *, char *))
+SDL_PROC(void, glGetShaderiv, (GLuint, GLenum, GLint *))
+SDL_PROC(GLint, glGetUniformLocation, (GLuint, const char *))
+SDL_PROC(void, glLinkProgram, (GLuint))
+SDL_PROC(void, glPixelStorei, (GLenum, GLint))
+SDL_PROC(void, glReadPixels, (GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid*))
+SDL_PROC(void, glShaderBinary, (GLsizei, const GLuint *, GLenum, const void *, GLsizei))
+SDL_PROC(void, glShaderSource, (GLuint, GLsizei, const char **, const GLint *))
+SDL_PROC(void, glTexImage2D, (GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const void *))
+SDL_PROC(void, glTexParameteri, (GLenum, GLenum, GLint))
+SDL_PROC(void, glTexSubImage2D, (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *))
+SDL_PROC(void, glUniform1i, (GLint, GLint))
+SDL_PROC(void, glUniform4f, (GLint, GLfloat, GLfloat, GLfloat, GLfloat))
+SDL_PROC(void, glUniformMatrix4fv, (GLint, GLsizei, GLboolean, const GLfloat *))
+SDL_PROC(void, glUseProgram, (GLuint))
+SDL_PROC(void, glVertexAttribPointer, (GLuint, GLint, GLenum, GLboolean, GLsizei, const void *))
+SDL_PROC(void, glViewport, (GLint, GLint, GLsizei, GLsizei))
--- a/src/render/opengles2/SDL_render_gles2.c	Sun Jan 08 01:15:20 2012 -0500
+++ b/src/render/opengles2/SDL_render_gles2.c	Sun Jan 08 02:23:37 2012 -0500
@@ -27,6 +27,9 @@
 #include "../SDL_sysrender.h"
 #include "SDL_shaders_gles2.h"
 
+/* Used to re-create the window with OpenGL capability */
+extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);
+
 /*************************************************************************************************
  * Bootstrap data                                                                                *
  *************************************************************************************************/
@@ -128,6 +131,10 @@
         SDL_bool tex_coords;
     } current;
 
+#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
+#include "SDL_gles2funcs.h"
+#undef SDL_PROC
+
     int shader_format_count;
     GLenum *shader_formats;
     GLES2_ShaderCache shader_cache;
@@ -149,6 +156,26 @@
 
 static SDL_GLContext SDL_CurrentContext = NULL;
 
+static int GLES2_LoadFunctions(GLES2_DriverContext * data)
+{
+#ifdef __SDL_NOGETPROCADDR__
+#define SDL_PROC(ret,func,params) data->func=func;
+#else
+#define SDL_PROC(ret,func,params) \
+    do { \
+        data->func = SDL_GL_GetProcAddress(#func); \
+        if ( ! data->func ) { \
+            SDL_SetError("Couldn't load GLES2 function %s: %s\n", #func, SDL_GetError()); \
+            return -1; \
+        } \
+    } while ( 0 );  
+#endif /* _SDL_NOGETPROCADDR_ */
+
+#include "SDL_gles2funcs.h"
+#undef SDL_PROC
+    return 0;
+}
+
 static int
 GLES2_ActivateRenderer(SDL_Renderer * renderer)
 {
@@ -171,6 +198,8 @@
 static void
 GLES2_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
 {
+    GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
+    
     if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
         /* Rebind the context to the window area */
         SDL_CurrentContext = NULL;
@@ -178,7 +207,7 @@
 
     if (event->event == SDL_WINDOWEVENT_MINIMIZED) {
         /* According to Apple documentation, we need to finish drawing NOW! */
-        glFinish();
+        rdata->glFinish();
     }
 }
 
@@ -192,7 +221,7 @@
         return 0;
     }
 
-    glViewport(renderer->viewport.x, renderer->viewport.y,
+    rdata->glViewport(renderer->viewport.x, renderer->viewport.y,
                renderer->viewport.w, renderer->viewport.h);
     return 0;
 }
@@ -212,7 +241,7 @@
             entry = rdata->shader_cache.head;
             while (entry)
             {
-                glDeleteShader(entry->id);
+                rdata->glDeleteShader(entry->id);
                 next = entry->next;
                 SDL_free(entry);
                 entry = next;
@@ -223,7 +252,7 @@
             GLES2_ProgramCacheEntry *next;
             entry = rdata->program_cache.head;
             while (entry) {
-                glDeleteProgram(entry->id);
+                rdata->glDeleteProgram(entry->id);
                 next = entry->next;
                 SDL_free(entry);
                 entry = next;
@@ -267,6 +296,7 @@
 static int
 GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
 {
+    GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
     GLES2_TextureData *tdata;
     GLenum format;
     GLenum type;
@@ -316,19 +346,19 @@
     }
 
     /* Allocate the texture */
-    glGetError();
-    glGenTextures(1, &tdata->texture);
-    glActiveTexture(GL_TEXTURE0);
-    glBindTexture(tdata->texture_type, tdata->texture);
-    glTexParameteri(tdata->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode);
-    glTexParameteri(tdata->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode);
-    glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    glTexImage2D(tdata->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL);
-    if (glGetError() != GL_NO_ERROR)
+    rdata->glGetError();
+    rdata->glGenTextures(1, &tdata->texture);
+    rdata->glActiveTexture(GL_TEXTURE0);
+    rdata->glBindTexture(tdata->texture_type, tdata->texture);
+    rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode);
+    rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode);
+    rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    rdata->glTexImage2D(tdata->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL);
+    if (rdata->glGetError() != GL_NO_ERROR)
     {
         SDL_SetError("Texture creation failed");
-        glDeleteTextures(1, &tdata->texture);
+        rdata->glDeleteTextures(1, &tdata->texture);
         SDL_free(tdata);
         return -1;
     }
@@ -339,6 +369,7 @@
 static void
 GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture)
 {
+    GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
     GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
 
     GLES2_ActivateRenderer(renderer);
@@ -346,7 +377,7 @@
     /* Destroy the texture */
     if (tdata)
     {
-        glDeleteTextures(1, &tdata->texture);
+        rdata->glDeleteTextures(1, &tdata->texture);
         SDL_free(tdata->pixel_data);
         SDL_free(tdata);
         texture->driverdata = NULL;
@@ -386,6 +417,7 @@
 GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
                     const void *pixels, int pitch)
 {
+    GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
     GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
     Uint8 *blob = NULL;
     Uint8 *src;
@@ -393,7 +425,7 @@
     int y;
 
     GLES2_ActivateRenderer(renderer);
-
+    
     /* Bail out if we're supposed to update an empty rectangle */
     if (rect->w <= 0 || rect->h <= 0)
         return 0;
@@ -420,11 +452,11 @@
     }
 
     /* Create a texture subimage with the supplied data */
-    glGetError();
-    glActiveTexture(GL_TEXTURE0);
-    glBindTexture(tdata->texture_type, tdata->texture);
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    glTexSubImage2D(tdata->texture_type,
+    rdata->glGetError();
+    rdata->glActiveTexture(GL_TEXTURE0);
+    rdata->glBindTexture(tdata->texture_type, tdata->texture);
+    rdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    rdata->glTexSubImage2D(tdata->texture_type,
                     0,
                     rect->x,
                     rect->y,
@@ -437,7 +469,7 @@
         SDL_free(blob);
     }
 
-    if (glGetError() != GL_NO_ERROR)
+    if (rdata->glGetError() != GL_NO_ERROR)
     {
         SDL_SetError("Failed to update texture");
         return -1;
@@ -505,33 +537,33 @@
     entry->blend_mode = blendMode;
     
     /* Create the program and link it */
-    glGetError();
-    entry->id = glCreateProgram();
-    glAttachShader(entry->id, vertex->id);
-    glAttachShader(entry->id, fragment->id);
-    glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION, "a_position");
-    glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD, "a_texCoord");
-    glLinkProgram(entry->id);
-    glGetProgramiv(entry->id, GL_LINK_STATUS, &linkSuccessful);
-    if (glGetError() != GL_NO_ERROR || !linkSuccessful)
+    rdata->glGetError();
+    entry->id = rdata->glCreateProgram();
+    rdata->glAttachShader(entry->id, vertex->id);
+    rdata->glAttachShader(entry->id, fragment->id);
+    rdata->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION, "a_position");
+    rdata->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD, "a_texCoord");
+    rdata->glLinkProgram(entry->id);
+    rdata->glGetProgramiv(entry->id, GL_LINK_STATUS, &linkSuccessful);
+    if (rdata->glGetError() != GL_NO_ERROR || !linkSuccessful)
     {
         SDL_SetError("Failed to link shader program");
-        glDeleteProgram(entry->id);
+        rdata->glDeleteProgram(entry->id);
         SDL_free(entry);
         return NULL;
     }
     
     /* Predetermine locations of uniform variables */
     entry->uniform_locations[GLES2_UNIFORM_PROJECTION] =
-        glGetUniformLocation(entry->id, "u_projection");
+        rdata->glGetUniformLocation(entry->id, "u_projection");
     entry->uniform_locations[GLES2_UNIFORM_TEXTURE] =
-        glGetUniformLocation(entry->id, "u_texture");
+        rdata->glGetUniformLocation(entry->id, "u_texture");
     entry->uniform_locations[GLES2_UNIFORM_MODULATION] =
-        glGetUniformLocation(entry->id, "u_modulation");
+        rdata->glGetUniformLocation(entry->id, "u_modulation");
     entry->uniform_locations[GLES2_UNIFORM_COLOR] =
-        glGetUniformLocation(entry->id, "u_color");
+        rdata->glGetUniformLocation(entry->id, "u_color");
     entry->uniform_locations[GLES2_UNIFORM_COLORTABLE] =
-        glGetUniformLocation(entry->id, "u_colorTable");
+        rdata->glGetUniformLocation(entry->id, "u_colorTable");
 
     /* Cache the linked program */
     if (rdata->program_cache.head)
@@ -559,7 +591,7 @@
         shaderEntry = rdata->program_cache.tail->fragment_shader;
         if (--shaderEntry->references <= 0)
             GLES2_EvictShader(renderer, shaderEntry);
-        glDeleteProgram(rdata->program_cache.tail->id);
+        rdata->glDeleteProgram(rdata->program_cache.tail->id);
         rdata->program_cache.tail = rdata->program_cache.tail->prev;
         SDL_free(rdata->program_cache.tail->next);
         rdata->program_cache.tail->next = NULL;
@@ -628,29 +660,29 @@
     entry->instance = instance;
 
     /* Compile or load the selected shader instance */
-    glGetError();
-    entry->id = glCreateShader(instance->type);
+    rdata->glGetError();
+    entry->id = rdata->glCreateShader(instance->type);
     if (instance->format == (GLenum)-1)
     {
-        glShaderSource(entry->id, 1, (const char **)&instance->data, NULL);
-        glCompileShader(entry->id);
-        glGetShaderiv(entry->id, GL_COMPILE_STATUS, &compileSuccessful);
+        rdata->glShaderSource(entry->id, 1, (const char **)&instance->data, NULL);
+        rdata->glCompileShader(entry->id);
+        rdata->glGetShaderiv(entry->id, GL_COMPILE_STATUS, &compileSuccessful);
     }
     else
     {
-        glShaderBinary(1, &entry->id, instance->format, instance->data, instance->length);
+        rdata->glShaderBinary(1, &entry->id, instance->format, instance->data, instance->length);
         compileSuccessful = GL_TRUE;
     }
-    if (glGetError() != GL_NO_ERROR || !compileSuccessful)
+    if (rdata->glGetError() != GL_NO_ERROR || !compileSuccessful)
     {
         char *info = NULL;
         int length = 0;
 
-        glGetShaderiv(entry->id, GL_INFO_LOG_LENGTH, &length);
+        rdata->glGetShaderiv(entry->id, GL_INFO_LOG_LENGTH, &length);
         if (length > 0) {
             info = SDL_stack_alloc(char, length);
             if (info) {
-                glGetShaderInfoLog(entry->id, length, &length, info);
+                rdata->glGetShaderInfoLog(entry->id, length, &length, info);
             }
         }
         if (info) {
@@ -659,7 +691,7 @@
         } else {
             SDL_SetError("Failed to load the shader");
         }
-        glDeleteShader(entry->id);
+        rdata->glDeleteShader(entry->id);
         SDL_free(entry);
         return NULL;
     }
@@ -690,7 +722,7 @@
     --rdata->shader_cache.count;
 
     /* Deallocate the shader */
-    glDeleteShader(entry->id);
+    rdata->glDeleteShader(entry->id);
     SDL_free(entry);
 }
 
@@ -746,9 +778,9 @@
         goto fault;
 
     /* Select that program in OpenGL */
-    glGetError();
-    glUseProgram(program->id);
-    if (glGetError() != GL_NO_ERROR)
+    rdata->glGetError();
+    rdata->glUseProgram(program->id);
+    if (rdata->glGetError() != GL_NO_ERROR)
     {
         SDL_SetError("Failed to select program");
         goto fault;
@@ -799,9 +831,9 @@
 
     /* Set the projection matrix */
     locProjection = rdata->current_program->uniform_locations[GLES2_UNIFORM_PROJECTION];
-    glGetError();
-    glUniformMatrix4fv(locProjection, 1, GL_FALSE, (GLfloat *)projection);
-    if (glGetError() != GL_NO_ERROR)
+    rdata->glGetError();
+    rdata->glUniformMatrix4fv(locProjection, 1, GL_FALSE, (GLfloat *)projection);
+    if (rdata->glGetError() != GL_NO_ERROR)
     {
         SDL_SetError("Failed to set orthographic projection");
         return -1;
@@ -829,14 +861,16 @@
 static int
 GLES2_RenderClear(SDL_Renderer * renderer)
 {
-    GLES2_ActivateRenderer(renderer);
+    GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
 
-    glClearColor((GLfloat) renderer->r * inv255f,
+    GLES2_ActivateRenderer(renderer);
+    
+    rdata->glClearColor((GLfloat) renderer->r * inv255f,
                  (GLfloat) renderer->g * inv255f,
                  (GLfloat) renderer->b * inv255f,
                  (GLfloat) renderer->a * inv255f);
 
-    glClear(GL_COLOR_BUFFER_BIT);
+    rdata->glClear(GL_COLOR_BUFFER_BIT);
 
     return 0;
 }
@@ -848,19 +882,19 @@
         switch (blendMode) {
         default:
         case SDL_BLENDMODE_NONE:
-            glDisable(GL_BLEND);
+            rdata->glDisable(GL_BLEND);
             break;
         case SDL_BLENDMODE_BLEND:
-            glEnable(GL_BLEND);
-            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+            rdata->glEnable(GL_BLEND);
+            rdata->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
             break;
         case SDL_BLENDMODE_ADD:
-            glEnable(GL_BLEND);
-            glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+            rdata->glEnable(GL_BLEND);
+            rdata->glBlendFunc(GL_SRC_ALPHA, GL_ONE);
             break;
         case SDL_BLENDMODE_MOD:
-            glEnable(GL_BLEND);
-            glBlendFunc(GL_ZERO, GL_SRC_COLOR);
+            rdata->glEnable(GL_BLEND);
+            rdata->glBlendFunc(GL_ZERO, GL_SRC_COLOR);
             break;
         }
         rdata->current.blendMode = blendMode;
@@ -872,9 +906,9 @@
 {
     if (enabled != rdata->current.tex_coords) {
         if (enabled) {
-            glEnableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
+            rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
         } else {
-            glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
+            rdata->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
         }
         rdata->current.tex_coords = enabled;
     }
@@ -887,7 +921,7 @@
     int blendMode = renderer->blendMode;
     GLuint locColor;
 
-    glGetError();
+    rdata->glGetError();
 
     GLES2_ActivateRenderer(renderer);
 
@@ -901,7 +935,7 @@
 
     /* Select the color to draw with */
     locColor = rdata->current_program->uniform_locations[GLES2_UNIFORM_COLOR];
-    glUniform4f(locColor,
+    rdata->glUniform4f(locColor,
                 renderer->r * inv255f,
                 renderer->g * inv255f,
                 renderer->b * inv255f,
@@ -912,6 +946,7 @@
 static int
 GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int count)
 {
+    GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
     GLfloat *vertices;
     int idx;
 
@@ -929,11 +964,11 @@
         vertices[idx * 2] = x;
         vertices[(idx * 2) + 1] = y;
     }
-    glGetError();
-    glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
-    glDrawArrays(GL_POINTS, 0, count);
+    rdata->glGetError();
+    rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
+    rdata->glDrawArrays(GL_POINTS, 0, count);
     SDL_stack_free(vertices);
-    if (glGetError() != GL_NO_ERROR)
+    if (rdata->glGetError() != GL_NO_ERROR)
     {
         SDL_SetError("Failed to render lines");
         return -1;
@@ -944,6 +979,7 @@
 static int
 GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count)
 {
+    GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
     GLfloat *vertices;
     int idx;
 
@@ -961,17 +997,17 @@
         vertices[idx * 2] = x;
         vertices[(idx * 2) + 1] = y;
     }
-    glGetError();
-    glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
-    glDrawArrays(GL_LINE_STRIP, 0, count);
+    rdata->glGetError();
+    rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
+    rdata->glDrawArrays(GL_LINE_STRIP, 0, count);
 
     /* We need to close the endpoint of the line */
     if (count == 2 ||
         points[0].x != points[count-1].x || points[0].y != points[count-1].y) {
-        glDrawArrays(GL_POINTS, count-1, 1);
+        rdata->glDrawArrays(GL_POINTS, count-1, 1);
     }
     SDL_stack_free(vertices);
-    if (glGetError() != GL_NO_ERROR)
+    if (rdata->glGetError() != GL_NO_ERROR)
     {
         SDL_SetError("Failed to render lines");
         return -1;
@@ -982,6 +1018,7 @@
 static int
 GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count)
 {
+    GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
     GLfloat vertices[8];
     int idx;
 
@@ -990,7 +1027,7 @@
     }
 
     /* Emit a line loop for each rectangle */
-    glGetError();
+    rdata->glGetError();
     for (idx = 0; idx < count; ++idx) {
         const SDL_Rect *rect = &rects[idx];
 
@@ -1007,10 +1044,10 @@
         vertices[5] = yMax;
         vertices[6] = xMax;
         vertices[7] = yMax;
-        glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
-        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+        rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
+        rdata->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
     }
-    if (glGetError() != GL_NO_ERROR)
+    if (rdata->glGetError() != GL_NO_ERROR)
     {
         SDL_SetError("Failed to render lines");
         return -1;
@@ -1055,14 +1092,14 @@
 
     /* Select the target texture */
     locTexture = rdata->current_program->uniform_locations[GLES2_UNIFORM_TEXTURE];
-    glGetError();
-    glActiveTexture(GL_TEXTURE0);
-    glBindTexture(tdata->texture_type, tdata->texture);
-    glUniform1i(locTexture, 0);
+    rdata->glGetError();
+    rdata->glActiveTexture(GL_TEXTURE0);
+    rdata->glBindTexture(tdata->texture_type, tdata->texture);
+    rdata->glUniform1i(locTexture, 0);
 
     /* Configure color modulation */
     locModulation = rdata->current_program->uniform_locations[GLES2_UNIFORM_MODULATION];
-    glUniform4f(locModulation,
+    rdata->glUniform4f(locModulation,
                 texture->r * inv255f,
                 texture->g * inv255f,
                 texture->b * inv255f,
@@ -1082,7 +1119,7 @@
     vertices[5] = (GLfloat)(dstrect->y + dstrect->h);
     vertices[6] = (GLfloat)(dstrect->x + dstrect->w);
     vertices[7] = (GLfloat)(dstrect->y + dstrect->h);
-    glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
+    rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
     texCoords[0] = srcrect->x / (GLfloat)texture->w;
     texCoords[1] = srcrect->y / (GLfloat)texture->h;
     texCoords[2] = (srcrect->x + srcrect->w) / (GLfloat)texture->w;
@@ -1091,9 +1128,9 @@
     texCoords[5] = (srcrect->y + srcrect->h) / (GLfloat)texture->h;
     texCoords[6] = (srcrect->x + srcrect->w) / (GLfloat)texture->w;
     texCoords[7] = (srcrect->y + srcrect->h) / (GLfloat)texture->h;
-    glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords);
-    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-    if (glGetError() != GL_NO_ERROR)
+    rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords);
+    rdata->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+    if (rdata->glGetError() != GL_NO_ERROR)
     {
         SDL_SetError("Failed to render texture");
         return -1;
@@ -1105,6 +1142,7 @@
 GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
                     Uint32 pixel_format, void * pixels, int pitch)
 {
+    GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
     SDL_Window *window = renderer->window;
     Uint32 temp_format = SDL_PIXELFORMAT_ABGR8888;
     void *temp_pixels;
@@ -1124,9 +1162,9 @@
 
     SDL_GetWindowSize(window, &w, &h);
 
-    glPixelStorei(GL_PACK_ALIGNMENT, 1);
+    rdata->glPixelStorei(GL_PACK_ALIGNMENT, 1);
 
-    glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h,
+    rdata->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h,
                        GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels);
 
     /* Flip the rows to be top-down */
@@ -1181,8 +1219,8 @@
     rdata->current.blendMode = -1;
     rdata->current.tex_coords = SDL_FALSE;
 
-    glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
-    glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
+    rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
+    rdata->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
 }
 
 static SDL_Renderer *
@@ -1194,6 +1232,19 @@
 #ifndef ZUNE_HD
     GLboolean hasCompiler;
 #endif
+    Uint32 windowFlags;
+    
+    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
+    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
+    
+    windowFlags = SDL_GetWindowFlags(window);
+    if (!(windowFlags & SDL_WINDOW_OPENGL)) {
+        if (SDL_RecreateWindow(window, windowFlags | SDL_WINDOW_OPENGL) < 0) {
+            /* Uh oh, better try to put it back... */
+            SDL_RecreateWindow(window, windowFlags);
+            return NULL;
+        }
+    }
 
     /* Create the renderer struct */
     renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(SDL_Renderer));
@@ -1214,9 +1265,6 @@
     renderer->window = window;
 
     /* Create an OpenGL ES 2.0 context */
-    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
-    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
-
     rdata->context = SDL_GL_CreateContext(window);
     if (!rdata->context)
     {
@@ -1228,6 +1276,11 @@
         return NULL;
     }
 
+    if (GLES2_LoadFunctions(rdata) < 0) {
+        GLES2_DestroyRenderer(renderer);
+        return NULL;
+    }
+
     if (flags & SDL_RENDERER_PRESENTVSYNC) {
         SDL_GL_SetSwapInterval(1);
     } else {
@@ -1239,12 +1292,12 @@
 
     /* Determine supported shader formats */
     /* HACK: glGetInteger is broken on the Zune HD's compositor, so we just hardcode this */
-    glGetError();
+    rdata->glGetError();
 #ifdef ZUNE_HD
     nFormats = 1;
 #else /* !ZUNE_HD */
-    glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &nFormats);
-    glGetBooleanv(GL_SHADER_COMPILER, &hasCompiler);
+    rdata->glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &nFormats);
+    rdata->glGetBooleanv(GL_SHADER_COMPILER, &hasCompiler);
     if (hasCompiler)
         ++nFormats;
 #endif /* ZUNE_HD */
@@ -1259,8 +1312,8 @@
 #ifdef ZUNE_HD
     rdata->shader_formats[0] = GL_NVIDIA_PLATFORM_BINARY_NV;
 #else /* !ZUNE_HD */
-    glGetIntegerv(GL_SHADER_BINARY_FORMATS, (GLint *)rdata->shader_formats);
-    if (glGetError() != GL_NO_ERROR)
+    rdata->glGetIntegerv(GL_SHADER_BINARY_FORMATS, (GLint *)rdata->shader_formats);
+    if (rdata->glGetError() != GL_NO_ERROR)
     {
         GLES2_DestroyRenderer(renderer);
         SDL_SetError("Failed to query supported shader formats");
--- a/src/video/SDL_sysvideo.h	Sun Jan 08 01:15:20 2012 -0500
+++ b/src/video/SDL_sysvideo.h	Sun Jan 08 02:23:37 2012 -0500
@@ -286,7 +286,7 @@
     void *driverdata;
     struct SDL_GLDriverData *gl_data;
 
-#if SDL_VIDEO_DRIVER_PANDORA
+#if SDL_VIDEO_OPENGL_ES
     struct SDL_PrivateGLESData *gles_data;
 #endif
 
--- a/src/video/SDL_video.c	Sun Jan 08 01:15:20 2012 -0500
+++ b/src/video/SDL_video.c	Sun Jan 08 02:23:37 2012 -0500
@@ -189,6 +189,9 @@
         }
         return hasAcceleratedOpenGL;
     }
+#elif SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
+    /* Let's be optimistic about this! */
+    return SDL_TRUE;
 #else
     return SDL_FALSE;
 #endif
@@ -1138,7 +1141,7 @@
     }
 
     /* Some platforms have OpenGL enabled by default */
-#if (SDL_VIDEO_OPENGL && __MACOSX__) || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
+#if (SDL_VIDEO_OPENGL && __MACOSX__) || __IPHONEOS__ || __ANDROID__
     flags |= SDL_WINDOW_OPENGL;
 #endif
     if (flags & SDL_WINDOW_OPENGL) {
--- a/src/video/x11/SDL_x11opengles.c	Sun Jan 08 01:15:20 2012 -0500
+++ b/src/video/x11/SDL_x11opengles.c	Sun Jan 08 02:23:37 2012 -0500
@@ -25,7 +25,10 @@
 #include "SDL_x11video.h"
 #include "SDL_x11opengles.h"
 
-#define DEFAULT_OPENGL	"/usr/lib/libGLES_CM.so"
+#define DEFAULT_EGL "/usr/lib/libEGL.so"
+#define DEFAULT_OGL_ES2 "/usr/lib/libGLESv2.so"
+#define DEFAULT_OGL_ES_PVR "/usr/lib/libGLES_CM.so"
+#define DEFAULT_OGL_ES "/usr/lib/libGLESv1_CM.so"
 
 #define LOAD_FUNC(NAME) \
 	*((void**)&_this->gles_data->NAME) = dlsym(handle, #NAME); \
@@ -44,13 +47,15 @@
     void *handle;
     void *retval;
 
-    handle = _this->gl_config.dll_handle;
+    handle = _this->gles_data->egl_dll_handle;
     if (_this->gles_data->eglGetProcAddress) {
         retval = _this->gles_data->eglGetProcAddress(proc);
         if (retval) {
             return retval;
         }
     }
+    
+    handle = _this->gl_config.dll_handle;
 #if defined(__OpenBSD__) && !defined(__ELF__)
 #undef dlsym(x,y);
 #endif
@@ -70,6 +75,7 @@
         _this->gles_data->eglTerminate(_this->gles_data->egl_display);
 
         dlclose(_this->gl_config.dll_handle);
+        dlclose(_this->gles_data->egl_dll_handle);
 
         _this->gles_data->eglGetProcAddress = NULL;
         _this->gles_data->eglChooseConfig = NULL;
@@ -111,7 +117,7 @@
         dlclose(handle);
         path = getenv("SDL_VIDEO_GL_DRIVER");
         if (path == NULL) {
-            path = DEFAULT_OPENGL;
+            path = DEFAULT_EGL;
         }
         handle = dlopen(path, dlopen_flags);
     }
@@ -153,6 +159,29 @@
         return -1;
     }
 
+    _this->gles_data->egl_dll_handle = handle;
+
+    path = getenv("SDL_VIDEO_GL_DRIVER");
+    handle = dlopen(path, dlopen_flags);
+    if ((path == NULL) | (handle == NULL)) {
+        if (_this->gl_config.major_version > 1) {
+            path = DEFAULT_OGL_ES2;
+            handle = dlopen(path, dlopen_flags);
+        } else {
+            path = DEFAULT_OGL_ES;
+            handle = dlopen(path, dlopen_flags);
+            if (handle == NULL) {
+                path = DEFAULT_OGL_ES_PVR;
+                handle = dlopen(path, dlopen_flags);
+            }
+        }
+    }
+
+    if (handle == NULL) {
+        SDL_SetError("Could not initialize OpenGL ES library");
+        return -1;
+    }
+
     _this->gl_config.dll_handle = handle;
     _this->gl_config.driver_loaded = 1;
 
@@ -218,6 +247,13 @@
         attribs[i++] = _this->gl_config.multisamplesamples;
     }
 
+    attribs[i++] = EGL_RENDERABLE_TYPE;
+    if (_this->gl_config.major_version == 2) {
+        attribs[i++] = EGL_OPENGL_ES2_BIT;
+    } else {
+        attribs[i++] = EGL_OPENGL_ES_BIT;
+    }
+
     attribs[i++] = EGL_NONE;
 
     if (_this->gles_data->eglChooseConfig(_this->gles_data->egl_display,
@@ -260,17 +296,25 @@
 SDL_GLContext
 X11_GLES_CreateContext(_THIS, SDL_Window * window)
 {
-    int retval;
+    EGLint context_attrib_list[] = {
+        EGL_CONTEXT_CLIENT_VERSION,
+        1,
+        EGL_NONE
+    };
+
     SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
     Display *display = data->videodata->display;
 
     XSync(display, False);
 
+    if (_this->gl_config.major_version) {
+        context_attrib_list[1] = _this->gl_config.major_version;
+    }
 
     _this->gles_data->egl_context =
         _this->gles_data->eglCreateContext(_this->gles_data->egl_display,
                                            _this->gles_data->egl_config,
-                                           EGL_NO_CONTEXT, NULL);
+                                           EGL_NO_CONTEXT, context_attrib_list);
     XSync(display, False);
 
     if (_this->gles_data->egl_context == EGL_NO_CONTEXT) {
@@ -280,12 +324,12 @@
 
     _this->gles_data->egl_active = 1;
 
-    if (_this->gles_data->egl_active)
-        retval = 1;
-    else
-        retval = 0;
+    if (X11_GLES_MakeCurrent(_this, window, context) < 0) {
+        X11_GLES_DeleteContext(_this, context);
+        return NULL;
+    }
 
-    return (retval);
+    return (SDL_GLContext)(1);
 }
 
 int
--- a/src/video/x11/SDL_x11opengles.h	Sun Jan 08 01:15:20 2012 -0500
+++ b/src/video/x11/SDL_x11opengles.h	Sun Jan 08 02:23:37 2012 -0500
@@ -32,6 +32,7 @@
 {
     int egl_active;             /* to stop switching drivers while we have a valid context */
     XVisualInfo *egl_visualinfo;
+    void *egl_dll_handle;
     EGLDisplay egl_display;
     EGLContext egl_context;     /* Current GLES context */
     EGLSurface egl_surface;
--- a/src/video/x11/SDL_x11video.c	Sun Jan 08 01:15:20 2012 -0500
+++ b/src/video/x11/SDL_x11video.c	Sun Jan 08 02:23:37 2012 -0500
@@ -34,7 +34,7 @@
 #include "SDL_x11shape.h"
 #include "SDL_x11touch.h" 
 
-#if SDL_VIDEO_DRIVER_PANDORA
+#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
 #include "SDL_x11opengles.h"
 #endif
 
@@ -110,7 +110,7 @@
     }
     SDL_free(data->windowlist);
     SDL_free(device->driverdata);
-#if SDL_VIDEO_DRIVER_PANDORA
+#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
     SDL_free(device->gles_data);
 #endif
     SDL_free(device);
@@ -143,7 +143,7 @@
     }
     device->driverdata = data;
 
-#if SDL_VIDEO_DRIVER_PANDORA
+#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
     device->gles_data = (struct SDL_PrivateGLESData *) SDL_calloc(1, sizeof(SDL_PrivateGLESData));
     if (!device->gles_data) {
         SDL_OutOfMemory();
@@ -226,7 +226,7 @@
     device->GL_SwapWindow = X11_GL_SwapWindow;
     device->GL_DeleteContext = X11_GL_DeleteContext;
 #endif
-#if SDL_VIDEO_DRIVER_PANDORA
+#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
     device->GL_LoadLibrary = X11_GLES_LoadLibrary;
     device->GL_GetProcAddress = X11_GLES_GetProcAddress;
     device->GL_UnloadLibrary = X11_GLES_UnloadLibrary;
--- a/src/video/x11/SDL_x11window.c	Sun Jan 08 01:15:20 2012 -0500
+++ b/src/video/x11/SDL_x11window.c	Sun Jan 08 02:23:37 2012 -0500
@@ -31,7 +31,7 @@
 #include "SDL_x11mouse.h"
 #include "SDL_x11shape.h"
 
-#ifdef SDL_VIDEO_DRIVER_PANDORA
+#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
 #include "SDL_x11opengles.h"
 #endif
 
@@ -289,7 +289,7 @@
         XFree(vinfo);
     } else
 #endif
-#ifdef SDL_VIDEO_DRIVER_PANDORA
+#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
     if (window->flags & SDL_WINDOW_OPENGL) {
         XVisualInfo *vinfo;
 
@@ -401,17 +401,19 @@
         SDL_SetError("Couldn't create window");
         return -1;
     }
-#if SDL_VIDEO_DRIVER_PANDORA
-    /* Create the GLES window surface */
-    _this->gles_data->egl_surface =
-        _this->gles_data->eglCreateWindowSurface(_this->gles_data->
+#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
+    if (window->flags & SDL_WINDOW_OPENGL) {
+        /* Create the GLES window surface */
+        _this->gles_data->egl_surface =
+            _this->gles_data->eglCreateWindowSurface(_this->gles_data->
                                                  egl_display,
                                                  _this->gles_data->egl_config,
                                                  (NativeWindowType) w, NULL);
 
-    if (_this->gles_data->egl_surface == EGL_NO_SURFACE) {
-        SDL_SetError("Could not create GLES window surface");
-        return -1;
+        if (_this->gles_data->egl_surface == EGL_NO_SURFACE) {
+            SDL_SetError("Could not create GLES window surface");
+            return -1;
+        }
     }
 #endif
 
--- a/test/configure	Sun Jan 08 01:15:20 2012 -0500
+++ b/test/configure	Sun Jan 08 02:23:37 2012 -0500
@@ -3764,12 +3764,10 @@
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 
- #if defined (__QNXNTO__)
-    #include <GLES/gl.h>
- #elif defined (__IPHONEOS__)
+ #if defined (__IPHONEOS__)
     #include <OpenGLES/ES1/gl.h>
  #else
-    #error "No OpenGL ES support"
+    #include <GLES/gl.h>
  #endif /* __QNXNTO__ */
 
 int
@@ -3812,12 +3810,13 @@
 { echo "$as_me:$LINENO: result: $have_opengles" >&5
 echo "${ECHO_T}$have_opengles" >&6; }
 
-if test x$have_opengl = xyes; then
+GLLIB=""
+if test x$have_opengles = xyes; then
+    CFLAGS="$CFLAGS -DHAVE_OPENGLES"
+    GLLIB="$XPATH -lGLESv1_CM"
+elif test x$have_opengl = xyes; then
     CFLAGS="$CFLAGS -DHAVE_OPENGL"
     GLLIB="$XPATH $SYS_GL_LIBS"
-elif test x$have_opengles = xyes; then
-    CFLAGS="$CFLAGS -DHAVE_OPENGLES"
-    GLLIB="$XPATH $SYS_GL_LIBS"
 else
     GLLIB=""
 fi
--- a/test/configure.in	Sun Jan 08 01:15:20 2012 -0500
+++ b/test/configure.in	Sun Jan 08 02:23:37 2012 -0500
@@ -103,12 +103,10 @@
 AC_MSG_CHECKING(for OpenGL ES support)
 have_opengles=no
 AC_TRY_COMPILE([
- #if defined (__QNXNTO__)
-    #include <GLES/gl.h>
- #elif defined (__IPHONEOS__)
+ #if defined (__IPHONEOS__)
     #include <OpenGLES/ES1/gl.h>
  #else
-    #error "No OpenGL ES support"
+    #include <GLES/gl.h>
  #endif /* __QNXNTO__ */
 ],[
 ],[
@@ -116,12 +114,13 @@
 ])
 AC_MSG_RESULT($have_opengles)
 
-if test x$have_opengl = xyes; then
+GLLIB=""
+if test x$have_opengles = xyes; then
+    CFLAGS="$CFLAGS -DHAVE_OPENGLES"
+    GLLIB="$XPATH -lGLESv1_CM"
+elif test x$have_opengl = xyes; then
     CFLAGS="$CFLAGS -DHAVE_OPENGL"
     GLLIB="$XPATH $SYS_GL_LIBS"
-elif test x$have_opengles = xyes; then
-    CFLAGS="$CFLAGS -DHAVE_OPENGLES"
-    GLLIB="$XPATH $SYS_GL_LIBS"
 else
     GLLIB=""
 fi