color-device: Apply HDR and colorspace calibration
The color device now updates the white point via a LUT and sets the colorspace and HDR metadata properties on monitors to get into the required configuration. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3904>
This commit is contained in:
@ -29,6 +29,7 @@
|
||||
#include "backends/meta-color-profile.h"
|
||||
#include "backends/meta-color-store.h"
|
||||
#include "backends/meta-monitor.h"
|
||||
#include "core/meta-debug-control-private.h"
|
||||
|
||||
#define EFI_PANEL_COLOR_INFO_PATH \
|
||||
"/sys/firmware/efi/efivars/INTERNAL_PANEL_COLOR_INFO-01e1ada1-79f2-46b3-8d3e-71fc0996ca6b"
|
||||
@ -1348,6 +1349,127 @@ meta_color_device_get_assigned_profile (MetaColorDevice *color_device)
|
||||
return color_device->assigned_profile;
|
||||
}
|
||||
|
||||
static void
|
||||
set_color_space_and_hdr_metadata (MetaMonitor *monitor,
|
||||
gboolean enable,
|
||||
MetaOutputColorspace *color_space,
|
||||
MetaOutputHdrMetadata *hdr_metadata)
|
||||
{
|
||||
MetaBackend *backend = meta_monitor_get_backend (monitor);
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
||||
|
||||
if (enable &&
|
||||
!cogl_context_has_feature (cogl_context, COGL_FEATURE_ID_TEXTURE_HALF_FLOAT))
|
||||
{
|
||||
g_warning ("Tried to enable HDR without half float rendering support, ignoring");
|
||||
enable = FALSE;
|
||||
}
|
||||
|
||||
if (enable)
|
||||
{
|
||||
*color_space = META_OUTPUT_COLORSPACE_BT2020;
|
||||
*hdr_metadata = (MetaOutputHdrMetadata) {
|
||||
.active = TRUE,
|
||||
.eotf = META_OUTPUT_HDR_METADATA_EOTF_PQ,
|
||||
};
|
||||
|
||||
meta_topic (META_DEBUG_COLOR,
|
||||
"ColorDevice: Trying to enabling HDR mode "
|
||||
"(Colorimetry: bt.2020, TF: PQ, HDR Metadata: Minimal):");
|
||||
}
|
||||
else
|
||||
{
|
||||
*color_space = META_OUTPUT_COLORSPACE_DEFAULT;
|
||||
*hdr_metadata = (MetaOutputHdrMetadata) {
|
||||
.active = FALSE,
|
||||
};
|
||||
|
||||
meta_topic (META_DEBUG_COLOR,
|
||||
"ColorDevice: Trying to enable default mode "
|
||||
"(Colorimetry: default, TF: default, HDR Metadata: None):");
|
||||
}
|
||||
}
|
||||
|
||||
static UpdateResult
|
||||
update_hdr (MetaColorDevice *color_device)
|
||||
{
|
||||
MetaMonitor *monitor = color_device->monitor;
|
||||
MetaBackend *backend = meta_monitor_get_backend (monitor);
|
||||
MetaContext *context = meta_backend_get_context (backend);
|
||||
MetaDebugControl *debug_control = meta_context_get_debug_control (context);
|
||||
MetaOutputColorspace color_space;
|
||||
MetaOutputHdrMetadata hdr_metadata;
|
||||
gboolean hdr_enabled;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
hdr_enabled = meta_debug_control_is_hdr_enabled (debug_control);
|
||||
set_color_space_and_hdr_metadata (monitor, hdr_enabled,
|
||||
&color_space, &hdr_metadata);
|
||||
|
||||
if (meta_monitor_get_color_space (monitor) == color_space &&
|
||||
meta_output_hdr_metadata_equal (meta_monitor_get_hdr_metadata (monitor),
|
||||
&hdr_metadata))
|
||||
return 0;
|
||||
|
||||
if (!meta_monitor_set_color_space (monitor, color_space, &error))
|
||||
{
|
||||
meta_monitor_set_color_space (monitor,
|
||||
META_OUTPUT_COLORSPACE_DEFAULT,
|
||||
NULL);
|
||||
meta_monitor_set_hdr_metadata (monitor, &(MetaOutputHdrMetadata) {
|
||||
.active = FALSE,
|
||||
}, NULL);
|
||||
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
|
||||
{
|
||||
meta_topic (META_DEBUG_COLOR,
|
||||
"ColorDevice: Colorimetry not supported "
|
||||
"on monitor %s",
|
||||
meta_monitor_get_display_name (monitor));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Failed to set color space on monitor %s: %s",
|
||||
meta_monitor_get_display_name (monitor), error->message);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!meta_monitor_set_hdr_metadata (monitor, &hdr_metadata, &error))
|
||||
{
|
||||
meta_monitor_set_color_space (monitor,
|
||||
META_OUTPUT_COLORSPACE_DEFAULT,
|
||||
NULL);
|
||||
meta_monitor_set_hdr_metadata (monitor, &(MetaOutputHdrMetadata) {
|
||||
.active = FALSE,
|
||||
}, NULL);
|
||||
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
|
||||
{
|
||||
meta_topic (META_DEBUG_COLOR,
|
||||
"ColorDevice: HDR Metadata not supported "
|
||||
"on monitor %s",
|
||||
meta_monitor_get_display_name (monitor));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Failed to set HDR metadata on monitor %s: %s",
|
||||
meta_monitor_get_display_name (monitor),
|
||||
error->message);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
meta_topic (META_DEBUG_COLOR,
|
||||
"ColorDevice: successfully set on monitor %s",
|
||||
meta_monitor_get_display_name (monitor));
|
||||
|
||||
return UPDATE_RESULT_CALIBRATION;
|
||||
}
|
||||
|
||||
static UpdateResult
|
||||
update_white_point (MetaColorDevice *color_device)
|
||||
{
|
||||
@ -1414,6 +1536,7 @@ meta_color_device_update (MetaColorDevice *color_device)
|
||||
if (!meta_monitor_is_active (monitor))
|
||||
return;
|
||||
|
||||
result |= update_hdr (color_device);
|
||||
result |= update_white_point (color_device);
|
||||
result |= update_color_state (color_device);
|
||||
|
||||
|
Reference in New Issue
Block a user