Commit 296e78b6 authored by Sam Lantinga's avatar Sam Lantinga

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.
parent 02fe2020
...@@ -1562,6 +1562,7 @@ Optional Features: ...@@ -1562,6 +1562,7 @@ Optional Features:
[default=yes] [default=yes]
--enable-video-dummy use dummy video driver [default=yes] --enable-video-dummy use dummy video driver [default=yes]
--enable-video-opengl include OpenGL support [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 --enable-input-events use Linux 2.4 unified input interface
[default=yes] [default=yes]
--enable-input-tslib use the Touchscreen library for input --enable-input-tslib use the Touchscreen library for input
...@@ -3772,13 +3773,13 @@ if test "${lt_cv_nm_interface+set}" = set; then ...@@ -3772,13 +3773,13 @@ if test "${lt_cv_nm_interface+set}" = set; then
else else
lt_cv_nm_interface="BSD nm" lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext 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) (eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5 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) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5 cat conftest.err >&5
(eval echo "\"\$as_me:3781: output\"" >&5) (eval echo "\"\$as_me:3782: output\"" >&5)
cat conftest.out >&5 cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin" lt_cv_nm_interface="MS dumpbin"
...@@ -5005,7 +5006,7 @@ ia64-*-hpux*) ...@@ -5005,7 +5006,7 @@ ia64-*-hpux*)
;; ;;
*-*-irix6*) *-*-irix6*)
# Find out which ABI we are using. # 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 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5 (eval $ac_compile) 2>&5
ac_status=$? ac_status=$?
...@@ -7166,11 +7167,11 @@ else ...@@ -7166,11 +7167,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -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) (eval "$lt_compile" 2>conftest.err)
ac_status=$? ac_status=$?
cat conftest.err >&5 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 if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output. # So say no if there are warnings other than the usual output.
...@@ -7505,11 +7506,11 @@ else ...@@ -7505,11 +7506,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -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) (eval "$lt_compile" 2>conftest.err)
ac_status=$? ac_status=$?
cat conftest.err >&5 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 if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output. # So say no if there are warnings other than the usual output.
...@@ -7610,11 +7611,11 @@ else ...@@ -7610,11 +7611,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -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) (eval "$lt_compile" 2>out/conftest.err)
ac_status=$? ac_status=$?
cat out/conftest.err >&5 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 if (exit $ac_status) && test -s out/conftest2.$ac_objext
then then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
...@@ -7665,11 +7666,11 @@ else ...@@ -7665,11 +7666,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -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) (eval "$lt_compile" 2>out/conftest.err)
ac_status=$? ac_status=$?
cat out/conftest.err >&5 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 if (exit $ac_status) && test -s out/conftest2.$ac_objext
then then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
...@@ -10423,7 +10424,7 @@ else ...@@ -10423,7 +10424,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF cat > conftest.$ac_ext <<_LT_EOF
#line 10426 "configure" #line 10427 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
...@@ -10519,7 +10520,7 @@ else ...@@ -10519,7 +10520,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF cat > conftest.$ac_ext <<_LT_EOF
#line 10522 "configure" #line 10523 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
...@@ -14201,11 +14202,11 @@ else ...@@ -14201,11 +14202,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -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) (eval "$lt_compile" 2>conftest.err)
ac_status=$? ac_status=$?
cat conftest.err >&5 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 if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output. # So say no if there are warnings other than the usual output.
...@@ -14300,11 +14301,11 @@ else ...@@ -14300,11 +14301,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -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) (eval "$lt_compile" 2>out/conftest.err)
ac_status=$? ac_status=$?
cat out/conftest.err >&5 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 if (exit $ac_status) && test -s out/conftest2.$ac_objext
then then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
...@@ -14352,11 +14353,11 @@ else ...@@ -14352,11 +14353,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -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) (eval "$lt_compile" 2>out/conftest.err)
ac_status=$? ac_status=$?
cat out/conftest.err >&5 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 if (exit $ac_status) && test -s out/conftest2.$ac_objext
then then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
...@@ -23752,6 +23753,201 @@ _ACEOF ...@@ -23752,6 +23753,201 @@ _ACEOF
fi 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() CheckWINDOWSGL()
{ {
if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then
...@@ -27000,6 +27196,7 @@ case "$host" in ...@@ -27000,6 +27196,7 @@ case "$host" in
CheckDirectFB CheckDirectFB
CheckFusionSound CheckFusionSound
CheckOpenGLX11 CheckOpenGLX11
CheckOpenGLESX11
CheckInputEvents CheckInputEvents
CheckTslib CheckTslib
CheckUSBHID CheckUSBHID
......
...@@ -1474,6 +1474,57 @@ CheckOpenGLX11() ...@@ -1474,6 +1474,57 @@ CheckOpenGLX11()
fi 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 dnl Check for Windows OpenGL
CheckWINDOWSGL() CheckWINDOWSGL()
{ {
...@@ -2043,6 +2094,7 @@ case "$host" in ...@@ -2043,6 +2094,7 @@ case "$host" in
CheckDirectFB CheckDirectFB
CheckFusionSound CheckFusionSound
CheckOpenGLX11 CheckOpenGLX11
CheckOpenGLESX11
CheckInputEvents CheckInputEvents
CheckTslib CheckTslib
CheckUSBHID CheckUSBHID
......
...@@ -271,6 +271,7 @@ ...@@ -271,6 +271,7 @@
#undef SDL_VIDEO_RENDER_D3D #undef SDL_VIDEO_RENDER_D3D
#undef SDL_VIDEO_RENDER_OGL #undef SDL_VIDEO_RENDER_OGL
#undef SDL_VIDEO_RENDER_OGL_ES #undef SDL_VIDEO_RENDER_OGL_ES
#undef SDL_VIDEO_RENDER_OGL_ES2
#undef SDL_VIDEO_RENDER_DIRECTFB #undef SDL_VIDEO_RENDER_DIRECTFB
/* Enable OpenGL support */ /* Enable OpenGL support */
......
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: */
...@@ -40,6 +40,9 @@ glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height) ...@@ -40,6 +40,9 @@ glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
/* OpenGL ES 1.1 renderer implementation, based on the OpenGL renderer */ /* 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 const float inv255f = 1.0f / 255.0f;
static SDL_Renderer *GLES_CreateRenderer(SDL_Window * window, Uint32 flags); static SDL_Renderer *GLES_CreateRenderer(SDL_Window * window, Uint32 flags);
...@@ -92,6 +95,10 @@ typedef struct ...@@ -92,6 +95,10 @@ typedef struct
SDL_bool tex_coords; SDL_bool tex_coords;
} current; } current;
#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
#include "SDL_glesfuncs.h"
#undef SDL_PROC
SDL_bool useDrawTexture; SDL_bool useDrawTexture;
SDL_bool GL_OES_draw_texture_supported; SDL_bool GL_OES_draw_texture_supported;
} GLES_RenderData; } GLES_RenderData;
...@@ -142,6 +149,26 @@ GLES_SetError(const char *prefix, GLenum result) ...@@ -142,6 +149,26 @@ GLES_SetError(const char *prefix, GLenum result)
SDL_SetError("%s: %s", prefix, error); 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 SDL_GLContext SDL_CurrentContext = NULL;
static int static int
...@@ -176,14 +203,14 @@ GLES_ResetState(SDL_Renderer *renderer) ...@@ -176,14 +203,14 @@ GLES_ResetState(SDL_Renderer *renderer)
data->current.blendMode = -1; data->current.blendMode = -1;
data->current.tex_coords = SDL_FALSE; data->current.tex_coords = SDL_FALSE;
glDisable(GL_DEPTH_TEST); data->glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE); data->glDisable(GL_CULL_FACE);
glMatrixMode(GL_MODELVIEW); data->glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); data->glLoadIdentity();
glEnableClientState(GL_VERTEX_ARRAY); data->glEnableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); data->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
} }
SDL_Renderer * SDL_Renderer *
...@@ -193,6 +220,19 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags) ...@@ -193,6 +220,19 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
SDL_Renderer *renderer; SDL_Renderer *renderer;
GLES_RenderData *data; GLES_RenderData *data;
GLint value; 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)); renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
if (!renderer) { if (!renderer) {
...@@ -227,9 +267,6 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags) ...@@ -227,9 +267,6 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->driverdata = data; renderer->driverdata = data;
renderer->window = window; 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); data->context = SDL_GL_CreateContext(window);
if (!data->context) { if (!data->context) {
GLES_DestroyRenderer(renderer); GLES_DestroyRenderer(renderer);
...@@ -240,6 +277,11 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags) ...@@ -240,6 +277,11 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
return NULL; return NULL;
} }
if (GLES_LoadFunctions(data) < 0) {
GLES_DestroyRenderer(renderer);
return NULL;
}
if (flags & SDL_RENDERER_PRESENTVSYNC) { if (flags & SDL_RENDERER_PRESENTVSYNC) {
SDL_GL_SetSwapInterval(1); SDL_GL_SetSwapInterval(1);
} else { } else {
...@@ -262,9 +304,9 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags) ...@@ -262,9 +304,9 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
} }
#endif #endif
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
renderer->info.max_texture_width = 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; renderer->info.max_texture_height = value;
/* Set up parameters for rendering */ /* Set up parameters for rendering */
...@@ -313,6 +355,7 @@ GetScaleQuality(void) ...@@ -313,6 +355,7 @@ GetScaleQuality(void)
static int static int
GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{ {
GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
GLES_TextureData *data; GLES_TextureData *data;
GLint internalFormat; GLint internalFormat;
GLenum format, type; GLenum format, type;
...@@ -351,9 +394,9 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -351,9 +394,9 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
texture->driverdata = data; texture->driverdata = data;
glGetError(); renderdata->glGetError();
glEnable(GL_TEXTURE_2D); renderdata->glEnable(GL_TEXTURE_2D);
glGenTextures(1, &data->texture); renderdata->glGenTextures(1, &data->texture);
data->type = GL_TEXTURE_2D; data->type = GL_TEXTURE_2D;
/* no NPOV textures allowed in OpenGL ES (yet) */ /* no NPOV textures allowed in OpenGL ES (yet) */
...@@ -365,17 +408,17 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -365,17 +408,17 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
data->format = format; data->format = format;
data->formattype = type; data->formattype = type;
scaleMode = GetScaleQuality(); scaleMode = GetScaleQuality();
glBindTexture(data->type, data->texture); renderdata->glBindTexture(data->type, data->texture);
glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, scaleMode); renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, scaleMode);
glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER, scaleMode); renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER, scaleMode);
glTexParameteri(data->type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(data->type, GL_TEXTURE_WRAP_T, 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); 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) { if (result != GL_NO_ERROR) {
GLES_SetError("glTexImage2D()", result); GLES_SetError("glTexImage2D()", result);
return -1; return -1;
...@@ -387,6 +430,7 @@ static int ...@@ -387,6 +430,7 @@ static int
GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, const void *pixels, int pitch) const SDL_Rect * rect, const void *pixels, int pitch)
{ {
GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
GLES_TextureData *data = (GLES_TextureData *) texture->driverdata; GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
Uint8 *blob = NULL; Uint8 *blob = NULL;
Uint8 *src; Uint8 *src;
...@@ -421,11 +465,11 @@ GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, ...@@ -421,11 +465,11 @@ GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
} }
/* Create a texture subimage with the supplied data */ /* Create a texture subimage with the supplied data */
glGetError(); renderdata->glGetError();
glEnable(data->type); renderdata->glEnable(data->type);
glBindTexture(data->type, data->texture); renderdata->glBindTexture(data->type, data->texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexSubImage2D(data->type, renderdata->glTexSubImage2D(data->type,
0, 0,
rect->x, rect->x,
rect->y, rect->y,
...@@ -438,7 +482,7 @@ GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, ...@@ -438,7 +482,7 @@ GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
SDL_free(blob); SDL_free(blob);
} }
if (glGetError() != GL_NO_ERROR) if (renderdata->glGetError() != GL_NO_ERROR)
{ {
SDL_SetError("Failed to update texture"); SDL_SetError("Failed to update texture");
return -1; return -1;
...@@ -483,12 +527,12 @@ GLES_UpdateViewport(SDL_Renderer * renderer) ...@@ -483,12 +527,12 @@ GLES_UpdateViewport(SDL_Renderer * renderer)
return 0; return 0;
} }
glViewport(renderer->viewport.x, renderer->viewport.y, data->glViewport(renderer->viewport.x, renderer->viewport.y,
renderer->viewport.w, renderer->viewport.h); renderer->viewport.w, renderer->viewport.h);
glMatrixMode(GL_PROJECTION); data->glMatrixMode(GL_PROJECTION);
glLoadIdentity(); data->glLoadIdentity();
glOrthof((GLfloat) 0, data->glOrthof((GLfloat) 0,
(GLfloat) renderer->viewport.w, (GLfloat) renderer->viewport.w,
(GLfloat) renderer->viewport.h, (GLfloat) renderer->viewport.h,
(GLfloat) 0, 0.0, 1.0); (GLfloat) 0, 0.0, 1.0);
...@@ -501,7 +545,7 @@ GLES_SetColor(GLES_RenderData * data, Uint8 r, Uint8 g, Uint8 b, Uint8 a) ...@@ -501,7 +545,7 @@ GLES_SetColor(GLES_RenderData * data, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b); Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
if (color != data->current.color) { if (color != data->current.color) {
glColor4f((GLfloat) r * inv255f, data->glColor4f((GLfloat) r * inv255f,
(GLfloat) g * inv255f, (GLfloat) g * inv255f,
(GLfloat) b * inv255f, (GLfloat) b * inv255f,
(GLfloat) a * inv255f); (GLfloat) a * inv255f);
...@@ -515,23 +559,23 @@ GLES_SetBlendMode(GLES_RenderData * data, int blendMode) ...@@ -515,23 +559,23 @@ GLES_SetBlendMode(GLES_RenderData * data, int blendMode)
if (blendMode != data->current.blendMode) { if (blendMode != data->current.blendMode) {
switch (blendMode) { switch (blendMode) {
case SDL_BLENDMODE_NONE: case SDL_BLENDMODE_NONE:
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glDisable(GL_BLEND); data->glDisable(GL_BLEND);
break; break;
case SDL_BLENDMODE_BLEND: case SDL_BLENDMODE_BLEND:
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_BLEND); data->glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); data->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
break; break;
case SDL_BLENDMODE_ADD: case SDL_BLENDMODE_ADD:
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_BLEND); data->glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE); data->glBlendFunc(GL_SRC_ALPHA, GL_ONE);
break; break;
case SDL_BLENDMODE_MOD: case SDL_BLENDMODE_MOD:
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_BLEND); data->glEnable(GL_BLEND);
glBlendFunc(GL_ZERO, GL_SRC_COLOR); data->glBlendFunc(GL_ZERO, GL_SRC_COLOR);
break; break;
} }
data->current.blendMode = blendMode; data->current.blendMode = blendMode;
...@@ -543,9 +587,9 @@ GLES_SetTexCoords(GLES_RenderData * data, SDL_bool enabled) ...@@ -543,9 +587,9 @@ GLES_SetTexCoords(GLES_RenderData * data, SDL_bool enabled)
{ {
if (enabled != data->current.tex_coords) { if (enabled != data->current.tex_coords) {
if (enabled) { if (enabled) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY); data->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
} else { } else {
glDisableClientState(GL_TEXTURE_COORD_ARRAY); data->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
} }
data->current.tex_coords = enabled; data->current.tex_coords = enabled;
} }
...@@ -571,14 +615,16 @@ GLES_SetDrawingState(SDL_Renderer * renderer) ...@@ -571,14 +615,16 @@ GLES_SetDrawingState(SDL_Renderer * renderer)
static int static int
GLES_RenderClear(SDL_Renderer * renderer) GLES_RenderClear(SDL_Renderer * renderer)
{ {
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
GLES_ActivateRenderer(renderer); GLES_ActivateRenderer(renderer);
glClearColor((GLfloat) renderer->r * inv255f, data->glClearColor((GLfloat) renderer->r * inv255f,
(GLfloat) renderer->g * inv255f, (GLfloat) renderer->g * inv255f,
(GLfloat) renderer->b * inv255f, (GLfloat) renderer->b * inv255f,
(GLfloat) renderer->a * inv255f); (GLfloat) renderer->a * inv255f);
glClear(GL_COLOR_BUFFER_BIT); data->glClear(GL_COLOR_BUFFER_BIT);
return 0; return 0;
} }
...@@ -587,6 +633,7 @@ static int ...@@ -587,6 +633,7 @@ static int
GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
int count) int count)
{ {
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
int i; int i;
GLshort *vertices; GLshort *vertices;
...@@ -597,8 +644,8 @@ GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, ...@@ -597,8 +644,8 @@ GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
vertices[2*i+0] = (GLshort)points[i].x; vertices[2*i+0] = (GLshort)points[i].x;
vertices[2*i+1] = (GLshort)points[i].y; vertices[2*i+1] = (GLshort)points[i].y;
} }
glVertexPointer(2, GL_SHORT, 0, vertices); data->glVertexPointer(2, GL_SHORT, 0, vertices);
glDrawArrays(GL_POINTS, 0, count); data->glDrawArrays(GL_POINTS, 0, count);
SDL_stack_free(vertices); SDL_stack_free(vertices);
return 0; return 0;
...@@ -608,6 +655,7 @@ static int ...@@ -608,6 +655,7 @@ static int
GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
int count) int count)
{ {
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
int i; int i;
GLshort *vertices; GLshort *vertices;
...@@ -618,16 +666,16 @@ GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, ...@@ -618,16 +666,16 @@ GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
vertices[2*i+0] = (GLshort)points[i].x; vertices[2*i+0] = (GLshort)points[i].x;
vertices[2*i+1] = (GLshort)points[i].y; vertices[2*i+1] = (GLshort)points[i].y;
} }
glVertexPointer(2, GL_SHORT, 0, vertices); data->glVertexPointer(2, GL_SHORT, 0, vertices);
if (count > 2 && if (count > 2 &&
points[0].x == points[count-1].x && points[0].y == points[count-1].y) { points[0].x == points[count-1].x && points[0].y == points[count-1].y) {
/* GL_LINE_LOOP takes care of the final segment */ /* GL_LINE_LOOP takes care of the final segment */
--count; --count;
glDrawArrays(GL_LINE_LOOP, 0, count); data->glDrawArrays(GL_LINE_LOOP, 0, count);
} else { } else {
glDrawArrays(GL_LINE_STRIP, 0, count); data->glDrawArrays(GL_LINE_STRIP, 0, count);
/* We need to close the endpoint of the line */ /* 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); SDL_stack_free(vertices);
...@@ -638,6 +686,7 @@ static int ...@@ -638,6 +686,7 @@ static int
GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects,
int count) int count)
{ {
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
int i; int i;
GLES_SetDrawingState(renderer); GLES_SetDrawingState(renderer);
...@@ -658,8 +707,8 @@ GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, ...@@ -658,8 +707,8 @@ GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects,
vertices[6] = maxx; vertices[6] = maxx;
vertices[7] = maxy; vertices[7] = maxy;
glVertexPointer(2, GL_SHORT, 0, vertices); data->glVertexPointer(2, GL_SHORT, 0, vertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
} }
return 0; return 0;
...@@ -677,9 +726,9 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, ...@@ -677,9 +726,9 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
GLES_ActivateRenderer(renderer); 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) { if (texture->modMode) {
GLES_SetColor(data, texture->r, texture->g, texture->b, texture->a); GLES_SetColor(data, texture->r, texture->g, texture->b, texture->a);
...@@ -702,9 +751,9 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, ...@@ -702,9 +751,9 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
cropRect[1] = srcrect->y + srcrect->h; cropRect[1] = srcrect->y + srcrect->h;
cropRect[2] = srcrect->w; cropRect[2] = srcrect->w;
cropRect[3] = -srcrect->h; cropRect[3] = -srcrect->h;
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, data->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES,
cropRect); cropRect);
glDrawTexiOES(renderer->viewport.x + dstrect->x, data->glDrawTexiOES(renderer->viewport.x + dstrect->x,
h - (renderer->viewport.y + dstrect->y) - dstrect->h, 0, h - (renderer->viewport.y + dstrect->y) - dstrect->h, 0,
dstrect->w, dstrect->h); dstrect->w, dstrect->h);
} else { } else {
...@@ -744,11 +793,11 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, ...@@ -744,11 +793,11 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
texCoords[6] = maxu; texCoords[6] = maxu;
texCoords[7] = maxv; texCoords[7] = maxv;
glVertexPointer(2, GL_SHORT, 0, vertices); data->glVertexPointer(2, GL_SHORT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords); data->glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
} }
glDisable(GL_TEXTURE_2D); data->glDisable(GL_TEXTURE_2D);
return 0; return 0;
} }
...@@ -757,6 +806,7 @@ static int ...@@ -757,6 +806,7 @@ static int
GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
Uint32 pixel_format, void * pixels, int pitch) Uint32 pixel_format, void * pixels, int pitch)
{ {
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
SDL_Window *window = renderer->window; SDL_Window *window = renderer->window;
Uint32 temp_format = SDL_PIXELFORMAT_ABGR8888; Uint32 temp_format = SDL_PIXELFORMAT_ABGR8888;
void *temp_pixels; void *temp_pixels;
...@@ -776,9 +826,9 @@ GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, ...@@ -776,9 +826,9 @@ GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
SDL_GetWindowSize(window, &w, &h); 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); GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels);
/* Flip the rows to be top-down */ /* Flip the rows to be top-down */
...@@ -815,6 +865,8 @@ GLES_RenderPresent(SDL_Renderer * renderer) ...@@ -815,6 +865,8 @@ GLES_RenderPresent(SDL_Renderer * renderer)
static void static void
GLES_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) GLES_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{ {
GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
GLES_TextureData *data = (GLES_TextureData *) texture->driverdata; GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
GLES_ActivateRenderer(renderer); GLES_ActivateRenderer(renderer);
...@@ -823,7 +875,7 @@ GLES_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -823,7 +875,7 @@ GLES_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
return; return;
} }
if (data->texture) { if (data->texture) {
glDeleteTextures(1, &data->texture); renderdata->glDeleteTextures(1, &data->texture);
} }
if (data->pixels) { if (data->pixels) {
SDL_free(data->pixels); SDL_free(data->pixels);
......
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))
...@@ -27,6 +27,9 @@ ...@@ -27,6 +27,9 @@
#include "../SDL_sysrender.h" #include "../SDL_sysrender.h"
#include "SDL_shaders_gles2.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 * * Bootstrap data *
*************************************************************************************************/ *************************************************************************************************/
...@@ -128,6 +131,10 @@ typedef struct GLES2_DriverContext ...@@ -128,6 +131,10 @@ typedef struct GLES2_DriverContext
SDL_bool tex_coords; SDL_bool tex_coords;
} current; } current;
#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
#include "SDL_gles2funcs.h"
#undef SDL_PROC
int shader_format_count; int shader_format_count;
GLenum *shader_formats; GLenum *shader_formats;
GLES2_ShaderCache shader_cache; GLES2_ShaderCache shader_cache;
...@@ -149,6 +156,26 @@ static void GLES2_DestroyRenderer(SDL_Renderer *renderer); ...@@ -149,6 +156,26 @@ static void GLES2_DestroyRenderer(SDL_Renderer *renderer);
static SDL_GLContext SDL_CurrentContext = NULL; 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 static int
GLES2_ActivateRenderer(SDL_Renderer * renderer) GLES2_ActivateRenderer(SDL_Renderer * renderer)
{ {
...@@ -171,6 +198,8 @@ GLES2_ActivateRenderer(SDL_Renderer * renderer) ...@@ -171,6 +198,8 @@ GLES2_ActivateRenderer(SDL_Renderer * renderer)
static void static void
GLES2_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) GLES2_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
{ {
GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) { if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
/* Rebind the context to the window area */ /* Rebind the context to the window area */
SDL_CurrentContext = NULL; SDL_CurrentContext = NULL;
...@@ -178,7 +207,7 @@ GLES2_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) ...@@ -178,7 +207,7 @@ GLES2_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
if (event->event == SDL_WINDOWEVENT_MINIMIZED) { if (event->event == SDL_WINDOWEVENT_MINIMIZED) {
/* According to Apple documentation, we need to finish drawing NOW! */ /* According to Apple documentation, we need to finish drawing NOW! */
glFinish(); rdata->glFinish();
} }
} }
...@@ -192,7 +221,7 @@ GLES2_UpdateViewport(SDL_Renderer * renderer) ...@@ -192,7 +221,7 @@ GLES2_UpdateViewport(SDL_Renderer * renderer)
return 0; return 0;
} }
glViewport(renderer->viewport.x, renderer->viewport.y, rdata->glViewport(renderer->viewport.x, renderer->viewport.y,
renderer->viewport.w, renderer->viewport.h); renderer->viewport.w, renderer->viewport.h);
return 0; return 0;
} }
...@@ -212,7 +241,7 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer) ...@@ -212,7 +241,7 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer)
entry = rdata->shader_cache.head; entry = rdata->shader_cache.head;
while (entry) while (entry)
{ {
glDeleteShader(entry->id); rdata->glDeleteShader(entry->id);
next = entry->next; next = entry->next;
SDL_free(entry); SDL_free(entry);
entry = next; entry = next;
...@@ -223,7 +252,7 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer) ...@@ -223,7 +252,7 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer)
GLES2_ProgramCacheEntry *next; GLES2_ProgramCacheEntry *next;
entry = rdata->program_cache.head; entry = rdata->program_cache.head;
while (entry) { while (entry) {
glDeleteProgram(entry->id); rdata->glDeleteProgram(entry->id);
next = entry->next; next = entry->next;
SDL_free(entry); SDL_free(entry);
entry = next; entry = next;
...@@ -267,6 +296,7 @@ GetScaleQuality(void) ...@@ -267,6 +296,7 @@ GetScaleQuality(void)
static int static int
GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
{ {
GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
GLES2_TextureData *tdata; GLES2_TextureData *tdata;
GLenum format; GLenum format;
GLenum type; GLenum type;
...@@ -316,19 +346,19 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) ...@@ -316,19 +346,19 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
} }
/* Allocate the texture */ /* Allocate the texture */
glGetError(); rdata->glGetError();
glGenTextures(1, &tdata->texture); rdata->glGenTextures(1, &tdata->texture);
glActiveTexture(GL_TEXTURE0); rdata->glActiveTexture(GL_TEXTURE0);
glBindTexture(tdata->texture_type, tdata->texture); rdata->glBindTexture(tdata->texture_type, tdata->texture);
glTexParameteri(tdata->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode); rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode);
glTexParameteri(tdata->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode); rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode);
glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); rdata->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); rdata->glTexImage2D(tdata->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL);
if (glGetError() != GL_NO_ERROR) if (rdata->glGetError() != GL_NO_ERROR)
{ {
SDL_SetError("Texture creation failed"); SDL_SetError("Texture creation failed");
glDeleteTextures(1, &tdata->texture); rdata->glDeleteTextures(1, &tdata->texture);
SDL_free(tdata); SDL_free(tdata);
return -1; return -1;
} }
...@@ -339,6 +369,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) ...@@ -339,6 +369,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
static void static void
GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture)
{ {
GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
GLES2_ActivateRenderer(renderer); GLES2_ActivateRenderer(renderer);
...@@ -346,7 +377,7 @@ GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) ...@@ -346,7 +377,7 @@ GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture)
/* Destroy the texture */ /* Destroy the texture */
if (tdata) if (tdata)
{ {
glDeleteTextures(1, &tdata->texture); rdata->glDeleteTextures(1, &tdata->texture);
SDL_free(tdata->pixel_data); SDL_free(tdata->pixel_data);
SDL_free(tdata); SDL_free(tdata);
texture->driverdata = NULL; texture->driverdata = NULL;
...@@ -386,6 +417,7 @@ static int ...@@ -386,6 +417,7 @@ static int
GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
const void *pixels, int pitch) const void *pixels, int pitch)
{ {
GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
Uint8 *blob = NULL; Uint8 *blob = NULL;
Uint8 *src; Uint8 *src;
...@@ -393,7 +425,7 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect ...@@ -393,7 +425,7 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect
int y; int y;
GLES2_ActivateRenderer(renderer); GLES2_ActivateRenderer(renderer);
/* Bail out if we're supposed to update an empty rectangle */ /* Bail out if we're supposed to update an empty rectangle */
if (rect->w <= 0 || rect->h <= 0) if (rect->w <= 0 || rect->h <= 0)
return 0; return 0;
...@@ -420,11 +452,11 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect ...@@ -420,11 +452,11 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect
} }
/* Create a texture subimage with the supplied data */ /* Create a texture subimage with the supplied data */
glGetError(); rdata->glGetError();
glActiveTexture(GL_TEXTURE0); rdata->glActiveTexture(GL_TEXTURE0);
glBindTexture(tdata->texture_type, tdata->texture); rdata->glBindTexture(tdata->texture_type, tdata->texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); rdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexSubImage2D(tdata->texture_type, rdata->glTexSubImage2D(tdata->texture_type,
0, 0,
rect->x, rect->x,
rect->y, rect->y,
...@@ -437,7 +469,7 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect ...@@ -437,7 +469,7 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect
SDL_free(blob); SDL_free(blob);
} }
if (glGetError() != GL_NO_ERROR) if (rdata->glGetError() != GL_NO_ERROR)
{ {
SDL_SetError("Failed to update texture"); SDL_SetError("Failed to update texture");
return -1; return -1;
...@@ -505,33 +537,33 @@ GLES2_CacheProgram(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *vertex, ...@@ -505,33 +537,33 @@ GLES2_CacheProgram(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *vertex,
entry->blend_mode = blendMode; entry->blend_mode = blendMode;
/* Create the program and link it */ /* Create the program and link it */
glGetError(); rdata->glGetError();
entry->id = glCreateProgram(); entry->id = rdata->glCreateProgram();
glAttachShader(entry->id, vertex->id); rdata->glAttachShader(entry->id, vertex->id);
glAttachShader(entry->id, fragment->id); rdata->glAttachShader(entry->id, fragment->id);
glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION, "a_position"); rdata->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION, "a_position");
glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD, "a_texCoord"); rdata->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD, "a_texCoord");
glLinkProgram(entry->id); rdata->glLinkProgram(entry->id);
glGetProgramiv(entry->id, GL_LINK_STATUS, &linkSuccessful); rdata->glGetProgramiv(entry->id, GL_LINK_STATUS, &linkSuccessful);
if (glGetError() != GL_NO_ERROR || !linkSuccessful) if (rdata->glGetError() != GL_NO_ERROR || !linkSuccessful)
{ {
SDL_SetError("Failed to link shader program"); SDL_SetError("Failed to link shader program");
glDeleteProgram(entry->id); rdata->glDeleteProgram(entry->id);
SDL_free(entry); SDL_free(entry);
return NULL; return NULL;
} }
/* Predetermine locations of uniform variables */ /* Predetermine locations of uniform variables */
entry->uniform_locations[GLES2_UNIFORM_PROJECTION] = entry->uniform_locations[GLES2_UNIFORM_PROJECTION] =
glGetUniformLocation(entry->id, "u_projection"); rdata->glGetUniformLocation(entry->id, "u_projection");
entry->uniform_locations[GLES2_UNIFORM_TEXTURE] = entry->uniform_locations[GLES2_UNIFORM_TEXTURE] =
glGetUniformLocation(entry->id, "u_texture"); rdata->glGetUniformLocation(entry->id, "u_texture");
entry->uniform_locations[GLES2_UNIFORM_MODULATION] = entry->uniform_locations[GLES2_UNIFORM_MODULATION] =
glGetUniformLocation(entry->id, "u_modulation"); rdata->glGetUniformLocation(entry->id, "u_modulation");
entry->uniform_locations[GLES2_UNIFORM_COLOR] = entry->uniform_locations[GLES2_UNIFORM_COLOR] =
glGetUniformLocation(entry->id, "u_color"); rdata->glGetUniformLocation(entry->id, "u_color");
entry->uniform_locations[GLES2_UNIFORM_COLORTABLE] = entry->uniform_locations[GLES2_UNIFORM_COLORTABLE] =
glGetUniformLocation(entry->id, "u_colorTable"); rdata->glGetUniformLocation(entry->id, "u_colorTable");
/* Cache the linked program */ /* Cache the linked program */
if (rdata->program_cache.head) if (rdata->program_cache.head)
...@@ -559,7 +591,7 @@ GLES2_CacheProgram(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *vertex, ...@@ -559,7 +591,7 @@ GLES2_CacheProgram(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *vertex,
shaderEntry = rdata->program_cache.tail->fragment_shader; shaderEntry = rdata->program_cache.tail->fragment_shader;
if (--shaderEntry->references <= 0) if (--shaderEntry->references <= 0)
GLES2_EvictShader(renderer, shaderEntry); 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; rdata->program_cache.tail = rdata->program_cache.tail->prev;
SDL_free(rdata->program_cache.tail->next); SDL_free(rdata->program_cache.tail->next);
rdata->program_cache.tail->next = NULL; rdata->program_cache.tail->next = NULL;
...@@ -628,29 +660,29 @@ GLES2_CacheShader(SDL_Renderer *renderer, GLES2_ShaderType type, SDL_BlendMode b ...@@ -628,29 +660,29 @@ GLES2_CacheShader(SDL_Renderer *renderer, GLES2_ShaderType type, SDL_BlendMode b
entry->instance = instance; entry->instance = instance;
/* Compile or load the selected shader instance */ /* Compile or load the selected shader instance */
glGetError(); rdata->glGetError();
entry->id = glCreateShader(instance->type); entry->id = rdata->glCreateShader(instance->type);
if (instance->format == (GLenum)-1) if (instance->format == (GLenum)-1)
{ {
glShaderSource(entry->id, 1, (const char **)&instance->data, NULL); rdata->glShaderSource(entry->id, 1, (const char **)&instance->data, NULL);
glCompileShader(entry->id); rdata->glCompileShader(entry->id);
glGetShaderiv(entry->id, GL_COMPILE_STATUS, &compileSuccessful); rdata->glGetShaderiv(entry->id, GL_COMPILE_STATUS, &compileSuccessful);
} }
else 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; compileSuccessful = GL_TRUE;
} }
if (glGetError() != GL_NO_ERROR || !compileSuccessful) if (rdata->glGetError() != GL_NO_ERROR || !compileSuccessful)
{ {
char *info = NULL; char *info = NULL;
int length = 0; int length = 0;
glGetShaderiv(entry->id, GL_INFO_LOG_LENGTH, &length); rdata->glGetShaderiv(entry->id, GL_INFO_LOG_LENGTH, &length);
if (length > 0) { if (length > 0) {
info = SDL_stack_alloc(char, length); info = SDL_stack_alloc(char, length);
if (info) { if (info) {
glGetShaderInfoLog(entry->id, length, &length, info); rdata->glGetShaderInfoLog(entry->id, length, &length, info);
} }
} }
if (info) { if (info) {
...@@ -659,7 +691,7 @@ GLES2_CacheShader(SDL_Renderer *renderer, GLES2_ShaderType type, SDL_BlendMode b ...@@ -659,7 +691,7 @@ GLES2_CacheShader(SDL_Renderer *renderer, GLES2_ShaderType type, SDL_BlendMode b
} else { } else {
SDL_SetError("Failed to load the shader"); SDL_SetError("Failed to load the shader");
} }
glDeleteShader(entry->id); rdata->glDeleteShader(entry->id);
SDL_free(entry); SDL_free(entry);
return NULL; return NULL;
} }
...@@ -690,7 +722,7 @@ GLES2_EvictShader(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *entry) ...@@ -690,7 +722,7 @@ GLES2_EvictShader(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *entry)
--rdata->shader_cache.count; --rdata->shader_cache.count;
/* Deallocate the shader */ /* Deallocate the shader */
glDeleteShader(entry->id); rdata->glDeleteShader(entry->id);
SDL_free(entry); SDL_free(entry);
} }
...@@ -746,9 +778,9 @@ GLES2_SelectProgram(SDL_Renderer *renderer, GLES2_ImageSource source, SDL_BlendM ...@@ -746,9 +778,9 @@ GLES2_SelectProgram(SDL_Renderer *renderer, GLES2_ImageSource source, SDL_BlendM
goto fault; goto fault;
/* Select that program in OpenGL */ /* Select that program in OpenGL */
glGetError(); rdata->glGetError();
glUseProgram(program->id); rdata->glUseProgram(program->id);
if (glGetError() != GL_NO_ERROR) if (rdata->glGetError() != GL_NO_ERROR)
{ {
SDL_SetError("Failed to select program"); SDL_SetError("Failed to select program");
goto fault; goto fault;
...@@ -799,9 +831,9 @@ GLES2_SetOrthographicProjection(SDL_Renderer *renderer) ...@@ -799,9 +831,9 @@ GLES2_SetOrthographicProjection(SDL_Renderer *renderer)
/* Set the projection matrix */ /* Set the projection matrix */
locProjection = rdata->current_program->uniform_locations[GLES2_UNIFORM_PROJECTION]; locProjection = rdata->current_program->uniform_locations[GLES2_UNIFORM_PROJECTION];
glGetError(); rdata->glGetError();
glUniformMatrix4fv(locProjection, 1, GL_FALSE, (GLfloat *)projection); rdata->glUniformMatrix4fv(locProjection, 1, GL_FALSE, (GLfloat *)projection);
if (glGetError() != GL_NO_ERROR) if (rdata->glGetError() != GL_NO_ERROR)
{ {
SDL_SetError("Failed to set orthographic projection"); SDL_SetError("Failed to set orthographic projection");
return -1; return -1;
...@@ -829,14 +861,16 @@ static void GLES2_RenderPresent(SDL_Renderer *renderer); ...@@ -829,14 +861,16 @@ static void GLES2_RenderPresent(SDL_Renderer *renderer);
static int static int
GLES2_RenderClear(SDL_Renderer * renderer) 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->g * inv255f,
(GLfloat) renderer->b * inv255f, (GLfloat) renderer->b * inv255f,
(GLfloat) renderer->a * inv255f); (GLfloat) renderer->a * inv255f);
glClear(GL_COLOR_BUFFER_BIT); rdata->glClear(GL_COLOR_BUFFER_BIT);
return 0; return 0;
} }
...@@ -848,19 +882,19 @@ GLES2_SetBlendMode(GLES2_DriverContext *rdata, int blendMode) ...@@ -848,19 +882,19 @@ GLES2_SetBlendMode(GLES2_DriverContext *rdata, int blendMode)
switch (blendMode) { switch (blendMode) {
default: default:
case SDL_BLENDMODE_NONE: case SDL_BLENDMODE_NONE:
glDisable(GL_BLEND); rdata->glDisable(GL_BLEND);
break; break;
case SDL_BLENDMODE_BLEND: case SDL_BLENDMODE_BLEND:
glEnable(GL_BLEND); rdata->glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); rdata->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
break; break;
case SDL_BLENDMODE_ADD: case SDL_BLENDMODE_ADD:
glEnable(GL_BLEND); rdata->glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE); rdata->glBlendFunc(GL_SRC_ALPHA, GL_ONE);
break; break;
case SDL_BLENDMODE_MOD: case SDL_BLENDMODE_MOD:
glEnable(GL_BLEND); rdata->glEnable(GL_BLEND);
glBlendFunc(GL_ZERO, GL_SRC_COLOR); rdata->glBlendFunc(GL_ZERO, GL_SRC_COLOR);
break; break;
} }
rdata->current.blendMode = blendMode; rdata->current.blendMode = blendMode;
...@@ -872,9 +906,9 @@ GLES2_SetTexCoords(GLES2_DriverContext * rdata, SDL_bool enabled) ...@@ -872,9 +906,9 @@ GLES2_SetTexCoords(GLES2_DriverContext * rdata, SDL_bool enabled)
{ {
if (enabled != rdata->current.tex_coords) { if (enabled != rdata->current.tex_coords) {
if (enabled) { if (enabled) {
glEnableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD); rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
} else { } else {
glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD); rdata->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
} }
rdata->current.tex_coords = enabled; rdata->current.tex_coords = enabled;
} }
...@@ -887,7 +921,7 @@ GLES2_SetDrawingState(SDL_Renderer * renderer) ...@@ -887,7 +921,7 @@ GLES2_SetDrawingState(SDL_Renderer * renderer)
int blendMode = renderer->blendMode; int blendMode = renderer->blendMode;
GLuint locColor; GLuint locColor;
glGetError(); rdata->glGetError();
GLES2_ActivateRenderer(renderer); GLES2_ActivateRenderer(renderer);
...@@ -901,7 +935,7 @@ GLES2_SetDrawingState(SDL_Renderer * renderer) ...@@ -901,7 +935,7 @@ GLES2_SetDrawingState(SDL_Renderer * renderer)
/* Select the color to draw with */ /* Select the color to draw with */
locColor = rdata->current_program->uniform_locations[GLES2_UNIFORM_COLOR]; locColor = rdata->current_program->uniform_locations[GLES2_UNIFORM_COLOR];
glUniform4f(locColor, rdata->glUniform4f(locColor,
renderer->r * inv255f, renderer->r * inv255f,
renderer->g * inv255f, renderer->g * inv255f,
renderer->b * inv255f, renderer->b * inv255f,
...@@ -912,6 +946,7 @@ GLES2_SetDrawingState(SDL_Renderer * renderer) ...@@ -912,6 +946,7 @@ GLES2_SetDrawingState(SDL_Renderer * renderer)
static int static int
GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int count) GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int count)
{ {
GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
GLfloat *vertices; GLfloat *vertices;
int idx; int idx;
...@@ -929,11 +964,11 @@ GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int coun ...@@ -929,11 +964,11 @@ GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int coun
vertices[idx * 2] = x; vertices[idx * 2] = x;
vertices[(idx * 2) + 1] = y; vertices[(idx * 2) + 1] = y;
} }
glGetError(); rdata->glGetError();
glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glDrawArrays(GL_POINTS, 0, count); rdata->glDrawArrays(GL_POINTS, 0, count);
SDL_stack_free(vertices); SDL_stack_free(vertices);
if (glGetError() != GL_NO_ERROR) if (rdata->glGetError() != GL_NO_ERROR)
{ {
SDL_SetError("Failed to render lines"); SDL_SetError("Failed to render lines");
return -1; return -1;
...@@ -944,6 +979,7 @@ GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int coun ...@@ -944,6 +979,7 @@ GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int coun
static int static int
GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count) GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count)
{ {
GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
GLfloat *vertices; GLfloat *vertices;
int idx; int idx;
...@@ -961,17 +997,17 @@ GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count ...@@ -961,17 +997,17 @@ GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count
vertices[idx * 2] = x; vertices[idx * 2] = x;
vertices[(idx * 2) + 1] = y; vertices[(idx * 2) + 1] = y;
} }
glGetError(); rdata->glGetError();
glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glDrawArrays(GL_LINE_STRIP, 0, count); rdata->glDrawArrays(GL_LINE_STRIP, 0, count);
/* We need to close the endpoint of the line */ /* We need to close the endpoint of the line */
if (count == 2 || if (count == 2 ||
points[0].x != points[count-1].x || points[0].y != points[count-1].y) { 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); SDL_stack_free(vertices);
if (glGetError() != GL_NO_ERROR) if (rdata->glGetError() != GL_NO_ERROR)
{ {
SDL_SetError("Failed to render lines"); SDL_SetError("Failed to render lines");
return -1; return -1;
...@@ -982,6 +1018,7 @@ GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count ...@@ -982,6 +1018,7 @@ GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count
static int static int
GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count) GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count)
{ {
GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
GLfloat vertices[8]; GLfloat vertices[8];
int idx; int idx;
...@@ -990,7 +1027,7 @@ GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count) ...@@ -990,7 +1027,7 @@ GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count)
} }
/* Emit a line loop for each rectangle */ /* Emit a line loop for each rectangle */
glGetError(); rdata->glGetError();
for (idx = 0; idx < count; ++idx) { for (idx = 0; idx < count; ++idx) {
const SDL_Rect *rect = &rects[idx]; const SDL_Rect *rect = &rects[idx];
...@@ -1007,10 +1044,10 @@ GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count) ...@@ -1007,10 +1044,10 @@ GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count)
vertices[5] = yMax; vertices[5] = yMax;
vertices[6] = xMax; vertices[6] = xMax;
vertices[7] = yMax; vertices[7] = yMax;
glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); rdata->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
} }
if (glGetError() != GL_NO_ERROR) if (rdata->glGetError() != GL_NO_ERROR)
{ {
SDL_SetError("Failed to render lines"); SDL_SetError("Failed to render lines");
return -1; return -1;
...@@ -1055,14 +1092,14 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s ...@@ -1055,14 +1092,14 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s
/* Select the target texture */ /* Select the target texture */
locTexture = rdata->current_program->uniform_locations[GLES2_UNIFORM_TEXTURE]; locTexture = rdata->current_program->uniform_locations[GLES2_UNIFORM_TEXTURE];
glGetError(); rdata->glGetError();
glActiveTexture(GL_TEXTURE0); rdata->glActiveTexture(GL_TEXTURE0);
glBindTexture(tdata->texture_type, tdata->texture); rdata->glBindTexture(tdata->texture_type, tdata->texture);
glUniform1i(locTexture, 0); rdata->glUniform1i(locTexture, 0);
/* Configure color modulation */ /* Configure color modulation */
locModulation = rdata->current_program->uniform_locations[GLES2_UNIFORM_MODULATION]; locModulation = rdata->current_program->uniform_locations[GLES2_UNIFORM_MODULATION];
glUniform4f(locModulation, rdata->glUniform4f(locModulation,
texture->r * inv255f, texture->r * inv255f,
texture->g * inv255f, texture->g * inv255f,
texture->b * inv255f, texture->b * inv255f,
...@@ -1082,7 +1119,7 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s ...@@ -1082,7 +1119,7 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s
vertices[5] = (GLfloat)(dstrect->y + dstrect->h); vertices[5] = (GLfloat)(dstrect->y + dstrect->h);
vertices[6] = (GLfloat)(dstrect->x + dstrect->w); vertices[6] = (GLfloat)(dstrect->x + dstrect->w);
vertices[7] = (GLfloat)(dstrect->y + dstrect->h); 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[0] = srcrect->x / (GLfloat)texture->w;
texCoords[1] = srcrect->y / (GLfloat)texture->h; texCoords[1] = srcrect->y / (GLfloat)texture->h;
texCoords[2] = (srcrect->x + srcrect->w) / (GLfloat)texture->w; texCoords[2] = (srcrect->x + srcrect->w) / (GLfloat)texture->w;
...@@ -1091,9 +1128,9 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s ...@@ -1091,9 +1128,9 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s
texCoords[5] = (srcrect->y + srcrect->h) / (GLfloat)texture->h; texCoords[5] = (srcrect->y + srcrect->h) / (GLfloat)texture->h;
texCoords[6] = (srcrect->x + srcrect->w) / (GLfloat)texture->w; texCoords[6] = (srcrect->x + srcrect->w) / (GLfloat)texture->w;
texCoords[7] = (srcrect->y + srcrect->h) / (GLfloat)texture->h; texCoords[7] = (srcrect->y + srcrect->h) / (GLfloat)texture->h;
glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords); rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); rdata->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
if (glGetError() != GL_NO_ERROR) if (rdata->glGetError() != GL_NO_ERROR)
{ {
SDL_SetError("Failed to render texture"); SDL_SetError("Failed to render texture");
return -1; return -1;
...@@ -1105,6 +1142,7 @@ static int ...@@ -1105,6 +1142,7 @@ static int
GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
Uint32 pixel_format, void * pixels, int pitch) Uint32 pixel_format, void * pixels, int pitch)
{ {
GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
SDL_Window *window = renderer->window; SDL_Window *window = renderer->window;
Uint32 temp_format = SDL_PIXELFORMAT_ABGR8888; Uint32 temp_format = SDL_PIXELFORMAT_ABGR8888;
void *temp_pixels; void *temp_pixels;
...@@ -1124,9 +1162,9 @@ GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, ...@@ -1124,9 +1162,9 @@ GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
SDL_GetWindowSize(window, &w, &h); 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); GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels);
/* Flip the rows to be top-down */ /* Flip the rows to be top-down */
...@@ -1181,8 +1219,8 @@ GLES2_ResetState(SDL_Renderer *renderer) ...@@ -1181,8 +1219,8 @@ GLES2_ResetState(SDL_Renderer *renderer)
rdata->current.blendMode = -1; rdata->current.blendMode = -1;
rdata->current.tex_coords = SDL_FALSE; rdata->current.tex_coords = SDL_FALSE;
glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION); rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD); rdata->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
} }
static SDL_Renderer * static SDL_Renderer *
...@@ -1194,6 +1232,19 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) ...@@ -1194,6 +1232,19 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
#ifndef ZUNE_HD #ifndef ZUNE_HD
GLboolean hasCompiler; GLboolean hasCompiler;
#endif #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 */ /* Create the renderer struct */
renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(SDL_Renderer)); renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(SDL_Renderer));
...@@ -1214,9 +1265,6 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) ...@@ -1214,9 +1265,6 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
renderer->window = window; renderer->window = window;
/* Create an OpenGL ES 2.0 context */ /* 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); rdata->context = SDL_GL_CreateContext(window);
if (!rdata->context) if (!rdata->context)
{ {
...@@ -1228,6 +1276,11 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) ...@@ -1228,6 +1276,11 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
return NULL; return NULL;
} }
if (GLES2_LoadFunctions(rdata) < 0) {
GLES2_DestroyRenderer(renderer);
return NULL;
}
if (flags & SDL_RENDERER_PRESENTVSYNC) { if (flags & SDL_RENDERER_PRESENTVSYNC) {
SDL_GL_SetSwapInterval(1); SDL_GL_SetSwapInterval(1);
} else { } else {
...@@ -1239,12 +1292,12 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) ...@@ -1239,12 +1292,12 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
/* Determine supported shader formats */ /* Determine supported shader formats */
/* HACK: glGetInteger is broken on the Zune HD's compositor, so we just hardcode this */ /* HACK: glGetInteger is broken on the Zune HD's compositor, so we just hardcode this */
glGetError(); rdata->glGetError();
#ifdef ZUNE_HD #ifdef ZUNE_HD
nFormats = 1; nFormats = 1;
#else /* !ZUNE_HD */ #else /* !ZUNE_HD */
glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &nFormats); rdata->glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &nFormats);
glGetBooleanv(GL_SHADER_COMPILER, &hasCompiler); rdata->glGetBooleanv(GL_SHADER_COMPILER, &hasCompiler);
if (hasCompiler) if (hasCompiler)
++nFormats; ++nFormats;
#endif /* ZUNE_HD */ #endif /* ZUNE_HD */
...@@ -1259,8 +1312,8 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) ...@@ -1259,8 +1312,8 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
#ifdef ZUNE_HD #ifdef ZUNE_HD
rdata->shader_formats[0] = GL_NVIDIA_PLATFORM_BINARY_NV; rdata->shader_formats[0] = GL_NVIDIA_PLATFORM_BINARY_NV;
#else /* !ZUNE_HD */ #else /* !ZUNE_HD */
glGetIntegerv(GL_SHADER_BINARY_FORMATS, (GLint *)rdata->shader_formats); rdata->glGetIntegerv(GL_SHADER_BINARY_FORMATS, (GLint *)rdata->shader_formats);
if (glGetError() != GL_NO_ERROR) if (rdata->glGetError() != GL_NO_ERROR)
{ {
GLES2_DestroyRenderer(renderer); GLES2_DestroyRenderer(renderer);
SDL_SetError("Failed to query supported shader formats"); SDL_SetError("Failed to query supported shader formats");
......
...@@ -286,7 +286,7 @@ struct SDL_VideoDevice ...@@ -286,7 +286,7 @@ struct SDL_VideoDevice
void *driverdata; void *driverdata;
struct SDL_GLDriverData *gl_data; struct SDL_GLDriverData *gl_data;
#if SDL_VIDEO_DRIVER_PANDORA #if SDL_VIDEO_OPENGL_ES
struct SDL_PrivateGLESData *gles_data; struct SDL_PrivateGLESData *gles_data;
#endif #endif
......
...@@ -189,6 +189,9 @@ ShouldUseTextureFramebuffer() ...@@ -189,6 +189,9 @@ ShouldUseTextureFramebuffer()
} }
return hasAcceleratedOpenGL; return hasAcceleratedOpenGL;
} }
#elif SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
/* Let's be optimistic about this! */
return SDL_TRUE;
#else #else
return SDL_FALSE; return SDL_FALSE;
#endif #endif
...@@ -1138,7 +1141,7 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) ...@@ -1138,7 +1141,7 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
} }
/* Some platforms have OpenGL enabled by default */ /* 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; flags |= SDL_WINDOW_OPENGL;
#endif #endif
if (flags & SDL_WINDOW_OPENGL) { if (flags & SDL_WINDOW_OPENGL) {
......
...@@ -25,7 +25,10 @@ ...@@ -25,7 +25,10 @@
#include "SDL_x11video.h" #include "SDL_x11video.h"
#include "SDL_x11opengles.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) \ #define LOAD_FUNC(NAME) \
*((void**)&_this->gles_data->NAME) = dlsym(handle, #NAME); \ *((void**)&_this->gles_data->NAME) = dlsym(handle, #NAME); \
...@@ -44,13 +47,15 @@ X11_GLES_GetProcAddress(_THIS, const char *proc) ...@@ -44,13 +47,15 @@ X11_GLES_GetProcAddress(_THIS, const char *proc)
void *handle; void *handle;
void *retval; void *retval;
handle = _this->gl_config.dll_handle; handle = _this->gles_data->egl_dll_handle;
if (_this->gles_data->eglGetProcAddress) { if (_this->gles_data->eglGetProcAddress) {
retval = _this->gles_data->eglGetProcAddress(proc); retval = _this->gles_data->eglGetProcAddress(proc);
if (retval) { if (retval) {
return retval; return retval;
} }
} }
handle = _this->gl_config.dll_handle;
#if defined(__OpenBSD__) && !defined(__ELF__) #if defined(__OpenBSD__) && !defined(__ELF__)
#undef dlsym(x,y); #undef dlsym(x,y);
#endif #endif
...@@ -70,6 +75,7 @@ X11_GLES_UnloadLibrary(_THIS) ...@@ -70,6 +75,7 @@ X11_GLES_UnloadLibrary(_THIS)
_this->gles_data->eglTerminate(_this->gles_data->egl_display); _this->gles_data->eglTerminate(_this->gles_data->egl_display);
dlclose(_this->gl_config.dll_handle); dlclose(_this->gl_config.dll_handle);
dlclose(_this->gles_data->egl_dll_handle);
_this->gles_data->eglGetProcAddress = NULL; _this->gles_data->eglGetProcAddress = NULL;
_this->gles_data->eglChooseConfig = NULL; _this->gles_data->eglChooseConfig = NULL;
...@@ -111,7 +117,7 @@ X11_GLES_LoadLibrary(_THIS, const char *path) ...@@ -111,7 +117,7 @@ X11_GLES_LoadLibrary(_THIS, const char *path)
dlclose(handle); dlclose(handle);
path = getenv("SDL_VIDEO_GL_DRIVER"); path = getenv("SDL_VIDEO_GL_DRIVER");
if (path == NULL) { if (path == NULL) {
path = DEFAULT_OPENGL; path = DEFAULT_EGL;
} }
handle = dlopen(path, dlopen_flags); handle = dlopen(path, dlopen_flags);
} }
...@@ -153,6 +159,29 @@ X11_GLES_LoadLibrary(_THIS, const char *path) ...@@ -153,6 +159,29 @@ X11_GLES_LoadLibrary(_THIS, const char *path)
return -1; 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.dll_handle = handle;
_this->gl_config.driver_loaded = 1; _this->gl_config.driver_loaded = 1;
...@@ -218,6 +247,13 @@ X11_GLES_GetVisual(_THIS, Display * display, int screen) ...@@ -218,6 +247,13 @@ X11_GLES_GetVisual(_THIS, Display * display, int screen)
attribs[i++] = _this->gl_config.multisamplesamples; 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; attribs[i++] = EGL_NONE;
if (_this->gles_data->eglChooseConfig(_this->gles_data->egl_display, if (_this->gles_data->eglChooseConfig(_this->gles_data->egl_display,
...@@ -260,17 +296,25 @@ X11_GLES_GetVisual(_THIS, Display * display, int screen) ...@@ -260,17 +296,25 @@ X11_GLES_GetVisual(_THIS, Display * display, int screen)
SDL_GLContext SDL_GLContext
X11_GLES_CreateContext(_THIS, SDL_Window * window) 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; SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
Display *display = data->videodata->display; Display *display = data->videodata->display;
XSync(display, False); 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->egl_context =
_this->gles_data->eglCreateContext(_this->gles_data->egl_display, _this->gles_data->eglCreateContext(_this->gles_data->egl_display,
_this->gles_data->egl_config, _this->gles_data->egl_config,
EGL_NO_CONTEXT, NULL); EGL_NO_CONTEXT, context_attrib_list);
XSync(display, False); XSync(display, False);
if (_this->gles_data->egl_context == EGL_NO_CONTEXT) { if (_this->gles_data->egl_context == EGL_NO_CONTEXT) {
...@@ -280,12 +324,12 @@ X11_GLES_CreateContext(_THIS, SDL_Window * window) ...@@ -280,12 +324,12 @@ X11_GLES_CreateContext(_THIS, SDL_Window * window)
_this->gles_data->egl_active = 1; _this->gles_data->egl_active = 1;
if (_this->gles_data->egl_active) if (X11_GLES_MakeCurrent(_this, window, context) < 0) {
retval = 1; X11_GLES_DeleteContext(_this, context);
else return NULL;
retval = 0; }
return (retval); return (SDL_GLContext)(1);
} }
int int
......
...@@ -32,6 +32,7 @@ typedef struct SDL_PrivateGLESData ...@@ -32,6 +32,7 @@ typedef struct SDL_PrivateGLESData
{ {
int egl_active; /* to stop switching drivers while we have a valid context */ int egl_active; /* to stop switching drivers while we have a valid context */
XVisualInfo *egl_visualinfo; XVisualInfo *egl_visualinfo;
void *egl_dll_handle;
EGLDisplay egl_display; EGLDisplay egl_display;
EGLContext egl_context; /* Current GLES context */ EGLContext egl_context; /* Current GLES context */
EGLSurface egl_surface; EGLSurface egl_surface;
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#include "SDL_x11shape.h" #include "SDL_x11shape.h"
#include "SDL_x11touch.h" #include "SDL_x11touch.h"
#if SDL_VIDEO_DRIVER_PANDORA #if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
#include "SDL_x11opengles.h" #include "SDL_x11opengles.h"
#endif #endif
...@@ -110,7 +110,7 @@ X11_DeleteDevice(SDL_VideoDevice * device) ...@@ -110,7 +110,7 @@ X11_DeleteDevice(SDL_VideoDevice * device)
} }
SDL_free(data->windowlist); SDL_free(data->windowlist);
SDL_free(device->driverdata); SDL_free(device->driverdata);
#if SDL_VIDEO_DRIVER_PANDORA #if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
SDL_free(device->gles_data); SDL_free(device->gles_data);
#endif #endif
SDL_free(device); SDL_free(device);
...@@ -143,7 +143,7 @@ X11_CreateDevice(int devindex) ...@@ -143,7 +143,7 @@ X11_CreateDevice(int devindex)
} }
device->driverdata = data; 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)); device->gles_data = (struct SDL_PrivateGLESData *) SDL_calloc(1, sizeof(SDL_PrivateGLESData));
if (!device->gles_data) { if (!device->gles_data) {
SDL_OutOfMemory(); SDL_OutOfMemory();
...@@ -226,7 +226,7 @@ X11_CreateDevice(int devindex) ...@@ -226,7 +226,7 @@ X11_CreateDevice(int devindex)
device->GL_SwapWindow = X11_GL_SwapWindow; device->GL_SwapWindow = X11_GL_SwapWindow;
device->GL_DeleteContext = X11_GL_DeleteContext; device->GL_DeleteContext = X11_GL_DeleteContext;
#endif #endif
#if SDL_VIDEO_DRIVER_PANDORA #if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
device->GL_LoadLibrary = X11_GLES_LoadLibrary; device->GL_LoadLibrary = X11_GLES_LoadLibrary;
device->GL_GetProcAddress = X11_GLES_GetProcAddress; device->GL_GetProcAddress = X11_GLES_GetProcAddress;
device->GL_UnloadLibrary = X11_GLES_UnloadLibrary; device->GL_UnloadLibrary = X11_GLES_UnloadLibrary;
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include "SDL_x11mouse.h" #include "SDL_x11mouse.h"
#include "SDL_x11shape.h" #include "SDL_x11shape.h"
#ifdef SDL_VIDEO_DRIVER_PANDORA #if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
#include "SDL_x11opengles.h" #include "SDL_x11opengles.h"
#endif #endif
...@@ -289,7 +289,7 @@ X11_CreateWindow(_THIS, SDL_Window * window) ...@@ -289,7 +289,7 @@ X11_CreateWindow(_THIS, SDL_Window * window)
XFree(vinfo); XFree(vinfo);
} else } else
#endif #endif
#ifdef SDL_VIDEO_DRIVER_PANDORA #if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
if (window->flags & SDL_WINDOW_OPENGL) { if (window->flags & SDL_WINDOW_OPENGL) {
XVisualInfo *vinfo; XVisualInfo *vinfo;
...@@ -401,17 +401,19 @@ X11_CreateWindow(_THIS, SDL_Window * window) ...@@ -401,17 +401,19 @@ X11_CreateWindow(_THIS, SDL_Window * window)
SDL_SetError("Couldn't create window"); SDL_SetError("Couldn't create window");
return -1; return -1;
} }
#if SDL_VIDEO_DRIVER_PANDORA #if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
/* Create the GLES window surface */ if (window->flags & SDL_WINDOW_OPENGL) {
_this->gles_data->egl_surface = /* Create the GLES window surface */
_this->gles_data->eglCreateWindowSurface(_this->gles_data-> _this->gles_data->egl_surface =
_this->gles_data->eglCreateWindowSurface(_this->gles_data->
egl_display, egl_display,
_this->gles_data->egl_config, _this->gles_data->egl_config,
(NativeWindowType) w, NULL); (NativeWindowType) w, NULL);
if (_this->gles_data->egl_surface == EGL_NO_SURFACE) { if (_this->gles_data->egl_surface == EGL_NO_SURFACE) {
SDL_SetError("Could not create GLES window surface"); SDL_SetError("Could not create GLES window surface");
return -1; return -1;
}
} }
#endif #endif
......
...@@ -3764,12 +3764,10 @@ cat confdefs.h >>conftest.$ac_ext ...@@ -3764,12 +3764,10 @@ cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */ /* end confdefs.h. */
#if defined (__QNXNTO__) #if defined (__IPHONEOS__)
#include <GLES/gl.h>
#elif defined (__IPHONEOS__)
#include <OpenGLES/ES1/gl.h> #include <OpenGLES/ES1/gl.h>
#else #else
#error "No OpenGL ES support" #include <GLES/gl.h>
#endif /* __QNXNTO__ */ #endif /* __QNXNTO__ */
int int
...@@ -3812,11 +3810,12 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ...@@ -3812,11 +3810,12 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ echo "$as_me:$LINENO: result: $have_opengles" >&5 { echo "$as_me:$LINENO: result: $have_opengles" >&5
echo "${ECHO_T}$have_opengles" >&6; } echo "${ECHO_T}$have_opengles" >&6; }
if test x$have_opengl = xyes; then GLLIB=""
CFLAGS="$CFLAGS -DHAVE_OPENGL" if test x$have_opengles = xyes; then
GLLIB="$XPATH $SYS_GL_LIBS"
elif test x$have_opengles = xyes; then
CFLAGS="$CFLAGS -DHAVE_OPENGLES" CFLAGS="$CFLAGS -DHAVE_OPENGLES"
GLLIB="$XPATH -lGLESv1_CM"
elif test x$have_opengl = xyes; then
CFLAGS="$CFLAGS -DHAVE_OPENGL"
GLLIB="$XPATH $SYS_GL_LIBS" GLLIB="$XPATH $SYS_GL_LIBS"
else else
GLLIB="" GLLIB=""
......
...@@ -103,12 +103,10 @@ dnl Check for OpenGL ES ...@@ -103,12 +103,10 @@ dnl Check for OpenGL ES
AC_MSG_CHECKING(for OpenGL ES support) AC_MSG_CHECKING(for OpenGL ES support)
have_opengles=no have_opengles=no
AC_TRY_COMPILE([ AC_TRY_COMPILE([
#if defined (__QNXNTO__) #if defined (__IPHONEOS__)
#include <GLES/gl.h>
#elif defined (__IPHONEOS__)
#include <OpenGLES/ES1/gl.h> #include <OpenGLES/ES1/gl.h>
#else #else
#error "No OpenGL ES support" #include <GLES/gl.h>
#endif /* __QNXNTO__ */ #endif /* __QNXNTO__ */
],[ ],[
],[ ],[
...@@ -116,11 +114,12 @@ have_opengles=yes ...@@ -116,11 +114,12 @@ have_opengles=yes
]) ])
AC_MSG_RESULT($have_opengles) AC_MSG_RESULT($have_opengles)
if test x$have_opengl = xyes; then GLLIB=""
CFLAGS="$CFLAGS -DHAVE_OPENGL" if test x$have_opengles = xyes; then
GLLIB="$XPATH $SYS_GL_LIBS"
elif test x$have_opengles = xyes; then
CFLAGS="$CFLAGS -DHAVE_OPENGLES" CFLAGS="$CFLAGS -DHAVE_OPENGLES"
GLLIB="$XPATH -lGLESv1_CM"
elif test x$have_opengl = xyes; then
CFLAGS="$CFLAGS -DHAVE_OPENGL"
GLLIB="$XPATH $SYS_GL_LIBS" GLLIB="$XPATH $SYS_GL_LIBS"
else else
GLLIB="" GLLIB=""
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment