mirror of
https://github.com/mpv-player/mpv
synced 2024-12-25 16:33:02 +00:00
fullscreen fixes and GUI support for vo_gl
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@13844 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
0e49449d13
commit
1a7a3f8b38
@ -17,3 +17,101 @@ void glAdjustAlignment(int stride) {
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
|
131
libvo/vo_gl.c
131
libvo/vo_gl.c
@ -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 @@ static vo_info_t info =
|
||||
|
||||
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 @@ static int find_gl_format (uint32_t format)
|
||||
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 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin
|
||||
// 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 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin
|
||||
|
||||
|
||||
|
||||
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 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin
|
||||
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,56 +305,21 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin
|
||||
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);
|
||||
|
||||
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 @@ static void
|
||||
uninit(void)
|
||||
{
|
||||
if ( !vo_config_count ) return;
|
||||
releaseGlContext(&gl_vinfo, &gl_context);
|
||||
vo_x11_uninit();
|
||||
}
|
||||
|
||||
@ -612,6 +627,8 @@ static uint32_t control(uint32_t request, void *data, ...)
|
||||
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;
|
||||
|
@ -1133,6 +1133,21 @@ int vo_x11_check_events(Display * mydisplay)
|
||||
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;
|
||||
|
@ -52,6 +52,7 @@ extern void vo_hidecursor ( Display* , Window );
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user