From 50cc4efec8aa20f6e225a68953e935fb5b428a30 Mon Sep 17 00:00:00 2001 From: mastermind Date: Wed, 10 Sep 2014 08:54:01 -0700 Subject: [PATCH] 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 | 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 diff --git a/CMakeLists.txt b/CMakeLists.txt index d585f0be4e96d..e1ab286ecf300 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -247,6 +247,7 @@ endforeach() 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 @@ if(UNIX AND NOT APPLE) CheckOpenGLX11() CheckOpenGLESX11() CheckWayland() + CheckMX6() endif() if(LINUX) diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake index fa8aa396e1669..713fe7b949019 100644 --- a/cmake/sdlchecks.cmake +++ b/cmake/sdlchecks.cmake @@ -600,6 +600,25 @@ macro(CheckDirectFB) endif(VIDEO_DIRECTFB) endmacro(CheckDirectFB) +# Requires: +# - n/a +macro(CheckMX6) + if(VIDEO_MX6) + check_c_source_compiles(" + #define EGL_API_FB + #include + 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) @@ -624,6 +643,7 @@ endmacro(CheckOpenGLX11) macro(CheckOpenGLESX11) if(VIDEO_OPENGLES) check_c_source_compiles(" + #define EGL_API_FB #include int main (int argc, char** argv) {}" HAVE_VIDEO_OPENGL_EGL) if(HAVE_VIDEO_OPENGL_EGL) diff --git a/configure b/configure index 3b282a34c5a69..2f1e5fee1a41e 100755 --- a/configure +++ b/configure @@ -832,6 +832,7 @@ enable_video_x11_xrandr 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 @@ Optional Features: --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 @@ $as_echo "#define SDL_VIDEO_DRIVER_X11_XVIDMODE 1" >>confdefs.h 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 + +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 @@ $as_echo_n "checking for EGL support... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ + #define EGL_API_FB #include #include @@ -22818,6 +22868,7 @@ case "$host" in CheckClockGettime CheckLinuxVersion CheckRPATH + CheckMX6Video # Set up files for the audio library if test x$enable_audio = xyes; then case $ARCH in diff --git a/configure.in b/configure.in index 4f534a2a12460..528a7a81ed36c 100644 --- a/configure.in +++ b/configure.in @@ -1729,6 +1729,32 @@ AC_HELP_STRING([--enable-video-x11-vm], [use X11 VM extension for fullscreen [[d 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 + ],[ + ],[ + 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 @@ CheckOpenGLESX11() AC_MSG_CHECKING(for EGL support) video_opengl_egl=no AC_TRY_COMPILE([ + #define EGL_API_FB #include #include ],[ @@ -2809,6 +2836,7 @@ case "$host" in CheckClockGettime CheckLinuxVersion CheckRPATH + CheckMX6Video # Set up files for the audio library if test x$enable_audio = xyes; then case $ARCH in diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake index 51500fb2b0e05..64f76bb05d138 100644 --- a/include/SDL_config.h.cmake +++ b/include/SDL_config.h.cmake @@ -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: */ diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index 145a7b7728c13..67c08a1457673 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -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 diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index f552cb5b9960a..8f05bb3e7eec8 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -391,6 +391,9 @@ extern VideoBootStrap Wayland_bootstrap; #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); diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 0c92a872da3fc..be32928b4e313 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -95,6 +95,9 @@ static VideoBootStrap *bootstrap[] = { #if SDL_VIDEO_DRIVER_NACL &NACL_bootstrap, #endif +#if SDL_VIDEO_DRIVER_MX6 + &MX6_bootstrap, +#endif #if SDL_VIDEO_DRIVER_DUMMY &DUMMY_bootstrap, #endif diff --git a/src/video/mx6/SDL_mx6events.c b/src/video/mx6/SDL_mx6events.c new file mode 100644 index 0000000000000..d024ce12d08bb --- /dev/null +++ b/src/video/mx6/SDL_mx6events.c @@ -0,0 +1,45 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + 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 */ + diff --git a/src/video/mx6/SDL_mx6events_c.h b/src/video/mx6/SDL_mx6events_c.h new file mode 100644 index 0000000000000..570e28f76537a --- /dev/null +++ b/src/video/mx6/SDL_mx6events_c.h @@ -0,0 +1,31 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + 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 */ diff --git a/src/video/mx6/SDL_mx6opengles.c b/src/video/mx6/SDL_mx6opengles.c new file mode 100644 index 0000000000000..9881dba749f30 --- /dev/null +++ b/src/video/mx6/SDL_mx6opengles.c @@ -0,0 +1,211 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + 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: */ + diff --git a/src/video/mx6/SDL_mx6opengles.h b/src/video/mx6/SDL_mx6opengles.h new file mode 100644 index 0000000000000..2cab8e9e3dcc8 --- /dev/null +++ b/src/video/mx6/SDL_mx6opengles.h @@ -0,0 +1,68 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + 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: */ diff --git a/src/video/mx6/SDL_mx6video.c b/src/video/mx6/SDL_mx6video.c new file mode 100644 index 0000000000000..06fe4a310df29 --- /dev/null +++ b/src/video/mx6/SDL_mx6video.c @@ -0,0 +1,301 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + 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: */ diff --git a/src/video/mx6/SDL_mx6video.h b/src/video/mx6/SDL_mx6video.h new file mode 100644 index 0000000000000..93de1317ce53e --- /dev/null +++ b/src/video/mx6/SDL_mx6video.h @@ -0,0 +1,78 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + 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: */