diff --git a/libvo/gl_common.c b/libvo/gl_common.c index c039953771..a4ef197035 100644 --- a/libvo/gl_common.c +++ b/libvo/gl_common.c @@ -1458,8 +1458,11 @@ static void *w32gpa(const GLubyte *procName) { return GetProcAddress(oglmod, procName); } -int setGlWindow(int *vinfo, HGLRC *context, HWND win) +static int setGlWindow_w32(MPGLContext *ctx) { + HWND win = vo_w32_window; + int *vinfo = &ctx->vinfo.w32; + HGLRC *context = &ctx->context.w32; int new_vinfo; HDC windc = vo_w32_get_dc(win); HGLRC new_context = 0; @@ -1518,7 +1521,9 @@ out: return res; } -void releaseGlContext(int *vinfo, HGLRC *context) { +static void releaseGlContext_w32(MPGLContext *ctx) { + int *vinfo = &ctx->vinfo.w32; + HGLRC *context = &ctx->context.w32; *vinfo = 0; if (*context) { wglMakeCurrent(0, 0); @@ -1527,12 +1532,13 @@ void releaseGlContext(int *vinfo, HGLRC *context) { *context = 0; } -void swapGlBuffers(void) { +static void swapGlBuffers_w32(MPGLContext *ctx) { HDC vo_hdc = vo_w32_get_dc(vo_w32_window); SwapBuffers(vo_hdc); vo_w32_release_dc(vo_w32_window, vo_hdc); } -#else +#endif +#ifdef CONFIG_X11 #ifdef HAVE_LIBDL #include #endif @@ -1595,8 +1601,11 @@ static void appendstr(char **dst, const char *str) * and the caller must initialize it correctly. * \ingroup glcontext */ -int setGlWindow(XVisualInfo **vinfo, GLXContext *context, Window win) +static int setGlWindow_x11(MPGLContext *ctx) { + XVisualInfo **vinfo = &ctx->vinfo.x11; + GLXContext *context = &ctx->context.x11; + Window win = vo_window; XVisualInfo *new_vinfo; GLXContext new_context = NULL; int keep_context = 0; @@ -1674,7 +1683,9 @@ int setGlWindow(XVisualInfo **vinfo, GLXContext *context, Window win) * \brief free the VisualInfo and GLXContext of an OpenGL context. * \ingroup glcontext */ -void releaseGlContext(XVisualInfo **vinfo, GLXContext *context) { +static void releaseGlContext_x11(MPGLContext *ctx) { + XVisualInfo **vinfo = &ctx->vinfo.x11; + GLXContext *context = &ctx->context.x11; if (*vinfo) XFree(*vinfo); *vinfo = NULL; @@ -1687,8 +1698,61 @@ void releaseGlContext(XVisualInfo **vinfo, GLXContext *context) { *context = 0; } -void swapGlBuffers(void) { +static void swapGlBuffers_x11(MPGLContext *ctx) { glXSwapBuffers(mDisplay, vo_window); } + +static int x11_check_events(void) { + return vo_x11_check_events(mDisplay); +} #endif +int init_mpglcontext(MPGLContext *ctx, enum MPGLType type) { + memset(ctx, 0, sizeof(*ctx)); + ctx->type = type; + switch (ctx->type) { +#ifdef GL_WIN32 + case GLTYPE_W32: + ctx->setGlWindow = setGlWindow_w32; + ctx->releaseGlContext = releaseGlContext_w32; + ctx->swapGlBuffers = swapGlBuffers_w32; + ctx->update_xinerama_info = w32_update_xinerama_info; + ctx->border = vo_w32_border; + ctx->check_events = vo_w32_check_events; + ctx->fullscreen = vo_w32_fullscreen; + ctx->ontop = vo_w32_ontop; + return vo_w32_init(); +#endif +#ifdef CONFIG_X11 + case GLTYPE_X11: + ctx->setGlWindow = setGlWindow_x11; + ctx->releaseGlContext = releaseGlContext_x11; + ctx->swapGlBuffers = swapGlBuffers_x11; + 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; + } +} + +void uninit_mpglcontext(MPGLContext *ctx) { + ctx->releaseGlContext(ctx); + switch (ctx->type) { +#ifdef GL_WIN32 + case GLTYPE_W32: + vo_w32_uninit(); + break; +#endif +#ifdef CONFIG_X11 + case GLTYPE_X11: + vo_x11_uninit(); + break; +#endif + } + memset(ctx, 0, sizeof(*ctx)); +} diff --git a/libvo/gl_common.h b/libvo/gl_common.h index 8f9ce55dab..53805f1299 100644 --- a/libvo/gl_common.h +++ b/libvo/gl_common.h @@ -31,7 +31,8 @@ #include #include #include "w32_common.h" -#else +#endif +#ifdef CONFIG_X11 #include #include #include @@ -352,24 +353,39 @@ void glDisableYUVConversion(GLenum target, int type); #define SET_WINDOW_REINIT 1 /** \} */ -#ifdef GL_WIN32 -#define vo_border() vo_w32_border() -#define vo_check_events() vo_w32_check_events() -#define vo_fullscreen() vo_w32_fullscreen() -#define vo_ontop() vo_w32_ontop() -#define vo_uninit() vo_w32_uninit() -int setGlWindow(int *vinfo, HGLRC *context, HWND win); -void releaseGlContext(int *vinfo, HGLRC *context); -#else -#define vo_border() vo_x11_border() -#define vo_check_events() vo_x11_check_events(mDisplay) -#define vo_fullscreen() vo_x11_fullscreen() -#define vo_ontop() vo_x11_ontop() -#define vo_uninit() vo_x11_uninit() -int setGlWindow(XVisualInfo **vinfo, GLXContext *context, Window win); -void releaseGlContext(XVisualInfo **vinfo, GLXContext *context); +enum MPGLType { + GLTYPE_W32, + GLTYPE_X11, +}; + +typedef struct MPGLContext { + enum MPGLType type; + union { + int w32; +#ifdef CONFIG_X11 + XVisualInfo *x11; #endif -void swapGlBuffers(void); + } vinfo; + union { +#ifdef GL_WIN32 + HGLRC w32; +#endif +#ifdef CONFIG_X11 + GLXContext x11; +#endif + } context; + int (*setGlWindow)(struct MPGLContext *); + void (*releaseGlContext)(struct MPGLContext *); + void (*swapGlBuffers)(struct MPGLContext *); + void (*update_xinerama_info)(void); + void (*border)(void); + int (*check_events)(void); + void (*fullscreen)(void); + void (*ontop)(void); +} MPGLContext; + +int init_mpglcontext(MPGLContext *ctx, enum MPGLType type); +void uninit_mpglcontext(MPGLContext *ctx); extern void (APIENTRY *GenBuffers)(GLsizei, GLuint *); extern void (APIENTRY *DeleteBuffers)(GLsizei, const GLuint *); diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c index 2fce305645..b4f4bb862f 100644 --- a/libvo/vo_gl.c +++ b/libvo/vo_gl.c @@ -48,15 +48,7 @@ static const vo_info_t info = const LIBVO_EXTERN(gl) -#ifdef GL_WIN32 -static int gl_vinfo = 0; -static HGLRC gl_context = 0; -#define update_xinerama_info w32_update_xinerama_info -#define vo_init vo_w32_init -#define vo_window vo_w32_window -#else -static XVisualInfo *gl_vinfo = NULL; -static GLXContext gl_context = 0; +#ifdef CONFIG_X11 static int wsGLXAttrib[] = { GLX_RGBA, GLX_RED_SIZE,1, GLX_GREEN_SIZE,1, @@ -64,6 +56,7 @@ static int wsGLXAttrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None }; #endif +static MPGLContext glctx; static int use_osd; static int scaled_osd; @@ -549,10 +542,11 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin } #endif #ifdef GL_WIN32 - if (!vo_w32_config(d_width, d_height, flags)) + if (glctx.type == GLTYPE_W32 && !vo_w32_config(d_width, d_height, flags)) return -1; -#else - { +#endif +#ifdef CONFIG_X11 + if (glctx.type == GLTYPE_X11) { XVisualInfo *vinfo=glXChooseVisual( mDisplay,mScreen,wsGLXAttrib ); if (vinfo == NULL) { @@ -570,7 +564,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin glconfig: if (vo_config_count) uninitGl(); - if (setGlWindow(&gl_vinfo, &gl_context, vo_window) == SET_WINDOW_FAILED) + if (glctx.setGlWindow(&glctx) == SET_WINDOW_FAILED) return -1; if (mesa_buffer && !AllocateMemoryMESA) { mp_msg(MSGT_VO, MSGL_ERR, "Can not enable mesa-buffer because AllocateMemoryMESA was not found\n"); @@ -583,7 +577,7 @@ glconfig: static void check_events(void) { - int e=vo_check_events(); + int e=glctx.check_events(); if(e&VO_EVENT_RESIZE) resize(vo_dwidth,vo_dheight); if(e&VO_EVENT_EXPOSE && int_pause) redraw(); } @@ -725,7 +719,7 @@ static void do_render_osd(int type) { static void flip_page(void) { if (vo_doublebuffering) { if (use_glFinish) glFinish(); - swapGlBuffers(); + glctx.swapGlBuffers(&glctx); if (aspect_scaling() && use_aspect) glClear(GL_COLOR_BUFFER_BIT); } else { @@ -972,12 +966,11 @@ uninit(void) { if (!vo_config_count) return; uninitGl(); - releaseGlContext(&gl_vinfo, &gl_context); if (custom_prog) free(custom_prog); custom_prog = NULL; if (custom_tex) free(custom_tex); custom_tex = NULL; - vo_uninit(); + uninit_mpglcontext(&glctx); } static const opt_t subopts[] = { @@ -1007,7 +1000,11 @@ static const opt_t subopts[] = { static int preinit(const char *arg) { + enum MPGLType gltype = GLTYPE_X11; // set defaults +#ifdef GL_WIN32 + gltype = GLTYPE_W32; +#endif many_fmts = 1; use_osd = 1; scaled_osd = 0; @@ -1102,7 +1099,7 @@ static int preinit(const char *arg) "Use -vo gl:nomanyfmts if playback fails.\n"); mp_msg(MSGT_VO, MSGL_V, "[gl] Using %d as slice height " "(0 means image height).\n", slice_height); - if (!vo_init()) return -1; // Can't open X11 + if (!init_mpglcontext(&glctx, gltype)) return -1; return 0; } @@ -1161,14 +1158,14 @@ static int control(uint32_t request, void *data, ...) case VOCTRL_GUISUPPORT: return VO_TRUE; case VOCTRL_ONTOP: - vo_ontop(); + glctx.ontop(); return VO_TRUE; case VOCTRL_FULLSCREEN: - vo_fullscreen(); + glctx.fullscreen(); resize(vo_dwidth, vo_dheight); return VO_TRUE; case VOCTRL_BORDER: - vo_border(); + glctx.border(); resize(vo_dwidth, vo_dheight); return VO_TRUE; case VOCTRL_GET_PANSCAN: @@ -1212,7 +1209,7 @@ static int control(uint32_t request, void *data, ...) } break; case VOCTRL_UPDATE_SCREENINFO: - update_xinerama_info(); + glctx.update_xinerama_info(); return VO_TRUE; } return VO_NOTIMPL; diff --git a/libvo/vo_gl2.c b/libvo/vo_gl2.c index ff44be4043..197f7cd1b1 100644 --- a/libvo/vo_gl2.c +++ b/libvo/vo_gl2.c @@ -62,16 +62,7 @@ const LIBVO_EXTERN(gl2) /* local data */ static unsigned char *ImageData=NULL; -#ifdef GL_WIN32 - static int gl_vinfo = 0; - static HGLRC gl_context = 0; -#define update_xinerama_info w32_update_xinerama_info -#define vo_init vo_w32_init -#define vo_window vo_w32_window -#else - static XVisualInfo *gl_vinfo = NULL; - static GLXContext gl_context = 0; -#endif +static MPGLContext glctx; static uint32_t image_width; static uint32_t image_height; @@ -115,7 +106,10 @@ struct TexSquare static GLint getInternalFormat(void) { + switch (glctx.type) { #ifdef GL_WIN32 + case GLTYPE_W32: + { PIXELFORMATDESCRIPTOR pfd; HDC vo_hdc = vo_w32_get_dc(vo_w32_window); int pf = GetPixelFormat(vo_hdc); @@ -128,12 +122,18 @@ static GLint getInternalFormat(void) a_sz = pfd.cAlphaBits; } vo_w32_release_dc(vo_w32_window, vo_hdc); -#else - if (glXGetConfig(mDisplay, gl_vinfo, GLX_RED_SIZE, &r_sz) != 0) r_sz = 0; - if (glXGetConfig(mDisplay, gl_vinfo, GLX_GREEN_SIZE, &g_sz) != 0) g_sz = 0; - if (glXGetConfig(mDisplay, gl_vinfo, GLX_BLUE_SIZE, &b_sz) != 0) b_sz = 0; - if (glXGetConfig(mDisplay, gl_vinfo, GLX_ALPHA_SIZE, &a_sz) != 0) a_sz = 0; + } + break; #endif +#ifdef CONFIG_X11 + case GLTYPE_X11: + if (glXGetConfig(mDisplay, glctx.vinfo.x11, GLX_RED_SIZE, &r_sz) != 0) r_sz = 0; + if (glXGetConfig(mDisplay, glctx.vinfo.x11, GLX_GREEN_SIZE, &g_sz) != 0) g_sz = 0; + if (glXGetConfig(mDisplay, glctx.vinfo.x11, GLX_BLUE_SIZE, &b_sz) != 0) b_sz = 0; + if (glXGetConfig(mDisplay, glctx.vinfo.x11, GLX_ALPHA_SIZE, &a_sz) != 0) a_sz = 0; + break; +#endif + } rgb_sz=r_sz+g_sz+b_sz; if(rgb_sz<=0) rgb_sz=24; @@ -637,7 +637,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin #endif return -1; - if (setGlWindow(&gl_vinfo, &gl_context, vo_window) == SET_WINDOW_FAILED) + if (glctx.setGlWindow(&glctx) == SET_WINDOW_FAILED) return -1; glVersion = glGetString(GL_VERSION); @@ -718,7 +718,7 @@ static void check_events(void) } } #endif - e=vo_check_events(); + e=glctx.check_events(); if(e&VO_EVENT_RESIZE) resize(vo_dwidth, vo_dheight); if(e&VO_EVENT_EXPOSE && int_pause) flip_page(); } @@ -737,7 +737,7 @@ flip_page(void) // glFlush(); if (use_glFinish) glFinish(); - swapGlBuffers(); + glctx.swapGlBuffers(&glctx); if (aspect_scaling()) // Avoid flickering borders in fullscreen mode glClear (GL_COLOR_BUFFER_BIT); @@ -834,12 +834,11 @@ static void uninit(void) { if ( !vo_config_count ) return; - releaseGlContext(&gl_vinfo, &gl_context); if (texgrid) { free(texgrid); texgrid = NULL; } - vo_uninit(); + uninit_mpglcontext(&glctx); } static const opt_t subopts[] = { @@ -850,7 +849,11 @@ static const opt_t subopts[] = { static int preinit(const char *arg) { + enum MPGLType gltype = GLTYPE_X11; // set defaults +#ifdef GL_WIN32 + gltype = GLTYPE_W32; +#endif use_yuv = 0; use_glFinish = 1; if (subopt_parse(arg, subopts) != 0) { @@ -870,7 +873,7 @@ static int preinit(const char *arg) "\n" ); return -1; } - if( !vo_init() ) return -1; // Can't open X11 + if(!init_mpglcontext(&glctx, gltype)) return -1; return 0; } @@ -886,16 +889,16 @@ static int control(uint32_t request, void *data, ...) case VOCTRL_GUISUPPORT: return VO_TRUE; case VOCTRL_ONTOP: - vo_ontop(); + glctx.ontop(); return VO_TRUE; case VOCTRL_FULLSCREEN: - vo_fullscreen(); - if (setGlWindow(&gl_vinfo, &gl_context, vo_window) == SET_WINDOW_REINIT) + glctx.fullscreen(); + if (glctx.setGlWindow(&glctx) == SET_WINDOW_REINIT) initGl(vo_dwidth, vo_dheight); resize(vo_dwidth, vo_dheight); return VO_TRUE; case VOCTRL_BORDER: - vo_border(); + glctx.border(); return VO_TRUE; case VOCTRL_GET_PANSCAN: return VO_TRUE; @@ -925,7 +928,7 @@ static int control(uint32_t request, void *data, ...) } #endif case VOCTRL_UPDATE_SCREENINFO: - update_xinerama_info(); + glctx.update_xinerama_info(); return VO_TRUE; } return VO_NOTIMPL;