Freescale i.MX6 video driver
authormastermind <denis.barkar@gmail.com>
Wed, 10 Sep 2014 08:54:01 -0700
changeset 9127 a8c38ed1a674
parent 9126 08f3b56969b1
child 9128 3476d867bf43
Freescale i.MX6 video driver --- CMakeLists.txt | 2 + cmake/sdlchecks.cmake | 20 +++ configure | 51 +++++++ configure.in | 28 ++++ include/SDL_config.h.cmake | 1 + include/SDL_config.h.in | 1 + src/video/SDL_sysvideo.h | 3 + src/video/SDL_video.c | 3 + src/video/mx6/SDL_mx6events.c | 45 ++++++ src/video/mx6/SDL_mx6events_c.h | 31 +++++ src/video/mx6/SDL_mx6opengles.c | 211 ++++++++++++++++++++++++++++ src/video/mx6/SDL_mx6opengles.h | 68 +++++++++ src/video/mx6/SDL_mx6video.c | 301 ++++++++++++++++++++++++++++++++++++++++ src/video/mx6/SDL_mx6video.h | 78 +++++++++++ 14 files changed, 843 insertions(+) create mode 100644 src/video/mx6/SDL_mx6events.c create mode 100644 src/video/mx6/SDL_mx6events_c.h create mode 100644 src/video/mx6/SDL_mx6opengles.c create mode 100644 src/video/mx6/SDL_mx6opengles.h create mode 100644 src/video/mx6/SDL_mx6video.c create mode 100644 src/video/mx6/SDL_mx6video.h
CMakeLists.txt
cmake/sdlchecks.cmake
configure
configure.in
include/SDL_config.h.cmake
include/SDL_config.h.in
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/mx6/SDL_mx6events.c
src/video/mx6/SDL_mx6events_c.h
src/video/mx6/SDL_mx6opengles.c
src/video/mx6/SDL_mx6opengles.h
src/video/mx6/SDL_mx6video.c
src/video/mx6/SDL_mx6video.h
--- a/CMakeLists.txt	Mon Sep 08 01:36:22 2014 -0400
+++ b/CMakeLists.txt	Wed Sep 10 08:54:01 2014 -0700
@@ -247,6 +247,7 @@
 set_option(VIDEO_COCOA         "Use Cocoa video driver" ${APPLE})
 set_option(DIRECTX             "Use DirectX for Windows audio/video" ${WINDOWS})
 set_option(RENDER_D3D          "Enable the Direct3D render driver" ${WINDOWS})
+set_option(VIDEO_MX6           "Use Freescale i.MX6 video driver" OFF)
 
 # TODO: We should (should we?) respect cmake's ${BUILD_SHARED_LIBS} flag here
 # The options below are for compatibility to configure's default behaviour.
@@ -678,6 +679,7 @@
     CheckOpenGLX11()
     CheckOpenGLESX11()
     CheckWayland()
+    CheckMX6()
   endif()
 
   if(LINUX)
--- a/cmake/sdlchecks.cmake	Mon Sep 08 01:36:22 2014 -0400
+++ b/cmake/sdlchecks.cmake	Wed Sep 10 08:54:01 2014 -0700
@@ -601,6 +601,25 @@
 endmacro(CheckDirectFB)
 
 # Requires:
+# - n/a
+macro(CheckMX6)
+  if(VIDEO_MX6)
+    check_c_source_compiles("
+        #define EGL_API_FB
+        #include <EGL/eglvivante.h>
+        int main(int argc, char** argv) {}" HAVE_VIDEO_OPENGL_EGL_VIVANTE)
+    if(HAVE_VIDEO_OPENGL_EGL_VIVANTE)
+      set(HAVE_VIDEO_MX6 TRUE)
+      set(HAVE_SDL_VIDEO TRUE)
+
+      file(GLOB MX6_SOURCES ${SDL2_SOURCE_DIR}/src/video/mx6/*.c)
+      set(SOURCE_FILES ${SOURCE_FILES} ${MX6_SOURCES})
+      set(SDL_VIDEO_DRIVER_MX6 1)
+    endif(HAVE_VIDEO_OPENGL_EGL_VIVANTE)
+  endif(VIDEO_MX6)
+endmacro(CheckMX6)
+
+# Requires:
 # - nada
 macro(CheckOpenGLX11)
   if(VIDEO_OPENGL)
@@ -624,6 +643,7 @@
 macro(CheckOpenGLESX11)
   if(VIDEO_OPENGLES)
     check_c_source_compiles("
+        #define EGL_API_FB
         #include <EGL/egl.h>
         int main (int argc, char** argv) {}" HAVE_VIDEO_OPENGL_EGL)
     if(HAVE_VIDEO_OPENGL_EGL)
--- a/configure	Mon Sep 08 01:36:22 2014 -0400
+++ b/configure	Wed Sep 10 08:54:01 2014 -0700
@@ -832,6 +832,7 @@
 enable_video_x11_scrnsaver
 enable_video_x11_xshape
 enable_video_x11_vm
+enable_video_mx6
 enable_video_cocoa
 enable_video_directfb
 enable_directfb_shared
@@ -1561,6 +1562,7 @@
   --enable-video-x11-xshape
                           enable X11 XShape support [[default=yes]]
   --enable-video-x11-vm   use X11 VM extension for fullscreen [[default=yes]]
+  --enable-video-mx6      use Freescale i.MX6 video driver [[default=no]]
   --enable-video-cocoa    use Cocoa video driver [[default=yes]]
   --enable-video-directfb use DirectFB video driver [[default=no]]
   --enable-directfb-shared
@@ -20591,6 +20593,53 @@
     fi
 }
 
+CheckMX6Video()
+{
+    # Check whether --enable-video-mx6 was given.
+if test "${enable_video_mx6+set}" = set; then :
+  enableval=$enable_video_mx6;
+else
+  enable_video_mx6=no
+fi
+
+    if test x$enable_video = xyes -a x$enable_video_mx6 = xyes; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Vivante GPU SDK" >&5
+$as_echo_n "checking for Vivante GPU SDK... " >&6; }
+        have_viv_sdk=no
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+          #define EGL_API_FB
+          #include <EGL/eglvivante.h>
+
+int
+main ()
+{
+
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+        have_viv_sdk=yes
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_viv_sdk" >&5
+$as_echo "$have_viv_sdk" >&6; }
+        if test x$have_viv_sdk = xyes; then
+
+$as_echo "#define SDL_VIDEO_DRIVER_MX6 1" >>confdefs.h
+
+            SOURCES="$SOURCES $srcdir/src/video/mx6/*.c"
+            SUMMARY_video="${SUMMARY_video} mx6"
+            have_video=yes
+        fi
+    fi
+}
+
 CheckHaikuVideo()
 {
     if test x$enable_video = xyes; then
@@ -21044,6 +21093,7 @@
         cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
+         #define EGL_API_FB
          #include <EGL/egl.h>
          #include <EGL/eglext.h>
 
@@ -22818,6 +22868,7 @@
         CheckClockGettime
         CheckLinuxVersion
         CheckRPATH
+        CheckMX6Video
         # Set up files for the audio library
         if test x$enable_audio = xyes; then
           case $ARCH in
--- a/configure.in	Mon Sep 08 01:36:22 2014 -0400
+++ b/configure.in	Wed Sep 10 08:54:01 2014 -0700
@@ -1729,6 +1729,32 @@
     fi
 }
 
+dnl Set up the MX6 video driver if enabled
+CheckMX6Video()
+{
+    AC_ARG_ENABLE(video-mx6,
+AC_HELP_STRING([--enable-video-mx6], [use Freescale i.MX6 video driver [[default=no]]]),
+                  , enable_video_mx6=no)
+    if test x$enable_video = xyes -a x$enable_video_mx6 = xyes; then
+        AC_MSG_CHECKING(for Vivante GPU SDK)
+        have_viv_sdk=no
+        AC_TRY_COMPILE([
+          #define EGL_API_FB
+          #include <EGL/eglvivante.h>
+        ],[
+        ],[
+        have_viv_sdk=yes
+        ])
+        AC_MSG_RESULT($have_viv_sdk)
+        if test x$have_viv_sdk = xyes; then
+            AC_DEFINE(SDL_VIDEO_DRIVER_MX6, 1, [ ])
+            SOURCES="$SOURCES $srcdir/src/video/mx6/*.c"
+            SUMMARY_video="${SUMMARY_video} mx6"
+            have_video=yes
+        fi
+    fi
+}
+
 dnl Set up the Haiku video driver if enabled
 CheckHaikuVideo()
 {
@@ -1955,6 +1981,7 @@
         AC_MSG_CHECKING(for EGL support)
         video_opengl_egl=no
         AC_TRY_COMPILE([
+         #define EGL_API_FB
          #include <EGL/egl.h>
          #include <EGL/eglext.h>
         ],[
@@ -2809,6 +2836,7 @@
         CheckClockGettime
         CheckLinuxVersion
         CheckRPATH
+        CheckMX6Video
         # Set up files for the audio library
         if test x$enable_audio = xyes; then
           case $ARCH in
--- a/include/SDL_config.h.cmake	Mon Sep 08 01:36:22 2014 -0400
+++ b/include/SDL_config.h.cmake	Wed Sep 10 08:54:01 2014 -0700
@@ -264,6 +264,7 @@
 #cmakedefine SDL_VIDEO_DRIVER_WINDOWS @SDL_VIDEO_DRIVER_WINDOWS@
 #cmakedefine SDL_VIDEO_DRIVER_WAYLAND @SDL_VIDEO_DRIVER_WAYLAND@
 #cmakedefine SDL_VIDEO_DRIVER_RPI @SDL_VIDEO_DRIVER_RPI@
+#cmakedefine SDL_VIDEO_DRIVER_MX6 @SDL_VIDEO_DRIVER_MX6@
 
 #if 0
 /* !!! FIXME: in configure script version, missing here: */
--- a/include/SDL_config.h.in	Mon Sep 08 01:36:22 2014 -0400
+++ b/include/SDL_config.h.in	Wed Sep 10 08:54:01 2014 -0700
@@ -308,6 +308,7 @@
 #undef SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY
 #undef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
 #undef SDL_VIDEO_DRIVER_NACL
+#undef SDL_VIDEO_DRIVER_MX6
 
 #undef SDL_VIDEO_RENDER_D3D
 #undef SDL_VIDEO_RENDER_D3D11
--- a/src/video/SDL_sysvideo.h	Mon Sep 08 01:36:22 2014 -0400
+++ b/src/video/SDL_sysvideo.h	Wed Sep 10 08:54:01 2014 -0700
@@ -391,6 +391,9 @@
 #if SDL_VIDEO_DRIVER_NACL
 extern VideoBootStrap NACL_bootstrap;
 #endif
+#if SDL_VIDEO_DRIVER_MX6
+extern VideoBootStrap MX6_bootstrap;
+#endif
 
 extern SDL_VideoDevice *SDL_GetVideoDevice(void);
 extern int SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode);
--- a/src/video/SDL_video.c	Mon Sep 08 01:36:22 2014 -0400
+++ b/src/video/SDL_video.c	Wed Sep 10 08:54:01 2014 -0700
@@ -95,6 +95,9 @@
 #if SDL_VIDEO_DRIVER_NACL
     &NACL_bootstrap,
 #endif
+#if SDL_VIDEO_DRIVER_MX6
+    &MX6_bootstrap,
+#endif
 #if SDL_VIDEO_DRIVER_DUMMY
     &DUMMY_bootstrap,
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/mx6/SDL_mx6events.c	Wed Sep 10 08:54:01 2014 -0700
@@ -0,0 +1,45 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_MX6
+
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "../../events/SDL_keyboard_c.h"
+#include "SDL_mx6video.h"
+#include "SDL_mx6events_c.h"
+
+#ifdef SDL_INPUT_LINUXEV
+#include "../../core/linux/SDL_evdev.h"
+#endif
+
+void MX6_PumpEvents(_THIS)
+{
+#ifdef SDL_INPUT_LINUXEV
+    SDL_EVDEV_Poll();
+#endif
+    
+}
+
+#endif /* SDL_VIDEO_DRIVER_MX6 */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/mx6/SDL_mx6events_c.h	Wed Sep 10 08:54:01 2014 -0700
@@ -0,0 +1,31 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef _SDL_mx6events_c_h
+#define _SDL_mx6events_c_h
+
+#include "SDL_mx6video.h"
+
+void MX6_PumpEvents(_THIS);
+void MX6_EventInit(_THIS);
+void MX6_EventQuit(_THIS);
+
+#endif /* _SDL_mx6events_c_h */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/mx6/SDL_mx6opengles.c	Wed Sep 10 08:54:01 2014 -0700
@@ -0,0 +1,211 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_MX6 && SDL_VIDEO_OPENGL_EGL
+
+#include "SDL_mx6opengles.h"
+#include "SDL_loadso.h"
+#include "SDL_mx6video.h"
+
+#define DEFAULT_OGL "libGL.so.1"
+#define DEFAULT_EGL "libEGL.so.1"
+#define DEFAULT_OGL_ES2 "libGLESv2.so.2"
+#define DEFAULT_OGL_ES "libGLESv1_CM.so.1"
+
+#define LOAD_FUNC(NAME) \
+*((void**)&_this->egl_data->NAME) = SDL_LoadFunction(_this->egl_data->dll_handle, #NAME); \
+if (!_this->egl_data->NAME) \
+{ \
+    return SDL_SetError("Could not retrieve EGL function " #NAME); \
+}
+
+#define LOAD_VIV_FUNC(NAME) \
+*((void**)&egl_viv_data->NAME) = SDL_LoadFunction(_this->egl_data->dll_handle, #NAME); \
+if (!egl_viv_data->NAME) \
+{ \
+    return SDL_SetError("Could not retrieve EGL function " #NAME); \
+}
+
+/* EGL implementation of SDL OpenGL support */
+
+int
+MX6_GLES_LoadLibrary(_THIS, const char *egl_path) {
+    /* The definitions of egl_dll_handle and dll_handle were interchanged for some reason.
+       Just left them as is for compatibility */
+    void *dll_handle = NULL, *egl_dll_handle = NULL;
+    char *path = NULL;
+    SDL_DisplayData *displaydata;
+
+    if (_this->egl_data) {
+        return SDL_SetError("OpenGL ES context already created");
+    }
+
+    _this->egl_data = (struct SDL_EGL_VideoData *) SDL_calloc(1, sizeof(SDL_EGL_VideoData));
+    if (!_this->egl_data) {
+        return SDL_OutOfMemory();
+    }
+
+    egl_viv_data = (struct MX6_EGL_VivanteData *) SDL_calloc(1, sizeof(MX6_EGL_VivanteData));
+    if (!egl_viv_data) {
+        return SDL_OutOfMemory();
+    }
+
+    path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
+    if (path != NULL) {
+        egl_dll_handle = SDL_LoadObject(path);
+    }
+
+    if (egl_dll_handle == NULL) {
+        if(_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
+            if (_this->gl_config.major_version > 1) {
+                path = DEFAULT_OGL_ES2;
+                egl_dll_handle = SDL_LoadObject(path);
+            }
+            else {
+                path = DEFAULT_OGL_ES;
+                egl_dll_handle = SDL_LoadObject(path);
+            }
+        }      
+        else {
+            path = DEFAULT_OGL;
+            egl_dll_handle = SDL_LoadObject(path);
+        }     
+    }
+    _this->egl_data->egl_dll_handle = egl_dll_handle;
+
+    if (egl_dll_handle == NULL) {
+        return SDL_SetError("Could not initialize OpenGL / GLES library");
+    }
+
+    if (egl_path != NULL) {
+        dll_handle = SDL_LoadObject(egl_path);
+    }   
+    
+    if (SDL_LoadFunction(dll_handle, "eglChooseConfig") == NULL) {
+        if (dll_handle != NULL) {
+            SDL_UnloadObject(dll_handle);
+        }
+        path = SDL_getenv("SDL_VIDEO_EGL_DRIVER");
+        if (path == NULL) {
+            path = DEFAULT_EGL;
+        }
+        dll_handle = SDL_LoadObject(path);
+        if (dll_handle == NULL) {
+            return SDL_SetError("Could not load EGL library");
+        }
+    }
+
+    _this->egl_data->dll_handle = dll_handle;
+
+    /* Load new function pointers */
+    LOAD_FUNC(eglGetDisplay);
+    LOAD_FUNC(eglInitialize);
+    LOAD_FUNC(eglTerminate);
+    LOAD_FUNC(eglGetProcAddress);
+    LOAD_FUNC(eglChooseConfig);
+    LOAD_FUNC(eglGetConfigAttrib);
+    LOAD_FUNC(eglCreateContext);
+    LOAD_FUNC(eglDestroyContext);
+    LOAD_FUNC(eglCreateWindowSurface);
+    LOAD_FUNC(eglDestroySurface);
+    LOAD_FUNC(eglMakeCurrent);
+    LOAD_FUNC(eglSwapBuffers);
+    LOAD_FUNC(eglSwapInterval);
+    LOAD_FUNC(eglWaitNative);
+    LOAD_FUNC(eglWaitGL);
+    LOAD_FUNC(eglBindAPI);
+    /* Functions from Vivante GPU SDK */
+    LOAD_VIV_FUNC(fbGetDisplay);
+    LOAD_VIV_FUNC(fbGetDisplayByIndex);
+    LOAD_VIV_FUNC(fbGetDisplayGeometry);
+    LOAD_VIV_FUNC(fbGetDisplayInfo);
+    LOAD_VIV_FUNC(fbDestroyDisplay);
+    LOAD_VIV_FUNC(fbCreateWindow);
+    LOAD_VIV_FUNC(fbGetWindowGeometry);
+    LOAD_VIV_FUNC(fbGetWindowInfo);
+    LOAD_VIV_FUNC(fbDestroyWindow);
+    LOAD_VIV_FUNC(fbCreatePixmap);
+    LOAD_VIV_FUNC(fbCreatePixmapWithBpp);
+    LOAD_VIV_FUNC(fbGetPixmapGeometry);
+    LOAD_VIV_FUNC(fbGetPixmapInfo);
+    LOAD_VIV_FUNC(fbDestroyPixmap);
+   
+    displaydata = SDL_GetDisplayDriverData(0);
+    displaydata->native_display = egl_viv_data->fbGetDisplayByIndex(0);
+    egl_viv_data->fbGetDisplayGeometry(displaydata->native_display, &displaydata->width, &displaydata->height);
+
+    _this->egl_data->egl_display = _this->egl_data->eglGetDisplay(displaydata->native_display);
+    if (!_this->egl_data->egl_display) {
+        return SDL_SetError("Could not get EGL display");
+    }
+    
+    if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
+        return SDL_SetError("Could not initialize EGL");
+    }
+
+    displaydata->egl_display = _this->egl_data->egl_display;
+
+    _this->gl_config.driver_loaded = 1;
+
+    if (path) {
+        SDL_strlcpy(_this->gl_config.driver_path, path, sizeof(_this->gl_config.driver_path) - 1);
+    } else {
+        *_this->gl_config.driver_path = '\0';
+    }
+    
+    return 0;
+}
+
+void
+MX6_GLES_UnloadLibrary(_THIS)
+{
+    if (_this->egl_data) {
+        if (_this->egl_data->egl_display) {
+            _this->egl_data->eglTerminate(_this->egl_data->egl_display);
+            _this->egl_data->egl_display = NULL;
+        }
+
+        if (_this->egl_data->dll_handle) {
+            SDL_UnloadObject(_this->egl_data->dll_handle);
+            _this->egl_data->dll_handle = NULL;
+        }
+        if (_this->egl_data->egl_dll_handle) {
+            SDL_UnloadObject(_this->egl_data->egl_dll_handle);
+            _this->egl_data->egl_dll_handle = NULL;
+        }
+        
+        SDL_free(_this->egl_data);
+        _this->egl_data = NULL;
+
+        SDL_free(egl_viv_data);
+        egl_viv_data = NULL;
+    }
+}
+
+SDL_EGL_CreateContext_impl(MX6)
+SDL_EGL_SwapWindow_impl(MX6)
+SDL_EGL_MakeCurrent_impl(MX6)
+
+#endif /* SDL_VIDEO_DRIVER_MX6 && SDL_VIDEO_OPENGL_EGL */
+
+/* vi: set ts=4 sw=4 expandtab: */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/mx6/SDL_mx6opengles.h	Wed Sep 10 08:54:01 2014 -0700
@@ -0,0 +1,68 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef _SDL_mx6opengles_h
+#define _SDL_mx6opengles_h
+
+#if SDL_VIDEO_DRIVER_MX6 && SDL_VIDEO_OPENGL_EGL
+
+#include "../SDL_sysvideo.h"
+#include "../SDL_egl_c.h"
+
+typedef struct MX6_EGL_VivanteData
+{
+    EGLNativeDisplayType(EGLAPIENTRY *fbGetDisplay) (void *context);
+    EGLNativeDisplayType(EGLAPIENTRY *fbGetDisplayByIndex) (int DisplayIndex);
+    void(EGLAPIENTRY *fbGetDisplayGeometry) (EGLNativeDisplayType Display, int *Width, int *Height);
+    void(EGLAPIENTRY *fbGetDisplayInfo) (EGLNativeDisplayType Display, int *Width, int *Height, unsigned long *Physical, int *Stride, int *BitsPerPixel);
+    void(EGLAPIENTRY *fbDestroyDisplay) (EGLNativeDisplayType Display);
+    EGLNativeWindowType(EGLAPIENTRY *fbCreateWindow) (EGLNativeDisplayType Display, int X, int Y, int Width, int Height);
+    void(EGLAPIENTRY *fbGetWindowGeometry) (EGLNativeWindowType Window, int *X, int *Y, int *Width, int *Height);
+    void(EGLAPIENTRY *fbGetWindowInfo) (EGLNativeWindowType Window, int *X, int *Y, int *Width, int *Height, int *BitsPerPixel, unsigned int *Offset);
+    void(EGLAPIENTRY *fbDestroyWindow) (EGLNativeWindowType Window);
+    EGLNativePixmapType(EGLAPIENTRY *fbCreatePixmap) (EGLNativeDisplayType Display, int Width, int Height);
+    EGLNativePixmapType(EGLAPIENTRY *fbCreatePixmapWithBpp) (EGLNativeDisplayType Display, int Width, int Height, int BitsPerPixel);
+    void(EGLAPIENTRY *fbGetPixmapGeometry) (EGLNativePixmapType Pixmap, int *Width, int *Height);
+    void(EGLAPIENTRY *fbGetPixmapInfo) (EGLNativePixmapType Pixmap, int *Width, int *Height, int *BitsPerPixel, int *Stride, void **Bits);
+    void(EGLAPIENTRY *fbDestroyPixmap) (EGLNativePixmapType Pixmap);
+} MX6_EGL_VivanteData;
+
+struct MX6_EGL_VivanteData *egl_viv_data;
+
+/* OpenGLES functions */
+#define MX6_GLES_GetAttribute SDL_EGL_GetAttribute
+#define MX6_GLES_GetProcAddress SDL_EGL_GetProcAddress
+#define MX6_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
+#define MX6_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
+#define MX6_GLES_DeleteContext SDL_EGL_DeleteContext
+
+extern int MX6_GLES_LoadLibrary(_THIS, const char *path);
+extern void MX6_GLES_UnloadLibrary(_THIS);
+extern SDL_GLContext MX6_GLES_CreateContext(_THIS, SDL_Window * window);
+extern void MX6_GLES_SwapWindow(_THIS, SDL_Window * window);
+extern int MX6_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+
+#endif /* SDL_VIDEO_DRIVER_MX6 && SDL_VIDEO_OPENGL_EGL */
+
+#endif /* _SDL_mx6opengles_h */
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/mx6/SDL_mx6video.c	Wed Sep 10 08:54:01 2014 -0700
@@ -0,0 +1,301 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_MX6
+
+/* SDL internals */
+#include "../SDL_sysvideo.h"
+#include "SDL_version.h"
+#include "SDL_syswm.h"
+#include "SDL_loadso.h"
+#include "SDL_events.h"
+
+#ifdef SDL_INPUT_LINUXEV
+#include "../../core/linux/SDL_evdev.h"
+#endif
+
+#include "SDL_mx6video.h"
+#include "SDL_mx6events_c.h"
+#include "SDL_mx6opengles.h"
+
+static int
+MX6_Available(void)
+{
+    return 1;
+}
+
+static void
+MX6_Destroy(SDL_VideoDevice * device)
+{
+    if (device->driverdata != NULL) {
+        device->driverdata = NULL;
+    }
+}
+
+static SDL_VideoDevice *
+MX6_Create()
+{
+    SDL_VideoDevice *device;
+    SDL_VideoData *phdata;
+
+    /* Initialize SDL_VideoDevice structure */
+    device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+    if (device == NULL) {
+        SDL_OutOfMemory();
+        return NULL;
+    }
+
+    /* Initialize internal data */
+    phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
+    if (phdata == NULL) {
+        SDL_OutOfMemory();
+        SDL_free(device);
+        return NULL;
+    }
+
+    device->driverdata = phdata;
+
+    /* Setup amount of available displays and current display */
+    device->num_displays = 0;
+
+    /* Set device free function */
+    device->free = MX6_Destroy;
+
+    /* Setup all functions which we can handle */
+    device->VideoInit = MX6_VideoInit;
+    device->VideoQuit = MX6_VideoQuit;
+    device->GetDisplayModes = MX6_GetDisplayModes;
+    device->SetDisplayMode = MX6_SetDisplayMode;
+    device->CreateWindow = MX6_CreateWindow;
+    device->CreateWindowFrom = MX6_CreateWindowFrom;
+    device->SetWindowTitle = MX6_SetWindowTitle;
+    device->SetWindowIcon = MX6_SetWindowIcon;
+    device->SetWindowPosition = MX6_SetWindowPosition;
+    device->SetWindowSize = MX6_SetWindowSize;
+    device->ShowWindow = MX6_ShowWindow;
+    device->HideWindow = MX6_HideWindow;
+    device->RaiseWindow = MX6_RaiseWindow;
+    device->MaximizeWindow = MX6_MaximizeWindow;
+    device->MinimizeWindow = MX6_MinimizeWindow;
+    device->RestoreWindow = MX6_RestoreWindow;
+    device->SetWindowGrab = MX6_SetWindowGrab;
+    device->DestroyWindow = MX6_DestroyWindow;
+    device->GetWindowWMInfo = MX6_GetWindowWMInfo;
+
+    device->GL_LoadLibrary = MX6_GLES_LoadLibrary;
+    device->GL_GetProcAddress = MX6_GLES_GetProcAddress;
+    device->GL_UnloadLibrary = MX6_GLES_UnloadLibrary;
+    device->GL_CreateContext = MX6_GLES_CreateContext;
+    device->GL_MakeCurrent = MX6_GLES_MakeCurrent;
+    device->GL_SetSwapInterval = MX6_GLES_SetSwapInterval;
+    device->GL_GetSwapInterval = MX6_GLES_GetSwapInterval;
+    device->GL_SwapWindow = MX6_GLES_SwapWindow;
+    device->GL_DeleteContext = MX6_GLES_DeleteContext;
+
+    device->PumpEvents = MX6_PumpEvents;
+
+    return device;
+}
+
+VideoBootStrap MX6_bootstrap = {
+    "MX6",
+    "Freescale i.MX6 Video Driver",
+    MX6_Available,
+    MX6_Create
+};
+
+/*****************************************************************************/
+/* SDL Video and Display initialization/handling functions                   */
+/*****************************************************************************/
+int
+MX6_VideoInit(_THIS)
+{
+    SDL_VideoDisplay display;
+    SDL_DisplayMode current_mode;
+    SDL_DisplayData *data;
+    
+    data = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData));
+    if (data == NULL) {
+        return SDL_OutOfMemory();
+    }
+    
+    /* Actual data will be set in SDL_GL_LoadLibrary call below */
+    SDL_zero(current_mode);
+    current_mode.w = 0;
+    current_mode.h = 0;
+    current_mode.refresh_rate = 60;
+    current_mode.format = SDL_PIXELFORMAT_RGB565;
+    current_mode.driverdata = NULL;
+
+    SDL_zero(display);
+    display.desktop_mode = current_mode;
+    display.current_mode = current_mode;
+    display.driverdata = data;
+    SDL_AddVideoDisplay(&display);
+
+    if (SDL_GL_LoadLibrary(NULL) < 0) {
+        return -1;
+    }
+
+#ifdef SDL_INPUT_LINUXEV    
+    SDL_EVDEV_Init();
+#endif    
+
+    return 1;
+}
+
+void
+MX6_VideoQuit(_THIS)
+{
+#ifdef SDL_INPUT_LINUXEV    
+    SDL_EVDEV_Quit();
+#endif    
+}
+
+void
+MX6_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
+{
+    /* Only one display mode available, the current one */
+    SDL_AddDisplayMode(display, &display->current_mode);
+}
+
+int
+MX6_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+    return 0;
+}
+
+int
+MX6_CreateWindow(_THIS, SDL_Window * window)
+{
+    SDL_DisplayData *displaydata;
+    SDL_WindowData *wdata;
+    
+    displaydata = SDL_GetDisplayDriverData(0);
+    
+    /* Allocate window internal data */
+    wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
+    if (wdata == NULL) {
+        return SDL_OutOfMemory();
+    }
+
+    /* Setup driver data for this window */
+    window->driverdata = wdata;
+    window->flags |= SDL_WINDOW_OPENGL;
+    
+    if (!_this->egl_data) {
+        return -1;
+    }
+
+    wdata->native_window = egl_viv_data->fbCreateWindow(displaydata->native_display, window->x, window->y, window->w, window->h);    
+    if (!wdata->native_window) {
+        return SDL_SetError("MX6: Can't create native window");
+    }
+
+    wdata->egl_surface = SDL_EGL_CreateSurface(_this, wdata->native_window);
+    if (wdata->egl_surface == EGL_NO_SURFACE) {
+        return SDL_SetError("MX6: Can't create EGL surface");
+    }
+
+    /* Window has been successfully created */
+    return 0;
+}
+
+void
+MX6_DestroyWindow(_THIS, SDL_Window * window)
+{
+    SDL_WindowData *wdata;
+    
+    wdata = window->driverdata;
+    if (wdata) {
+        SDL_EGL_DestroySurface(_this, wdata->egl_surface);
+    }
+
+    if (egl_viv_data) {
+        egl_viv_data->fbDestroyWindow(wdata->native_window);
+    }
+}
+
+int
+MX6_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
+{
+    return -1;
+}
+
+void
+MX6_SetWindowTitle(_THIS, SDL_Window * window)
+{
+}
+void
+MX6_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
+{
+}
+void
+MX6_SetWindowPosition(_THIS, SDL_Window * window)
+{
+}
+void
+MX6_SetWindowSize(_THIS, SDL_Window * window)
+{
+}
+void
+MX6_ShowWindow(_THIS, SDL_Window * window)
+{
+}
+void
+MX6_HideWindow(_THIS, SDL_Window * window)
+{
+}
+void
+MX6_RaiseWindow(_THIS, SDL_Window * window)
+{
+}
+void
+MX6_MaximizeWindow(_THIS, SDL_Window * window)
+{
+}
+void
+MX6_MinimizeWindow(_THIS, SDL_Window * window)
+{
+}
+void
+MX6_RestoreWindow(_THIS, SDL_Window * window)
+{
+}
+void
+MX6_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
+{
+}
+
+/*****************************************************************************/
+/* SDL Window Manager function                                               */
+/*****************************************************************************/
+SDL_bool
+MX6_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
+{
+    return SDL_TRUE;
+}
+
+#endif /* SDL_VIDEO_DRIVER_MX6 */
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/mx6/SDL_mx6video.h	Wed Sep 10 08:54:01 2014 -0700
@@ -0,0 +1,78 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef __SDL_MX6VIDEO_H__
+#define __SDL_MX6VIDEO_H__
+
+#include "../../SDL_internal.h"
+#include "../SDL_sysvideo.h"
+
+#include "SDL_egl.h"
+
+typedef struct SDL_VideoData
+{
+} SDL_VideoData;
+
+typedef struct SDL_DisplayData
+{
+    EGLNativeDisplayType native_display;
+    EGLDisplay egl_display;
+    int width;
+    int height;
+} SDL_DisplayData;
+
+typedef struct SDL_WindowData
+{
+    EGLNativeWindowType native_window;
+    EGLSurface egl_surface;
+} SDL_WindowData;
+
+/****************************************************************************/
+/* SDL_VideoDevice functions declaration                                    */
+/****************************************************************************/
+
+/* Display and window functions */
+int MX6_VideoInit(_THIS);
+void MX6_VideoQuit(_THIS);
+void MX6_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
+int MX6_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+int MX6_CreateWindow(_THIS, SDL_Window * window);
+int MX6_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
+void MX6_SetWindowTitle(_THIS, SDL_Window * window);
+void MX6_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
+void MX6_SetWindowPosition(_THIS, SDL_Window * window);
+void MX6_SetWindowSize(_THIS, SDL_Window * window);
+void MX6_ShowWindow(_THIS, SDL_Window * window);
+void MX6_HideWindow(_THIS, SDL_Window * window);
+void MX6_RaiseWindow(_THIS, SDL_Window * window);
+void MX6_MaximizeWindow(_THIS, SDL_Window * window);
+void MX6_MinimizeWindow(_THIS, SDL_Window * window);
+void MX6_RestoreWindow(_THIS, SDL_Window * window);
+void MX6_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
+void MX6_DestroyWindow(_THIS, SDL_Window * window);
+
+/* Window manager function */
+SDL_bool MX6_GetWindowWMInfo(_THIS, SDL_Window * window,
+                             struct SDL_SysWMinfo *info);
+
+#endif /* __SDL_MX6VIDEO_H__ */
+
+/* vi: set ts=4 sw=4 expandtab: */