From a2e442ab9d88acd2f894defdcd99172a6d3b8d04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Tue, 14 Feb 2023 20:15:51 +0100 Subject: [PATCH] kms/result-listener: Let listeners own a feedback ref Dispatch results via a helper, and let each result hold a reference to the feedback. This allows for more asynchronous feedback management. Part-of: --- src/backends/native/meta-kms-private.h | 4 +++ src/backends/native/meta-kms-types-private.h | 25 +++++++++++++ src/backends/native/meta-kms-update-private.h | 13 ++++--- src/backends/native/meta-kms-update.c | 35 +++++++++++++++++-- src/backends/native/meta-kms-update.h | 4 +++ src/backends/native/meta-kms.c | 29 ++++++++++----- src/meson.build | 1 + 7 files changed, 95 insertions(+), 16 deletions(-) create mode 100644 src/backends/native/meta-kms-types-private.h diff --git a/src/backends/native/meta-kms-private.h b/src/backends/native/meta-kms-private.h index 615e2bdf7..16ecf2470 100644 --- a/src/backends/native/meta-kms-private.h +++ b/src/backends/native/meta-kms-private.h @@ -25,6 +25,7 @@ #include #include "backends/native/meta-kms-types.h" +#include "backends/native/meta-kms-types-private.h" typedef void (* MetaKmsCallback) (MetaKms *kms, gpointer user_data); @@ -38,6 +39,9 @@ void meta_kms_queue_callback (MetaKms *kms, gpointer user_data, GDestroyNotify user_data_destroy); +void meta_kms_queue_result_callback (MetaKms *kms, + MetaKmsResultListener *listener); + gpointer meta_kms_run_impl_task_sync (MetaKms *kms, MetaKmsImplTaskFunc func, gpointer user_data, diff --git a/src/backends/native/meta-kms-types-private.h b/src/backends/native/meta-kms-types-private.h new file mode 100644 index 000000000..275ea00b7 --- /dev/null +++ b/src/backends/native/meta-kms-types-private.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2022 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_KMS_TYPES_PRIVATE_H +#define META_KMS_TYPES_PRIVATE_H + +typedef struct _MetaKmsResultListener MetaKmsResultListener; + +#endif /* META_KMS_TYPES_PRIVATE_H */ diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h index 362c29b30..e7fa6f957 100644 --- a/src/backends/native/meta-kms-update-private.h +++ b/src/backends/native/meta-kms-update-private.h @@ -26,6 +26,7 @@ #include "backends/native/meta-kms-crtc.h" #include "backends/native/meta-kms-plane-private.h" #include "backends/native/meta-kms-types.h" +#include "backends/native/meta-kms-types-private.h" #include "backends/native/meta-kms-update.h" typedef struct _MetaKmsCrtcColorUpdate @@ -113,11 +114,13 @@ typedef struct _MetaKmsPageFlipListener GDestroyNotify destroy_notify; } MetaKmsPageFlipListener; -typedef struct _MetaKmsResultListener +struct _MetaKmsResultListener { MetaKmsResultListenerFunc func; gpointer user_data; -} MetaKmsResultListener; + + MetaKmsFeedback *feedback; +}; typedef struct _MetaKmsCustomPageFlip { @@ -185,8 +188,10 @@ META_EXPORT_TEST void meta_kms_update_merge_from (MetaKmsUpdate *update, MetaKmsUpdate *other_update); -void meta_kms_result_listener_notify (MetaKmsResultListener *listener, - const MetaKmsFeedback *feedback); +void meta_kms_result_listener_set_feedback (MetaKmsResultListener *listener, + MetaKmsFeedback *feedback); + +void meta_kms_result_listener_notify (MetaKmsResultListener *listener); void meta_kms_result_listener_free (MetaKmsResultListener *listener); diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c index ead8d2544..27832b2c0 100644 --- a/src/backends/native/meta-kms-update.c +++ b/src/backends/native/meta-kms-update.c @@ -27,6 +27,7 @@ #include "backends/native/meta-kms-crtc.h" #include "backends/native/meta-kms-mode-private.h" #include "backends/native/meta-kms-plane.h" +#include "backends/native/meta-kms-private.h" struct _MetaKmsUpdate { @@ -149,6 +150,23 @@ meta_kms_feedback_get_error (const MetaKmsFeedback *feedback) return feedback->error; } +void +meta_kms_feedback_dispatch_result (MetaKmsFeedback *feedback, + MetaKms *kms, + GList *result_listeners) +{ + GList *l; + + for (l = result_listeners; l; l = l->next) + { + MetaKmsResultListener *listener = l->data; + + meta_kms_result_listener_set_feedback (listener, feedback); + meta_kms_queue_result_callback (kms, listener); + } + g_list_free (result_listeners); +} + static void meta_kms_fb_damage_free (MetaKmsFbDamage *fb_damage) { @@ -549,15 +567,26 @@ meta_kms_update_take_result_listeners (MetaKmsUpdate *update) } void -meta_kms_result_listener_notify (MetaKmsResultListener *listener, - const MetaKmsFeedback *feedback) +meta_kms_result_listener_set_feedback (MetaKmsResultListener *listener, + MetaKmsFeedback *feedback) { - listener->func (feedback, listener->user_data); + g_return_if_fail (!listener->feedback); + + listener->feedback = meta_kms_feedback_ref (feedback); +} + +void +meta_kms_result_listener_notify (MetaKmsResultListener *listener) +{ + g_return_if_fail (listener->feedback); + + listener->func (listener->feedback, listener->user_data); } void meta_kms_result_listener_free (MetaKmsResultListener *listener) { + g_clear_pointer (&listener->feedback, meta_kms_feedback_unref); g_free (listener); } diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h index b4b696115..26f7f9fdb 100644 --- a/src/backends/native/meta-kms-update.h +++ b/src/backends/native/meta-kms-update.h @@ -91,6 +91,10 @@ GList * meta_kms_feedback_get_failed_planes (const MetaKmsFeedback *feedback); const GError * meta_kms_feedback_get_error (const MetaKmsFeedback *feedback); +void meta_kms_feedback_dispatch_result (MetaKmsFeedback *feedback, + MetaKms *kms, + GList *result_listeners); + META_EXPORT_TEST MetaKmsUpdate * meta_kms_update_new (MetaKmsDevice *device); diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c index fc578ec83..6c7974427 100644 --- a/src/backends/native/meta-kms.c +++ b/src/backends/native/meta-kms.c @@ -247,6 +247,25 @@ meta_kms_take_pending_update (MetaKms *kms, return NULL; } +static void +invoke_result_listener (MetaKms *kms, + gpointer user_data) +{ + MetaKmsResultListener *listener = user_data; + + meta_kms_result_listener_notify (listener); +} + +void +meta_kms_queue_result_callback (MetaKms *kms, + MetaKmsResultListener *listener) +{ + meta_kms_queue_callback (kms, + invoke_result_listener, + listener, + (GDestroyNotify) meta_kms_result_listener_free); +} + MetaKmsFeedback * meta_kms_post_pending_update_sync (MetaKms *kms, MetaKmsDevice *device, @@ -255,7 +274,6 @@ meta_kms_post_pending_update_sync (MetaKms *kms, MetaKmsUpdate *update; MetaKmsFeedback *feedback; GList *result_listeners; - GList *l; COGL_TRACE_BEGIN_SCOPED (MetaKmsPostUpdateSync, "KMS (post update)"); @@ -270,14 +288,7 @@ meta_kms_post_pending_update_sync (MetaKms *kms, meta_kms_update_free (update); - for (l = result_listeners; l; l = l->next) - { - MetaKmsResultListener *listener = l->data; - - meta_kms_result_listener_notify (listener, feedback); - meta_kms_result_listener_free (listener); - } - g_list_free (result_listeners); + meta_kms_feedback_dispatch_result (feedback, kms, result_listeners); return feedback; } diff --git a/src/meson.build b/src/meson.build index b6241f0e1..13dd8492f 100644 --- a/src/meson.build +++ b/src/meson.build @@ -788,6 +788,7 @@ if have_native_backend 'backends/native/meta-kms-plane-private.h', 'backends/native/meta-kms-plane.h', 'backends/native/meta-kms-private.h', + 'backends/native/meta-kms-types-private.h', 'backends/native/meta-kms-types.h', 'backends/native/meta-kms-update-private.h', 'backends/native/meta-kms-update.c',