diff options
author | wm4 <wm4@nowhere> | 2013-03-28 21:44:27 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2013-03-28 21:46:17 +0100 |
commit | 8099cbe9dd64f48050918242e088a1f998c77a15 (patch) | |
tree | 76abcee94beef81308e3d9f871161f3595006a21 /video/out/gl_video.c | |
parent | 69c4baad91b953afbd0ea9b76b57a7040812bb24 (diff) | |
download | mpv-8099cbe9dd64f48050918242e088a1f998c77a15.tar.bz2 mpv-8099cbe9dd64f48050918242e088a1f998c77a15.tar.xz |
vo_opengl: add alpha output
Allows playing video with alpha information on X11, as long as the video
contains alpha and the window manager does compositing. See vo.rst.
Whether a window can be transparent is decided by the choice of the X
Visual used for window creation. Unfortunately, there's no direct way to
request such a Visual through the GLX or the X API, and use of the
XRender extension is required to find out whether a Visual implies a
framebuffer with alpha used by XRender (see for example [1]). Instead of
depending on the XRender wrapper library (which would require annoying
configure checks, even though XRender is virtually always supported),
use a simple heuristics to find out whether a Visual has alpha. Since
getting it wrong just means an optional feature will not work as
expected, we consider this ok.
[1] http://stackoverflow.com/questions/4052940/how-to-make-an-opengl-
rendering-context-with-transparent-background/9215724#9215724
Diffstat (limited to 'video/out/gl_video.c')
-rw-r--r-- | video/out/gl_video.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/video/out/gl_video.c b/video/out/gl_video.c index 6bc78e6b4e..961249f1cf 100644 --- a/video/out/gl_video.c +++ b/video/out/gl_video.c @@ -253,6 +253,7 @@ const struct m_sub_options gl_video_conf = { {"rgb16f", GL_RGB16F}, {"rgb32f", GL_RGB32F})), OPT_INTRANGE("dither-depth", dither_depth, 0, -1, 16), + OPT_FLAG("alpha", enable_alpha, 0), {0} }, .size = sizeof(struct gl_video_opts), @@ -668,6 +669,9 @@ static void compile_shaders(struct gl_video *p) char *header = talloc_asprintf(tmp, "#version %d\n%s", gl->glsl_version, shader_prelude); + // Need to pass alpha through the whole chain. (Not needed for OSD shaders.) + shader_def_opt(&header, "USE_ALPHA", p->opts.enable_alpha); + char *header_osd = talloc_strdup(tmp, header); shader_def_opt(&header_osd, "USE_OSD_LINEAR_CONV", p->opts.srgb && !p->use_lut_3d); @@ -701,6 +705,8 @@ static void compile_shaders(struct gl_video *p) shader_def_opt(&header_conv, "USE_YGRAY", p->is_yuv && p->plane_count == 1); shader_def_opt(&header_conv, "USE_COLORMATRIX", p->is_yuv); shader_def_opt(&header_conv, "USE_LINEAR_CONV", convert_input_to_linear); + if (p->opts.enable_alpha && p->plane_count == 4) + shader_def(&header_conv, "USE_ALPHA_PLANE", "3"); shader_def_opt(&header_final, "USE_LINEAR_CONV_INV", p->use_lut_3d); shader_def_opt(&header_final, "USE_GAMMA_POW", p->opts.gamma); @@ -1550,7 +1556,7 @@ static int init_gl(struct gl_video *p) gl->BindBuffer(GL_ARRAY_BUFFER, 0); - gl->ClearColor(0.0f, 0.0f, 0.0f, 0.0f); + gl->ClearColor(0.0f, 0.0f, 0.0f, 1.0f); debug_check_gl(p, "after init_gl"); @@ -1642,6 +1648,10 @@ static bool init_format(int fmt, struct gl_video *init) found: ; } + // Stuff like IMGFMT_420AP10. Untested, most likely insane. + if (desc.num_planes == 4 && (init->plane_bits % 8) != 0) + return false; + init->is_yuv = desc.flags & MP_IMGFLAG_YUV; init->is_linear_rgb = false; init->plane_count = desc.num_planes; |