kms: Notify about privacy screen changes via predictions
When we change the privacy screen, we added a result listener to the KMS update object to notify the upper layer about the privacy screen state change. This was slightly awkward as one might have changed the state multiple times for a single update, thus it was necessary to remove any old result listeners to an update before adding a new one. Doing this will not be possible when updates are fully async and managed by the KMS impl device. To handle this, instead make the post-commit prediction notify about changes that happens in response to a successfully committed update. We already predicted the new privacy screen state, so the necessary change was to plumb the actual change into a callback which emits the signal if there actually was a privacy screen change. This will then be communicated via the same signal listener that already listens to the 'resources-changed' signal. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2340>
This commit is contained in:
parent
1b0aa0b3ad
commit
81b28a1d97
@ -246,9 +246,6 @@ struct _MetaMonitorManagerClass
|
||||
unsigned short *green,
|
||||
unsigned short *blue);
|
||||
|
||||
gboolean (* set_privacy_screen_enabled) (MetaMonitorManager *manager,
|
||||
gboolean enabled);
|
||||
|
||||
void (* tiled_monitor_added) (MetaMonitorManager *manager,
|
||||
MetaMonitor *monitor);
|
||||
|
||||
|
@ -1009,17 +1009,21 @@ experimental_features_changed (MetaSettings *settings,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_monitor_manager_real_set_privacy_screen_enabled (MetaMonitorManager *manager,
|
||||
gboolean enabled)
|
||||
ensure_privacy_screen_settings (MetaMonitorManager *manager)
|
||||
{
|
||||
MetaSettings *settings = meta_backend_get_settings (manager->backend);
|
||||
gboolean privacy_screen_enabled;
|
||||
GList *l;
|
||||
|
||||
privacy_screen_enabled = meta_settings_is_privacy_screen_enabled (settings);
|
||||
for (l = manager->monitors; l; l = l->next)
|
||||
{
|
||||
g_autoptr (GError) error = NULL;
|
||||
MetaMonitor *monitor = l->data;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
if (!meta_monitor_set_privacy_screen_enabled (monitor, enabled, &error))
|
||||
if (!meta_monitor_set_privacy_screen_enabled (monitor,
|
||||
privacy_screen_enabled,
|
||||
&error))
|
||||
{
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
|
||||
continue;
|
||||
@ -1033,25 +1037,6 @@ meta_monitor_manager_real_set_privacy_screen_enabled (MetaMonitorManager *manage
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_privacy_screen_enabled (MetaMonitorManager *manager,
|
||||
gboolean enabled)
|
||||
{
|
||||
MetaMonitorManagerClass *manager_class =
|
||||
META_MONITOR_MANAGER_GET_CLASS (manager);
|
||||
|
||||
return manager_class->set_privacy_screen_enabled (manager, enabled);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_monitors_settings (MetaMonitorManager *manager)
|
||||
{
|
||||
MetaSettings *settings = meta_backend_get_settings (manager->backend);
|
||||
|
||||
return set_privacy_screen_enabled (
|
||||
manager, meta_settings_is_privacy_screen_enabled (settings));
|
||||
}
|
||||
|
||||
static MetaPrivacyScreenState
|
||||
get_global_privacy_screen_state (MetaMonitorManager *manager)
|
||||
{
|
||||
@ -1098,7 +1083,7 @@ static void
|
||||
apply_privacy_screen_settings (MetaMonitorManager *manager)
|
||||
{
|
||||
if (privacy_screen_needs_update (manager) &&
|
||||
ensure_monitors_settings (manager))
|
||||
ensure_privacy_screen_settings (manager))
|
||||
{
|
||||
manager->privacy_screen_change_state =
|
||||
META_PRIVACY_SCREEN_CHANGE_STATE_PENDING_SETTING;
|
||||
@ -1396,8 +1381,6 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
|
||||
|
||||
klass->read_edid = meta_monitor_manager_real_read_edid;
|
||||
klass->read_current_state = meta_monitor_manager_real_read_current_state;
|
||||
klass->set_privacy_screen_enabled =
|
||||
meta_monitor_manager_real_set_privacy_screen_enabled;
|
||||
|
||||
signals[MONITORS_CHANGED] =
|
||||
g_signal_new ("monitors-changed",
|
||||
@ -3619,7 +3602,7 @@ meta_monitor_manager_rebuild (MetaMonitorManager *manager,
|
||||
|
||||
meta_monitor_manager_notify_monitors_changed (manager);
|
||||
|
||||
ensure_monitors_settings (manager);
|
||||
ensure_privacy_screen_settings (manager);
|
||||
|
||||
g_list_free_full (old_logical_monitors, g_object_unref);
|
||||
}
|
||||
|
@ -106,8 +106,8 @@ MetaKmsResourceChanges meta_kms_connector_update_state (MetaKmsConnector *connec
|
||||
|
||||
void meta_kms_connector_disable (MetaKmsConnector *connector);
|
||||
|
||||
void meta_kms_connector_predict_state (MetaKmsConnector *connector,
|
||||
MetaKmsUpdate *update);
|
||||
MetaKmsResourceChanges meta_kms_connector_predict_state (MetaKmsConnector *connector,
|
||||
MetaKmsUpdate *update);
|
||||
|
||||
MetaKmsConnector * meta_kms_connector_new (MetaKmsImplDevice *impl_device,
|
||||
drmModeConnector *drm_connector,
|
||||
|
@ -758,7 +758,7 @@ meta_kms_connector_disable (MetaKmsConnector *connector)
|
||||
current_state->current_crtc_id = 0;
|
||||
}
|
||||
|
||||
void
|
||||
MetaKmsResourceChanges
|
||||
meta_kms_connector_predict_state (MetaKmsConnector *connector,
|
||||
MetaKmsUpdate *update)
|
||||
{
|
||||
@ -766,10 +766,11 @@ meta_kms_connector_predict_state (MetaKmsConnector *connector,
|
||||
MetaKmsConnectorState *current_state;
|
||||
GList *mode_sets;
|
||||
GList *l;
|
||||
MetaKmsResourceChanges changes = META_KMS_RESOURCE_CHANGE_NONE;
|
||||
|
||||
current_state = connector->current_state;
|
||||
if (!current_state)
|
||||
return;
|
||||
return META_KMS_RESOURCE_CHANGE_NONE;
|
||||
|
||||
mode_sets = meta_kms_update_get_mode_sets (update);
|
||||
for (l = mode_sets; l; l = l->next)
|
||||
@ -812,11 +813,19 @@ meta_kms_connector_predict_state (MetaKmsConnector *connector,
|
||||
{
|
||||
if (connector_update->privacy_screen.is_enabled)
|
||||
{
|
||||
if (current_state->privacy_screen_state !=
|
||||
META_PRIVACY_SCREEN_ENABLED)
|
||||
changes |= META_KMS_RESOURCE_CHANGE_PRIVACY_SCREEN;
|
||||
|
||||
current_state->privacy_screen_state =
|
||||
META_PRIVACY_SCREEN_ENABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (current_state->privacy_screen_state !=
|
||||
META_PRIVACY_SCREEN_DISABLED)
|
||||
changes |= META_KMS_RESOURCE_CHANGE_PRIVACY_SCREEN;
|
||||
|
||||
current_state->privacy_screen_state =
|
||||
META_PRIVACY_SCREEN_DISABLED;
|
||||
}
|
||||
@ -826,6 +835,8 @@ meta_kms_connector_predict_state (MetaKmsConnector *connector,
|
||||
|
||||
impl_device = meta_kms_device_get_impl_device (connector->device);
|
||||
sync_fd_held (connector, impl_device);
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -42,8 +42,8 @@ MetaKmsResourceChanges meta_kms_crtc_update_state (MetaKmsCrtc *crtc);
|
||||
|
||||
void meta_kms_crtc_disable (MetaKmsCrtc *crtc);
|
||||
|
||||
void meta_kms_crtc_predict_state (MetaKmsCrtc *crtc,
|
||||
MetaKmsUpdate *update);
|
||||
MetaKmsResourceChanges meta_kms_crtc_predict_state (MetaKmsCrtc *crtc,
|
||||
MetaKmsUpdate *update);
|
||||
|
||||
uint32_t meta_kms_crtc_get_prop_id (MetaKmsCrtc *crtc,
|
||||
MetaKmsCrtcProp prop);
|
||||
|
@ -278,13 +278,14 @@ meta_kms_crtc_disable (MetaKmsCrtc *crtc)
|
||||
crtc->current_state.drm_mode = (drmModeModeInfo) { 0 };
|
||||
}
|
||||
|
||||
void
|
||||
MetaKmsResourceChanges
|
||||
meta_kms_crtc_predict_state (MetaKmsCrtc *crtc,
|
||||
MetaKmsUpdate *update)
|
||||
{
|
||||
GList *mode_sets;
|
||||
GList *crtc_gammas;
|
||||
GList *l;
|
||||
MetaKmsResourceChanges changes = META_KMS_RESOURCE_CHANGE_NONE;
|
||||
|
||||
mode_sets = meta_kms_update_get_mode_sets (update);
|
||||
for (l = mode_sets; l; l = l->next)
|
||||
@ -337,8 +338,11 @@ meta_kms_crtc_predict_state (MetaKmsCrtc *crtc,
|
||||
crtc->current_state.gamma.blue =
|
||||
g_memdup2 (gamma->blue, gamma->size * sizeof (uint16_t));
|
||||
|
||||
changes |= META_KMS_RESOURCE_CHANGE_GAMMA;
|
||||
break;
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -914,17 +914,30 @@ err:
|
||||
return META_KMS_RESOURCE_CHANGE_FULL;
|
||||
}
|
||||
|
||||
static void
|
||||
static MetaKmsResourceChanges
|
||||
meta_kms_impl_device_predict_states (MetaKmsImplDevice *impl_device,
|
||||
MetaKmsUpdate *update)
|
||||
{
|
||||
MetaKmsImplDevicePrivate *priv =
|
||||
meta_kms_impl_device_get_instance_private (impl_device);
|
||||
MetaKmsResourceChanges changes = META_KMS_RESOURCE_CHANGE_NONE;
|
||||
GList *l;
|
||||
|
||||
g_list_foreach (priv->crtcs, (GFunc) meta_kms_crtc_predict_state,
|
||||
update);
|
||||
g_list_foreach (priv->connectors, (GFunc) meta_kms_connector_predict_state,
|
||||
update);
|
||||
for (l = priv->crtcs; l; l = l->next)
|
||||
{
|
||||
MetaKmsCrtc *crtc = l->data;
|
||||
|
||||
changes |= meta_kms_crtc_predict_state (crtc, update);
|
||||
}
|
||||
|
||||
for (l = priv->connectors; l; l = l->next)
|
||||
{
|
||||
MetaKmsConnector *connector = l->data;
|
||||
|
||||
changes |= meta_kms_connector_predict_state (connector, update);
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
void
|
||||
@ -944,14 +957,26 @@ meta_kms_impl_device_get_fd (MetaKmsImplDevice *impl_device)
|
||||
return meta_device_file_get_fd (priv->device_file);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_resources_changed_callback (MetaKms *kms,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaKmsResourceChanges changes = GPOINTER_TO_UINT (user_data);
|
||||
|
||||
meta_kms_emit_resources_changed (kms, changes);
|
||||
}
|
||||
|
||||
MetaKmsFeedback *
|
||||
meta_kms_impl_device_process_update (MetaKmsImplDevice *impl_device,
|
||||
MetaKmsUpdate *update,
|
||||
MetaKmsUpdateFlag flags)
|
||||
{
|
||||
MetaKmsImplDevicePrivate *priv =
|
||||
meta_kms_impl_device_get_instance_private (impl_device);
|
||||
MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
|
||||
MetaKmsFeedback *feedback;
|
||||
g_autoptr (GError) error = NULL;
|
||||
MetaKmsResourceChanges changes = META_KMS_RESOURCE_CHANGE_NONE;
|
||||
|
||||
if (!ensure_device_file (impl_device, &error))
|
||||
return meta_kms_feedback_new_failed (NULL, g_steal_pointer (&error));
|
||||
@ -959,9 +984,17 @@ meta_kms_impl_device_process_update (MetaKmsImplDevice *impl_device,
|
||||
meta_kms_impl_device_hold_fd (impl_device);
|
||||
feedback = klass->process_update (impl_device, update, flags);
|
||||
if (!(flags & META_KMS_UPDATE_FLAG_TEST_ONLY))
|
||||
meta_kms_impl_device_predict_states (impl_device, update);
|
||||
changes = meta_kms_impl_device_predict_states (impl_device, update);
|
||||
meta_kms_impl_device_unhold_fd (impl_device);
|
||||
|
||||
if (changes != META_KMS_RESOURCE_CHANGE_NONE)
|
||||
{
|
||||
MetaKms *kms = meta_kms_device_get_kms (priv->device);
|
||||
|
||||
meta_kms_queue_callback (kms,
|
||||
emit_resources_changed_callback,
|
||||
GUINT_TO_POINTER (changes), NULL);
|
||||
}
|
||||
return feedback;
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,9 @@ gboolean meta_kms_in_impl_task (MetaKms *kms);
|
||||
|
||||
gboolean meta_kms_is_waiting_for_impl_task (MetaKms *kms);
|
||||
|
||||
void meta_kms_emit_resources_changed (MetaKms *kms,
|
||||
MetaKmsResourceChanges changes);
|
||||
|
||||
#define meta_assert_in_kms_impl(kms) \
|
||||
g_assert (meta_kms_in_impl_task (kms))
|
||||
#define meta_assert_not_in_kms_impl(kms) \
|
||||
|
@ -651,7 +651,7 @@ handle_hotplug_event (MetaKms *kms,
|
||||
changes |= meta_kms_update_states_sync (kms, udev_device);
|
||||
|
||||
if (changes != META_KMS_RESOURCE_CHANGE_NONE)
|
||||
g_signal_emit (kms, signals[RESOURCES_CHANGED], 0, changes);
|
||||
meta_kms_emit_resources_changed (kms, changes);
|
||||
}
|
||||
|
||||
void
|
||||
@ -799,3 +799,10 @@ meta_kms_class_init (MetaKmsClass *klass)
|
||||
G_TYPE_NONE, 1,
|
||||
META_TYPE_KMS_RESOURCE_CHANGES);
|
||||
}
|
||||
|
||||
void
|
||||
meta_kms_emit_resources_changed (MetaKms *kms,
|
||||
MetaKmsResourceChanges changes)
|
||||
{
|
||||
g_signal_emit (kms, signals[RESOURCES_CHANGED], 0, changes);
|
||||
}
|
||||
|
@ -736,69 +736,6 @@ allocate_virtual_monitor_id (MetaMonitorManagerNative *manager_native)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_kms_privacy_screen_update_result (const MetaKmsFeedback *kms_feedback,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaMonitorManager *manager = user_data;
|
||||
MetaBackend *backend = meta_monitor_manager_get_backend (manager);
|
||||
MetaKms *kms = meta_backend_native_get_kms (META_BACKEND_NATIVE (backend));
|
||||
|
||||
if (meta_kms_feedback_get_result (kms_feedback) == META_KMS_FEEDBACK_FAILED)
|
||||
{
|
||||
manager->privacy_screen_change_state =
|
||||
META_PRIVACY_SCREEN_CHANGE_STATE_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
on_kms_resources_changed (kms,
|
||||
META_KMS_RESOURCE_CHANGE_PRIVACY_SCREEN,
|
||||
manager);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_monitor_manager_native_set_privacy_screen_enabled (MetaMonitorManager *manager,
|
||||
gboolean enabled)
|
||||
{
|
||||
MetaMonitorManagerClass *manager_class;
|
||||
MetaBackend *backend = meta_monitor_manager_get_backend (manager);
|
||||
MetaKms *kms = meta_backend_native_get_kms (META_BACKEND_NATIVE (backend));
|
||||
gboolean any_update = FALSE;
|
||||
GList *l;
|
||||
|
||||
manager_class =
|
||||
META_MONITOR_MANAGER_CLASS (meta_monitor_manager_native_parent_class);
|
||||
|
||||
if (!manager_class->set_privacy_screen_enabled (manager, enabled))
|
||||
return FALSE;
|
||||
|
||||
for (l = meta_kms_get_devices (kms); l; l = l->next)
|
||||
{
|
||||
MetaKmsDevice *kms_device = l->data;
|
||||
MetaKmsUpdate *kms_update;
|
||||
|
||||
kms_update = meta_kms_get_pending_update (kms, kms_device);
|
||||
|
||||
if (kms_update)
|
||||
{
|
||||
meta_kms_update_remove_result_listeners (
|
||||
kms_update, on_kms_privacy_screen_update_result, manager);
|
||||
meta_kms_update_add_result_listener (
|
||||
kms_update, on_kms_privacy_screen_update_result, manager);
|
||||
any_update = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (any_update)
|
||||
{
|
||||
ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
|
||||
|
||||
clutter_stage_schedule_update (stage);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
rebuild_virtual_idle_cb (gpointer user_data)
|
||||
{
|
||||
@ -956,8 +893,6 @@ meta_monitor_manager_native_class_init (MetaMonitorManagerNativeClass *klass)
|
||||
meta_monitor_manager_native_get_crtc_gamma;
|
||||
manager_class->set_crtc_gamma =
|
||||
meta_monitor_manager_native_set_crtc_gamma;
|
||||
manager_class->set_privacy_screen_enabled =
|
||||
meta_monitor_manager_native_set_privacy_screen_enabled;
|
||||
manager_class->is_transform_handled =
|
||||
meta_monitor_manager_native_is_transform_handled;
|
||||
manager_class->calculate_monitor_mode_scale =
|
||||
|
@ -114,12 +114,15 @@ meta_output_kms_set_privacy_screen_enabled (MetaOutput *output,
|
||||
gboolean enabled,
|
||||
GError **error)
|
||||
{
|
||||
MetaGpu *gpu;
|
||||
MetaKms *kms;
|
||||
MetaKmsDevice *kms_device;
|
||||
MetaKmsUpdate *kms_update;
|
||||
MetaGpu *gpu = meta_output_get_gpu (output);
|
||||
MetaBackend *backend = meta_gpu_get_backend (gpu);
|
||||
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||
MetaKmsDevice *kms_device = meta_gpu_kms_get_kms_device (META_GPU_KMS (gpu));
|
||||
MetaKms *kms = meta_kms_device_get_kms (kms_device);
|
||||
MetaOutputKms *output_kms = META_OUTPUT_KMS (output);
|
||||
MetaKmsConnector *connector = meta_output_kms_get_kms_connector (output_kms);
|
||||
MetaKmsUpdate *kms_update;
|
||||
MetaCrtc *crtc;
|
||||
|
||||
if (!meta_kms_connector_is_privacy_screen_supported (connector))
|
||||
{
|
||||
@ -128,13 +131,19 @@ meta_output_kms_set_privacy_screen_enabled (MetaOutput *output,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gpu = meta_output_get_gpu (META_OUTPUT (output_kms));
|
||||
kms_device = meta_gpu_kms_get_kms_device (META_GPU_KMS (gpu));
|
||||
kms = meta_kms_device_get_kms (kms_device);
|
||||
kms_update = meta_kms_ensure_pending_update (kms, kms_device);
|
||||
|
||||
meta_kms_update_set_privacy_screen (kms_update, connector, enabled);
|
||||
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
if (crtc)
|
||||
{
|
||||
MetaRendererView *view;
|
||||
|
||||
view = meta_renderer_get_view_for_crtc (renderer, crtc);
|
||||
clutter_stage_view_schedule_update (CLUTTER_STAGE_VIEW (view));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user