kms/update: Make explicit page flip just listeners

Page flipping shouldn't necessarily be an actively requested action, but
happen implicitly depending on the given state. Thus, change the "page
flip" update into adding listeners for page flip feedback instead.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
This commit is contained in:
Jonas Ådahl 2020-10-02 16:06:35 +02:00 committed by Marge Bot
parent 0acae7f3c1
commit 5c7e2bfe22
8 changed files with 195 additions and 70 deletions

View File

@ -633,7 +633,6 @@ mode_set_fallback_feedback_idle (gpointer user_data)
static gboolean
mode_set_fallback (MetaKmsImplDeviceSimple *impl_device_simple,
MetaKmsUpdate *update,
MetaKmsPageFlip *page_flip,
MetaKmsPlaneAssignment *plane_assignment,
MetaKmsPageFlipData *page_flip_data,
GError **error)
@ -641,7 +640,7 @@ mode_set_fallback (MetaKmsImplDeviceSimple *impl_device_simple,
MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (impl_device_simple);
MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device);
MetaKms *kms = meta_kms_device_get_kms (device);
MetaKmsCrtc *crtc = page_flip->crtc;
MetaKmsCrtc *crtc = meta_kms_page_flip_data_get_crtc (page_flip_data);
CachedModeSet *cached_mode_set;
g_autofree uint32_t *connectors = NULL;
int n_connectors;
@ -704,31 +703,24 @@ mode_set_fallback (MetaKmsImplDeviceSimple *impl_device_simple,
}
static gboolean
process_page_flip (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update,
gpointer update_entry,
GError **error)
dispatch_page_flip (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update,
MetaKmsPageFlipData *page_flip_data,
GError **error)
{
MetaKmsImplDeviceSimple *impl_device_simple =
META_KMS_IMPL_DEVICE_SIMPLE (impl_device);
MetaKmsPageFlip *page_flip = update_entry;
MetaKmsCrtc *crtc;
MetaKmsPlaneAssignment *plane_assignment;
MetaKmsPageFlipData *page_flip_data;
MetaKmsCustomPageFlipFunc custom_page_flip_func;
gpointer custom_page_flip_user_data;
int fd;
int ret;
crtc = page_flip->crtc;
crtc = meta_kms_page_flip_data_get_crtc (page_flip_data);
plane_assignment = meta_kms_update_get_primary_plane_assignment (update,
crtc);
page_flip_data = meta_kms_page_flip_data_new (impl_device,
crtc,
page_flip->feedback,
page_flip->user_data);
fd = meta_kms_impl_device_get_fd (impl_device);
meta_kms_update_get_custom_page_flip_func (update,
&custom_page_flip_func,
@ -791,7 +783,6 @@ process_page_flip (MetaKmsImplDevice *impl_device,
{
if (!mode_set_fallback (impl_device_simple,
update,
page_flip,
plane_assignment,
page_flip_data,
error))
@ -814,6 +805,95 @@ process_page_flip (MetaKmsImplDevice *impl_device,
return TRUE;
}
static GList *
generate_page_flip_datas (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update)
{
GList *listeners;
GList *page_flip_datas = NULL;
listeners = g_list_copy (meta_kms_update_get_page_flip_listeners (update));
while (listeners)
{
MetaKmsPageFlipListener *listener = listeners->data;
MetaKmsCrtc *crtc = listener->crtc;
MetaKmsPageFlipData *page_flip_data;
GList *l;
page_flip_data = meta_kms_page_flip_data_new (impl_device, crtc);
page_flip_datas = g_list_append (page_flip_datas, page_flip_data);
meta_kms_page_flip_data_add_listener (page_flip_data,
listener->vtable,
listener->user_data);
listeners = g_list_delete_link (listeners, listeners);
l = listeners;
while (l)
{
MetaKmsPageFlipListener *other_listener = l->data;
GList *l_next = l->next;
if (other_listener->crtc == crtc)
{
meta_kms_page_flip_data_add_listener (page_flip_data,
other_listener->vtable,
other_listener->user_data);
listeners = g_list_delete_link (listeners, l);
}
l = l_next;
}
}
return page_flip_datas;
}
static gboolean
maybe_dispatch_page_flips (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update,
GList **failed_planes,
GError **error)
{
g_autoptr (GList) page_flip_datas = NULL;
GList *l;
page_flip_datas = generate_page_flip_datas (impl_device, update);
for (l = page_flip_datas; l; l = l->next)
{
MetaKmsPageFlipData *page_flip_data = l->data;
if (!dispatch_page_flip (impl_device, update, page_flip_data, error))
{
if (!g_error_matches (*error,
G_IO_ERROR,
G_IO_ERROR_PERMISSION_DENIED))
{
MetaKmsCrtc *crtc =
meta_kms_page_flip_data_get_crtc (page_flip_data);
MetaKmsPlaneAssignment *plane_assignment;
MetaKmsPlaneFeedback *plane_feedback;
plane_assignment =
meta_kms_update_get_primary_plane_assignment (update, crtc);
plane_feedback =
meta_kms_plane_feedback_new_take_error (plane_assignment->plane,
plane_assignment->crtc,
g_error_copy (*error));
*failed_planes = g_list_prepend (*failed_planes, plane_feedback);
}
return FALSE;
}
}
return TRUE;
}
static gboolean
process_entries (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update,
@ -1023,11 +1103,7 @@ meta_kms_impl_device_simple_process_update (MetaKmsImplDevice *impl_device,
if (!process_plane_assignments (impl_device, update, &failed_planes, &error))
goto err;
if (!process_entries (impl_device,
update,
meta_kms_update_get_page_flips (update),
process_page_flip,
&error))
if (!maybe_dispatch_page_flips (impl_device, update, &failed_planes, &error))
goto err;
return meta_kms_feedback_new_passed (failed_planes);

View File

@ -28,17 +28,21 @@ typedef struct _MetaKmsPageFlipData MetaKmsPageFlipData;
typedef void (* MetaPageFlipDataFeedbackFunc) (MetaKmsPageFlipData *page_flip_data);
MetaKmsPageFlipData * meta_kms_page_flip_data_new (MetaKmsImplDevice *impl_device,
MetaKmsCrtc *crtc,
const MetaKmsPageFlipFeedback *feedback,
gpointer user_data);
MetaKmsPageFlipData * meta_kms_page_flip_data_new (MetaKmsImplDevice *impl_device,
MetaKmsCrtc *crtc);
MetaKmsPageFlipData * meta_kms_page_flip_data_ref (MetaKmsPageFlipData *page_flip_data);
void meta_kms_page_flip_data_unref (MetaKmsPageFlipData *page_flip_data);
void meta_kms_page_flip_data_add_listener (MetaKmsPageFlipData *page_flip_data,
const MetaKmsPageFlipListenerVtable *vtable,
gpointer user_data);
MetaKmsImplDevice * meta_kms_page_flip_data_get_impl_device (MetaKmsPageFlipData *page_flip_data);
MetaKmsCrtc * meta_kms_page_flip_data_get_crtc (MetaKmsPageFlipData *page_flip_data);
void meta_kms_page_flip_data_set_timings_in_impl (MetaKmsPageFlipData *page_flip_data,
unsigned int sequence,
unsigned int sec,

View File

@ -25,6 +25,12 @@
#include "backends/native/meta-kms-private.h"
#include "backends/native/meta-kms-update.h"
typedef struct _MetaKmsPageFlipClosure
{
const MetaKmsPageFlipListenerVtable *vtable;
gpointer user_data;
} MetaKmsPageFlipClosure;
struct _MetaKmsPageFlipData
{
int ref_count;
@ -32,8 +38,7 @@ struct _MetaKmsPageFlipData
MetaKmsImplDevice *impl_device;
MetaKmsCrtc *crtc;
const MetaKmsPageFlipFeedback *feedback;
gpointer user_data;
GList *closures;
unsigned int sequence;
unsigned int sec;
@ -43,10 +48,8 @@ struct _MetaKmsPageFlipData
};
MetaKmsPageFlipData *
meta_kms_page_flip_data_new (MetaKmsImplDevice *impl_device,
MetaKmsCrtc *crtc,
const MetaKmsPageFlipFeedback *feedback,
gpointer user_data)
meta_kms_page_flip_data_new (MetaKmsImplDevice *impl_device,
MetaKmsCrtc *crtc)
{
MetaKmsPageFlipData *page_flip_data;
@ -55,8 +58,6 @@ meta_kms_page_flip_data_new (MetaKmsImplDevice *impl_device,
.ref_count = 1,
.impl_device = impl_device,
.crtc = crtc,
.feedback = feedback,
.user_data = user_data,
};
return page_flip_data;
@ -77,30 +78,59 @@ meta_kms_page_flip_data_unref (MetaKmsPageFlipData *page_flip_data)
if (page_flip_data->ref_count == 0)
{
g_list_free_full (page_flip_data->closures, g_free);
g_clear_error (&page_flip_data->error);
g_free (page_flip_data);
}
}
void
meta_kms_page_flip_data_add_listener (MetaKmsPageFlipData *page_flip_data,
const MetaKmsPageFlipListenerVtable *vtable,
gpointer user_data)
{
MetaKmsPageFlipClosure *closure;
closure = g_new0 (MetaKmsPageFlipClosure, 1);
*closure = (MetaKmsPageFlipClosure) {
.vtable = vtable,
.user_data = user_data,
};
page_flip_data->closures = g_list_append (page_flip_data->closures, closure);
}
MetaKmsImplDevice *
meta_kms_page_flip_data_get_impl_device (MetaKmsPageFlipData *page_flip_data)
{
return page_flip_data->impl_device;
}
MetaKmsCrtc *
meta_kms_page_flip_data_get_crtc (MetaKmsPageFlipData *page_flip_data)
{
return page_flip_data->crtc;
}
static void
meta_kms_page_flip_data_flipped (MetaKms *kms,
gpointer user_data)
{
MetaKmsPageFlipData *page_flip_data = user_data;
GList *l;
meta_assert_not_in_kms_impl (kms);
page_flip_data->feedback->flipped (page_flip_data->crtc,
page_flip_data->sequence,
page_flip_data->sec,
page_flip_data->usec,
page_flip_data->user_data);
for (l = page_flip_data->closures; l; l = l->next)
{
MetaKmsPageFlipClosure *closure = l->data;
closure->vtable->flipped (page_flip_data->crtc,
page_flip_data->sequence,
page_flip_data->sec,
page_flip_data->usec,
closure->user_data);
}
}
static MetaKms *
@ -144,11 +174,17 @@ meta_kms_page_flip_data_mode_set_fallback (MetaKms *kms,
gpointer user_data)
{
MetaKmsPageFlipData *page_flip_data = user_data;
GList *l;
meta_assert_not_in_kms_impl (kms);
page_flip_data->feedback->mode_set_fallback (page_flip_data->crtc,
page_flip_data->user_data);
for (l = page_flip_data->closures; l; l = l->next)
{
MetaKmsPageFlipClosure *closure = l->data;
closure->vtable->mode_set_fallback (page_flip_data->crtc,
closure->user_data);
}
}
void
@ -169,12 +205,18 @@ meta_kms_page_flip_data_discard (MetaKms *kms,
gpointer user_data)
{
MetaKmsPageFlipData *page_flip_data = user_data;
GList *l;
meta_assert_not_in_kms_impl (kms);
page_flip_data->feedback->discarded (page_flip_data->crtc,
page_flip_data->user_data,
page_flip_data->error);
for (l = page_flip_data->closures; l; l = l->next)
{
MetaKmsPageFlipClosure *closure = l->data;
closure->vtable->discarded (page_flip_data->crtc,
closure->user_data,
page_flip_data->error);
}
}
void

View File

@ -37,7 +37,7 @@ typedef struct _MetaKmsMode MetaKmsMode;
typedef struct _MetaKmsFeedback MetaKmsFeedback;
typedef struct _MetaKmsPageFlipFeedback MetaKmsPageFlipFeedback;
typedef struct _MetaKmsPageFlipListenerVtable MetaKmsPageFlipListenerVtable;
typedef struct _MetaKmsImpl MetaKmsImpl;
typedef struct _MetaKmsImplDevice MetaKmsImplDevice;

View File

@ -86,12 +86,12 @@ typedef struct _MetaKmsCrtcGamma
uint16_t *blue;
} MetaKmsCrtcGamma;
typedef struct _MetaKmsPageFlip
typedef struct _MetaKmsPageFlipListener
{
MetaKmsCrtc *crtc;
const MetaKmsPageFlipFeedback *feedback;
const MetaKmsPageFlipListenerVtable *vtable;
gpointer user_data;
} MetaKmsPageFlip;
} MetaKmsPageFlipListener;
void meta_kms_plane_feedback_free (MetaKmsPlaneFeedback *plane_feedback);
@ -120,7 +120,7 @@ GList * meta_kms_update_get_plane_assignments (MetaKmsUpdate *update);
GList * meta_kms_update_get_mode_sets (MetaKmsUpdate *update);
GList * meta_kms_update_get_page_flips (MetaKmsUpdate *update);
GList * meta_kms_update_get_page_flip_listeners (MetaKmsUpdate *update);
GList * meta_kms_update_get_connector_updates (MetaKmsUpdate *update);

View File

@ -37,12 +37,13 @@ struct _MetaKmsUpdate
MetaPowerSave power_save;
GList *mode_sets;
GList *plane_assignments;
GList *page_flips;
GList *connector_updates;
GList *crtc_gammas;
MetaKmsCustomPageFlipFunc custom_page_flip_func;
gpointer custom_page_flip_user_data;
GList *page_flip_listeners;
};
void
@ -326,24 +327,25 @@ meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update,
}
void
meta_kms_update_page_flip (MetaKmsUpdate *update,
MetaKmsCrtc *crtc,
const MetaKmsPageFlipFeedback *feedback,
gpointer user_data)
meta_kms_update_add_page_flip_listener (MetaKmsUpdate *update,
MetaKmsCrtc *crtc,
const MetaKmsPageFlipListenerVtable *vtable,
gpointer user_data)
{
MetaKmsPageFlip *page_flip;
MetaKmsPageFlipListener *listener;
g_assert (!meta_kms_update_is_sealed (update));
g_assert (meta_kms_crtc_get_device (crtc) == update->device);
page_flip = g_new0 (MetaKmsPageFlip, 1);
*page_flip = (MetaKmsPageFlip) {
listener = g_new0 (MetaKmsPageFlipListener, 1);
*listener = (MetaKmsPageFlipListener) {
.crtc = crtc,
.feedback = feedback,
.vtable = vtable,
.user_data = user_data,
};
update->page_flips = g_list_prepend (update->page_flips, page_flip);
update->page_flip_listeners = g_list_prepend (update->page_flip_listeners,
listener);
}
void
@ -407,9 +409,9 @@ meta_kms_update_get_mode_sets (MetaKmsUpdate *update)
}
GList *
meta_kms_update_get_page_flips (MetaKmsUpdate *update)
meta_kms_update_get_page_flip_listeners (MetaKmsUpdate *update)
{
return update->page_flips;
return update->page_flip_listeners;
}
GList *
@ -469,7 +471,7 @@ meta_kms_update_free (MetaKmsUpdate *update)
(GDestroyNotify) meta_kms_plane_assignment_free);
g_list_free_full (update->mode_sets,
(GDestroyNotify) meta_kms_mode_set_free);
g_list_free_full (update->page_flips, g_free);
g_list_free_full (update->page_flip_listeners, g_free);
g_list_free_full (update->connector_updates, g_free);
g_list_free_full (update->crtc_gammas, (GDestroyNotify) meta_kms_crtc_gamma_free);

View File

@ -43,7 +43,7 @@ typedef enum _MetaKmsAssignPlaneFlag
META_KMS_ASSIGN_PLANE_FLAG_ALLOW_FAIL = 1 << 1,
} MetaKmsAssignPlaneFlag;
struct _MetaKmsPageFlipFeedback
struct _MetaKmsPageFlipListenerVtable
{
void (* flipped) (MetaKmsCrtc *crtc,
unsigned int sequence,
@ -117,10 +117,10 @@ MetaKmsPlaneAssignment * meta_kms_update_unassign_plane (MetaKmsUpdate *update,
MetaKmsCrtc *crtc,
MetaKmsPlane *plane);
void meta_kms_update_page_flip (MetaKmsUpdate *update,
MetaKmsCrtc *crtc,
const MetaKmsPageFlipFeedback *feedback,
gpointer user_data);
void meta_kms_update_add_page_flip_listener (MetaKmsUpdate *update,
MetaKmsCrtc *crtc,
const MetaKmsPageFlipListenerVtable *vtable,
gpointer user_data);
void meta_kms_update_set_custom_page_flip (MetaKmsUpdate *update,
MetaKmsCustomPageFlipFunc func,

View File

@ -1160,7 +1160,7 @@ page_flip_feedback_discarded (MetaKmsCrtc *kms_crtc,
g_object_unref (view);
}
static const MetaKmsPageFlipFeedback page_flip_feedback = {
static const MetaKmsPageFlipListenerVtable page_flip_listener_vtable = {
.flipped = page_flip_feedback_flipped,
.mode_set_fallback = page_flip_feedback_mode_set_fallback,
.discarded = page_flip_feedback_discarded,
@ -1259,6 +1259,7 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
MetaRendererNative *renderer_native = onscreen_native->renderer_native;
MetaGpuKms *render_gpu = onscreen_native->render_gpu;
MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
MetaRendererNativeGpuData *renderer_gpu_data;
MetaGpuKms *gpu_kms;
MetaKmsDevice *kms_device;
@ -1301,10 +1302,10 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
#endif
}
meta_kms_update_page_flip (kms_update,
meta_crtc_kms_get_kms_crtc (crtc_kms),
&page_flip_feedback,
g_object_ref (view));
meta_kms_update_add_page_flip_listener (kms_update,
kms_crtc,
&page_flip_listener_vtable,
g_object_ref (view));
}
static void