[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