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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2854>
This commit is contained in:
Jonas Ådahl 2023-02-14 20:15:51 +01:00 committed by Marge Bot
parent 5dbd9cc1b8
commit a2e442ab9d
7 changed files with 95 additions and 16 deletions

View File

@ -25,6 +25,7 @@
#include <gudev/gudev.h>
#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,

View File

@ -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 */

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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',