summaryrefslogtreecommitdiffstats
path: root/video/out
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-04-30 00:52:32 +0200
committerwm4 <wm4@nowhere>2013-04-30 00:52:32 +0200
commitea7b920184a865a3343001318fc4a32dcfc7b4f5 (patch)
treefbefd8539b77ee7473ad73740cc8ffa97bc4ffbe /video/out
parent3dcc83a70609d392c8ecd917dd5c16995424e9c4 (diff)
parentd98e61ea438db66323734ad1b6bea66411a3c97b (diff)
downloadmpv-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')
-rw-r--r--video/out/aspect.c94
-rw-r--r--video/out/aspect.h10
-rw-r--r--video/out/cocoa_common.m82
-rw-r--r--video/out/gl_cocoa.c67
-rw-r--r--video/out/gl_common.c855
-rw-r--r--video/out/gl_common.h25
-rw-r--r--video/out/gl_header_fixes.h3
-rw-r--r--video/out/gl_lcms.c219
-rw-r--r--video/out/gl_lcms.h16
-rw-r--r--video/out/gl_video.c1799
-rw-r--r--video/out/gl_video.h72
-rw-r--r--video/out/gl_video_shaders.glsl (renamed from video/out/vo_opengl_shaders.glsl)47
-rw-r--r--video/out/gl_w32.c218
-rw-r--r--video/out/gl_wayland.c261
-rw-r--r--video/out/gl_x11.c317
-rw-r--r--video/out/vo.c34
-rw-r--r--video/out/vo.h29
-rw-r--r--video/out/vo_corevideo.m103
-rw-r--r--video/out/vo_direct3d.c1
-rw-r--r--video/out/vo_opengl.c2082
-rw-r--r--video/out/vo_opengl_old.c99
-rw-r--r--video/out/vo_sdl.c15
-rw-r--r--video/out/vo_vdpau.c1
-rw-r--r--video/out/vo_x11.c236
-rw-r--r--video/out/vo_xv.c34
-rw-r--r--video/out/w32_common.c12
-rw-r--r--video/out/w32_common.h2
-rw-r--r--video/out/wayland_common.c53
-rw-r--r--video/out/x11_common.c86
-rw-r--r--video/out/x11_common.h5
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->gl, (void *)glXGetProcAddress, glxstr);
-
- if (!glXIsDirect(vo->x11->display, context))
- ctx->gl->mpgl_caps &= ~MPGL_CAP_NO_SW;
-
- return true;
-}
-
-// The GL3/FBC initialization code roughly follows/copies from:
-// http://www.opengl.org/wiki/Tutorial:_OpenGL_3.0_Context_Creation_(GLX)
-// but also uses some of the old code.
-
-static GLXFBConfig select_fb_config(struct vo *vo, const int *attribs)
-{
- int fbcount;
- GLXFBConfig *fbc =