# HG changeset patch # User reimar # Date 1099340677 0 # Node ID 3f28d2a56758bd570436df7de309d9f1c16aeb89 # Parent 78e5886bc2119de63a0a5c4385b0f7be418b22e6 fullscreen fixes and GUI support for vo_gl diff -r 78e5886bc211 -r 3f28d2a56758 libvo/gl_common.c --- 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 + diff -r 78e5886bc211 -r 3f28d2a56758 libvo/gl_common.h --- 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 +#include "video_out.h" + +#ifndef GL_WIN32 +#include +#include +#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 diff -r 78e5886bc211 -r 3f28d2a56758 libvo/vo_gl.c --- 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