kms/update: Allow page flip callback listeners on any thread
This hooks into the MetaThread GMainContext callback machinery just added; and allows receiving page flip callbacks on any thread. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
This commit is contained in:
parent
f83c30bae5
commit
d77b5935cd
@ -755,6 +755,7 @@ process_page_flip_listener (MetaKmsImplDevice *impl_device,
|
|||||||
meta_kms_page_flip_data_add_listener (page_flip_data,
|
meta_kms_page_flip_data_add_listener (page_flip_data,
|
||||||
listener->vtable,
|
listener->vtable,
|
||||||
listener->flags,
|
listener->flags,
|
||||||
|
listener->main_context,
|
||||||
listener_user_data,
|
listener_user_data,
|
||||||
listener_destroy_notify);
|
listener_destroy_notify);
|
||||||
|
|
||||||
|
@ -1091,6 +1091,7 @@ generate_page_flip_datas (MetaKmsImplDevice *impl_device,
|
|||||||
meta_kms_page_flip_data_add_listener (page_flip_data,
|
meta_kms_page_flip_data_add_listener (page_flip_data,
|
||||||
listener->vtable,
|
listener->vtable,
|
||||||
listener->flags,
|
listener->flags,
|
||||||
|
listener->main_context,
|
||||||
user_data,
|
user_data,
|
||||||
destroy_notify);
|
destroy_notify);
|
||||||
|
|
||||||
@ -1113,6 +1114,7 @@ generate_page_flip_datas (MetaKmsImplDevice *impl_device,
|
|||||||
meta_kms_page_flip_data_add_listener (page_flip_data,
|
meta_kms_page_flip_data_add_listener (page_flip_data,
|
||||||
other_listener->vtable,
|
other_listener->vtable,
|
||||||
other_listener->flags,
|
other_listener->flags,
|
||||||
|
other_listener->main_context,
|
||||||
other_user_data,
|
other_user_data,
|
||||||
other_destroy_notify);
|
other_destroy_notify);
|
||||||
listeners = g_list_delete_link (listeners, l);
|
listeners = g_list_delete_link (listeners, l);
|
||||||
|
@ -1064,6 +1064,7 @@ meta_kms_impl_device_process_update (MetaKmsImplDevice *impl_device,
|
|||||||
MetaKms *kms = meta_kms_device_get_kms (priv->device);
|
MetaKms *kms = meta_kms_device_get_kms (priv->device);
|
||||||
|
|
||||||
meta_kms_queue_callback (kms,
|
meta_kms_queue_callback (kms,
|
||||||
|
NULL,
|
||||||
emit_resources_changed_callback,
|
emit_resources_changed_callback,
|
||||||
GUINT_TO_POINTER (changes), NULL);
|
GUINT_TO_POINTER (changes), NULL);
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ void meta_kms_page_flip_data_unref (MetaKmsPageFlipData *page_flip_data);
|
|||||||
void meta_kms_page_flip_data_add_listener (MetaKmsPageFlipData *page_flip_data,
|
void meta_kms_page_flip_data_add_listener (MetaKmsPageFlipData *page_flip_data,
|
||||||
const MetaKmsPageFlipListenerVtable *vtable,
|
const MetaKmsPageFlipListenerVtable *vtable,
|
||||||
MetaKmsPageFlipListenerFlag flags,
|
MetaKmsPageFlipListenerFlag flags,
|
||||||
|
GMainContext *main_context,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify destroy_notify);
|
GDestroyNotify destroy_notify);
|
||||||
|
|
||||||
|
@ -30,8 +30,11 @@ typedef struct _MetaKmsPageFlipClosure
|
|||||||
{
|
{
|
||||||
const MetaKmsPageFlipListenerVtable *vtable;
|
const MetaKmsPageFlipListenerVtable *vtable;
|
||||||
MetaKmsPageFlipListenerFlag flags;
|
MetaKmsPageFlipListenerFlag flags;
|
||||||
|
GMainContext *main_context;
|
||||||
gpointer user_data;
|
gpointer user_data;
|
||||||
GDestroyNotify destroy_notify;
|
GDestroyNotify destroy_notify;
|
||||||
|
|
||||||
|
MetaKmsPageFlipData *page_flip_data;
|
||||||
} MetaKmsPageFlipClosure;
|
} MetaKmsPageFlipClosure;
|
||||||
|
|
||||||
struct _MetaKmsPageFlipData
|
struct _MetaKmsPageFlipData
|
||||||
@ -55,6 +58,7 @@ struct _MetaKmsPageFlipData
|
|||||||
static MetaKmsPageFlipClosure *
|
static MetaKmsPageFlipClosure *
|
||||||
meta_kms_page_flip_closure_new (const MetaKmsPageFlipListenerVtable *vtable,
|
meta_kms_page_flip_closure_new (const MetaKmsPageFlipListenerVtable *vtable,
|
||||||
MetaKmsPageFlipListenerFlag flags,
|
MetaKmsPageFlipListenerFlag flags,
|
||||||
|
GMainContext *main_context,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify destroy_notify)
|
GDestroyNotify destroy_notify)
|
||||||
{
|
{
|
||||||
@ -64,6 +68,7 @@ meta_kms_page_flip_closure_new (const MetaKmsPageFlipListenerVtable *vtable,
|
|||||||
*closure = (MetaKmsPageFlipClosure) {
|
*closure = (MetaKmsPageFlipClosure) {
|
||||||
.vtable = vtable,
|
.vtable = vtable,
|
||||||
.flags = flags,
|
.flags = flags,
|
||||||
|
.main_context = main_context,
|
||||||
.user_data = user_data,
|
.user_data = user_data,
|
||||||
.destroy_notify = destroy_notify,
|
.destroy_notify = destroy_notify,
|
||||||
};
|
};
|
||||||
@ -74,10 +79,20 @@ meta_kms_page_flip_closure_new (const MetaKmsPageFlipListenerVtable *vtable,
|
|||||||
static void
|
static void
|
||||||
meta_kms_page_flip_closure_free (MetaKmsPageFlipClosure *closure)
|
meta_kms_page_flip_closure_free (MetaKmsPageFlipClosure *closure)
|
||||||
{
|
{
|
||||||
|
g_clear_pointer (&closure->page_flip_data, meta_kms_page_flip_data_unref);
|
||||||
g_clear_pointer (&closure->user_data, closure->destroy_notify);
|
g_clear_pointer (&closure->user_data, closure->destroy_notify);
|
||||||
g_free (closure);
|
g_free (closure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_kms_page_closure_set_data (MetaKmsPageFlipClosure *closure,
|
||||||
|
MetaKmsPageFlipData *page_flip_data)
|
||||||
|
{
|
||||||
|
g_return_if_fail (!closure->page_flip_data);
|
||||||
|
|
||||||
|
closure->page_flip_data = meta_kms_page_flip_data_ref (page_flip_data);
|
||||||
|
}
|
||||||
|
|
||||||
MetaKmsPageFlipData *
|
MetaKmsPageFlipData *
|
||||||
meta_kms_page_flip_data_new (MetaKmsImplDevice *impl_device,
|
meta_kms_page_flip_data_new (MetaKmsImplDevice *impl_device,
|
||||||
MetaKmsCrtc *crtc)
|
MetaKmsCrtc *crtc)
|
||||||
@ -118,12 +133,14 @@ void
|
|||||||
meta_kms_page_flip_data_add_listener (MetaKmsPageFlipData *page_flip_data,
|
meta_kms_page_flip_data_add_listener (MetaKmsPageFlipData *page_flip_data,
|
||||||
const MetaKmsPageFlipListenerVtable *vtable,
|
const MetaKmsPageFlipListenerVtable *vtable,
|
||||||
MetaKmsPageFlipListenerFlag flags,
|
MetaKmsPageFlipListenerFlag flags,
|
||||||
|
GMainContext *main_context,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify destroy_notify)
|
GDestroyNotify destroy_notify)
|
||||||
{
|
{
|
||||||
MetaKmsPageFlipClosure *closure;
|
MetaKmsPageFlipClosure *closure;
|
||||||
|
|
||||||
closure = meta_kms_page_flip_closure_new (vtable, flags,
|
closure = meta_kms_page_flip_closure_new (vtable, flags,
|
||||||
|
main_context,
|
||||||
user_data,
|
user_data,
|
||||||
destroy_notify);
|
destroy_notify);
|
||||||
page_flip_data->closures = g_list_append (page_flip_data->closures, closure);
|
page_flip_data->closures = g_list_append (page_flip_data->closures, closure);
|
||||||
@ -142,31 +159,26 @@ meta_kms_page_flip_data_get_crtc (MetaKmsPageFlipData *page_flip_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_kms_page_flip_data_flipped (MetaThread *thread,
|
invoke_page_flip_closure_flipped (MetaThread *thread,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
MetaKmsPageFlipData *page_flip_data = user_data;
|
MetaKmsPageFlipClosure *closure = user_data;
|
||||||
GList *l;
|
MetaKmsPageFlipData *page_flip_data = closure->page_flip_data;
|
||||||
|
|
||||||
meta_assert_not_in_kms_impl (META_KMS (thread));
|
meta_assert_not_in_kms_impl (META_KMS (thread));
|
||||||
|
|
||||||
for (l = page_flip_data->closures; l; l = l->next)
|
if (page_flip_data->is_symbolic)
|
||||||
{
|
{
|
||||||
MetaKmsPageFlipClosure *closure = l->data;
|
closure->vtable->ready (page_flip_data->crtc,
|
||||||
|
closure->user_data);
|
||||||
if (page_flip_data->is_symbolic)
|
}
|
||||||
{
|
else
|
||||||
closure->vtable->ready (page_flip_data->crtc,
|
{
|
||||||
closure->user_data);
|
closure->vtable->flipped (page_flip_data->crtc,
|
||||||
}
|
page_flip_data->sequence,
|
||||||
else
|
page_flip_data->sec,
|
||||||
{
|
page_flip_data->usec,
|
||||||
closure->vtable->flipped (page_flip_data->crtc,
|
closure->user_data);
|
||||||
page_flip_data->sequence,
|
|
||||||
page_flip_data->sec,
|
|
||||||
page_flip_data->usec,
|
|
||||||
closure->user_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,63 +221,78 @@ void
|
|||||||
meta_kms_page_flip_data_flipped_in_impl (MetaKmsPageFlipData *page_flip_data)
|
meta_kms_page_flip_data_flipped_in_impl (MetaKmsPageFlipData *page_flip_data)
|
||||||
{
|
{
|
||||||
MetaKms *kms = meta_kms_from_impl_device (page_flip_data->impl_device);
|
MetaKms *kms = meta_kms_from_impl_device (page_flip_data->impl_device);
|
||||||
|
g_autoptr (GList) closures = NULL;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
meta_assert_in_kms_impl (kms);
|
meta_assert_in_kms_impl (kms);
|
||||||
|
|
||||||
meta_kms_queue_callback (kms,
|
closures = g_steal_pointer (&page_flip_data->closures);
|
||||||
meta_kms_page_flip_data_flipped,
|
for (l = closures; l; l = l->next)
|
||||||
page_flip_data,
|
|
||||||
(GDestroyNotify) meta_kms_page_flip_data_unref);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_kms_page_flip_data_mode_set_fallback (MetaThread *thread,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
MetaKmsPageFlipData *page_flip_data = user_data;
|
|
||||||
GList *l;
|
|
||||||
|
|
||||||
meta_assert_not_in_kms_impl (META_KMS (thread));
|
|
||||||
|
|
||||||
for (l = page_flip_data->closures; l; l = l->next)
|
|
||||||
{
|
{
|
||||||
MetaKmsPageFlipClosure *closure = l->data;
|
MetaKmsPageFlipClosure *closure = l->data;
|
||||||
|
|
||||||
closure->vtable->mode_set_fallback (page_flip_data->crtc,
|
meta_kms_page_closure_set_data (closure, page_flip_data);
|
||||||
closure->user_data);
|
meta_kms_queue_callback (kms,
|
||||||
|
closure->main_context,
|
||||||
|
invoke_page_flip_closure_flipped,
|
||||||
|
closure,
|
||||||
|
(GDestroyNotify) meta_kms_page_flip_closure_free);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
meta_kms_page_flip_data_unref (page_flip_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
invoke_page_flip_closure_mode_set_fallback (MetaThread *thread,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MetaKmsPageFlipClosure *closure = user_data;
|
||||||
|
MetaKmsPageFlipData *page_flip_data = closure->page_flip_data;
|
||||||
|
|
||||||
|
meta_assert_not_in_kms_impl (META_KMS (thread));
|
||||||
|
|
||||||
|
closure->vtable->mode_set_fallback (page_flip_data->crtc,
|
||||||
|
closure->user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_kms_page_flip_data_mode_set_fallback_in_impl (MetaKmsPageFlipData *page_flip_data)
|
meta_kms_page_flip_data_mode_set_fallback_in_impl (MetaKmsPageFlipData *page_flip_data)
|
||||||
{
|
{
|
||||||
MetaKms *kms = meta_kms_from_impl_device (page_flip_data->impl_device);
|
MetaKms *kms = meta_kms_from_impl_device (page_flip_data->impl_device);
|
||||||
|
g_autoptr (GList) closures = NULL;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
meta_assert_in_kms_impl (kms);
|
meta_assert_in_kms_impl (kms);
|
||||||
|
|
||||||
meta_kms_queue_callback (kms,
|
closures = g_steal_pointer (&page_flip_data->closures);
|
||||||
meta_kms_page_flip_data_mode_set_fallback,
|
for (l = closures; l; l = l->next)
|
||||||
page_flip_data,
|
|
||||||
(GDestroyNotify) meta_kms_page_flip_data_unref);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_kms_page_flip_data_discard (MetaThread *thread,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
MetaKmsPageFlipData *page_flip_data = user_data;
|
|
||||||
GList *l;
|
|
||||||
|
|
||||||
meta_assert_not_in_kms_impl (META_KMS (thread));
|
|
||||||
|
|
||||||
for (l = page_flip_data->closures; l; l = l->next)
|
|
||||||
{
|
{
|
||||||
MetaKmsPageFlipClosure *closure = l->data;
|
MetaKmsPageFlipClosure *closure = l->data;
|
||||||
|
|
||||||
closure->vtable->discarded (page_flip_data->crtc,
|
meta_kms_page_closure_set_data (closure, page_flip_data);
|
||||||
closure->user_data,
|
meta_kms_queue_callback (kms,
|
||||||
page_flip_data->error);
|
closure->main_context,
|
||||||
|
invoke_page_flip_closure_mode_set_fallback,
|
||||||
|
closure,
|
||||||
|
(GDestroyNotify) meta_kms_page_flip_closure_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
meta_kms_page_flip_data_unref (page_flip_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
invoke_page_flip_closure_discarded (MetaThread *thread,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MetaKmsPageFlipClosure *closure = user_data;
|
||||||
|
MetaKmsPageFlipData *page_flip_data = closure->page_flip_data;
|
||||||
|
|
||||||
|
meta_assert_not_in_kms_impl (META_KMS (thread));
|
||||||
|
|
||||||
|
closure->vtable->discarded (page_flip_data->crtc,
|
||||||
|
closure->user_data,
|
||||||
|
page_flip_data->error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -282,14 +309,27 @@ meta_kms_page_flip_data_discard_in_impl (MetaKmsPageFlipData *page_flip_data,
|
|||||||
const GError *error)
|
const GError *error)
|
||||||
{
|
{
|
||||||
MetaKms *kms = meta_kms_from_impl_device (page_flip_data->impl_device);
|
MetaKms *kms = meta_kms_from_impl_device (page_flip_data->impl_device);
|
||||||
|
g_autoptr (GList) closures = NULL;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
meta_assert_in_kms_impl (kms);
|
meta_assert_in_kms_impl (kms);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
meta_kms_page_flip_data_take_error (page_flip_data, g_error_copy (error));
|
meta_kms_page_flip_data_take_error (page_flip_data, g_error_copy (error));
|
||||||
|
|
||||||
meta_kms_queue_callback (kms,
|
closures = g_steal_pointer (&page_flip_data->closures);
|
||||||
meta_kms_page_flip_data_discard,
|
for (l = closures; l; l = l->next)
|
||||||
page_flip_data,
|
{
|
||||||
(GDestroyNotify) meta_kms_page_flip_data_unref);
|
MetaKmsPageFlipClosure *closure = l->data;
|
||||||
|
|
||||||
|
meta_kms_page_closure_set_data (closure, page_flip_data);
|
||||||
|
|
||||||
|
meta_kms_queue_callback (kms,
|
||||||
|
closure->main_context,
|
||||||
|
invoke_page_flip_closure_discarded,
|
||||||
|
closure,
|
||||||
|
(GDestroyNotify) meta_kms_page_flip_closure_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_kms_page_flip_data_unref (page_flip_data);
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ typedef void (* MetaKmsCallback) (MetaKms *kms,
|
|||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
void meta_kms_queue_callback (MetaKms *kms,
|
void meta_kms_queue_callback (MetaKms *kms,
|
||||||
|
GMainContext *main_context,
|
||||||
MetaThreadCallback callback,
|
MetaThreadCallback callback,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify user_data_destroy);
|
GDestroyNotify user_data_destroy);
|
||||||
|
@ -121,6 +121,7 @@ typedef struct _MetaKmsPageFlipListener
|
|||||||
MetaKmsCrtc *crtc;
|
MetaKmsCrtc *crtc;
|
||||||
const MetaKmsPageFlipListenerVtable *vtable;
|
const MetaKmsPageFlipListenerVtable *vtable;
|
||||||
MetaKmsPageFlipListenerFlag flags;
|
MetaKmsPageFlipListenerFlag flags;
|
||||||
|
GMainContext *main_context;
|
||||||
gpointer user_data;
|
gpointer user_data;
|
||||||
GDestroyNotify destroy_notify;
|
GDestroyNotify destroy_notify;
|
||||||
} MetaKmsPageFlipListener;
|
} MetaKmsPageFlipListener;
|
||||||
|
@ -193,14 +193,35 @@ meta_kms_mode_set_free (MetaKmsModeSet *mode_set)
|
|||||||
g_free (mode_set);
|
g_free (mode_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
noop_callback (gpointer user_data)
|
||||||
|
{
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_kms_page_flip_listener_unref (MetaKmsPageFlipListener *listener)
|
meta_kms_page_flip_listener_unref (MetaKmsPageFlipListener *listener)
|
||||||
{
|
{
|
||||||
if (!g_atomic_ref_count_dec (&listener->ref_count))
|
if (!g_atomic_ref_count_dec (&listener->ref_count))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_clear_pointer (&listener->user_data, listener->destroy_notify);
|
if (listener->main_context == g_main_context_get_thread_default ())
|
||||||
g_free (listener);
|
{
|
||||||
|
g_clear_pointer (&listener->user_data, listener->destroy_notify);
|
||||||
|
g_free (listener);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GSource *source;
|
||||||
|
|
||||||
|
source = g_idle_source_new ();
|
||||||
|
g_source_set_callback (source, noop_callback,
|
||||||
|
g_steal_pointer (&listener->user_data),
|
||||||
|
g_steal_pointer (&listener->destroy_notify));
|
||||||
|
g_source_attach (source, listener->main_context);
|
||||||
|
g_source_unref (source);
|
||||||
|
g_free (listener);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -497,6 +518,7 @@ meta_kms_update_add_page_flip_listener (MetaKmsUpdate *upd
|
|||||||
MetaKmsCrtc *crtc,
|
MetaKmsCrtc *crtc,
|
||||||
const MetaKmsPageFlipListenerVtable *vtable,
|
const MetaKmsPageFlipListenerVtable *vtable,
|
||||||
MetaKmsPageFlipListenerFlag flags,
|
MetaKmsPageFlipListenerFlag flags,
|
||||||
|
GMainContext *main_context,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify destroy_notify)
|
GDestroyNotify destroy_notify)
|
||||||
{
|
{
|
||||||
@ -510,6 +532,7 @@ meta_kms_update_add_page_flip_listener (MetaKmsUpdate *upd
|
|||||||
.crtc = crtc,
|
.crtc = crtc,
|
||||||
.vtable = vtable,
|
.vtable = vtable,
|
||||||
.flags = flags,
|
.flags = flags,
|
||||||
|
.main_context = main_context,
|
||||||
.user_data = user_data,
|
.user_data = user_data,
|
||||||
.destroy_notify = destroy_notify,
|
.destroy_notify = destroy_notify,
|
||||||
};
|
};
|
||||||
|
@ -168,6 +168,7 @@ void meta_kms_update_add_page_flip_listener (MetaKmsUpdate
|
|||||||
MetaKmsCrtc *crtc,
|
MetaKmsCrtc *crtc,
|
||||||
const MetaKmsPageFlipListenerVtable *vtable,
|
const MetaKmsPageFlipListenerVtable *vtable,
|
||||||
MetaKmsPageFlipListenerFlag flags,
|
MetaKmsPageFlipListenerFlag flags,
|
||||||
|
GMainContext *main_context,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify destroy_notify);
|
GDestroyNotify destroy_notify);
|
||||||
|
|
||||||
|
@ -170,6 +170,7 @@ meta_kms_queue_result_callback (MetaKms *kms,
|
|||||||
MetaKmsResultListener *listener)
|
MetaKmsResultListener *listener)
|
||||||
{
|
{
|
||||||
meta_kms_queue_callback (kms,
|
meta_kms_queue_callback (kms,
|
||||||
|
NULL,
|
||||||
invoke_result_listener,
|
invoke_result_listener,
|
||||||
listener,
|
listener,
|
||||||
(GDestroyNotify) meta_kms_result_listener_free);
|
(GDestroyNotify) meta_kms_result_listener_free);
|
||||||
@ -219,6 +220,7 @@ meta_kms_notify_modes_set (MetaKms *kms)
|
|||||||
|
|
||||||
void
|
void
|
||||||
meta_kms_queue_callback (MetaKms *kms,
|
meta_kms_queue_callback (MetaKms *kms,
|
||||||
|
GMainContext *main_context,
|
||||||
MetaThreadCallback callback,
|
MetaThreadCallback callback,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify user_data_destroy)
|
GDestroyNotify user_data_destroy)
|
||||||
@ -226,7 +228,7 @@ meta_kms_queue_callback (MetaKms *kms,
|
|||||||
MetaThread *thread = META_THREAD (kms);
|
MetaThread *thread = META_THREAD (kms);
|
||||||
|
|
||||||
meta_thread_queue_callback (thread,
|
meta_thread_queue_callback (thread,
|
||||||
NULL,
|
main_context,
|
||||||
callback,
|
callback,
|
||||||
user_data,
|
user_data,
|
||||||
user_data_destroy);
|
user_data_destroy);
|
||||||
|
@ -474,6 +474,7 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
|
|||||||
kms_crtc,
|
kms_crtc,
|
||||||
&page_flip_listener_vtable,
|
&page_flip_listener_vtable,
|
||||||
flags,
|
flags,
|
||||||
|
NULL,
|
||||||
g_object_ref (view),
|
g_object_ref (view),
|
||||||
g_object_unref);
|
g_object_unref);
|
||||||
}
|
}
|
||||||
@ -1548,6 +1549,7 @@ meta_onscreen_native_finish_frame (CoglOnscreen *onscreen,
|
|||||||
kms_crtc,
|
kms_crtc,
|
||||||
&page_flip_listener_vtable,
|
&page_flip_listener_vtable,
|
||||||
META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE,
|
META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE,
|
||||||
|
NULL,
|
||||||
g_object_ref (onscreen_native->view),
|
g_object_ref (onscreen_native->view),
|
||||||
g_object_unref);
|
g_object_unref);
|
||||||
add_onscreen_frame_info (crtc);
|
add_onscreen_frame_info (crtc);
|
||||||
|
@ -351,6 +351,7 @@ meta_test_kms_update_page_flip (void)
|
|||||||
meta_kms_update_add_page_flip_listener (update, crtc,
|
meta_kms_update_add_page_flip_listener (update, crtc,
|
||||||
&page_flip_listener_vtable,
|
&page_flip_listener_vtable,
|
||||||
META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE,
|
META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE,
|
||||||
|
NULL,
|
||||||
&data,
|
&data,
|
||||||
page_flip_data_destroy);
|
page_flip_data_destroy);
|
||||||
|
|
||||||
@ -375,6 +376,7 @@ meta_test_kms_update_page_flip (void)
|
|||||||
meta_kms_update_add_page_flip_listener (update, crtc,
|
meta_kms_update_add_page_flip_listener (update, crtc,
|
||||||
&page_flip_listener_vtable,
|
&page_flip_listener_vtable,
|
||||||
META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE,
|
META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE,
|
||||||
|
NULL,
|
||||||
&data,
|
&data,
|
||||||
page_flip_data_destroy);
|
page_flip_data_destroy);
|
||||||
|
|
||||||
@ -594,6 +596,132 @@ meta_test_kms_update_merge (void)
|
|||||||
meta_kms_update_free (update1);
|
meta_kms_update_free (update1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _ThreadData
|
||||||
|
{
|
||||||
|
GMutex init_mutex;
|
||||||
|
GMainContext *main_context;
|
||||||
|
GMainLoop *main_thread_loop;
|
||||||
|
GThread *thread;
|
||||||
|
} ThreadData;
|
||||||
|
|
||||||
|
static gpointer
|
||||||
|
off_thread_page_flip_thread_func (gpointer user_data)
|
||||||
|
{
|
||||||
|
ThreadData *data = user_data;
|
||||||
|
MetaKmsDevice *device;
|
||||||
|
MetaKms *kms;
|
||||||
|
MetaKmsUpdate *update;
|
||||||
|
MetaKmsCrtc *crtc;
|
||||||
|
MetaKmsConnector *connector;
|
||||||
|
MetaKmsMode *mode;
|
||||||
|
g_autoptr (MetaDrmBuffer) primary_buffer1 = NULL;
|
||||||
|
g_autoptr (MetaDrmBuffer) primary_buffer2 = NULL;
|
||||||
|
MetaKmsPlane *primary_plane;
|
||||||
|
PageFlipData page_flip_data = {};
|
||||||
|
MetaKmsFeedback *feedback;
|
||||||
|
|
||||||
|
g_mutex_lock (&data->init_mutex);
|
||||||
|
g_mutex_unlock (&data->init_mutex);
|
||||||
|
|
||||||
|
device = meta_get_test_kms_device (test_context);
|
||||||
|
kms = meta_kms_device_get_kms (device);
|
||||||
|
crtc = meta_get_test_kms_crtc (device);
|
||||||
|
connector = meta_get_test_kms_connector (device);
|
||||||
|
mode = meta_kms_connector_get_preferred_mode (connector);
|
||||||
|
|
||||||
|
meta_thread_register_callback_context (META_THREAD (kms),
|
||||||
|
data->main_context);
|
||||||
|
|
||||||
|
update = meta_kms_update_new (device);
|
||||||
|
|
||||||
|
meta_kms_update_mode_set (update, crtc,
|
||||||
|
g_list_append (NULL, connector),
|
||||||
|
mode);
|
||||||
|
|
||||||
|
primary_buffer1 = meta_create_test_mode_dumb_buffer (device, mode);
|
||||||
|
|
||||||
|
primary_plane = meta_kms_device_get_primary_plane_for (device, crtc);
|
||||||
|
meta_kms_update_assign_plane (update,
|
||||||
|
crtc,
|
||||||
|
primary_plane,
|
||||||
|
primary_buffer1,
|
||||||
|
meta_get_mode_fixed_rect_16 (mode),
|
||||||
|
meta_get_mode_rect (mode),
|
||||||
|
META_KMS_ASSIGN_PLANE_FLAG_NONE);
|
||||||
|
|
||||||
|
page_flip_data.loop = g_main_loop_new (data->main_context, FALSE);
|
||||||
|
page_flip_data.thread = g_thread_self ();
|
||||||
|
meta_kms_update_add_page_flip_listener (update, crtc,
|
||||||
|
&page_flip_listener_vtable,
|
||||||
|
META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE,
|
||||||
|
data->main_context,
|
||||||
|
&page_flip_data,
|
||||||
|
page_flip_data_destroy);
|
||||||
|
|
||||||
|
feedback =
|
||||||
|
meta_kms_device_process_update_sync (device, update,
|
||||||
|
META_KMS_UPDATE_FLAG_NONE);
|
||||||
|
meta_kms_feedback_unref (feedback);
|
||||||
|
|
||||||
|
g_main_loop_run (page_flip_data.loop);
|
||||||
|
g_assert_cmpint (page_flip_data.state, ==, DESTROYED);
|
||||||
|
|
||||||
|
page_flip_data.state = INIT;
|
||||||
|
update = meta_kms_update_new (device);
|
||||||
|
primary_buffer2 = meta_create_test_mode_dumb_buffer (device, mode);
|
||||||
|
meta_kms_update_assign_plane (update,
|
||||||
|
crtc,
|
||||||
|
primary_plane,
|
||||||
|
primary_buffer2,
|
||||||
|
meta_get_mode_fixed_rect_16 (mode),
|
||||||
|
meta_get_mode_rect (mode),
|
||||||
|
META_KMS_ASSIGN_PLANE_FLAG_NONE);
|
||||||
|
meta_kms_update_add_page_flip_listener (update, crtc,
|
||||||
|
&page_flip_listener_vtable,
|
||||||
|
META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE,
|
||||||
|
data->main_context,
|
||||||
|
&page_flip_data,
|
||||||
|
page_flip_data_destroy);
|
||||||
|
|
||||||
|
feedback =
|
||||||
|
meta_kms_device_process_update_sync (device, update,
|
||||||
|
META_KMS_UPDATE_FLAG_NONE);
|
||||||
|
meta_kms_feedback_unref (feedback);
|
||||||
|
|
||||||
|
g_main_loop_run (page_flip_data.loop);
|
||||||
|
g_assert_cmpint (page_flip_data.state, ==, DESTROYED);
|
||||||
|
|
||||||
|
g_main_loop_unref (page_flip_data.loop);
|
||||||
|
|
||||||
|
g_main_loop_quit (data->main_thread_loop);
|
||||||
|
|
||||||
|
meta_thread_unregister_callback_context (META_THREAD (kms),
|
||||||
|
data->main_context);
|
||||||
|
|
||||||
|
return GINT_TO_POINTER (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_test_kms_update_off_thread_page_flip (void)
|
||||||
|
{
|
||||||
|
ThreadData data = {};
|
||||||
|
|
||||||
|
g_mutex_init (&data.init_mutex);
|
||||||
|
g_mutex_lock (&data.init_mutex);
|
||||||
|
data.main_context = g_main_context_new ();
|
||||||
|
data.main_thread_loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
data.thread = g_thread_new ("Off-thread page flip test",
|
||||||
|
off_thread_page_flip_thread_func,
|
||||||
|
&data);
|
||||||
|
g_mutex_unlock (&data.init_mutex);
|
||||||
|
|
||||||
|
g_main_loop_run (data.main_thread_loop);
|
||||||
|
g_assert_cmpint (GPOINTER_TO_INT (g_thread_join (data.thread)), ==, TRUE);
|
||||||
|
g_main_loop_unref (data.main_thread_loop);
|
||||||
|
g_main_context_unref (data.main_context);
|
||||||
|
g_mutex_clear (&data.init_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_tests (void)
|
init_tests (void)
|
||||||
{
|
{
|
||||||
@ -609,6 +737,8 @@ init_tests (void)
|
|||||||
meta_test_kms_update_page_flip);
|
meta_test_kms_update_page_flip);
|
||||||
g_test_add_func ("/backends/native/kms/update/merge",
|
g_test_add_func ("/backends/native/kms/update/merge",
|
||||||
meta_test_kms_update_merge);
|
meta_test_kms_update_merge);
|
||||||
|
g_test_add_func ("/backends/native/kms/update/off-thread-page-flip",
|
||||||
|
meta_test_kms_update_off_thread_page_flip);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
Loading…
Reference in New Issue
Block a user