[MPlayer-cvslog] r34426 - in trunk: configure libvo/gl_common.c libvo/gl_common.h libvo/vo_gl.c

reimar subversion at mplayerhq.hu
Sat Dec 10 21:55:31 CET 2011


Author: reimar
Date: Sat Dec 10 21:55:31 2011
New Revision: 34426

Log:
Add highly experimental support for OpenGL ES.

It only supports EGL/X11, uses/supports only ES v1,
will crash if certain features are used, compiling
without desktop GL installed is not tested and
possibly more caveats.
However it is close enough to be able to display
a video on a BeagleBoard via OpenGL.
Performance could not be tested properly since I do
not have a display that is compatible with the
BeagleBoard output...

Modified:
   trunk/configure
   trunk/libvo/gl_common.c
   trunk/libvo/gl_common.h
   trunk/libvo/vo_gl.c

Modified: trunk/configure
==============================================================================
--- trunk/configure	Sat Dec 10 21:21:50 2011	(r34425)
+++ trunk/configure	Sat Dec 10 21:55:31 2011	(r34426)
@@ -5064,6 +5064,10 @@ if (test "$_x11" = yes || test "$_sdl" =
 // we allow SDL hacking our main() only on OSX
 #undef main
 #endif
+#elif defined(GL_EGL_X11)
+#include <GL/gl.h>
+#include <X11/Xlib.h>
+#include <EGL/egl.h>
 #else
 #include <GL/gl.h>
 #include <X11/Xlib.h>
@@ -5075,10 +5079,15 @@ int main(int argc, char *argv[]) {
   wglCreateContext(dc);
 #elif defined(GL_SDL)
   SDL_GL_SwapBuffers();
+#elif defined(GL_EGL_X11)
+  EGLDisplay eglDisplay = EGL_NO_DISPLAY;
+  eglInitialize(eglDisplay, NULL, NULL);
 #else
   glXCreateContext(NULL, NULL, NULL, True);
 #endif
+#ifndef GL_EGL_X11
   glFinish();
+#endif
   return 0;
 }
 EOF
@@ -5091,6 +5100,11 @@ EOF
       break
     fi
   done
+  if cc_check -DGL_EGL_X11 -lEGL ; then
+    _gl=yes
+    _gl_egl_x11=yes
+    libs_mplayer="$libs_mplayer -lEGL $ld_dl"
+  fi
   if cc_check -DGL_WIN32 -lopengl32 ; then
     _gl=yes
     _gl_win32=yes
@@ -5123,6 +5137,10 @@ if test "$_gl" = yes ; then
     def_gl_x11='#define CONFIG_GL_X11 1'
     res_comment="$res_comment x11"
   fi
+  if test "$_gl_egl_x11" = yes ; then
+    def_gl_egl_x11='#define CONFIG_GL_EGL_X11 1'
+    res_comment="$res_comment egl_x11"
+  fi
   if test "$_gl_sdl" = yes ; then
     def_gl_sdl='#define CONFIG_GL_SDL 1'
     res_comment="$res_comment sdl"
@@ -5132,6 +5150,7 @@ else
   def_gl='#undef CONFIG_GL'
   def_gl_win32='#undef CONFIG_GL_WIN32'
   def_gl_x11='#undef CONFIG_GL_X11'
+  def_gl_egl_x11='#undef CONFIG_GL_EGL_X11'
   def_gl_sdl='#undef CONFIG_GL_SDL'
   novomodules="opengl $novomodules"
 fi
@@ -8030,6 +8049,7 @@ GGI = $_ggi
 GL = $_gl
 GL_WIN32 = $_gl_win32
 GL_X11 = $_gl_x11
+GL_EGL_X11 = $_gl_egl_x11
 GL_SDL = $_gl_sdl
 MATRIXVIEW = $matrixview
 GUI = $_gui
@@ -8569,6 +8589,7 @@ $def_gif_tvt_hack
 $def_gl
 $def_gl_win32
 $def_gl_x11
+$def_gl_egl_x11
 $def_gl_sdl
 $def_matrixview
 $def_ivtv

Modified: trunk/libvo/gl_common.c
==============================================================================
--- trunk/libvo/gl_common.c	Sat Dec 10 21:21:50 2011	(r34425)
+++ trunk/libvo/gl_common.c	Sat Dec 10 21:55:31 2011	(r34426)
@@ -139,6 +139,14 @@ void* (GLAPIENTRY *mpglAllocateMemoryMES
 void (GLAPIENTRY *mpglFreeMemoryMESA)(void *, int, void *);
 /** \} */ // end of glextfunctions group
 
+
+void (GLAPIENTRY *mpglVertexPointer)(GLint, GLenum, GLsizei, const GLvoid *);
+void (GLAPIENTRY *mpglTexCoordPointer)(GLint, GLenum, GLsizei, const GLvoid *);
+void (GLAPIENTRY *mpglClientActiveTexture)(GLenum);
+void (GLAPIENTRY *mpglEnableClientState)(GLenum);
+void (GLAPIENTRY *mpglDisableClientState)(GLenum);
+void (GLAPIENTRY *mpglDrawArrays)(GLenum, GLint, GLsizei);
+
 //! \defgroup glgeneral OpenGL general helper functions
 
 //! \defgroup glcontext OpenGL context management helper functions
@@ -384,7 +392,11 @@ typedef struct {
   void *fallback;
 } extfunc_desc_t;
 
+#if !defined(CONFIG_GL_WIN32) && !defined(CONFIG_GL_X11)
+#define DEF_FUNC_DESC(name) {&mpgl##name, NULL, {"gl"#name, NULL}, NULL}
+#else
 #define DEF_FUNC_DESC(name) {&mpgl##name, NULL, {"gl"#name, NULL}, gl ##name}
+#endif
 static const extfunc_desc_t extfuncs[] = {
   // these aren't extension functions but we query them anyway to allow
   // different "backends" with one binary
@@ -466,6 +478,14 @@ static const extfunc_desc_t extfuncs[] =
   {&mpglTexImage3D, NULL, {"glTexImage3D", NULL}},
   {&mpglAllocateMemoryMESA, "GLX_MESA_allocate_memory", {"glXAllocateMemoryMESA", NULL}},
   {&mpglFreeMemoryMESA, "GLX_MESA_allocate_memory", {"glXFreeMemoryMESA", NULL}},
+
+  // Things needed to run on GLES
+  {&mpglVertexPointer, NULL, {"glVertexPointer", NULL}},
+  {&mpglTexCoordPointer, NULL, {"glTexCoordPointer", NULL}},
+  {&mpglClientActiveTexture, NULL, {"glClientActiveTexture", NULL}},
+  {&mpglEnableClientState, NULL, {"glEnableClientState", NULL}},
+  {&mpglDisableClientState, NULL, {"glDisableClientState", NULL}},
+  {&mpglDrawArrays, NULL, {"glDrawArrays", NULL}},
   {NULL}
 };
 
@@ -1685,6 +1705,36 @@ void glDrawTex(GLfloat x, GLfloat y, GLf
     y += h;
     h = -h;
   }
+
+  if (!mpglBegin) {
+    GLfloat vertices  [8] = { x,   y,   x,   y  +  h,   x  +  w,   y,   x  +  w,   y  +  h};
+    GLfloat texcoords [8] = {tx,  ty,  tx,  ty  + th,  tx  + tw,  ty,  tx  + tw,  ty  + th};
+    GLfloat texcoords2[8] = {tx2, ty2, tx2, ty2 + th2, tx2 + tw2, ty2, tx2 + tw2, ty2 + th2};
+    mpglEnableClientState(GL_VERTEX_ARRAY);
+    mpglVertexPointer(2, GL_FLOAT, 0, vertices);
+    mpglEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    mpglTexCoordPointer(2, GL_FLOAT, 0, texcoords);
+    if (is_yv12) {
+      mpglClientActiveTexture(GL_TEXTURE1);
+      mpglEnableClientState(GL_TEXTURE_COORD_ARRAY);
+      mpglTexCoordPointer(2, GL_FLOAT, 0, texcoords2);
+      mpglClientActiveTexture(GL_TEXTURE2);
+      mpglEnableClientState(GL_TEXTURE_COORD_ARRAY);
+      mpglTexCoordPointer(2, GL_FLOAT, 0, texcoords2);
+      mpglClientActiveTexture(GL_TEXTURE0);
+    }
+    mpglDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+    if (is_yv12) {
+      mpglClientActiveTexture(GL_TEXTURE1);
+      mpglDisableClientState(GL_TEXTURE_COORD_ARRAY);
+      mpglClientActiveTexture(GL_TEXTURE2);
+      mpglDisableClientState(GL_TEXTURE_COORD_ARRAY);
+      mpglClientActiveTexture(GL_TEXTURE0);
+    }
+    mpglDisableClientState(GL_VERTEX_ARRAY);
+    return;
+  }
+
   mpglBegin(GL_QUADS);
   mpglTexCoord2f(tx, ty);
   if (is_yv12) {
@@ -1957,7 +2007,9 @@ static void releaseGlContext_x11(MPGLCon
 static void swapGlBuffers_x11(MPGLContext *ctx) {
   glXSwapBuffers(mDisplay, vo_window);
 }
+#endif
 
+#if defined(CONFIG_GL_X11) || defined(CONFIG_GL_EGL_X11)
 static int x11_check_events(void) {
   return vo_x11_check_events(mDisplay);
 }
@@ -1997,6 +2049,99 @@ static int sdl_check_events(void) {
 
 #endif
 
+#ifdef CONFIG_GL_EGL_X11
+static EGLDisplay eglDisplay = EGL_NO_DISPLAY;
+static EGLSurface eglSurface = EGL_NO_SURFACE;
+
+/*
+ * Some genius thought it a good idea to make
+ * eglGetProcAddress not work for core functions.
+ * 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!
+ */
+static void *eglgpa(const GLubyte *name) {
+  void *res = eglGetProcAddress(name);
+  if (!res) {
+    void *h = dlopen("/usr/lib/libGLESv1_CM.so", RTLD_LAZY);
+    res = dlsym(h, name);
+    dlclose(h);
+  }
+  return res;
+}
+
+static int setGlWindow_egl(MPGLContext *ctx)
+{
+  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;
+  if (eglDisplay == EGL_NO_DISPLAY) {
+    eglDisplay = eglGetDisplay(mDisplay);
+    if (eglDisplay == EGL_NO_DISPLAY) {
+      mp_msg(MSGT_VO, MSGL_FATAL, "eglGetDisplay failed: 0x%x\n", eglGetError());
+      return SET_WINDOW_FAILED;
+    }
+    if (!eglInitialize(eglDisplay, NULL, NULL)) {
+      mp_msg(MSGT_VO, MSGL_FATAL, "eglInitialize failed: 0x%x\n", eglGetError());
+      return SET_WINDOW_FAILED;
+    }
+  }
+  if (*context != EGL_NO_CONTEXT) {
+    eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+    eglDestroyContext(eglDisplay, *context);
+    eglDestroySurface(eglDisplay, eglSurface);
+  }
+  if (!eglChooseConfig(eglDisplay, cfg_attribs, &eglConfig, 1, &num_configs) ||
+      num_configs != 1)
+    return SET_WINDOW_FAILED;
+  eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, win, NULL);
+  if (eglSurface == EGL_NO_SURFACE)
+    return SET_WINDOW_FAILED;
+
+  new_context = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, ctx_attribs);
+  if (new_context == EGL_NO_CONTEXT)
+    return SET_WINDOW_FAILED;
+  if (!eglMakeCurrent(eglDisplay, eglSurface, eglSurface, new_context))
+    return SET_WINDOW_FAILED;
+
+  // set new values
+  vo_window = win;
+  vo_x11_update_geometry();
+  *context = new_context;
+
+  getFunctions(eglgpa, eglQueryString(eglDisplay, EGL_EXTENSIONS));
+  mpglBegin = NULL;
+  mpglDrawBuffer = NULL;
+
+  // and inform that reinit is necessary
+  return SET_WINDOW_REINIT;
+}
+
+/**
+ * \brief free the VisualInfo and GLXContext of an OpenGL context.
+ * \ingroup glcontext
+ */
+static void releaseGlContext_egl(MPGLContext *ctx) {
+  EGLContext *context = &ctx->context.egl;
+  if (*context != EGL_NO_CONTEXT)
+  {
+    mpglFinish();
+    eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+    eglDestroyContext(eglDisplay, *context);
+  }
+  *context = EGL_NO_CONTEXT;
+}
+
+static void swapGlBuffers_egl(MPGLContext *ctx) {
+  eglSwapBuffers(eglDisplay, eglSurface);
+}
+
+#endif
+
 static int setGlWindow_dummy(MPGLContext *ctx) {
   getFunctions(NULL, NULL);
   return SET_WINDOW_OK;
@@ -2026,6 +2171,8 @@ int init_mpglcontext(MPGLContext *ctx, e
     res = init_mpglcontext(ctx, GLTYPE_X11);
     if (res) return res;
     res = init_mpglcontext(ctx, GLTYPE_SDL);
+    if (res) return res;
+    res = init_mpglcontext(ctx, GLTYPE_EGL_X11);
     return res;
   }
   memset(ctx, 0, sizeof(*ctx));
@@ -2068,6 +2215,18 @@ int init_mpglcontext(MPGLContext *ctx, e
     ctx->fullscreen = vo_sdl_fullscreen;
     return vo_sdl_init();
 #endif
+#ifdef CONFIG_GL_EGL_X11
+  case GLTYPE_EGL_X11:
+    ctx->setGlWindow = setGlWindow_egl;
+    ctx->releaseGlContext = releaseGlContext_egl;
+    ctx->swapGlBuffers = swapGlBuffers_egl;
+    ctx->update_xinerama_info = update_xinerama_info;
+    ctx->border = vo_x11_border;
+    ctx->check_events = x11_check_events;
+    ctx->fullscreen = vo_x11_fullscreen;
+    ctx->ontop = vo_x11_ontop;
+    return vo_init();
+#endif
   default:
     return 0;
   }

Modified: trunk/libvo/gl_common.h
==============================================================================
--- trunk/libvo/gl_common.h	Sat Dec 10 21:21:50 2011	(r34425)
+++ trunk/libvo/gl_common.h	Sat Dec 10 21:55:31 2011	(r34426)
@@ -40,6 +40,10 @@
 #include <GL/glx.h>
 #include "x11_common.h"
 #endif
+#ifdef CONFIG_GL_EGL_X11
+#include <EGL/egl.h>
+#include "x11_common.h"
+#endif
 #include <GL/gl.h>
 
 // workaround for some gl.h headers
@@ -405,6 +409,7 @@ enum MPGLType {
   GLTYPE_W32,
   GLTYPE_X11,
   GLTYPE_SDL,
+  GLTYPE_EGL_X11,
 };
 
 typedef struct MPGLContext {
@@ -422,6 +427,9 @@ typedef struct MPGLContext {
 #ifdef CONFIG_GL_X11
     GLXContext x11;
 #endif
+#ifdef CONFIG_GL_EGL_X11
+    EGLContext egl;
+#endif
   } context;
   int (*setGlWindow)(struct MPGLContext *);
   void (*releaseGlContext)(struct MPGLContext *);

Modified: trunk/libvo/vo_gl.c
==============================================================================
--- trunk/libvo/vo_gl.c	Sat Dec 10 21:21:50 2011	(r34425)
+++ trunk/libvo/vo_gl.c	Sat Dec 10 21:55:31 2011	(r34426)
@@ -547,7 +547,8 @@ static int initGl(uint32_t d_width, uint
   mpglDepthMask(GL_FALSE);
   mpglDisable(GL_CULL_FACE);
   mpglEnable(gl_target);
-  mpglDrawBuffer(vo_doublebuffering?GL_BACK:GL_FRONT);
+  if (mpglDrawBuffer)
+    mpglDrawBuffer(vo_doublebuffering?GL_BACK:GL_FRONT);
   mpglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 
   mp_msg(MSGT_VO, MSGL_V, "[gl] Creating %dx%d texture...\n",
@@ -618,6 +619,13 @@ static int create_window(uint32_t d_widt
   if (glctx.type == GLTYPE_W32 && !vo_w32_config(d_width, d_height, flags))
     return -1;
 #endif
+#ifdef CONFIG_GL_EGL_X11
+  if (glctx.type == GLTYPE_EGL_X11) {
+    XVisualInfo vinfo = { .visual = CopyFromParent, .depth = CopyFromParent };
+    vo_x11_create_vo_window(&vinfo, vo_dx, vo_dy, d_width, d_height, flags,
+            CopyFromParent, "gl", title);
+  }
+#endif
 #ifdef CONFIG_GL_X11
   if (glctx.type == GLTYPE_X11) {
     static int default_glx_attribs[] = {


More information about the MPlayer-cvslog mailing list