mirror of
https://github.com/mpv-player/mpv.git
synced 2026-10-28 23:13:18 +08:00
wayland: reduce branching in color-management info_done
This commit is contained in:
+51
-48
@@ -2161,59 +2161,62 @@ static void info_done(void *data, struct wp_image_description_info_v1 *image_des
|
||||
struct vo_wayland_state *wl = wd->wl;
|
||||
wl->image_description_info_done = true;
|
||||
wp_image_description_info_v1_destroy(image_description_info);
|
||||
if (!wd->icc_file) {
|
||||
MP_VERBOSE(wl, "Preferred surface feedback received:\n");
|
||||
log_color_space(wl->log, wd);
|
||||
if (!wd->csp.primaries) {
|
||||
wd->csp.primaries = mp_get_best_prim_container(&wd->raw_prim);
|
||||
MP_VERBOSE(wl, "Setting best primary container from raw primaries: %s\n",
|
||||
m_opt_choice_str(pl_csp_prim_names, wd->csp.primaries));
|
||||
}
|
||||
// We don't support extended ranges output where luminance exceeds
|
||||
// maximum nominal luminance range (1.0), so switch to PQ.
|
||||
if (fabsf(wd->csp.hdr.max_luma / wd->ref_luma - 1.0f) > 1e-4f &&
|
||||
!pl_color_transfer_is_hdr(wd->csp.transfer)) {
|
||||
MP_VERBOSE(wl, "Setting preferred transfer to PQ for HDR output.\n");
|
||||
wd->csp.transfer = PL_COLOR_TRC_PQ;
|
||||
}
|
||||
// Wayland luminances are always in reference to the reference luminance. That is,
|
||||
// if max_luma == 2*ref_luma, then there is 2x headroom above paper white. On the
|
||||
// other hand, libplacebo hardcodes PL_COLOR_SDR_WHITE as the reference luminance.
|
||||
// We must scale all wayland values to correspond to the libplacebo scale,
|
||||
// otherwise libplacebo will assume that there is too little or too much headroom
|
||||
// when ref_luma != PL_COLOR_SDR_WHITE.
|
||||
float a = wd->min_luma;
|
||||
// Wayland treats all transfers as display referred, don't scale min
|
||||
// luminance, and hope compositors will do the right thing mapping it,
|
||||
// or to be specific, not mapping it, because we set the same value.
|
||||
float c = wd->min_luma;
|
||||
float b = (PL_COLOR_SDR_WHITE - c) / (wd->ref_luma - a);
|
||||
wd->csp.hdr.min_luma = (wd->csp.hdr.min_luma - a) * b + c;
|
||||
wd->csp.hdr.max_luma = (wd->csp.hdr.max_luma - a) * b + c;
|
||||
if (wd->csp.hdr.max_cll != 0)
|
||||
wd->csp.hdr.max_cll = (wd->csp.hdr.max_cll - a) * b + c;
|
||||
if (wd->csp.hdr.max_fall != 0)
|
||||
wd->csp.hdr.max_fall = (wd->csp.hdr.max_fall - a) * b + c;
|
||||
// Ensure that min_luma doesn't become negative.
|
||||
wd->csp.hdr.min_luma = MPMAX(wd->csp.hdr.min_luma, 0.0);
|
||||
// Since we want to do some exact comparisons of max_luma with PL_COLOR_SDR_WHITE,
|
||||
// we need to round it.
|
||||
if (fabsf(wd->csp.hdr.max_luma - PL_COLOR_SDR_WHITE) < 1e-2f) {
|
||||
wd->csp.hdr.max_luma = PL_COLOR_SDR_WHITE;
|
||||
if (wd->csp.hdr.max_cll != 0)
|
||||
wd->csp.hdr.max_cll = MPMIN(wd->csp.hdr.max_cll, wd->csp.hdr.max_luma);
|
||||
if (wd->csp.hdr.max_fall != 0)
|
||||
wd->csp.hdr.max_fall = MPMIN(wd->csp.hdr.max_fall, wd->csp.hdr.max_luma);
|
||||
}
|
||||
wl->preferred_csp = wd->csp;
|
||||
} else {
|
||||
if (wl->icc_size) {
|
||||
|
||||
if (wd->icc_file) {
|
||||
if (wl->icc_size)
|
||||
munmap(wl->icc_file, wl->icc_size);
|
||||
}
|
||||
|
||||
wl->icc_file = wd->icc_file;
|
||||
wl->icc_size = wd->icc_size;
|
||||
wl->pending_vo_events |= VO_EVENT_ICC_PROFILE_CHANGED;
|
||||
talloc_free(wd);
|
||||
return;
|
||||
}
|
||||
|
||||
MP_VERBOSE(wl, "Preferred surface feedback received:\n");
|
||||
log_color_space(wl->log, wd);
|
||||
if (!wd->csp.primaries) {
|
||||
wd->csp.primaries = mp_get_best_prim_container(&wd->raw_prim);
|
||||
MP_VERBOSE(wl, "Setting best primary container from raw primaries: %s\n",
|
||||
m_opt_choice_str(pl_csp_prim_names, wd->csp.primaries));
|
||||
}
|
||||
// We don't support extended ranges output where luminance exceeds
|
||||
// maximum nominal luminance range (1.0), so switch to PQ.
|
||||
if (fabsf(wd->csp.hdr.max_luma / wd->ref_luma - 1.0f) > 1e-4f &&
|
||||
!pl_color_transfer_is_hdr(wd->csp.transfer)) {
|
||||
MP_VERBOSE(wl, "Setting preferred transfer to PQ for HDR output.\n");
|
||||
wd->csp.transfer = PL_COLOR_TRC_PQ;
|
||||
}
|
||||
// Wayland luminances are always in reference to the reference luminance. That is,
|
||||
// if max_luma == 2*ref_luma, then there is 2x headroom above paper white. On the
|
||||
// other hand, libplacebo hardcodes PL_COLOR_SDR_WHITE as the reference luminance.
|
||||
// We must scale all wayland values to correspond to the libplacebo scale,
|
||||
// otherwise libplacebo will assume that there is too little or too much headroom
|
||||
// when ref_luma != PL_COLOR_SDR_WHITE.
|
||||
float a = wd->min_luma;
|
||||
// Wayland treats all transfers as display referred, don't scale min
|
||||
// luminance, and hope compositors will do the right thing mapping it,
|
||||
// or to be specific, not mapping it, because we set the same value.
|
||||
float c = wd->min_luma;
|
||||
float b = (PL_COLOR_SDR_WHITE - c) / (wd->ref_luma - a);
|
||||
wd->csp.hdr.min_luma = (wd->csp.hdr.min_luma - a) * b + c;
|
||||
wd->csp.hdr.max_luma = (wd->csp.hdr.max_luma - a) * b + c;
|
||||
if (wd->csp.hdr.max_cll != 0)
|
||||
wd->csp.hdr.max_cll = (wd->csp.hdr.max_cll - a) * b + c;
|
||||
if (wd->csp.hdr.max_fall != 0)
|
||||
wd->csp.hdr.max_fall = (wd->csp.hdr.max_fall - a) * b + c;
|
||||
// Ensure that min_luma doesn't become negative.
|
||||
wd->csp.hdr.min_luma = MPMAX(wd->csp.hdr.min_luma, 0.0);
|
||||
// Since we want to do some exact comparisons of max_luma with PL_COLOR_SDR_WHITE,
|
||||
// we need to round it.
|
||||
if (fabsf(wd->csp.hdr.max_luma - PL_COLOR_SDR_WHITE) < 1e-2f) {
|
||||
wd->csp.hdr.max_luma = PL_COLOR_SDR_WHITE;
|
||||
if (wd->csp.hdr.max_cll != 0)
|
||||
wd->csp.hdr.max_cll = MPMIN(wd->csp.hdr.max_cll, wd->csp.hdr.max_luma);
|
||||
if (wd->csp.hdr.max_fall != 0)
|
||||
wd->csp.hdr.max_fall = MPMIN(wd->csp.hdr.max_fall, wd->csp.hdr.max_luma);
|
||||
}
|
||||
wl->preferred_csp = wd->csp;
|
||||
talloc_free(wd);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user