diff --git a/video/out/drm_common.c b/video/out/drm_common.c index 536fefbeb5399..29a6d298ca57c 100644 --- a/video/out/drm_common.c +++ b/video/out/drm_common.c @@ -1365,7 +1365,8 @@ bool vo_drm_set_hdr_metadata(struct vo *vo, bool force_sdr) destroy_hdr_blob(drm); drm->target_params = target_params; - bool use_sdr = !target_params_supported_by_display(drm) || force_sdr; + drm->supported_colorspace = target_params_supported_by_display(drm); + bool use_sdr = !drm->supported_colorspace || force_sdr; // For any HDR, the BT2020 drm colorspace is the only one that works in practice. struct drm_atomic_context *atomic_ctx = drm->atomic_context; diff --git a/video/out/drm_common.h b/video/out/drm_common.h index b527dc4b5db57..56de557387eb4 100644 --- a/video/out/drm_common.h +++ b/video/out/drm_common.h @@ -138,6 +138,7 @@ struct vo_drm_state { const struct di_edid_chromaticity_coords *chromaticity; const struct di_cta_hdr_static_metadata_block *hdr_static_metadata; const struct di_cta_colorimetry_block *colorimetry; + bool supported_colorspace; bool active; bool paused; diff --git a/video/out/gpu/context.h b/video/out/gpu/context.h index 74b02c4e57198..490a13e8258f7 100644 --- a/video/out/gpu/context.h +++ b/video/out/gpu/context.h @@ -41,6 +41,10 @@ struct ra_ctx_fns { // display size etc. are determined by it. bool (*reconfig)(struct ra_ctx *ctx); + // Signal if the underlying context can use colorspace/hdr related functionality + // on its own. + bool (*pass_colorspace)(struct ra_ctx *ctx); + // This behaves exactly like vo_driver.control(). int (*control)(struct ra_ctx *ctx, int *events, int request, void *arg); diff --git a/video/out/opengl/context_drm_egl.c b/video/out/opengl/context_drm_egl.c index 1c82f39dc5390..ee30ce6d4eaa1 100644 --- a/video/out/opengl/context_drm_egl.c +++ b/video/out/opengl/context_drm_egl.c @@ -708,6 +708,11 @@ static bool drm_egl_reconfig(struct ra_ctx *ctx) return true; } +static bool drm_egl_pass_colorspace(struct ra_ctx *ctx) +{ + return ctx->vo->drm->supported_colorspace; +} + static int drm_egl_control(struct ra_ctx *ctx, int *events, int request, void *arg) { @@ -726,13 +731,14 @@ static void drm_egl_wakeup(struct ra_ctx *ctx) } const struct ra_ctx_fns ra_ctx_drm_egl = { - .type = "opengl", - .name = "drm", - .description = "DRM/EGL", - .reconfig = drm_egl_reconfig, - .control = drm_egl_control, - .init = drm_egl_init, - .uninit = drm_egl_uninit, - .wait_events = drm_egl_wait_events, - .wakeup = drm_egl_wakeup, + .type = "opengl", + .name = "drm", + .description = "DRM/EGL", + .reconfig = drm_egl_reconfig, + .pass_colorspace = drm_egl_pass_colorspace, + .control = drm_egl_control, + .init = drm_egl_init, + .uninit = drm_egl_uninit, + .wait_events = drm_egl_wait_events, + .wakeup = drm_egl_wakeup, }; diff --git a/video/out/vo_gpu_next.c b/video/out/vo_gpu_next.c index 00d8c5c65bf66..221ef2ff028aa 100644 --- a/video/out/vo_gpu_next.c +++ b/video/out/vo_gpu_next.c @@ -990,8 +990,12 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) p->last_id = id; } + bool pass_colorspace = false; + struct pl_color_space hint; if (p->next_opts->target_hint && frame->current) { - struct pl_color_space hint = frame->current->params.color; + hint = frame->current->params.color; + if (p->ra_ctx->fns->pass_colorspace && p->ra_ctx->fns->pass_colorspace(p->ra_ctx)) + pass_colorspace = true; if (opts->target_prim) hint.primaries = opts->target_prim; if (opts->target_trc) @@ -999,7 +1003,8 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) if (opts->target_peak) hint.hdr.max_luma = opts->target_peak; apply_target_contrast(p, &hint); - pl_swapchain_colorspace_hint(p->sw, &hint); + if (!pass_colorspace) + pl_swapchain_colorspace_hint(p->sw, &hint); } else if (!p->next_opts->target_hint) { pl_swapchain_colorspace_hint(p->sw, NULL); } @@ -1142,7 +1147,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) ? swframe.fbo->params.format->name : NULL, .w = mp_rect_w(p->dst), .h = mp_rect_h(p->dst), - .color = target.color, + .color = pass_colorspace ? hint : target.color, .repr = target.repr, .rotate = target.rotation, };