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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2814>
This commit is contained in:
Jonas Ådahl 2022-12-20 12:15:25 +01:00
parent 24bdafa220
commit e97c7851d3
4 changed files with 74 additions and 70 deletions

View File

@ -31,6 +31,7 @@ enum
PROP_ID, PROP_ID,
PROP_GPU, PROP_GPU,
PROP_INFO, PROP_INFO,
PROP_IS_PRIVACY_SCREEN_ENABLED,
N_PROPS N_PROPS
}; };
@ -59,6 +60,9 @@ typedef struct _MetaOutputPrivate
unsigned int max_bpc; unsigned int max_bpc;
int backlight; int backlight;
MetaPrivacyScreenState privacy_screen_state;
gboolean is_privacy_screen_enabled;
} MetaOutputPrivate; } MetaOutputPrivate;
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaOutput, meta_output, G_TYPE_OBJECT) 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: case PROP_INFO:
priv->info = meta_output_info_ref (g_value_get_boxed (value)); priv->info = meta_output_info_ref (g_value_get_boxed (value));
break; break;
case PROP_IS_PRIVACY_SCREEN_ENABLED:
priv->is_privacy_screen_enabled = g_value_get_boolean (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
} }
@ -418,6 +425,9 @@ meta_output_get_property (GObject *object,
case PROP_INFO: case PROP_INFO:
g_value_set_boxed (value, priv->info); g_value_set_boxed (value, priv->info);
break; break;
case PROP_IS_PRIVACY_SCREEN_ENABLED:
g_value_set_boolean (value, priv->is_privacy_screen_enabled);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); 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); 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 gboolean
meta_output_set_privacy_screen_enabled (MetaOutput *output, meta_output_set_privacy_screen_enabled (MetaOutput *output,
gboolean enabled, gboolean enabled,
GError **error) GError **error)
{ {
MetaOutputClass *output_class = META_OUTPUT_GET_CLASS (output); MetaOutputPrivate *priv = meta_output_get_instance_private (output);
MetaPrivacyScreenState state; MetaPrivacyScreenState state;
state = meta_output_get_privacy_screen_state (output); state = priv->privacy_screen_state;
if (state == META_PRIVACY_SCREEN_UNAVAILABLE) if (state == META_PRIVACY_SCREEN_UNAVAILABLE)
{ {
@ -473,8 +498,6 @@ meta_output_set_privacy_screen_enabled (MetaOutput *output,
return FALSE; return FALSE;
} }
g_assert (output_class->set_privacy_screen_enabled != NULL);
if (state & META_PRIVACY_SCREEN_LOCKED) if (state & META_PRIVACY_SCREEN_LOCKED)
{ {
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, 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; return FALSE;
} }
if (!!(state & META_PRIVACY_SCREEN_ENABLED) == enabled) if (priv->is_privacy_screen_enabled == enabled)
return TRUE; 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 static void
@ -531,6 +557,14 @@ meta_output_class_init (MetaOutputClass *klass)
G_PARAM_READWRITE | G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS); 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); g_object_class_install_properties (object_class, N_PROPS, obj_props);
} }

View File

@ -203,6 +203,10 @@ int meta_output_get_backlight (MetaOutput *output);
MetaPrivacyScreenState meta_output_get_privacy_screen_state (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 meta_output_set_privacy_screen_enabled (MetaOutput *output,
gboolean enabled, gboolean enabled,
GError **error); GError **error);

View File

@ -109,6 +109,7 @@ struct _MetaOnscreenNative
MetaRendererView *view; MetaRendererView *view;
gboolean is_gamma_lut_invalid; gboolean is_gamma_lut_invalid;
gboolean is_privacy_screen_invalid;
}; };
G_DEFINE_TYPE (MetaOnscreenNative, meta_onscreen_native, G_DEFINE_TYPE (MetaOnscreenNative, meta_onscreen_native,
@ -234,6 +235,7 @@ notify_view_crtc_presented (MetaRendererView *view,
g_return_if_fail (frame_info != NULL); g_return_if_fail (frame_info != NULL);
onscreen_native->is_gamma_lut_invalid = FALSE; 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)); crtc = META_CRTC (meta_crtc_kms_from_kms_crtc (kms_crtc));
maybe_update_frame_info (crtc, frame_info, time_us, flags, sequence); 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; MetaKmsUpdate *kms_update;
gboolean enabled;
kms_update = meta_kms_ensure_pending_update (kms, kms_device); 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) if (meta_crtc_get_gamma_lut_size (onscreen_native->crtc) > 0)
onscreen_native->is_gamma_lut_invalid = TRUE; 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 static void
@ -2168,6 +2177,17 @@ on_gamma_lut_changed (MetaCrtc *crtc,
clutter_stage_view_schedule_update (stage_view); 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 * MetaOnscreenNative *
meta_onscreen_native_new (MetaRendererNative *renderer_native, meta_onscreen_native_new (MetaRendererNative *renderer_native,
MetaGpuKms *render_gpu, MetaGpuKms *render_gpu,
@ -2203,6 +2223,14 @@ meta_onscreen_native_new (MetaRendererNative *renderer_native,
onscreen_native, G_CONNECT_DEFAULT); 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; return onscreen_native;
} }

View File

@ -45,9 +45,6 @@ struct _MetaOutputKms
MetaOutputNative parent; MetaOutputNative parent;
MetaKmsConnector *kms_connector; MetaKmsConnector *kms_connector;
gboolean is_privacy_screen_valid;
gboolean is_privacy_screen_enabled;
}; };
G_DEFINE_TYPE (MetaOutputKms, meta_output_kms, META_TYPE_OUTPUT_NATIVE) 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; 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 uint32_t
meta_output_kms_get_connector_id (MetaOutputKms *output_kms) 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 = output_class->get_privacy_screen_state =
meta_output_kms_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; output_native_class->read_edid = meta_output_kms_read_edid;
} }