changeset 35889:a51578d7e264

Add (hackish) support for OpenGL on Android. The only to run that actually works in my system is running from adb shell, since trying to create a window from native code is not possible when running from a app.
author reimar
date Sat, 16 Mar 2013 19:15:42 +0000
parents f464ea910bd2
children 3be8afb83629
files Changelog configure libvo/gl_common.c libvo/gl_common.h libvo/gl_compat.h libvo/vo_gl.c
diffstat 6 files changed, 84 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/Changelog	Sat Mar 16 15:18:15 2013 +0000
+++ b/Changelog	Sat Mar 16 19:15:42 2013 +0000
@@ -18,6 +18,10 @@
     Ports:
     * Windows: support file names as UTF-8 in slave mode and passing
       file names as wchar command line arguments.
+    * Android: MPlayer can be run from adb shell and display videos
+      via OpenGL ES.
+      Note that just a bit of seeking etc. would cause reproducible
+      system reboots after just a few seconds on my Galaxy S2.
 
   1.1: "We gave up on 1.0"
 
--- a/configure	Sat Mar 16 15:18:15 2013 +0000
+++ b/configure	Sat Mar 16 19:15:42 2013 +0000
@@ -5317,7 +5317,7 @@
 # conflicts between -lGL and -framework OpenGL
 echocheck "OpenGL"
 #Note: this test is run even with --enable-gl since we autodetect linker flags
-if (test "$_x11" = yes || test "$_sdl" = yes || win32 || test "$_corevideo" = yes) && test "$_gl" != no ; then
+if test "$_gl" != no ; then
   cat > $TMPC << EOF
 #ifdef GL_WIN32
 #include <windows.h>
@@ -5337,6 +5337,9 @@
 #include <GL/gl.h>
 #include <X11/Xlib.h>
 #include <EGL/egl.h>
+#elif defined(GL_EGL_ANDROID)
+#include <GLES/gl.h>
+#include <EGL/egl.h>
 #else
 #include <GL/gl.h>
 #include <X11/Xlib.h>
@@ -5348,13 +5351,16 @@
   wglCreateContext(dc);
 #elif defined(GL_SDL)
   SDL_GL_SwapBuffers();
-#elif defined(GL_EGL_X11)
+#elif defined(GL_EGL_X11) || defined(GL_EGL_ANDROID)
   EGLDisplay eglDisplay = EGL_NO_DISPLAY;
   eglInitialize(eglDisplay, NULL, NULL);
 #else
   glXCreateContext(NULL, NULL, NULL, True);
 #endif
-#ifndef GL_EGL_X11
+#ifdef GL_EGL_ANDROID
+  EGLNativeWindowType android_createDisplaySurface(void);
+  android_createDisplaySurface();
+#elif !defined(GL_EGL_X11)
   glFinish();
 #endif
   return 0;
@@ -5369,6 +5375,11 @@
       break
     fi
   done
+  if cc_check -DGL_EGL_ANDROID -lEGL -lui ; then
+    _gl=yes
+    _gl_egl_android=yes
+    libs_mplayer="$libs_mplayer -lEGL -lui $ld_dl"
+  fi
   if test "$_x11" = yes && cc_check -DGL_EGL_X11 -lEGL ; then
     _gl=yes
     _gl_egl_x11=yes
@@ -5410,6 +5421,10 @@
     def_gl_x11='#define CONFIG_GL_X11 1'
     res_comment="$res_comment x11"
   fi
+  if test "$_gl_egl_android" = yes ; then
+    def_gl_egl_android='#define CONFIG_GL_EGL_ANDROID 1'
+    res_comment="$res_comment egl_android"
+  fi
   if test "$_gl_egl_x11" = yes ; then
     def_gl_egl_x11='#define CONFIG_GL_EGL_X11 1'
     res_comment="$res_comment egl_x11"
@@ -5427,6 +5442,7 @@
   def_gl='#undef CONFIG_GL'
   def_gl_win32='#undef CONFIG_GL_WIN32'
   def_gl_x11='#undef CONFIG_GL_X11'
+  def_gl_egl_android='#undef CONFIG_GL_EGL_ANDROID'
   def_gl_egl_x11='#undef CONFIG_GL_EGL_X11'
   def_gl_sdl='#undef CONFIG_GL_SDL'
   def_gl_osx='#undef CONFIG_GL_OSX'
@@ -8916,6 +8932,7 @@
 $def_gl
 $def_gl_win32
 $def_gl_x11
+$def_gl_egl_android
 $def_gl_egl_x11
 $def_gl_sdl
 $def_gl_osx
--- a/libvo/gl_common.c	Sat Mar 16 15:18:15 2013 +0000
+++ b/libvo/gl_common.c	Sat Mar 16 19:15:42 2013 +0000
@@ -2181,7 +2181,7 @@
 
 #endif
 
-#ifdef CONFIG_GL_EGL_X11
+#if defined(CONFIG_GL_EGL_X11) || defined(CONFIG_GL_EGL_ANDROID)
 static EGLDisplay eglDisplay = EGL_NO_DISPLAY;
 static EGLSurface eglSurface = EGL_NO_SURFACE;
 
@@ -2191,7 +2191,16 @@
  * So we have to use a non-portable way that in addition
  * might also return symbols from a different library
  * that the one providing the current context, great job!
+ * In addition the implementation of eglGetProcAddress
+ * on Galaxy S2 Android seems to actively return wrong
+ * pointers, it just gets better and better...
  */
+#ifdef CONFIG_GL_EGL_ANDROID
+static EGLNativeWindowType vo_window;
+#define eglGetProcAddress(a) 0
+#define mDisplay EGL_DEFAULT_DISPLAY
+EGLNativeWindowType android_createDisplaySurface(void);
+#endif
 static void *eglgpa(const GLubyte *name) {
   void *res = eglGetProcAddress(name);
   if (!res) {
@@ -2207,10 +2216,23 @@
   static const EGLint cfg_attribs[] = { EGL_NONE };
   static const EGLint ctx_attribs[] = { EGL_NONE };
   EGLContext *context = &ctx->context.egl;
-  Window win = vo_window;
   EGLContext new_context = NULL;
   EGLConfig eglConfig;
   int num_configs;
+#ifdef CONFIG_GL_EGL_ANDROID
+  EGLint w, h;
+  if (vo_window) {
+    eglQuerySurface(eglDisplay, eglSurface, EGL_WIDTH, &w);
+    eglQuerySurface(eglDisplay, eglSurface, EGL_HEIGHT, &h);
+    vo_screenwidth = vo_dwidth = w;
+    vo_screenheight = vo_dheight = h;
+    return SET_WINDOW_OK;
+  }
+  if (!vo_window)
+    vo_window = android_createDisplaySurface();
+  if (!vo_window)
+    return SET_WINDOW_FAILED;
+#endif
   if (eglDisplay == EGL_NO_DISPLAY) {
     eglDisplay = eglGetDisplay(mDisplay);
     if (eglDisplay == EGL_NO_DISPLAY) {
@@ -2230,7 +2252,7 @@
   if (!eglChooseConfig(eglDisplay, cfg_attribs, &eglConfig, 1, &num_configs) ||
       num_configs != 1)
     return SET_WINDOW_FAILED;
-  eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, win, NULL);
+  eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, vo_window, NULL);
   if (eglSurface == EGL_NO_SURFACE)
     return SET_WINDOW_FAILED;
 
@@ -2241,8 +2263,14 @@
     return SET_WINDOW_FAILED;
 
   // set new values
-  vo_window = win;
+#ifdef CONFIG_GL_EGL_X11
   vo_x11_update_geometry();
+#else
+  eglQuerySurface(eglDisplay, eglSurface, EGL_WIDTH, &w);
+  eglQuerySurface(eglDisplay, eglSurface, EGL_HEIGHT, &h);
+  vo_screenwidth = vo_dwidth = w;
+  vo_screenheight = vo_dheight = h;
+#endif
   *context = new_context;
 
   getFunctions(eglgpa, eglQueryString(eglDisplay, EGL_EXTENSIONS));
@@ -2289,6 +2317,10 @@
   return 0;
 }
 
+static void dummy_fullscreen(void) {
+  vo_fs = !vo_fs;
+}
+
 static void dummy_update_xinerama_info(void) {
   if (vo_screenwidth <= 0 || vo_screenheight <= 0) {
     mp_msg(MSGT_VO, MSGL_ERR, "You must specify the screen dimensions "
@@ -2309,6 +2341,8 @@
     if (res) return res;
     res = init_mpglcontext(ctx, GLTYPE_SDL);
     if (res) return res;
+    res = init_mpglcontext(ctx, GLTYPE_EGL_ANDROID);
+    if (res) return res;
     res = init_mpglcontext(ctx, GLTYPE_EGL_X11);
     return res;
   }
@@ -2318,6 +2352,7 @@
   ctx->swapGlBuffers = swapGlBuffers_dummy;
   ctx->update_xinerama_info = dummy_update_xinerama_info;
   ctx->check_events = dummy_check_events;
+  ctx->fullscreen = dummy_fullscreen;
   ctx->type = type;
   switch (ctx->type) {
 #ifdef CONFIG_GL_WIN32
@@ -2353,6 +2388,13 @@
     ctx->fullscreen = vo_sdl_fullscreen;
     return vo_sdl_init();
 #endif
+#ifdef CONFIG_GL_EGL_ANDROID
+  case GLTYPE_EGL_ANDROID:
+    ctx->setGlWindow = setGlWindow_egl;
+    ctx->releaseGlContext = releaseGlContext_egl;
+    ctx->swapGlBuffers = swapGlBuffers_egl;
+    return 1;
+#endif
 #ifdef CONFIG_GL_EGL_X11
   case GLTYPE_EGL_X11:
     ctx->setGlWindow = setGlWindow_egl;
--- a/libvo/gl_common.h	Sat Mar 16 15:18:15 2013 +0000
+++ b/libvo/gl_common.h	Sat Mar 16 19:15:42 2013 +0000
@@ -47,6 +47,9 @@
 #ifdef CONFIG_GL_OSX
 #include "osx_common.h"
 #include <OpenGL/gl.h>
+#elif defined(CONFIG_GL_EGL_ANDROID)
+#include <EGL/egl.h>
+#include <GLES/gl.h>
 #else
 #include <GL/gl.h>
 #endif
@@ -192,6 +195,7 @@
   GLTYPE_SDL,
   GLTYPE_EGL_X11,
   GLTYPE_OSX,
+  GLTYPE_EGL_ANDROID,
   GLTYPE_COUNT
 };
 
@@ -210,7 +214,7 @@
 #ifdef CONFIG_GL_X11
     GLXContext x11;
 #endif
-#ifdef CONFIG_GL_EGL_X11
+#if defined(CONFIG_GL_EGL_X11) || defined(CONFIG_GL_EGL_ANDROID)
     EGLContext egl;
 #endif
   } context;
--- a/libvo/gl_compat.h	Sat Mar 16 15:18:15 2013 +0000
+++ b/libvo/gl_compat.h	Sat Mar 16 19:15:42 2013 +0000
@@ -80,6 +80,9 @@
 #ifndef GL_INT
 #define GL_INT 0x1404
 #endif
+#ifndef GL_UNSIGNED_INT
+#define GL_UNSIGNED_INT 0x1405
+#endif
 #ifndef GL_2_BYTES
 #define GL_2_BYTES 0x1407
 #endif
--- a/libvo/vo_gl.c	Sat Mar 16 15:18:15 2013 +0000
+++ b/libvo/vo_gl.c	Sat Mar 16 19:15:42 2013 +0000
@@ -1164,7 +1164,12 @@
     int depth;
     int caps = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW |
                VFCAP_FLIP |
-               VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE;
+               VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN;
+    // TODO: This assumes backend auto-detection was run
+    // before this code.
+    // In addition strides might not work with X11 GLES either.
+    if (glctx.type != GLTYPE_EGL_ANDROID)
+      caps |= VFCAP_ACCEPT_STRIDE;
     if (use_osd)
       caps |= VFCAP_OSD | VFCAP_EOSD | (scaled_osd ? 0 : VFCAP_EOSD_UNSCALED);
     if (format == IMGFMT_RGB24 || format == IMGFMT_RGBA)