summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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