diff options
author | wm4 <wm4@nowhere> | 2013-04-30 00:52:32 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2013-04-30 00:52:32 +0200 |
commit | ea7b920184a865a3343001318fc4a32dcfc7b4f5 (patch) | |
tree | fbefd8539b77ee7473ad73740cc8ffa97bc4ffbe /video/out | |
parent | 3dcc83a70609d392c8ecd917dd5c16995424e9c4 (diff) | |
parent | d98e61ea438db66323734ad1b6bea66411a3c97b (diff) | |
download | mpv-ea7b920184a865a3343001318fc4a32dcfc7b4f5.tar.bz2 mpv-ea7b920184a865a3343001318fc4a32dcfc7b4f5.tar.xz |
Merge branch 'master' into low_quality_intel_crap
Conflicts:
video/out/gl_video_shaders.glsl
video/out/vo_opengl.c
Diffstat (limited to 'video/out')
30 files changed, 3587 insertions, 3290 deletions
diff --git a/video/out/aspect.c b/video/out/aspect.c index cf2b0ca383..0259c0f3ea 100644 --- a/video/out/aspect.c +++ b/video/out/aspect.c @@ -16,6 +16,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include <libavutil/common.h> + /* Stuff for correct aspect scaling. */ #include "aspect.h" #include "vo.h" @@ -43,33 +45,39 @@ void aspect_save_screenres(struct vo *vo, int scrw, int scrh) scrh = (scrw * 3 + 3) / 4; if (scrw <= 0) scrw = (scrh * 4 + 2) / 3; - vo->aspdat.scrw = scrw; - vo->aspdat.scrh = scrh; if (opts->force_monitor_aspect) - vo->monitor_par = opts->force_monitor_aspect * scrh / scrw; + vo->aspdat.monitor_par = opts->force_monitor_aspect * scrh / scrw; else - vo->monitor_par = 1.0 / opts->monitor_pixel_aspect; + vo->aspdat.monitor_par = 1.0 / opts->monitor_pixel_aspect; } -/* aspect is called with the source resolution and the - * resolution, that the scaled image should fit into - */ +void aspect_calc_monitor(struct vo *vo, int *w, int *h) +{ + float pixelaspect = vo->aspdat.monitor_par; -void aspect_fit(struct vo *vo, int *srcw, int *srch, int fitw, int fith) + if (pixelaspect < 1) { + *h /= pixelaspect; + } else { + *w *= pixelaspect; + } +} + +static void aspect_calc(struct vo *vo, int *srcw, int *srch) { struct aspect_data *aspdat = &vo->aspdat; - float pixelaspect = vo->monitor_par; + float pixelaspect = aspdat->monitor_par; + + int fitw = FFMAX(1, vo->dwidth); + int fith = FFMAX(1, vo->dheight); mp_msg(MSGT_VO, MSGL_DBG2, "aspect(0) fitin: %dx%d monitor_par: %.2f\n", - fitw, fith, vo->monitor_par); + fitw, fith, aspdat->monitor_par); *srcw = fitw; *srch = (float)fitw / aspdat->prew * aspdat->preh / pixelaspect; - *srch += *srch % 2; // round mp_msg(MSGT_VO, MSGL_DBG2, "aspect(1) wh: %dx%d (org: %dx%d)\n", *srcw, *srch, aspdat->prew, aspdat->preh); if (*srch > fith || *srch < aspdat->orgh) { int tmpw = (float)fith / aspdat->preh * aspdat->prew * pixelaspect; - tmpw += tmpw % 2; // round if (tmpw <= fitw) { *srch = fith; *srcw = tmpw; @@ -83,65 +91,21 @@ void aspect_fit(struct vo *vo, int *srcw, int *srch, int fitw, int fith) *srcw, *srch, aspdat->prew, aspdat->preh); } -static void get_max_dims(struct vo *vo, int *w, int *h, int zoom) +void aspect_calc_panscan(struct vo *vo, int *out_w, int *out_h) { - struct aspect_data *aspdat = &vo->aspdat; - *w = zoom ? aspdat->scrw : aspdat->prew; - *h = zoom ? aspdat->scrh : aspdat->preh; - if (zoom && vo->opts->WinID >= 0) - zoom = A_WINZOOM; - if (zoom == A_WINZOOM) { - *w = vo->dwidth; - *h = vo->dheight; - } -} - -void aspect(struct vo *vo, int *srcw, int *srch, int zoom) -{ - int fitw; - int fith; - get_max_dims(vo, &fitw, &fith, zoom); - if (!zoom && vo->opts->geometry.wh_valid) { - mp_msg(MSGT_VO, MSGL_DBG2, "aspect(0) no aspect forced!\n"); - return; // the user doesn't want to fix aspect - } - aspect_fit(vo, srcw, srch, fitw, fith); -} - -void panscan_init(struct vo *vo) -{ - vo->panscan_x = 0; - vo->panscan_y = 0; - vo->panscan_amount = 0.0f; -} - -static void panscan_calc_internal(struct vo *vo, int zoom) -{ - int fwidth, fheight; - int vo_panscan_area; - int max_w, max_h; - get_max_dims(vo, &max_w, &max_h, zoom); struct mp_vo_opts *opts = vo->opts; + int fwidth, fheight; + aspect_calc(vo, &fwidth, &fheight); + int vo_panscan_area; if (opts->panscanrange > 0) { - aspect(vo, &fwidth, &fheight, zoom); - vo_panscan_area = max_h - fheight; + vo_panscan_area = vo->dheight - fheight; if (!vo_panscan_area) - vo_panscan_area = max_w - fwidth; + vo_panscan_area = vo->dwidth - fwidth; vo_panscan_area *= opts->panscanrange; } else - vo_panscan_area = -opts->panscanrange * max_h; - - vo->panscan_amount = opts->fs || zoom == A_WINZOOM ? opts->panscan : 0; - vo->panscan_x = vo_panscan_area * vo->panscan_amount * vo->aspdat.asp; - vo->panscan_y = vo_panscan_area * vo->panscan_amount; -} + vo_panscan_area = -opts->panscanrange * vo->dheight; -/** - * vos that set vo_dwidth and v_dheight correctly should call this to update - * vo_panscan_x and vo_panscan_y - */ -void panscan_calc_windowed(struct vo *vo) -{ - panscan_calc_internal(vo, A_WINZOOM); + *out_w = fwidth + vo_panscan_area * opts->panscan * vo->aspdat.asp; + *out_h = fheight + vo_panscan_area * opts->panscan; } diff --git a/video/out/aspect.h b/video/out/aspect.h index c5247421d2..8455985153 100644 --- a/video/out/aspect.h +++ b/video/out/aspect.h @@ -21,17 +21,11 @@ /* Stuff for correct aspect scaling. */ struct vo; -void panscan_init(struct vo *vo); -void panscan_calc_windowed(struct vo *vo); void aspect_save_videores(struct vo *vo, int w, int h, int d_w, int d_h); void aspect_save_screenres(struct vo *vo, int scrw, int scrh); -#define A_WINZOOM 2 ///< zoom to fill window size -#define A_ZOOM 1 -#define A_NOZOOM 0 - -void aspect(struct vo *vo, int *srcw, int *srch, int zoom); -void aspect_fit(struct vo *vo, int *srcw, int *srch, int fitw, int fith); +void aspect_calc_monitor(struct vo *vo, int *w, int *h); +void aspect_calc_panscan(struct vo *vo, int *out_w, int *out_h); #endif /* MPLAYER_ASPECT_H */ diff --git a/video/out/cocoa_common.m b/video/out/cocoa_common.m index 50b0d2889c..8e06e637a4 100644 --- a/video/out/cocoa_common.m +++ b/video/out/cocoa_common.m @@ -92,6 +92,8 @@ static bool RightAltPressed(NSEvent *event) - (void)fullscreen; - (void)mouseEvent:(NSEvent *)theEvent; - (void)mulSize:(float)multiplier; +- (int)titleHeight; +- (NSRect)clipFrame:(NSRect)frame withContentAspect:(NSSize) aspect; - (void)setContentSize:(NSSize)newSize keepCentered:(BOOL)keepCentered; @end @@ -201,7 +203,7 @@ static void disable_power_management(struct vo *vo) assertion_type = kIOPMAssertionTypePreventUserIdleDisplaySleep; IOPMAssertionCreateWithName(assertion_type, kIOPMAssertionLevelOn, - CFSTR("org.mplayer2.power_mgmt"), &s->power_mgmt_assertion); + CFSTR("io.mpv.power_management"), &s->power_mgmt_assertion); } int vo_cocoa_init(struct vo *vo) @@ -409,6 +411,9 @@ static int create_window(struct vo *vo, uint32_t d_width, uint32_t d_height, [NSApp setDelegate:s->window]; [s->window setDelegate:s->window]; + [s->window setContentSize:s->current_video_size keepCentered:YES]; + [s->window setContentAspectRatio:s->current_video_size]; + return 0; } @@ -453,6 +458,8 @@ int vo_cocoa_config_window(struct vo *vo, uint32_t d_width, update_window(vo); } + [s->window setFrameOrigin:NSMakePoint(vo->dx, vo->dy)]; + if (flags & VOFLAG_HIDDEN) { [s->window orderOut:nil]; } else { @@ -460,15 +467,11 @@ int vo_cocoa_config_window(struct vo *vo, uint32_t d_width, [NSApp activateIgnoringOtherApps:YES]; } - if (flags & VOFLAG_FULLSCREEN) + if (flags & VOFLAG_FULLSCREEN && !vo->opts->fs) vo_cocoa_fullscreen(vo); vo_set_level(vo, opts->ontop); - [s->window setContentSize:s->current_video_size]; - [s->window setContentAspectRatio:s->current_video_size]; - [s->window setFrameOrigin:NSMakePoint(vo->dx, vo->dy)]; - resize_window(vo); if (s->window_title) @@ -902,35 +905,58 @@ void create_menu() } } -- (void)setCenteredContentSize:(NSSize)ns +- (int)titleHeight { - NSRect nf = [self frame]; - NSRect vf = [[self screen] visibleFrame]; - NSRect cb = [[self contentView] bounds]; - int title_height = nf.size.height - cb.size.height; - double ratio = (double)ns.width / (double)ns.height; + NSRect of = [self frame]; + NSRect cb = [[self contentView] bounds]; + return of.size.height - cb.size.height; +} - // clip the new size to the visibleFrame's size if needed - if (ns.width > vf.size.width || ns.height + title_height > vf.size.height) { - ns = vf.size; - ns.height -= title_height; // make space for the title bar +- (NSRect)clipFrame:(NSRect)frame withContentAspect:(NSSize) aspect +{ + NSRect vf = [[self screen] visibleFrame]; + double ratio = (double)aspect.width / (double)aspect.height; - if (ns.width > ns.height) { - ns.height = ((double)ns.width * 1/ratio + 0.5); - } else { - ns.width = ((double)ns.height * ratio + 0.5); - } + // clip frame to screens visibile frame + frame = CGRectIntersection(frame, vf); + + NSSize s = frame.size; + s.height -= [self titleHeight]; + + if (s.width > s.height) { + s.width = ((double)s.height * ratio); + } else { + s.height = ((double)s.width * 1.0/ratio); } - int dw = nf.size.width - ns.width; - int dh = nf.size.height - ns.height - title_height; + s.height += [self titleHeight]; + frame.size = s; + + return frame; +} + +- (void)setCenteredContentSize:(NSSize)ns +{ +#define get_center(x) NSMakePoint(CGRectGetMidX((x)), CGRectGetMidY((x))) + NSRect of = [self frame]; + NSRect vf = [[self screen] visibleFrame]; + NSPoint old_center = get_center(of); + + NSRect nf = NSMakeRect(vf.origin.x, vf.origin.y, + ns.width, ns.height + [self titleHeight]); + + nf = [self clipFrame:nf withContentAspect:ns]; + + NSPoint new_center = get_center(nf); + + int dx0 = old_center.x - new_center.x; + int dy0 = old_center.y - new_center.y; - nf.origin.x += dw / 2; - nf.origin.y += dh / 2; + nf.origin.x += dx0; + nf.origin.y += dy0; - NSRect new_frame = - NSMakeRect(nf.origin.x, nf.origin.y, ns.width, ns.height + title_height); - [self setFrame:new_frame display:YES animate:NO]; + [self setFrame:nf display:YES animate:NO]; +#undef get_center } - (void)setContentSize:(NSSize)ns keepCentered:(BOOL)keepCentered diff --git a/video/out/gl_cocoa.c b/video/out/gl_cocoa.c new file mode 100644 index 0000000000..81be21da58 --- /dev/null +++ b/video/out/gl_cocoa.c @@ -0,0 +1,67 @@ +/* + * MPlayer is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * MPlayer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * You can alternatively redistribute this file and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + */ + +#include "cocoa_common.h" +#include "gl_common.h" + +static bool config_window_cocoa(struct MPGLContext *ctx, uint32_t d_width, + uint32_t d_height, uint32_t flags) +{ + int rv = vo_cocoa_config_window(ctx->vo, d_width, d_height, flags, + ctx->requested_gl_version >= MPGL_VER(3, 0)); + if (rv != 0) + return false; + + mpgl_load_functions(ctx->gl, (void *)vo_cocoa_glgetaddr, NULL); + + ctx->depth_r = vo_cocoa_cgl_color_size(ctx->vo); + ctx->depth_g = vo_cocoa_cgl_color_size(ctx->vo); + ctx->depth_b = vo_cocoa_cgl_color_size(ctx->vo); + + if (!ctx->gl->SwapInterval) + ctx->gl->SwapInterval = vo_cocoa_swap_interval; + + return true; +} + +static void releaseGlContext_cocoa(MPGLContext *ctx) +{ +} + +static void swapGlBuffers_cocoa(MPGLContext *ctx) +{ + vo_cocoa_swap_buffers(ctx->vo); +} + +void mpgl_set_backend_cocoa(MPGLContext *ctx) +{ + ctx->config_window = config_window_cocoa; + ctx->releaseGlContext = releaseGlContext_cocoa; + ctx->swapGlBuffers = swapGlBuffers_cocoa; + ctx->check_events = vo_cocoa_check_events; + ctx->update_xinerama_info = vo_cocoa_update_xinerama_info; + ctx->fullscreen = vo_cocoa_fullscreen; + ctx->ontop = vo_cocoa_ontop; + ctx->vo_init = vo_cocoa_init; + ctx->pause = vo_cocoa_pause; + ctx->resume = vo_cocoa_resume; + ctx->vo_uninit = vo_cocoa_uninit; +} diff --git a/video/out/gl_common.c b/video/out/gl_common.c index 1eda2eaf30..685258406a 100644 --- a/video/out/gl_common.c +++ b/video/out/gl_common.c @@ -42,7 +42,6 @@ #include <assert.h> #include "talloc.h" #include "gl_common.h" -#include "aspect.h" #include "core/options.h" #include "sub/sub.h" #include "bitmap_packer.h" @@ -145,12 +144,8 @@ static bool is_software_gl(GL *gl) #ifdef HAVE_LIBDL #include <dlfcn.h> #endif -/** - * \brief find address of a linked function - * \param s name of function to find - * \return address of function or NULL if not found - */ -static void *getdladdr(const char *s) + +void *mp_getdladdr(const char *s) { void *ret = NULL; #ifdef HAVE_LIBDL @@ -457,12 +452,12 @@ struct gl_functions gl_functions[] = { // Fill the GL struct with function pointers and extensions from the current -// GL context. +// GL context. Called by the backend. // getProcAddress: function to resolve function names, may be NULL // ext2: an extra extension string // Note: if you create a CONTEXT_FORWARD_COMPATIBLE_BIT_ARB with OpenGL 3.0, // you must append "GL_ARB_compatibility" to ext2. -static void getFunctions(GL *gl, void *(*getProcAddress)(const GLubyte *), +void mpgl_load_functions(GL *gl, void *(*getProcAddress)(const GLubyte *), const char *ext2) { talloc_free_children(gl); @@ -471,7 +466,7 @@ static void getFunctions(GL *gl, void *(*getProcAddress)(const GLubyte *), }; if (!getProcAddress) - getProcAddress = (void *)getdladdr; + getProcAddress = (void *)mp_getdladdr; gl->GetString = getProcAddress("glGetString"); if (!gl->GetString) @@ -483,6 +478,12 @@ static void getFunctions(GL *gl, void *(*getProcAddress)(const GLubyte *), gl->version = MPGL_VER(major, minor); mp_msg(MSGT_VO, MSGL_V, "[gl] Detected OpenGL %d.%d.\n", major, minor); + mp_msg(MSGT_VO, MSGL_V, "GL_VENDOR='%s'\n", gl->GetString(GL_VENDOR)); + mp_msg(MSGT_VO, MSGL_V, "GL_RENDERER='%s'\n", gl->GetString(GL_RENDERER)); + mp_msg(MSGT_VO, MSGL_V, "GL_VERSION='%s'\n", gl->GetString(GL_VERSION)); + mp_msg(MSGT_VO, MSGL_V, "GL_SHADING_LANGUAGE_VERSION='%s'\n", + gl->GetString(GL_SHADING_LANGUAGE_VERSION)); + // Note: This code doesn't handle CONTEXT_FORWARD_COMPATIBLE_BIT_ARB // on OpenGL 3.0 correctly. Apparently there's no way to detect this // situation, because GL_ARB_compatibility is specified only for 3.1 @@ -840,827 +841,69 @@ mp_image_t *glGetWindowScreenshot(GL *gl) return image; } -#ifdef CONFIG_GL_COCOA -#include "cocoa_common.h" - -static bool config_window_cocoa(struct MPGLContext *ctx, uint32_t d_width, - uint32_t d_height, uint32_t flags) -{ - int rv = vo_cocoa_config_window(ctx->vo, d_width, d_height, flags, - ctx->requested_gl_version >= MPGL_VER(3, 0)); - if (rv != 0) - return false; - - getFunctions(ctx->gl, (void *)vo_cocoa_glgetaddr, NULL); +typedef void (*MPGLSetBackendFn)(MPGLContext *ctx); - ctx->depth_r = vo_cocoa_cgl_color_size(ctx->vo); - ctx->depth_g = vo_cocoa_cgl_color_size(ctx->vo); - ctx->depth_b = vo_cocoa_cgl_color_size(ctx->vo); - - if (!ctx->gl->SwapInterval) - ctx->gl->SwapInterval = vo_cocoa_swap_interval; - - return true; -} - -static void releaseGlContext_cocoa(MPGLContext *ctx) -{ -} +struct backend { + const char *name; + MPGLSetBackendFn init; +}; -static void swapGlBuffers_cocoa(MPGLContext *ctx) -{ - vo_cocoa_swap_buffers(ctx->vo); -} +static struct backend backends[] = { +#ifdef CONFIG_GL_COCOA + {"cocoa", mpgl_set_backend_cocoa}, #endif - #ifdef CONFIG_GL_WIN32 -#include <windows.h> -#include "w32_common.h" - -struct w32_context { - HGLRC context; -}; - -static void *w32gpa(const GLubyte *procName) -{ - HMODULE oglmod; - void *res = wglGetProcAddress(procName); - if (res) - return res; - oglmod = GetModuleHandle("opengl32.dll"); - return GetProcAddress(oglmod, procName); -} - -static bool create_context_w32_old(struct MPGLContext *ctx) -{ - GL *gl = ctx->gl; - - struct w32_context *w32_ctx = ctx->priv; - HGLRC *context = &w32_ctx->context; - - if (*context) { - gl->Finish(); // supposedly to prevent flickering - return true; - } - - HWND win = ctx->vo->w32->window; - HDC windc = GetDC(win); - bool res = false; - - HGLRC new_context = wglCreateContext(windc); - if (!new_context) { - mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not create GL context!\n"); - goto out; - } - - if (!wglMakeCurrent(windc, new_context)) { - mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not set GL context!\n"); - wglDeleteContext(new_context); - goto out; - } - - *context = new_context; - - getFunctions(ctx->gl, w32gpa, NULL); - res = true; - -out: - ReleaseDC(win, windc); - return res; -} - -static bool create_context_w32_gl3(struct MPGLContext *ctx) -{ - struct w32_context *w32_ctx = ctx->priv; - HGLRC *context = &w32_ctx->context; - - if (*context) // reuse existing context - return true; // not reusing it breaks gl3! - - HWND win = ctx->vo->w32->window; - HDC windc = GetDC(win); - HGLRC new_context = 0; - - new_context = wglCreateContext(windc); - if (!new_context) { - mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not create GL context!\n"); - return false; - } - - // set context - if (!wglMakeCurrent(windc, new_context)) { - mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not set GL context!\n"); - goto out; - } - - const char *(GLAPIENTRY *wglGetExtensionsStringARB)(HDC hdc) - = w32gpa((const GLubyte*)"wglGetExtensionsStringARB"); - - if (!wglGetExtensionsStringARB) - goto unsupported; - - const char *wgl_exts = wglGetExtensionsStringARB(windc); - if (!strstr(wgl_exts, "WGL_ARB_create_context")) - goto unsupported; - - HGLRC (GLAPIENTRY *wglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext, - const int *attribList) - = w32gpa((const GLubyte*)"wglCreateContextAttribsARB"); - - if (!wglCreateContextAttribsARB) - goto unsupported; - - int gl_version = ctx->requested_gl_version; - int attribs[] = { - WGL_CONTEXT_MAJOR_VERSION_ARB, MPGL_VER_GET_MAJOR(gl_version), - WGL_CONTEXT_MINOR_VERSION_ARB, MPGL_VER_GET_MINOR(gl_version), - WGL_CONTEXT_FLAGS_ARB, 0, - WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, - 0 - }; - - *context = wglCreateContextAttribsARB(windc, 0, attribs); - if (! *context) { - // NVidia, instead of ignoring WGL_CONTEXT_FLAGS_ARB, will error out if - // it's present on pre-3.2 contexts. - // Remove it from attribs and retry the context creation. - attribs[6] = attribs[7] = 0; - *context = wglCreateContextAttribsARB(windc, 0, attribs); - } - if (! *context) { - int err = GetLastError(); - mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not create an OpenGL 3.x" - " context: error 0x%x\n", err); - goto out; - } - - wglMakeCurrent(NULL, NULL); - wglDeleteContext(new_context); - - if (!wglMakeCurrent(windc, *context)) { - mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not set GL3 context!\n"); - wglDeleteContext(*context); - return false; - } - - /* update function pointers */ - getFunctions(ctx->gl, w32gpa, NULL); - - int pfmt = GetPixelFormat(windc); - PIXELFORMATDESCRIPTOR pfd; - if (DescribePixelFormat(windc, pfmt, sizeof(PIXELFORMATDESCRIPTOR), &pfd)) { - ctx->depth_r = pfd.cRedBits; - ctx->depth_g = pfd.cGreenBits; - ctx->depth_b = pfd.cBlueBits; - } - - return true; - -unsupported: - mp_msg(MSGT_VO, MSGL_ERR, "[gl] The current OpenGL implementation does" - " not support OpenGL 3.x \n"); -out: - wglDeleteContext(new_context); - return false; -} - -static bool config_window_w32(struct MPGLContext *ctx, uint32_t d_width, - uint32_t d_height, uint32_t flags) -{ - if (!vo_w32_config(ctx->vo, d_width, d_height, flags)) - return false; - - bool success = false; - if (ctx->requested_gl_version >= MPGL_VER(3, 0)) - success = create_context_w32_gl3(ctx); - if (!success) - success = create_context_w32_old(ctx); - return success; -} - -static void releaseGlContext_w32(MPGLContext *ctx) -{ - struct w32_context *w32_ctx = ctx->priv; - HGLRC *context = &w32_ctx->context; - if (*context) { - wglMakeCurrent(0, 0); - wglDeleteContext(*context); - } - *context = 0; -} - -static void swapGlBuffers_w32(MPGLContext *ctx) -{ - HDC vo_hdc = GetDC(ctx->vo->w32->window); - SwapBuffers(vo_hdc); - ReleaseDC(ctx->vo->w32->window, vo_hdc); -} + {"win", mpgl_set_backend_w32}, #endif - #ifdef CONFIG_GL_X11 -#include <X11/Xlib.h> -#include <GL/glx.h> - -#include "x11_common.h" - -#define MP_GET_GLX_WORKAROUNDS -#include "gl_header_fixes.h" - -struct glx_context { - XVisualInfo *vinfo; - GLXContext context; - GLXFBConfig fbc; -}; - -static bool create_context_x11_old(struct MPGLContext *ctx) -{ - struct glx_context *glx_ctx = ctx->priv; - Display *display = ctx->vo->x11->display; - struct vo *vo = ctx->vo; - GL *gl = ctx->gl; - - if (glx_ctx->context) - return true; - - GLXContext new_context = glXCreateContext(display, glx_ctx->vinfo, NULL, - True); - if (!new_context) { - mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not create GLX context!\n"); - return false; - } - - if (!glXMakeCurrent(display, ctx->vo->x11->window, new_context)) { - mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not set GLX context!\n"); - glXDestroyContext(display, new_context); - return false; - } - - void *(*getProcAddress)(const GLubyte *); - getProcAddress = getdladdr("glXGetProcAddress"); - if (!getProcAddress) - getProcAddress = getdladdr("glXGetProcAddressARB"); - - const char *glxstr = ""; - const char *(*glXExtStr)(Display *, int) - = getdladdr("glXQueryExtensionsString"); - if (glXExtStr) - glxstr = glXExtStr(display, ctx->vo->x11->screen); - - getFunctions(gl, getProcAddress, glxstr); - if (!gl->GenPrograms && gl->GetString && - gl->version < MPGL_VER(3, 0) && - getProcAddress && - strstr(gl->GetString(GL_EXTENSIONS), "GL_ARB_vertex_program")) - { - mp_msg(MSGT_VO, MSGL_WARN, - "Broken glXGetProcAddress detected, trying workaround\n"); - getFunctions(gl, NULL, glxstr); - } - - glx_ctx->context = new_context; - - if (!glXIsDirect(vo->x11->display, new_context)) - ctx->gl->mpgl_caps &= ~MPGL_CAP_NO_SW; - - return true; -} - -typedef GLXContext (*glXCreateContextAttribsARBProc) - (Display*, GLXFBConfig, GLXContext, Bool, const int*); - -static bool create_context_x11_gl3(struct MPGLContext *ctx, bool debug) -{ - struct glx_context *glx_ctx = ctx->priv; - struct vo *vo = ctx->vo; - - if (glx_ctx->context) - return true; - - glXCreateContextAttribsARBProc glXCreateContextAttribsARB = - (glXCreateContextAttribsARBProc) - glXGetProcAddressARB((const GLubyte *)"glXCreateContextAttribsARB"); - - const char *glxstr = ""; - const char *(*glXExtStr)(Display *, int) - = getdladdr("glXQueryExtensionsString"); - if (glXExtStr) - glxstr = glXExtStr(vo->x11->display, vo->x11->screen); - bool have_ctx_ext = glxstr && !!strstr(glxstr, "GLX_ARB_create_context"); - - if (!(have_ctx_ext && glXCreateContextAttribsARB)) { - return false; - } - - int gl_version = ctx->requested_gl_version; - int context_attribs[] = { - GLX_CONTEXT_MAJOR_VERSION_ARB, MPGL_VER_GET_MAJOR(gl_version), - GLX_CONTEXT_MINOR_VERSION_ARB, MPGL_VER_GET_MINOR(gl_version), - GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - GLX_CONTEXT_FLAGS_ARB, debug ? GLX_CONTEXT_DEBUG_BIT_ARB : 0, - None - }; - GLXContext context = glXCreateContextAttribsARB(vo->x11->display, - glx_ctx->fbc, 0, True, - context_attribs); - if (!context) { - mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not create GLX context!\n"); - return false; - } - - // set context - if (!glXMakeCurrent(vo->x11->display, vo->x11->window, context)) { - mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not set GLX context!\n"); - glXDestroyContext(vo->x11->display, context); - return false; - } - - glx_ctx->context = context; - - getFunctions(ctx-> |