diff --git a/src/backends/native/meta-kms-impl-device-atomic.c b/src/backends/native/meta-kms-impl-device-atomic.c index d1f2e7b82..4115b9b05 100644 --- a/src/backends/native/meta-kms-impl-device-atomic.c +++ b/src/backends/native/meta-kms-impl-device-atomic.c @@ -849,7 +849,8 @@ process_power_save (MetaKmsImplDevice *impl_device, static MetaKmsFeedback * meta_kms_impl_device_atomic_process_update (MetaKmsImplDevice *impl_device, - MetaKmsUpdate *update) + MetaKmsUpdate *update, + MetaKmsUpdateFlag flags) { GError *error = NULL; GList *failed_planes = NULL; @@ -973,14 +974,17 @@ commit: err: meta_topic (META_DEBUG_KMS, "[atomic] KMS update failed: %s", error->message); - process_entries (impl_device, - update, - req, - blob_ids, - meta_kms_update_get_page_flip_listeners (update), - error, - discard_page_flip_listener, - NULL); + if (!(flags & META_KMS_UPDATE_FLAG_PRESERVE_ON_ERROR)) + { + process_entries (impl_device, + update, + req, + blob_ids, + meta_kms_update_get_page_flip_listeners (update), + error, + discard_page_flip_listener, + NULL); + } release_blob_ids (impl_device, blob_ids); diff --git a/src/backends/native/meta-kms-impl-device-simple.c b/src/backends/native/meta-kms-impl-device-simple.c index 1519962b8..4f9fe7884 100644 --- a/src/backends/native/meta-kms-impl-device-simple.c +++ b/src/backends/native/meta-kms-impl-device-simple.c @@ -1085,6 +1085,7 @@ static gboolean maybe_dispatch_page_flips (MetaKmsImplDevice *impl_device, MetaKmsUpdate *update, GList **failed_planes, + MetaKmsUpdateFlag flags, GError **error) { g_autoptr (GList) page_flip_datas = NULL; @@ -1122,7 +1123,8 @@ maybe_dispatch_page_flips (MetaKmsImplDevice *impl_device, *failed_planes = g_list_prepend (*failed_planes, plane_feedback); } - meta_kms_page_flip_data_discard_in_impl (page_flip_data, *error); + if (!(flags & META_KMS_UPDATE_FLAG_PRESERVE_ON_ERROR)) + meta_kms_page_flip_data_discard_in_impl (page_flip_data, *error); goto err; } @@ -1131,11 +1133,14 @@ maybe_dispatch_page_flips (MetaKmsImplDevice *impl_device, return TRUE; err: - for (l = page_flip_datas; l; l = l->next) + if (!(flags & META_KMS_UPDATE_FLAG_PRESERVE_ON_ERROR)) { - MetaKmsPageFlipData *page_flip_data = l->data; + 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); + meta_kms_page_flip_data_discard_in_impl (page_flip_data, *error); + } } g_list_free (page_flip_datas); @@ -1375,7 +1380,8 @@ meta_kms_impl_device_simple_setup_drm_event_context (MetaKmsImplDevice *impl_dev static MetaKmsFeedback * meta_kms_impl_device_simple_process_update (MetaKmsImplDevice *impl_device, - MetaKmsUpdate *update) + MetaKmsUpdate *update, + MetaKmsUpdateFlag flags) { GError *error = NULL; GList *failed_planes = NULL; @@ -1415,7 +1421,8 @@ meta_kms_impl_device_simple_process_update (MetaKmsImplDevice *impl_device, if (!process_plane_assignments (impl_device, update, &failed_planes, &error)) goto err; - if (!maybe_dispatch_page_flips (impl_device, update, &failed_planes, &error)) + if (!maybe_dispatch_page_flips (impl_device, update, &failed_planes, flags, + &error)) goto err; out: diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c index 9dc631b57..75920fe6b 100644 --- a/src/backends/native/meta-kms-impl-device.c +++ b/src/backends/native/meta-kms-impl-device.c @@ -651,11 +651,12 @@ meta_kms_impl_device_leak_fd (MetaKmsImplDevice *impl_device) MetaKmsFeedback * meta_kms_impl_device_process_update (MetaKmsImplDevice *impl_device, - MetaKmsUpdate *update) + MetaKmsUpdate *update, + MetaKmsUpdateFlag flags) { MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device); - return klass->process_update (impl_device, update); + return klass->process_update (impl_device, update, flags); } void diff --git a/src/backends/native/meta-kms-impl-device.h b/src/backends/native/meta-kms-impl-device.h index 6e8ec2378..913ba992f 100644 --- a/src/backends/native/meta-kms-impl-device.h +++ b/src/backends/native/meta-kms-impl-device.h @@ -29,6 +29,7 @@ #include "backends/native/meta-kms-page-flip-private.h" #include "backends/native/meta-kms-types.h" #include "backends/native/meta-kms-update.h" +#include "backends/native/meta-kms.h" typedef struct _MetaKmsDeviceCaps { @@ -64,7 +65,8 @@ struct _MetaKmsImplDeviceClass void (* setup_drm_event_context) (MetaKmsImplDevice *impl_device, drmEventContext *drm_event_context); MetaKmsFeedback * (* process_update) (MetaKmsImplDevice *impl_device, - MetaKmsUpdate *update); + MetaKmsUpdate *update, + MetaKmsUpdateFlag flags); void (* handle_page_flip_callback) (MetaKmsImplDevice *impl_device, MetaKmsPageFlipData *page_flip_data); void (* discard_pending_page_flips) (MetaKmsImplDevice *impl_device); @@ -132,7 +134,8 @@ void meta_kms_impl_device_reload_prop_values (MetaKmsImplDevice *impl_device, ...); MetaKmsFeedback * meta_kms_impl_device_process_update (MetaKmsImplDevice *impl_device, - MetaKmsUpdate *update); + MetaKmsUpdate *update, + MetaKmsUpdateFlag flags); void meta_kms_impl_device_handle_page_flip_callback (MetaKmsImplDevice *impl_device, MetaKmsPageFlipData *page_flip_data); diff --git a/src/backends/native/meta-kms-impl.c b/src/backends/native/meta-kms-impl.c index 036a0d783..3a186209c 100644 --- a/src/backends/native/meta-kms-impl.c +++ b/src/backends/native/meta-kms-impl.c @@ -78,8 +78,9 @@ meta_kms_impl_remove_impl_device (MetaKmsImpl *impl, } MetaKmsFeedback * -meta_kms_impl_process_update (MetaKmsImpl *impl, - MetaKmsUpdate *update) +meta_kms_impl_process_update (MetaKmsImpl *impl, + MetaKmsUpdate *update, + MetaKmsUpdateFlag flags) { MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl); MetaKmsDevice *device; @@ -90,7 +91,7 @@ meta_kms_impl_process_update (MetaKmsImpl *impl, device = meta_kms_update_get_device (update); impl_device = meta_kms_device_get_impl_device (device); - return meta_kms_impl_device_process_update (impl_device, update); + return meta_kms_impl_device_process_update (impl_device, update, flags); } void diff --git a/src/backends/native/meta-kms-impl.h b/src/backends/native/meta-kms-impl.h index 723a21cd2..00cf5538d 100644 --- a/src/backends/native/meta-kms-impl.h +++ b/src/backends/native/meta-kms-impl.h @@ -31,8 +31,9 @@ G_DECLARE_FINAL_TYPE (MetaKmsImpl, meta_kms_impl, MetaKms * meta_kms_impl_get_kms (MetaKmsImpl *impl); -MetaKmsFeedback * meta_kms_impl_process_update (MetaKmsImpl *impl, - MetaKmsUpdate *update); +MetaKmsFeedback * meta_kms_impl_process_update (MetaKmsImpl *impl, + MetaKmsUpdate *update, + MetaKmsUpdateFlag flags); void meta_kms_impl_add_impl_device (MetaKmsImpl *impl, MetaKmsImplDevice *impl_device); diff --git a/src/backends/native/meta-kms-page-flip.c b/src/backends/native/meta-kms-page-flip.c index 130fba06c..817f4e7c8 100644 --- a/src/backends/native/meta-kms-page-flip.c +++ b/src/backends/native/meta-kms-page-flip.c @@ -255,9 +255,6 @@ 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); diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h index 1954c7a78..22491ece2 100644 --- a/src/backends/native/meta-kms-update-private.h +++ b/src/backends/native/meta-kms-update-private.h @@ -126,6 +126,8 @@ GList * meta_kms_update_get_mode_sets (MetaKmsUpdate *update); GList * meta_kms_update_get_page_flip_listeners (MetaKmsUpdate *update); +void meta_kms_update_drop_defunct_page_flip_listeners (MetaKmsUpdate *update); + GList * meta_kms_update_get_connector_updates (MetaKmsUpdate *update); GList * meta_kms_update_get_crtc_gammas (MetaKmsUpdate *update); diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c index 06d6d7515..be6eaefcc 100644 --- a/src/backends/native/meta-kms-update.c +++ b/src/backends/native/meta-kms-update.c @@ -417,6 +417,28 @@ meta_kms_update_add_page_flip_listener (MetaKmsUpdate *upd listener); } +void +meta_kms_update_drop_defunct_page_flip_listeners (MetaKmsUpdate *update) +{ + GList *l; + + l = update->page_flip_listeners; + while (l) + { + MetaKmsPageFlipListener *listener = l->data; + GList *l_next = l->next; + + if (listener->flags & META_KMS_PAGE_FLIP_LISTENER_FLAG_DROP_ON_ERROR) + { + meta_kms_page_flip_listener_free (listener); + update->page_flip_listeners = + g_list_delete_link (update->page_flip_listeners, l); + } + + l = l_next; + } +} + void meta_kms_update_set_custom_page_flip (MetaKmsUpdate *update, MetaKmsCustomPageFlipFunc func, diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h index 98fb8088f..0c7707bbc 100644 --- a/src/backends/native/meta-kms-update.h +++ b/src/backends/native/meta-kms-update.h @@ -46,7 +46,7 @@ typedef enum _MetaKmsAssignPlaneFlag enum _MetaKmsPageFlipListenerFlag { META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE = 0, - META_KMS_PAGE_FLIP_LISTENER_FLAG_NO_DISCARD = 1 << 0, + META_KMS_PAGE_FLIP_LISTENER_FLAG_DROP_ON_ERROR = 1 << 0, }; struct _MetaKmsPageFlipListenerVtable diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c index 57bb88e5f..edb6f29ee 100644 --- a/src/backends/native/meta-kms.c +++ b/src/backends/native/meta-kms.c @@ -239,15 +239,22 @@ meta_kms_take_pending_update (MetaKms *kms, return NULL; } +typedef struct +{ + MetaKmsUpdate *update; + MetaKmsUpdateFlag flags; +} PostUpdateData; + static gpointer meta_kms_process_update_in_impl (MetaKmsImpl *impl, gpointer user_data, GError **error) { + PostUpdateData *data = user_data; + MetaKmsUpdate *update = data->update; MetaKmsFeedback *feedback; - MetaKmsUpdate *update = user_data; - feedback = meta_kms_impl_process_update (impl, update); + feedback = meta_kms_impl_process_update (impl, data->update, data->flags); meta_kms_device_predict_states_in_impl (meta_kms_update_get_device (update), update); @@ -260,6 +267,7 @@ meta_kms_post_pending_update_sync (MetaKms *kms, MetaKmsUpdateFlag flags) { MetaKmsUpdate *update; + PostUpdateData data; MetaKmsFeedback *feedback; GList *result_listeners; GList *l; @@ -273,9 +281,13 @@ meta_kms_post_pending_update_sync (MetaKms *kms, meta_kms_update_lock (update); + data = (PostUpdateData) { + .update = update, + .flags = flags, + }; feedback = meta_kms_run_impl_task_sync (kms, meta_kms_process_update_in_impl, - update, + &data, NULL); result_listeners = meta_kms_update_take_result_listeners (update); @@ -294,6 +306,8 @@ meta_kms_post_pending_update_sync (MetaKms *kms, meta_kms_update_drop_plane_assignment (update, plane); } + meta_kms_update_drop_defunct_page_flip_listeners (update); + meta_kms_add_pending_update (kms, update); } else diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c index da75b03ec..02cd5da2e 100644 --- a/src/backends/native/meta-onscreen-native.c +++ b/src/backends/native/meta-onscreen-native.c @@ -1259,7 +1259,7 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen, meta_onscreen_native_flip_crtc (onscreen, onscreen_native->view, onscreen_native->crtc, - META_KMS_PAGE_FLIP_LISTENER_FLAG_NO_DISCARD); + META_KMS_PAGE_FLIP_LISTENER_FLAG_DROP_ON_ERROR); kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (onscreen_native->crtc)); kms_device = meta_kms_crtc_get_device (kms_crtc);