Mercurial > mplayer.hg
changeset 13843:3f28d2a56758
fullscreen fixes and GUI support for vo_gl
author | reimar |
---|---|
date | Mon, 01 Nov 2004 20:24:37 +0000 |
parents | 78e5886bc211 |
children | a609c6d5dc3b |
files | libvo/gl_common.c libvo/gl_common.h libvo/vo_gl.c libvo/x11_common.c libvo/x11_common.h |
diffstat | 5 files changed, 209 insertions(+), 57 deletions(-) [+] |
line wrap: on
line diff
--- a/libvo/gl_common.c Mon Nov 01 17:57:00 2004 +0000 +++ b/libvo/gl_common.c Mon Nov 01 20:24:37 2004 +0000 @@ -17,3 +17,101 @@ glPixelStorei (GL_UNPACK_ALIGNMENT, gl_alignment); } +#ifndef GL_WIN32 +/** + * Returns the XVisualInfo associated with Window win. + * \param win Window whose XVisualInfo is returne. + * \return XVisualInfo of the window. Caller must use XFree to free it. + */ +static XVisualInfo *getWindowVisualInfo(Window win) { + XWindowAttributes xw_attr; + XVisualInfo vinfo_template; + int tmp; + XGetWindowAttributes(mDisplay, win, &xw_attr); + vinfo_template.visualid = XVisualIDFromVisual(xw_attr.visual); + return XGetVisualInfo(mDisplay, VisualIDMask, &vinfo_template, &tmp); +} + +/** + * \brief Changes the window in which video is displayed. + * If possible only transfers the context to the new window, otherwise + * creates a new one, which must be initialized by the caller. + * \param vinfo Currently used visual. + * \param context Currently used context. + * \param win window that should be used for drawing. + * \return one of SET_WINDOW_FAILED, SET_WINDOW_OK or SET_WINDOW_REINIT. + * In case of SET_WINDOW_REINIT the context could not be transfered + * and the caller must initialize it correctly. + */ +int setGlWindow(XVisualInfo **vinfo, GLXContext *context, Window win) +{ + XVisualInfo *new_vinfo; + GLXContext new_context = NULL; + int keep_context = 0; + + // should only be needed when keeping context, but not doing glFinish + // can cause flickering even when we do not keep it. + glFinish(); + new_vinfo = getWindowVisualInfo(win); + if (*context && *vinfo && new_vinfo && + (*vinfo)->visualid == new_vinfo->visualid) { + // we can keep the GLXContext + new_context = *context; + XFree(new_vinfo); + new_vinfo = *vinfo; + keep_context = 1; + } else { + // create a context + new_context = glXCreateContext(mDisplay, new_vinfo, NULL, True); + if (!new_context) { + mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not create GLX context!\n"); + XFree(new_vinfo); + return SET_WINDOW_FAILED; + } + } + + // set context + if (!glXMakeCurrent(mDisplay, vo_window, new_context)) { + mp_msg (MSGT_VO, MSGL_FATAL, "[gl] Could not set GLX context!\n"); + if (!keep_context) { + glXDestroyContext (mDisplay, new_context); + XFree(new_vinfo); + } + return SET_WINDOW_FAILED; + } + + // set new values + vo_window = win; + { + Window root; + int tmp; + XGetGeometry(mDisplay, vo_window, &root, &tmp, &tmp, + &vo_dwidth, &vo_dheight, &tmp, &tmp); + } + if (!keep_context) { + if (*context) + glXDestroyContext(mDisplay, *context); + *context = new_context; + if (*vinfo) + XFree(*vinfo); + *vinfo = new_vinfo; + + // and inform that reinit is neccessary + return SET_WINDOW_REINIT; + } + return SET_WINDOW_OK; +} + +/** + * \brief free the VisualInfo and GLXContext of an OpenGL context. + */ +void releaseGlContext(XVisualInfo **vinfo, GLXContext *context) { + if (*vinfo) + XFree(*vinfo); + *vinfo = NULL; + if (*context) + glXDestroyContext(mDisplay, *context); + *context = 0; +} +#endif +
--- a/libvo/gl_common.h Mon Nov 01 17:57:00 2004 +0000 +++ b/libvo/gl_common.h Mon Nov 01 20:24:37 2004 +0000 @@ -1,8 +1,29 @@ #ifndef __GL_COMMON_H__ #define __GL_COMMON_H__ +#include "mp_msg.h" +#include "config.h" + #include <GL/gl.h> +#include "video_out.h" + +#ifndef GL_WIN32 +#include <X11/Xlib.h> +#include <GL/glx.h> +#include "x11_common.h" +#endif void glAdjustAlignment(int stride); +//! could not set new window, will continue drawing into the old one. +#define SET_WINDOW_FAILED -1 +//! new window is set, could even transfer the OpenGL context. +#define SET_WINDOW_OK 0 +//! new window is set, but the OpenGL context needs to be reinitialized. +#define SET_WINDOW_REINIT 1 + +#ifndef GL_WIN32 +int setGlWindow(XVisualInfo **vinfo, GLXContext *context, Window win); #endif + +#endif
--- a/libvo/vo_gl.c Mon Nov 01 17:57:00 2004 +0000 +++ b/libvo/vo_gl.c Mon Nov 01 20:24:37 2004 +0000 @@ -24,6 +24,9 @@ #include "gl_common.h" #include "x11_common.h" #include "aspect.h" +#ifdef HAVE_NEW_GUI +#include "Gui/interface.h" +#endif static vo_info_t info = { @@ -35,7 +38,8 @@ LIBVO_EXTERN(gl) -static GLXContext wsGLXContext; +static XVisualInfo *gl_vinfo = NULL; +static GLXContext gl_context = 0; static int wsGLXAttrib[] = { GLX_RGBA, GLX_RED_SIZE,1, GLX_GREEN_SIZE,1, @@ -172,26 +176,54 @@ return 1; } +/** + * \brief Initialize a (new or reused) OpenGL context. + */ +static int initGl(uint32_t d_width, uint32_t d_height) { + unsigned char *ImageData = NULL; + texture_width = 32; + while (texture_width < image_width || + texture_width < image_height) + texture_width *= 2; + texture_height = texture_width; + + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glDepthMask(GL_FALSE); + glDisable(GL_CULL_FACE); + glEnable(GL_TEXTURE_2D); + + mp_msg(MSGT_VO, MSGL_V, "[gl] Creating %dx%d texture...\n", + texture_width, texture_height); + + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glAdjustAlignment(texture_width * image_bytes); + ImageData = malloc(texture_width * texture_height * image_bytes); + memset(ImageData, 0, texture_width * texture_height * image_bytes); + glTexImage2D(GL_TEXTURE_2D, 0, gl_texfmt, texture_width, texture_height, 0, + gl_format, gl_type, ImageData); + free (ImageData); + + // set alignment as default is 4 which will break some files + glAdjustAlignment(image_width * image_bytes); + + resize(d_width, d_height); + + glClearColor( 0.0f,0.0f,0.0f,0.0f ); + glClear( GL_COLOR_BUFFER_BIT ); +} + /* connect to server, create and map window, * allocate colors and (shared) memory */ static uint32_t config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { - unsigned char *ImageData=NULL; -// int screen; - unsigned int fg, bg; - XSizeHints hint; - XVisualInfo *vinfo; - XEvent xev; - -// XGCValues xgcv; - image_height = height; image_width = width; find_gl_format (format); - vo_dwidth = d_width; - vo_dheight = d_height; sub_bg_alpha = 255; // We need alpha = 255 for invisible part of the OSD int_pause = 0; @@ -207,6 +239,26 @@ // aspect(&d_width,&d_height,A_ZOOM); // } #endif +#ifdef HAVE_NEW_GUI + if (use_gui) { + // GUI creates and manages window for us + vo_dwidth = d_width; + vo_dheight= d_height; + guiGetEvent(guiSetShVideo, 0); + setGlWindow(&gl_vinfo, &gl_context, vo_window); + initGl(vo_dwidth, vo_dheight); + return 0; + } +#endif + if ( vo_window == None ) { + unsigned int fg, bg; + XSizeHints hint; + XVisualInfo *vinfo; + XEvent xev; + + vo_dwidth = d_width; + vo_dheight = d_height; + hint.x = 0; hint.y = 0; hint.width = d_width; @@ -229,8 +281,6 @@ - if ( vo_window == None ) - { vo_window = vo_x11_create_smooth_window(mDisplay, mRootWin, vinfo->visual, hint.x, hint.y, hint.width, hint.height, vinfo->depth, XCreateColormap(mDisplay, mRootWin, vinfo->visual, AllocNone)); @@ -243,7 +293,6 @@ XSetStandardProperties(mDisplay, vo_window, title, title, None, NULL, 0, &hint); /* Map window. */ XMapWindow(mDisplay, vo_window); - if ( flags&1 ) vo_x11_fullscreen(); #ifdef HAVE_XINERAMA vo_x11_xinerama_move(mDisplay,vo_window); #endif @@ -256,55 +305,20 @@ while (xev.type != MapNotify || xev.xmap.event != vo_window); XSelectInput(mDisplay, vo_window, NoEventMask); - } - - if ( vo_config_count ) glXDestroyContext( mDisplay,wsGLXContext ); - wsGLXContext=glXCreateContext( mDisplay,vinfo,NULL,True ); - glXMakeCurrent( mDisplay,vo_window,wsGLXContext ); XSync(mDisplay, False); vo_x11_selectinput_witherr(mDisplay, vo_window, StructureNotifyMask | KeyPressMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ExposureMask ); - - texture_width=32; - while(texture_width<image_width || texture_width<image_height) texture_width*=2; - texture_height=texture_width; - - ImageData=malloc(texture_width*texture_height*image_bytes); - memset(ImageData,0,texture_width*texture_height*image_bytes); - - glDisable(GL_BLEND); - glDisable(GL_DEPTH_TEST); - glDepthMask(GL_FALSE); - glDisable(GL_CULL_FACE); - - glEnable(GL_TEXTURE_2D); - - // set alignment as default is 4 which will break some files - glAdjustAlignment(image_width * image_bytes); + } + if (vo_ontop) vo_x11_setlayer(mDisplay, vo_window, vo_ontop); - mp_msg(MSGT_VO, MSGL_V, "[gl] Creating %dx%d texture...\n",texture_width,texture_height); - -#if 1 -// glBindTexture(GL_TEXTURE_2D, texture_id); - glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, gl_texfmt, texture_width, texture_height, 0, - gl_format, gl_type, ImageData); -#endif - - free (ImageData); - - resize(d_width,d_height); - - glClearColor( 0.0f,0.0f,0.0f,0.0f ); - glClear( GL_COLOR_BUFFER_BIT ); - -// printf("OpenGL setup OK!\n"); - - if (vo_ontop) vo_x11_setlayer(mDisplay, vo_window, vo_ontop); + vo_x11_nofs_sizepos(0, 0, d_width, d_height); + if (vo_fs ^ (flags & VOFLAG_FULLSCREEN)) + vo_x11_fullscreen(); + setGlWindow(&gl_vinfo, &gl_context, vo_window); + initGl(vo_dwidth, vo_dheight); return 0; } @@ -519,6 +533,7 @@ uninit(void) { if ( !vo_config_count ) return; + releaseGlContext(&gl_vinfo, &gl_context); vo_x11_uninit(); } @@ -612,6 +627,8 @@ case VOCTRL_RESUME: return (int_pause=0); case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); + case VOCTRL_GUISUPPORT: + return VO_TRUE; case VOCTRL_ONTOP: vo_x11_ontop(); return VO_TRUE;
--- a/libvo/x11_common.c Mon Nov 01 17:57:00 2004 +0000 +++ b/libvo/x11_common.c Mon Nov 01 20:24:37 2004 +0000 @@ -1133,6 +1133,21 @@ return ret; } +/** + * \brief sets the size and position of the non-fullscreen window. + */ +void vo_x11_nofs_sizepos(int x, int y, int width, int height) +{ + if (vo_fs) { + vo_old_x = x; + vo_old_y = y; + vo_old_width = width; + vo_old_height = height; + } + else + XMoveResizeWindow(mDisplay, vo_window, x, y, width, height); +} + void vo_x11_sizehint(int x, int y, int width, int height, int max) { vo_hint.flags = PPosition | PSize | PWinGravity;
--- a/libvo/x11_common.h Mon Nov 01 17:57:00 2004 +0000 +++ b/libvo/x11_common.h Mon Nov 01 20:24:37 2004 +0000 @@ -52,6 +52,7 @@ extern void vo_showcursor( Display *disp, Window win ); extern void vo_x11_decoration( Display * vo_Display,Window w,int d ); extern void vo_x11_classhint( Display * display,Window window,char *name ); +extern void vo_x11_nofs_sizepos(int x, int y, int width, int height); extern void vo_x11_sizehint( int x, int y, int width, int height, int max ); extern int vo_x11_check_events(Display *mydisplay); extern void vo_x11_selectinput_witherr(Display *display, Window w, long event_mask);