diff --git a/src/backends/native/meta-kms-impl-device-simple.c b/src/backends/native/meta-kms-impl-device-simple.c index 1b6efa984..e435e2776 100644 --- a/src/backends/native/meta-kms-impl-device-simple.c +++ b/src/backends/native/meta-kms-impl-device-simple.c @@ -703,7 +703,7 @@ schedule_retry_page_flip (MetaKmsImplDeviceSimple *impl_device_simple, *retry_page_flip_data = (RetryPageFlipData) { .crtc = crtc, .fb_id = fb_id, - .page_flip_data = meta_kms_page_flip_data_ref (page_flip_data), + .page_flip_data = page_flip_data, .refresh_rate = refresh_rate, .retry_time_us = retry_time_us, .custom_page_flip_func = custom_page_flip_func, @@ -758,9 +758,7 @@ invoke_page_flip_datas (GList *page_flip_datas, static void clear_page_flip_datas (GList **page_flip_datas) { - g_list_free_full (*page_flip_datas, - (GDestroyNotify) meta_kms_page_flip_data_unref); - *page_flip_datas = NULL; + g_clear_pointer (page_flip_datas, g_list_free); } static gboolean @@ -853,7 +851,7 @@ mode_set_fallback (MetaKmsImplDeviceSimple *impl_device_simple, impl_device_simple->mode_set_fallback_page_flip_datas = g_list_prepend (impl_device_simple->mode_set_fallback_page_flip_datas, - meta_kms_page_flip_data_ref (page_flip_data)); + page_flip_data); return TRUE; } @@ -929,7 +927,7 @@ dispatch_page_flip (MetaKmsImplDevice *impl_device, meta_kms_crtc_get_id (crtc), meta_kms_impl_device_get_path (impl_device)); ret = custom_page_flip_func (custom_page_flip_user_data, - meta_kms_page_flip_data_ref (page_flip_data)); + page_flip_data); } else { @@ -948,12 +946,9 @@ dispatch_page_flip (MetaKmsImplDevice *impl_device, meta_kms_crtc_get_id (crtc), fb_id, DRM_MODE_PAGE_FLIP_EVENT, - meta_kms_page_flip_data_ref (page_flip_data)); + page_flip_data); } - if (ret != 0) - meta_kms_page_flip_data_unref (page_flip_data); - if (ret == -EBUSY) { CachedModeSet *cached_mode_set; @@ -989,7 +984,6 @@ dispatch_page_flip (MetaKmsImplDevice *impl_device, g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Page flip of %u failed, and no mode set available", meta_kms_crtc_get_id (crtc)); - meta_kms_page_flip_data_unref (page_flip_data); return FALSE; } } @@ -1005,10 +999,7 @@ dispatch_page_flip (MetaKmsImplDevice *impl_device, plane_assignment, page_flip_data, error)) - { - meta_kms_page_flip_data_unref (page_flip_data); - return FALSE; - } + return FALSE; } else if (ret != 0) { @@ -1016,11 +1007,9 @@ dispatch_page_flip (MetaKmsImplDevice *impl_device, "drmModePageFlip on CRTC %u failed: %s", meta_kms_crtc_get_id (crtc), g_strerror (-ret)); - meta_kms_page_flip_data_unref (page_flip_data); return FALSE; } - meta_kms_page_flip_data_unref (page_flip_data); return TRUE; } @@ -1038,14 +1027,20 @@ generate_page_flip_datas (MetaKmsImplDevice *impl_device, MetaKmsPageFlipListener *listener = listeners->data; MetaKmsCrtc *crtc = listener->crtc; MetaKmsPageFlipData *page_flip_data; + gpointer user_data; + GDestroyNotify destroy_notify; 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); + user_data = g_steal_pointer (&listener->user_data); + destroy_notify = g_steal_pointer (&listener->destroy_notify); meta_kms_page_flip_data_add_listener (page_flip_data, listener->vtable, - listener->user_data); + listener->flags, + user_data, + destroy_notify); listeners = g_list_delete_link (listeners, listeners); @@ -1057,9 +1052,17 @@ generate_page_flip_datas (MetaKmsImplDevice *impl_device, if (other_listener->crtc == crtc) { + gpointer other_user_data; + GDestroyNotify other_destroy_notify; + + other_user_data = g_steal_pointer (&other_listener->user_data); + other_destroy_notify = + g_steal_pointer (&other_listener->destroy_notify); meta_kms_page_flip_data_add_listener (page_flip_data, other_listener->vtable, - other_listener->user_data); + other_listener->flags, + other_user_data, + other_destroy_notify); listeners = g_list_delete_link (listeners, l); } @@ -1081,9 +1084,14 @@ maybe_dispatch_page_flips (MetaKmsImplDevice *impl_device, page_flip_datas = generate_page_flip_datas (impl_device, update); - for (l = page_flip_datas; l; l = l->next) + while (page_flip_datas) { - MetaKmsPageFlipData *page_flip_data = l->data; + g_autoptr (GList) l = NULL; + MetaKmsPageFlipData *page_flip_data; + + l = page_flip_datas; + page_flip_datas = g_list_remove_link (page_flip_datas, l); + page_flip_data = g_steal_pointer (&l->data); if (!dispatch_page_flip (impl_device, update, page_flip_data, error)) { @@ -1106,11 +1114,24 @@ maybe_dispatch_page_flips (MetaKmsImplDevice *impl_device, *failed_planes = g_list_prepend (*failed_planes, plane_feedback); } - return FALSE; + meta_kms_page_flip_data_discard_in_impl (page_flip_data, *error); + + goto err; } } return TRUE; + +err: + for (l = page_flip_datas; l; l = l->next) + { + MetaKmsPageFlipData *page_flip_data = l->data; + + meta_kms_page_flip_data_discard_in_impl (page_flip_data, *error); + } + g_list_free (page_flip_datas); + + return FALSE; } static gboolean @@ -1417,14 +1438,12 @@ meta_kms_impl_device_simple_handle_page_flip_callback (MetaKmsImplDevice *impl { impl_device_simple->postponed_page_flip_datas = g_list_append (impl_device_simple->postponed_page_flip_datas, - meta_kms_page_flip_data_ref (page_flip_data)); + page_flip_data); } else { meta_kms_page_flip_data_flipped_in_impl (page_flip_data); } - - meta_kms_page_flip_data_unref (page_flip_data); } static void @@ -1469,9 +1488,9 @@ meta_kms_impl_device_simple_finalize (GObject *object) g_list_free_full (impl_device_simple->pending_page_flip_retries, (GDestroyNotify) retry_page_flip_data_free); g_list_free_full (impl_device_simple->postponed_page_flip_datas, - (GDestroyNotify) meta_kms_page_flip_data_unref); + (GDestroyNotify) meta_kms_page_flip_data_discard_in_impl); g_list_free_full (impl_device_simple->postponed_mode_set_fallback_datas, - (GDestroyNotify) meta_kms_page_flip_data_unref); + (GDestroyNotify) meta_kms_page_flip_data_discard_in_impl); g_clear_pointer (&impl_device_simple->mode_set_fallback_feedback_source, g_source_destroy); diff --git a/src/backends/native/meta-kms-page-flip-private.h b/src/backends/native/meta-kms-page-flip-private.h index 1aed388f8..b23272ad9 100644 --- a/src/backends/native/meta-kms-page-flip-private.h +++ b/src/backends/native/meta-kms-page-flip-private.h @@ -37,7 +37,9 @@ 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); + MetaKmsPageFlipListenerFlag flags, + gpointer user_data, + GDestroyNotify destroy_notify); MetaKmsImplDevice * meta_kms_page_flip_data_get_impl_device (MetaKmsPageFlipData *page_flip_data); diff --git a/src/backends/native/meta-kms-page-flip.c b/src/backends/native/meta-kms-page-flip.c index a3221c911..130fba06c 100644 --- a/src/backends/native/meta-kms-page-flip.c +++ b/src/backends/native/meta-kms-page-flip.c @@ -28,7 +28,9 @@ typedef struct _MetaKmsPageFlipClosure { const MetaKmsPageFlipListenerVtable *vtable; + MetaKmsPageFlipListenerFlag flags; gpointer user_data; + GDestroyNotify destroy_notify; } MetaKmsPageFlipClosure; struct _MetaKmsPageFlipData @@ -51,14 +53,18 @@ struct _MetaKmsPageFlipData static MetaKmsPageFlipClosure * meta_kms_page_flip_closure_new (const MetaKmsPageFlipListenerVtable *vtable, - gpointer user_data) + MetaKmsPageFlipListenerFlag flags, + gpointer user_data, + GDestroyNotify destroy_notify) { MetaKmsPageFlipClosure *closure; closure = g_new0 (MetaKmsPageFlipClosure, 1); *closure = (MetaKmsPageFlipClosure) { .vtable = vtable, + .flags = flags, .user_data = user_data, + .destroy_notify = destroy_notify, }; return closure; @@ -67,6 +73,7 @@ meta_kms_page_flip_closure_new (const MetaKmsPageFlipListenerVtable *vtable, static void meta_kms_page_flip_closure_free (MetaKmsPageFlipClosure *closure) { + g_clear_pointer (&closure->user_data, closure->destroy_notify); g_free (closure); } @@ -109,11 +116,15 @@ 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) + MetaKmsPageFlipListenerFlag flags, + gpointer user_data, + GDestroyNotify destroy_notify) { MetaKmsPageFlipClosure *closure; - closure = meta_kms_page_flip_closure_new (vtable, user_data); + closure = meta_kms_page_flip_closure_new (vtable, flags, + user_data, + destroy_notify); page_flip_data->closures = g_list_append (page_flip_data->closures, closure); } @@ -196,7 +207,7 @@ meta_kms_page_flip_data_flipped_in_impl (MetaKmsPageFlipData *page_flip_data) meta_kms_queue_callback (kms, meta_kms_page_flip_data_flipped, - meta_kms_page_flip_data_ref (page_flip_data), + page_flip_data, (GDestroyNotify) meta_kms_page_flip_data_unref); } @@ -227,7 +238,7 @@ meta_kms_page_flip_data_mode_set_fallback_in_impl (MetaKmsPageFlipData *page_fli meta_kms_queue_callback (kms, meta_kms_page_flip_data_mode_set_fallback, - meta_kms_page_flip_data_ref (page_flip_data), + page_flip_data, (GDestroyNotify) meta_kms_page_flip_data_unref); } @@ -244,6 +255,9 @@ meta_kms_page_flip_data_discard (MetaKms *kms, { MetaKmsPageFlipClosure *closure = l->data; + if (closure->flags & META_KMS_PAGE_FLIP_LISTENER_FLAG_NO_DISCARD) + continue; + closure->vtable->discarded (page_flip_data->crtc, closure->user_data, page_flip_data->error); @@ -272,6 +286,6 @@ meta_kms_page_flip_data_discard_in_impl (MetaKmsPageFlipData *page_flip_data, meta_kms_queue_callback (kms, meta_kms_page_flip_data_discard, - meta_kms_page_flip_data_ref (page_flip_data), + page_flip_data, (GDestroyNotify) meta_kms_page_flip_data_unref); } diff --git a/src/backends/native/meta-kms-types.h b/src/backends/native/meta-kms-types.h index 7cfd79ad9..cf1adc44e 100644 --- a/src/backends/native/meta-kms-types.h +++ b/src/backends/native/meta-kms-types.h @@ -38,6 +38,7 @@ typedef struct _MetaKmsMode MetaKmsMode; typedef struct _MetaKmsFeedback MetaKmsFeedback; typedef struct _MetaKmsPageFlipListenerVtable MetaKmsPageFlipListenerVtable; +typedef enum _MetaKmsPageFlipListenerFlag MetaKmsPageFlipListenerFlag; typedef struct _MetaKmsImpl MetaKmsImpl; typedef struct _MetaKmsImplDevice MetaKmsImplDevice; diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h index 6546eb915..d3f298d5e 100644 --- a/src/backends/native/meta-kms-update-private.h +++ b/src/backends/native/meta-kms-update-private.h @@ -76,7 +76,9 @@ typedef struct _MetaKmsPageFlipListener { MetaKmsCrtc *crtc; const MetaKmsPageFlipListenerVtable *vtable; + MetaKmsPageFlipListenerFlag flags; gpointer user_data; + GDestroyNotify destroy_notify; } MetaKmsPageFlipListener; typedef struct _MetaKmsResultListener diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c index 36c1761c3..427a5b009 100644 --- a/src/backends/native/meta-kms-update.c +++ b/src/backends/native/meta-kms-update.c @@ -143,6 +143,13 @@ meta_kms_mode_set_free (MetaKmsModeSet *mode_set) g_free (mode_set); } +static void +meta_kms_page_flip_listener_free (MetaKmsPageFlipListener *listener) +{ + g_clear_pointer (&listener->user_data, listener->destroy_notify); + g_free (listener); +} + static gboolean drop_plane_assignment (MetaKmsUpdate *update, MetaKmsPlane *plane, @@ -389,7 +396,9 @@ void meta_kms_update_add_page_flip_listener (MetaKmsUpdate *update, MetaKmsCrtc *crtc, const MetaKmsPageFlipListenerVtable *vtable, - gpointer user_data) + MetaKmsPageFlipListenerFlag flags, + gpointer user_data, + GDestroyNotify destroy_notify) { MetaKmsPageFlipListener *listener; @@ -400,7 +409,9 @@ meta_kms_update_add_page_flip_listener (MetaKmsUpdate *upd *listener = (MetaKmsPageFlipListener) { .crtc = crtc, .vtable = vtable, + .flags = flags, .user_data = user_data, + .destroy_notify = destroy_notify, }; update->page_flip_listeners = g_list_prepend (update->page_flip_listeners, @@ -595,7 +606,8 @@ 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_flip_listeners, g_free); + g_list_free_full (update->page_flip_listeners, + (GDestroyNotify) meta_kms_page_flip_listener_free); g_list_free_full (update->connector_updates, g_free); g_list_free_full (update->crtc_gammas, (GDestroyNotify) meta_kms_crtc_gamma_free); diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h index 6438ff99b..98fb8088f 100644 --- a/src/backends/native/meta-kms-update.h +++ b/src/backends/native/meta-kms-update.h @@ -43,6 +43,12 @@ typedef enum _MetaKmsAssignPlaneFlag META_KMS_ASSIGN_PLANE_FLAG_ALLOW_FAIL = 1 << 1, } MetaKmsAssignPlaneFlag; +enum _MetaKmsPageFlipListenerFlag +{ + META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE = 0, + META_KMS_PAGE_FLIP_LISTENER_FLAG_NO_DISCARD = 1 << 0, +}; + struct _MetaKmsPageFlipListenerVtable { void (* flipped) (MetaKmsCrtc *crtc, @@ -124,7 +130,9 @@ MetaKmsPlaneAssignment * meta_kms_update_unassign_plane (MetaKmsUpdate *update, void meta_kms_update_add_page_flip_listener (MetaKmsUpdate *update, MetaKmsCrtc *crtc, const MetaKmsPageFlipListenerVtable *vtable, - gpointer user_data); + MetaKmsPageFlipListenerFlag flags, + gpointer user_data, + GDestroyNotify destroy_notify); void meta_kms_update_set_custom_page_flip (MetaKmsUpdate *update, MetaKmsCustomPageFlipFunc func, diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index 5c3fe4980..85ba1d998 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -1111,8 +1111,6 @@ page_flip_feedback_flipped (MetaKmsCrtc *kms_crtc, notify_view_crtc_presented (view, kms_crtc, timeval_to_nanoseconds (&page_flip_time)); - - g_object_unref (view); } static void @@ -1129,8 +1127,6 @@ page_flip_feedback_ready (MetaKmsCrtc *kms_crtc, frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC; meta_onscreen_native_notify_frame_complete (onscreen); - - g_object_unref (view); } static void @@ -1152,8 +1148,6 @@ page_flip_feedback_mode_set_fallback (MetaKmsCrtc *kms_crtc, now_ns = meta_gpu_kms_get_current_time_ns (gpu_kms); notify_view_crtc_presented (view, kms_crtc, now_ns); - - g_object_unref (view); } static void @@ -1171,7 +1165,10 @@ page_flip_feedback_discarded (MetaKmsCrtc *kms_crtc, * the frame clack, pretend we flipped. */ - if (error) + if (error && + !g_error_matches (error, + G_IO_ERROR, + G_IO_ERROR_PERMISSION_DENIED)) g_warning ("Page flip discarded: %s", error->message); crtc = META_CRTC (meta_crtc_kms_from_kms_crtc (kms_crtc)); @@ -1179,8 +1176,6 @@ page_flip_feedback_discarded (MetaKmsCrtc *kms_crtc, now_ns = meta_gpu_kms_get_current_time_ns (gpu_kms); notify_view_crtc_presented (view, kms_crtc, now_ns); - - g_object_unref (view); } static const MetaKmsPageFlipListenerVtable page_flip_listener_vtable = { @@ -1279,9 +1274,10 @@ queue_dummy_power_save_page_flip (CoglOnscreen *onscreen) } static void -meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, - MetaRendererView *view, - MetaCrtc *crtc) +meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, + MetaRendererView *view, + MetaCrtc *crtc, + MetaKmsPageFlipListenerFlag flags) { CoglOnscreenEGL *onscreen_egl = onscreen->winsys; MetaOnscreenNative *onscreen_native = onscreen_egl->platform; @@ -1297,6 +1293,9 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state = NULL; MetaDrmBuffer *buffer; + COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeFlipCrtcs, + "Onscreen (flip CRTCs)"); + gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc)); kms_device = meta_gpu_kms_get_kms_device (gpu_kms); kms = meta_kms_device_get_kms (kms_device); @@ -1334,7 +1333,9 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, meta_kms_update_add_page_flip_listener (kms_update, kms_crtc, &page_flip_listener_vtable, - g_object_ref (view)); + flags, + g_object_ref (view), + g_object_unref); } static void @@ -1375,19 +1376,6 @@ meta_onscreen_native_set_crtc_mode (CoglOnscreen *onscreen, kms_update); } -static void -meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen) -{ - CoglOnscreenEGL *onscreen_egl = onscreen->winsys; - MetaOnscreenNative *onscreen_native = onscreen_egl->platform; - MetaRendererView *view = onscreen_native->view; - - COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeFlipCrtcs, - "Onscreen (flip CRTCs)"); - - meta_onscreen_native_flip_crtc (onscreen, view, onscreen_native->crtc); -} - static gboolean import_shared_framebuffer (CoglOnscreen *onscreen, MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state) @@ -1903,19 +1891,6 @@ ensure_crtc_modes (CoglOnscreen *onscreen) } } -static MetaKmsCrtc * -kms_crtc_from_view (MetaRendererView *view) -{ - CoglFramebuffer *framebuffer = - clutter_stage_view_get_onscreen (CLUTTER_STAGE_VIEW (view)); - CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); - CoglOnscreenEGL *onscreen_egl = onscreen->winsys; - MetaOnscreenNative *onscreen_native = onscreen_egl->platform; - MetaCrtcKms *crtc_kms = META_CRTC_KMS (onscreen_native->crtc); - - return meta_crtc_kms_get_kms_crtc (crtc_kms); -} - static MetaKmsDevice * kms_device_from_view (MetaRendererView *view) { @@ -1942,41 +1917,6 @@ gpu_from_view (MetaRendererView *view) return meta_crtc_get_gpu (onscreen_native->crtc); } -typedef struct -{ - MetaRendererNative *renderer_native; - GList *failed_views; -} DispatchFailedModeSetViews; - -static gboolean -dispatch_failed_mode_set_views_cb (gpointer user_data) -{ - DispatchFailedModeSetViews *data = user_data; - GList *l; - - for (l = data->failed_views; l; l = l->next) - { - MetaRendererView *view = l->data; - int64_t now_us; - - now_us = g_get_monotonic_time (); - notify_view_crtc_presented (view, - kms_crtc_from_view (view), - us2ns (now_us)); - } - - data->renderer_native->mode_set_failed_feedback_source_id = 0; - - return G_SOURCE_REMOVE; -} - -static void -dispatch_failed_mode_data_free (DispatchFailedModeSetViews *data) -{ - g_list_free (data->failed_views); - g_free (data); -} - static void configure_disabled_crtcs (MetaGpu *gpu, MetaKmsUpdate *kms_update) @@ -2014,7 +1954,6 @@ meta_renderer_native_post_mode_set_updates (MetaRendererNative *renderer_native) MetaBackend *backend = meta_renderer_get_backend (renderer); MetaKms *kms = meta_backend_native_get_kms (META_BACKEND_NATIVE (backend)); GList *l; - GList *failed_views = NULL; for (l = meta_renderer_get_views (renderer); l; l = l->next) { @@ -2023,6 +1962,7 @@ meta_renderer_native_post_mode_set_updates (MetaRendererNative *renderer_native) MetaKmsUpdate *kms_update; MetaKmsUpdateFlag flags; g_autoptr (MetaKmsFeedback) kms_feedback = NULL; + const GError *feedback_error; kms_device = kms_device_from_view (view); @@ -2040,27 +1980,16 @@ meta_renderer_native_post_mode_set_updates (MetaRendererNative *renderer_native) case META_KMS_FEEDBACK_PASSED: break; case META_KMS_FEEDBACK_FAILED: - failed_views = g_list_prepend (failed_views, view); + feedback_error = meta_kms_feedback_get_error (kms_feedback); + if (!g_error_matches (feedback_error, + G_IO_ERROR, + G_IO_ERROR_PERMISSION_DENIED)) + g_warning ("Failed to post KMS update: %s", feedback_error->message); break; } } clear_kept_alive_onscreens (renderer_native); - - if (failed_views) - { - DispatchFailedModeSetViews *data; - - data = g_new0 (DispatchFailedModeSetViews, 1); - data->failed_views = failed_views; - data->renderer_native = renderer_native; - - renderer_native->mode_set_failed_feedback_source_id = - g_idle_add_full (G_PRIORITY_HIGH, - dispatch_failed_mode_set_views_cb, - data, - (GDestroyNotify) dispatch_failed_mode_data_free); - } } static void @@ -2195,7 +2124,10 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, if (power_save_mode == META_POWER_SAVE_ON) { ensure_crtc_modes (onscreen); - meta_onscreen_native_flip_crtcs (onscreen); + meta_onscreen_native_flip_crtc (onscreen, + onscreen_native->view, + onscreen_native->crtc, + META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE); } else { @@ -2275,7 +2207,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, break; case META_KMS_FEEDBACK_FAILED: clutter_frame_set_result (frame, - CLUTTER_FRAME_RESULT_IDLE); + CLUTTER_FRAME_RESULT_PENDING_PRESENTED); feedback_error = meta_kms_feedback_get_error (kms_feedback); if (!g_error_matches (feedback_error, @@ -2467,7 +2399,10 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen, g_set_object (&onscreen_native->gbm.next_fb, META_DRM_BUFFER (scanout)); ensure_crtc_modes (onscreen); - meta_onscreen_native_flip_crtcs (onscreen); + meta_onscreen_native_flip_crtc (onscreen, + onscreen_native->view, + onscreen_native->crtc, + META_KMS_PAGE_FLIP_LISTENER_FLAG_NO_DISCARD); kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (onscreen_native->crtc)); kms_device = meta_kms_crtc_get_device (kms_crtc); @@ -3379,7 +3314,9 @@ meta_renderer_native_finish_frame (MetaRendererNative *renderer_native, meta_kms_update_add_page_flip_listener (kms_update, kms_crtc, &page_flip_listener_vtable, - g_object_ref (view)); + META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE, + g_object_ref (view), + g_object_unref); flags = META_KMS_UPDATE_FLAG_NONE; kms_feedback = meta_kms_post_pending_update_sync (kms, @@ -3394,7 +3331,7 @@ meta_renderer_native_finish_frame (MetaRendererNative *renderer_native, break; case META_KMS_FEEDBACK_FAILED: clutter_frame_set_result (frame, - CLUTTER_FRAME_RESULT_IDLE); + CLUTTER_FRAME_RESULT_PENDING_PRESENTED); error = meta_kms_feedback_get_error (kms_feedback); if (!g_error_matches (error,