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:
parent
dc6632f19b
commit
e3afa1a1d1
2 changed files with 135 additions and 133 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -55,7 +55,6 @@
|
|||
#include "backends/meta-output.h"
|
||||
#include "backends/meta-virtual-monitor.h"
|
||||
#include "clutter/clutter.h"
|
||||
#include "core/meta-debug-control-private.h"
|
||||
#include "core/util-private.h"
|
||||
#include "meta/main.h"
|
||||
#include "meta/meta-enum-types.h"
|
||||
|
@ -489,125 +488,6 @@ prepare_shutdown (MetaBackend *backend,
|
|||
g_clear_handle_id (&priv->reload_monitor_manager_id, g_source_remove);
|
||||
}
|
||||
|
||||
static void
|
||||
set_color_space_and_hdr_metadata (MetaMonitorManager *manager,
|
||||
gboolean enable,
|
||||
MetaOutputColorspace *color_space,
|
||||
MetaOutputHdrMetadata *hdr_metadata)
|
||||
{
|
||||
MetaBackend *backend = meta_monitor_manager_get_backend (manager);
|
||||
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,
|
||||
"MonitorManager: 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,
|
||||
"MonitorManager: Trying to enable default mode "
|
||||
"(Colorimetry: default, TF: default, HDR Metadata: None):");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_hdr_settings (MetaMonitorManager *manager)
|
||||
{
|
||||
MetaBackend *backend = manager->backend;
|
||||
MetaContext *context = meta_backend_get_context (backend);
|
||||
MetaDebugControl *debug_control = meta_context_get_debug_control (context);
|
||||
MetaOutputColorspace color_space;
|
||||
MetaOutputHdrMetadata hdr_metadata;
|
||||
GList *l;
|
||||
|
||||
set_color_space_and_hdr_metadata (manager,
|
||||
meta_debug_control_is_hdr_enabled (debug_control),
|
||||
&color_space,
|
||||
&hdr_metadata);
|
||||
|
||||
for (l = manager->monitors; l; l = l->next)
|
||||
{
|
||||
MetaMonitor *monitor = l->data;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
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,
|
||||
"MonitorManager: 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);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
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,
|
||||
"MonitorManager: 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);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
meta_topic (META_DEBUG_COLOR,
|
||||
"MonitorManager: successfully set on monitor %s",
|
||||
meta_monitor_get_display_name (monitor));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_monitor_manager_is_headless:
|
||||
* @manager: A #MetaMonitorManager object
|
||||
|
@ -1323,6 +1203,17 @@ update_night_light_supported (MetaMonitorManager *manager)
|
|||
night_light_supported);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_notify_monitors_changed (MetaMonitorManager *manager)
|
||||
{
|
||||
meta_backend_monitors_changed (manager->backend);
|
||||
|
||||
g_signal_emit (manager, signals[MONITORS_CHANGED_INTERNAL], 0);
|
||||
g_signal_emit (manager, signals[MONITORS_CHANGED], 0);
|
||||
|
||||
meta_dbus_display_config_emit_monitors_changed (manager->display_config);
|
||||
}
|
||||
|
||||
void
|
||||
meta_monitor_manager_setup (MetaMonitorManager *manager)
|
||||
{
|
||||
|
@ -1350,7 +1241,7 @@ meta_monitor_manager_setup (MetaMonitorManager *manager)
|
|||
if (privacy_screen_needs_update (manager))
|
||||
manager->privacy_screen_change_state = META_PRIVACY_SCREEN_CHANGE_STATE_INIT;
|
||||
|
||||
ensure_hdr_settings (manager);
|
||||
meta_monitor_manager_notify_monitors_changed (manager);
|
||||
|
||||
manager->in_init = FALSE;
|
||||
}
|
||||
|
@ -3688,17 +3579,6 @@ meta_monitor_manager_read_current_state (MetaMonitorManager *manager)
|
|||
manager_class->read_current_state (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_notify_monitors_changed (MetaMonitorManager *manager)
|
||||
{
|
||||
meta_backend_monitors_changed (manager->backend);
|
||||
|
||||
g_signal_emit (manager, signals[MONITORS_CHANGED_INTERNAL], 0);
|
||||
g_signal_emit (manager, signals[MONITORS_CHANGED], 0);
|
||||
|
||||
meta_dbus_display_config_emit_monitors_changed (manager->display_config);
|
||||
}
|
||||
|
||||
static void
|
||||
set_logical_monitor_modes (MetaMonitorManager *manager,
|
||||
MetaLogicalMonitorConfig *logical_monitor_config)
|
||||
|
@ -3780,7 +3660,6 @@ meta_monitor_manager_rebuild (MetaMonitorManager *manager,
|
|||
meta_monitor_manager_update_logical_state (manager, config);
|
||||
|
||||
ensure_privacy_screen_settings (manager);
|
||||
ensure_hdr_settings (manager);
|
||||
|
||||
meta_monitor_manager_notify_monitors_changed (manager);
|
||||
|
||||
|
|
Loading…
Reference in a new issue