summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Ekström <jeebjp@gmail.com>2019-10-12 16:08:11 +0300
committerJan Ekström <jeebjp@gmail.com>2019-10-30 02:41:25 +0200
commit4e712e627c5ef3c7499cd3143174e344af24a90f (patch)
tree12d78be4d572b72d3ad52326871e0824fc8146ec
parentb27836011e26f04ec51645e41ac31b84d3d593da (diff)
downloadmpv-4e712e627c5ef3c7499cd3143174e344af24a90f.tar.bz2
mpv-4e712e627c5ef3c7499cd3143174e344af24a90f.tar.xz
vo_gpu: add and utilize color space information from ra_fbo
This lets us set primaries, transfer function and the target peak based on what the presenting layer would want us to have. Now that this mechanism is available, warn if the user has overridden values such as primaries or transfer function.
-rw-r--r--video/out/gpu/context.h5
-rw-r--r--video/out/gpu/video.c43
2 files changed, 40 insertions, 8 deletions
diff --git a/video/out/gpu/context.h b/video/out/gpu/context.h
index b080e836c8..4cf2af9e3e 100644
--- a/video/out/gpu/context.h
+++ b/video/out/gpu/context.h
@@ -1,6 +1,7 @@
#pragma once
#include "video/out/vo.h"
+#include "video/csputils.h"
#include "config.h"
#include "ra.h"
@@ -62,6 +63,10 @@ struct ra_swapchain {
struct ra_fbo {
struct ra_tex *tex;
bool flip; // rendering needs to be inverted
+
+ // Host system's colorspace that it will be interpreting
+ // the frame buffer as.
+ struct mp_colorspace color_space;
};
struct ra_swapchain_fns {
diff --git a/video/out/gpu/video.c b/video/out/gpu/video.c
index 3658866237..62ae7de9b7 100644
--- a/video/out/gpu/video.c
+++ b/video/out/gpu/video.c
@@ -291,6 +291,8 @@ struct gl_video {
bool dsi_warned;
bool broken_frame; // temporary error state
+
+ bool colorspace_override_warned;
};
static const struct gl_video_opts gl_video_opts_def = {
@@ -2496,19 +2498,44 @@ static void pass_scale_main(struct gl_video *p)
// rendering)
// If OSD is true, ignore any changes that may have been made to the video
// by previous passes (i.e. linear scaling)
-static void pass_colormanage(struct gl_video *p, struct mp_colorspace src, bool osd)
+static void pass_colormanage(struct gl_video *p, struct mp_colorspace src,
+ struct mp_colorspace fbo_csp, bool osd)
{
struct ra *ra = p->ra;
- // Figure out the target color space from the options, or auto-guess if
- // none were set
+ // Configure the destination according to the FBO color space,
+ // unless specific transfer function, primaries or target peak
+ // is set. If values are set to _AUTO, the most likely intended
+ // values are guesstimated later in this function.
struct mp_colorspace dst = {
- .gamma = p->opts.target_trc,
- .primaries = p->opts.target_prim,
+ .gamma = p->opts.target_trc == MP_CSP_TRC_AUTO ?
+ fbo_csp.gamma : p->opts.target_trc,
+ .primaries = p->opts.target_prim == MP_CSP_PRIM_AUTO ?
+ fbo_csp.primaries : p->opts.target_prim,
.light = MP_CSP_LIGHT_DISPLAY,
- .sig_peak = p->opts.target_peak / MP_REF_WHITE,
+ .sig_peak = !p->opts.target_peak ?
+ fbo_csp.sig_peak : p->opts.target_peak / MP_REF_WHITE,
};
+ if (!p->colorspace_override_warned &&
+ ((fbo_csp.gamma && dst.gamma != fbo_csp.gamma) ||
+ (fbo_csp.primaries && dst.primaries != fbo_csp.primaries)))
+ {
+ MP_WARN(p, "One or more colorspace value is being overridden "
+ "by user while the FBO provides colorspace information: "
+ "transfer function: (dst: %s, fbo: %s), "
+ "primaries: (dst: %s, fbo: %s). "
+ "Rendering can lead to incorrect results!\n",
+ m_opt_choice_str(mp_csp_trc_names, dst.gamma),
+ m_opt_choice_str(mp_csp_trc_names, fbo_csp.gamma),
+ m_opt_choice_str(mp_csp_prim_names, dst.primaries),
+ m_opt_choice_str(mp_csp_prim_names, fbo_csp.primaries));
+ p->colorspace_override_warned = true;
+ }
+
+ if (dst.gamma == MP_CSP_TRC_HLG)
+ dst.light = MP_CSP_LIGHT_SCENE_HLG;
+
if (p->use_lut_3d) {
// The 3DLUT is always generated against the video's original source
// space, *not* the reference space. (To avoid having to regenerate
@@ -2797,7 +2824,7 @@ static void pass_draw_osd(struct gl_video *p, int draw_flags, double pts,
.light = MP_CSP_LIGHT_DISPLAY,
};
- pass_colormanage(p, csp_srgb, true);
+ pass_colormanage(p, csp_srgb, fbo.color_space, true);
}
mpgl_osd_draw_finish(p->osd, n, p->sc, fbo);
}
@@ -2948,7 +2975,7 @@ static void pass_draw_to_screen(struct gl_video *p, struct ra_fbo fbo)
GLSL(color.rgb = pow(color.rgb, vec3(user_gamma));)
}
- pass_colormanage(p, p->image_params.color, false);
+ pass_colormanage(p, p->image_params.color, fbo.color_space, false);
// Since finish_pass_fbo doesn't work with compute shaders, and neither
// does the checkerboard/dither code, we may need an indirection via