From e97c7851d302b15c9eb043f54ad1b52856c698f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Tue, 20 Dec 2022 12:15:25 +0100 Subject: [PATCH] onscreen/native: Also track privacy screen KMS state here As with GAMMA_LUT, track whether privacy screen state has been pushed to KMS in the onscreen. This leaves MetaOutput and MetaCrtc to be about configuration, and not application. Part-of: --- src/backends/meta-output.c | 46 +++++++++++++--- src/backends/meta-output.h | 4 ++ src/backends/native/meta-onscreen-native.c | 32 ++++++++++- src/backends/native/meta-output-kms.c | 62 ---------------------- 4 files changed, 74 insertions(+), 70 deletions(-) diff --git a/src/backends/meta-output.c b/src/backends/meta-output.c index f8dd64fbe..0a98bac4d 100644 --- a/src/backends/meta-output.c +++ b/src/backends/meta-output.c @@ -31,6 +31,7 @@ enum PROP_ID, PROP_GPU, PROP_INFO, + PROP_IS_PRIVACY_SCREEN_ENABLED, N_PROPS }; @@ -59,6 +60,9 @@ typedef struct _MetaOutputPrivate unsigned int max_bpc; int backlight; + + MetaPrivacyScreenState privacy_screen_state; + gboolean is_privacy_screen_enabled; } MetaOutputPrivate; G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaOutput, meta_output, G_TYPE_OBJECT) @@ -393,6 +397,9 @@ meta_output_set_property (GObject *object, case PROP_INFO: priv->info = meta_output_info_ref (g_value_get_boxed (value)); break; + case PROP_IS_PRIVACY_SCREEN_ENABLED: + priv->is_privacy_screen_enabled = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -418,6 +425,9 @@ meta_output_get_property (GObject *object, case PROP_INFO: g_value_set_boxed (value, priv->info); break; + case PROP_IS_PRIVACY_SCREEN_ENABLED: + g_value_set_boolean (value, priv->is_privacy_screen_enabled); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -456,15 +466,30 @@ meta_output_get_privacy_screen_state (MetaOutput *output) return output_class->get_privacy_screen_state (output); } +gboolean +meta_output_is_privacy_screen_supported (MetaOutput *output) +{ + return !(meta_output_get_privacy_screen_state (output) == + META_PRIVACY_SCREEN_UNAVAILABLE); +} + +gboolean +meta_output_is_privacy_screen_enabled (MetaOutput *output) +{ + MetaOutputPrivate *priv = meta_output_get_instance_private (output); + + return priv->privacy_screen_state; +} + gboolean meta_output_set_privacy_screen_enabled (MetaOutput *output, gboolean enabled, GError **error) { - MetaOutputClass *output_class = META_OUTPUT_GET_CLASS (output); + MetaOutputPrivate *priv = meta_output_get_instance_private (output); MetaPrivacyScreenState state; - state = meta_output_get_privacy_screen_state (output); + state = priv->privacy_screen_state; if (state == META_PRIVACY_SCREEN_UNAVAILABLE) { @@ -473,8 +498,6 @@ meta_output_set_privacy_screen_enabled (MetaOutput *output, return FALSE; } - g_assert (output_class->set_privacy_screen_enabled != NULL); - if (state & META_PRIVACY_SCREEN_LOCKED) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, @@ -483,10 +506,13 @@ meta_output_set_privacy_screen_enabled (MetaOutput *output, return FALSE; } - if (!!(state & META_PRIVACY_SCREEN_ENABLED) == enabled) + if (priv->is_privacy_screen_enabled == enabled) return TRUE; - return output_class->set_privacy_screen_enabled (output, enabled, error); + priv->is_privacy_screen_enabled = enabled; + g_object_notify_by_pspec (G_OBJECT (output), + obj_props[PROP_IS_PRIVACY_SCREEN_ENABLED]); + return TRUE; } static void @@ -531,6 +557,14 @@ meta_output_class_init (MetaOutputClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_props[PROP_IS_PRIVACY_SCREEN_ENABLED] = + g_param_spec_boolean ("is-privacy-screen-enabled", + "is-privacy-screen-enabled", + "Is privacy screen enabled", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, N_PROPS, obj_props); } diff --git a/src/backends/meta-output.h b/src/backends/meta-output.h index bdaf2ed49..5fb81e443 100644 --- a/src/backends/meta-output.h +++ b/src/backends/meta-output.h @@ -203,6 +203,10 @@ int meta_output_get_backlight (MetaOutput *output); MetaPrivacyScreenState meta_output_get_privacy_screen_state (MetaOutput *output); +gboolean meta_output_is_privacy_screen_supported (MetaOutput *output); + +gboolean meta_output_is_privacy_screen_enabled (MetaOutput *output); + gboolean meta_output_set_privacy_screen_enabled (MetaOutput *output, gboolean enabled, GError **error); diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c index 38673109d..d6b4f7ca5 100644 --- a/src/backends/native/meta-onscreen-native.c +++ b/src/backends/native/meta-onscreen-native.c @@ -109,6 +109,7 @@ struct _MetaOnscreenNative MetaRendererView *view; gboolean is_gamma_lut_invalid; + gboolean is_privacy_screen_invalid; }; G_DEFINE_TYPE (MetaOnscreenNative, meta_onscreen_native, @@ -234,6 +235,7 @@ notify_view_crtc_presented (MetaRendererView *view, g_return_if_fail (frame_info != NULL); onscreen_native->is_gamma_lut_invalid = FALSE; + onscreen_native->is_privacy_screen_invalid = FALSE; crtc = META_CRTC (meta_crtc_kms_from_kms_crtc (kms_crtc)); maybe_update_frame_info (crtc, frame_info, time_us, flags, sequence); @@ -1421,12 +1423,17 @@ meta_onscreen_native_prepare_frame (CoglOnscreen *onscreen, } } - if (meta_output_kms_is_privacy_screen_invalid (output_kms)) + if (onscreen_native->is_privacy_screen_invalid) { + MetaKmsConnector *kms_connector = + meta_output_kms_get_kms_connector (output_kms); MetaKmsUpdate *kms_update; + gboolean enabled; kms_update = meta_kms_ensure_pending_update (kms, kms_device); - meta_output_kms_set_privacy_screen (output_kms, kms_update); + + enabled = meta_output_is_privacy_screen_enabled (onscreen_native->output); + meta_kms_update_set_privacy_screen (kms_update, kms_connector, enabled); } } @@ -2156,6 +2163,8 @@ meta_onscreen_native_invalidate (MetaOnscreenNative *onscreen_native) { if (meta_crtc_get_gamma_lut_size (onscreen_native->crtc) > 0) onscreen_native->is_gamma_lut_invalid = TRUE; + if (meta_output_is_privacy_screen_supported (onscreen_native->output)) + onscreen_native->is_privacy_screen_invalid = TRUE; } static void @@ -2168,6 +2177,17 @@ on_gamma_lut_changed (MetaCrtc *crtc, clutter_stage_view_schedule_update (stage_view); } +static void +on_privacy_screen_enabled_changed (MetaOutput *output, + GParamSpec *pspec, + MetaOnscreenNative *onscreen_native) +{ + ClutterStageView *stage_view = CLUTTER_STAGE_VIEW (onscreen_native->view); + + onscreen_native->is_privacy_screen_invalid = TRUE; + clutter_stage_view_schedule_update (stage_view); +} + MetaOnscreenNative * meta_onscreen_native_new (MetaRendererNative *renderer_native, MetaGpuKms *render_gpu, @@ -2203,6 +2223,14 @@ meta_onscreen_native_new (MetaRendererNative *renderer_native, onscreen_native, G_CONNECT_DEFAULT); } + if (meta_output_is_privacy_screen_supported (output)) + { + onscreen_native->is_privacy_screen_invalid = TRUE; + g_signal_connect_object (output, "notify::is-privacy-screen-enabled", + G_CALLBACK (on_privacy_screen_enabled_changed), + onscreen_native, G_CONNECT_DEFAULT); + } + return onscreen_native; } diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c index a87580fd6..e6ba57c1f 100644 --- a/src/backends/native/meta-output-kms.c +++ b/src/backends/native/meta-output-kms.c @@ -45,9 +45,6 @@ struct _MetaOutputKms MetaOutputNative parent; MetaKmsConnector *kms_connector; - - gboolean is_privacy_screen_valid; - gboolean is_privacy_screen_enabled; }; G_DEFINE_TYPE (MetaOutputKms, meta_output_kms, META_TYPE_OUTPUT_NATIVE) @@ -142,63 +139,6 @@ meta_output_kms_get_privacy_screen_state (MetaOutput *output) return connector_state->privacy_screen_state; } -static gboolean -meta_output_kms_set_privacy_screen_enabled (MetaOutput *output, - gboolean enabled, - GError **error) -{ - MetaGpu *gpu = meta_output_get_gpu (output); - MetaBackend *backend = meta_gpu_get_backend (gpu); - MetaRenderer *renderer = meta_backend_get_renderer (backend); - MetaOutputKms *output_kms = META_OUTPUT_KMS (output); - MetaKmsConnector *connector = meta_output_kms_get_kms_connector (output_kms); - MetaCrtc *crtc; - - if (!meta_kms_connector_is_privacy_screen_supported (connector)) - { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "No privacy screen support"); - return FALSE; - } - - output_kms->is_privacy_screen_valid = FALSE; - output_kms->is_privacy_screen_enabled = 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; -} - -gboolean -meta_output_kms_is_privacy_screen_invalid (MetaOutputKms *output_kms) -{ - return !output_kms->is_privacy_screen_valid; -} - -void -meta_output_kms_set_privacy_screen (MetaOutputKms *output_kms, - MetaKmsUpdate *kms_update) -{ - MetaKmsConnector *connector = meta_output_kms_get_kms_connector (output_kms); - - g_return_if_fail (!output_kms->is_privacy_screen_valid); - - output_kms->is_privacy_screen_valid = TRUE; - - if (!meta_kms_connector_is_privacy_screen_supported (connector)) - return; - - meta_kms_update_set_privacy_screen (kms_update, connector, - output_kms->is_privacy_screen_enabled); -} - uint32_t meta_output_kms_get_connector_id (MetaOutputKms *output_kms) { @@ -571,8 +511,6 @@ meta_output_kms_class_init (MetaOutputKmsClass *klass) output_class->get_privacy_screen_state = meta_output_kms_get_privacy_screen_state; - output_class->set_privacy_screen_enabled = - meta_output_kms_set_privacy_screen_enabled; output_native_class->read_edid = meta_output_kms_read_edid; }