From 2df632736718df8466bde3cfca32d0ed421d02ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 2 Oct 2020 10:38:57 +0200 Subject: [PATCH] kms: Post pending updates per device Instead of a "post all pending updates", pass an update specific to a single device. This gets rid of the awkward "combine feedback" function, and makes it possible to queue updates to a multiple devices without always posting them together. Part-of: --- .../native/meta-cursor-renderer-native.c | 38 ++++-- src/backends/native/meta-kms.c | 114 +++++++----------- src/backends/native/meta-kms.h | 5 +- .../native/meta-monitor-manager-kms.c | 17 +-- src/backends/native/meta-renderer-native.c | 69 ++++++----- 5 files changed, 124 insertions(+), 119 deletions(-) diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c index 2e89a3f0e..96e032f35 100644 --- a/src/backends/native/meta-cursor-renderer-native.c +++ b/src/backends/native/meta-cursor-renderer-native.c @@ -544,7 +544,6 @@ update_hw_cursor (MetaCursorRendererNative *native, GList *l; graphene_rect_t rect; gboolean painted = FALSE; - g_autoptr (MetaKmsFeedback) feedback = NULL; if (cursor_sprite) rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite); @@ -589,23 +588,36 @@ update_hw_cursor (MetaCursorRendererNative *native, painted = painted || data.out_painted; } - feedback = meta_kms_post_pending_updates_sync (kms); - if (meta_kms_feedback_get_result (feedback) != META_KMS_FEEDBACK_PASSED) + for (l = meta_kms_get_devices (kms); l; l = l->next) { - for (l = meta_kms_feedback_get_failed_planes (feedback); l; l = l->next) + MetaKmsDevice *kms_device = l->data; + MetaKmsUpdate *kms_update; + g_autoptr (MetaKmsFeedback) feedback = NULL; + + kms_update = meta_kms_get_pending_update (kms, kms_device); + if (!kms_update) + continue; + + feedback = meta_kms_post_pending_update_sync (kms, kms_device); + if (meta_kms_feedback_get_result (feedback) != META_KMS_FEEDBACK_PASSED) { - MetaKmsPlaneFeedback *plane_feedback = l->data; + GList *k; - if (!g_error_matches (plane_feedback->error, - G_IO_ERROR, - G_IO_ERROR_PERMISSION_DENIED)) + for (k = meta_kms_feedback_get_failed_planes (feedback); k; k = k->next) { - disable_hw_cursor_for_crtc (plane_feedback->crtc, - plane_feedback->error); - } - } + MetaKmsPlaneFeedback *plane_feedback = k->data; - priv->has_hw_cursor = FALSE; + if (!g_error_matches (plane_feedback->error, + G_IO_ERROR, + G_IO_ERROR_PERMISSION_DENIED)) + { + disable_hw_cursor_for_crtc (plane_feedback->crtc, + plane_feedback->error); + } + } + + priv->has_hw_cursor = FALSE; + } } priv->hw_state_invalidated = FALSE; diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c index f658dda1f..f4c2b6848 100644 --- a/src/backends/native/meta-kms.c +++ b/src/backends/native/meta-kms.c @@ -210,95 +210,65 @@ meta_kms_get_pending_update (MetaKms *kms, return NULL; } -static void -meta_kms_predict_states_in_impl (MetaKms *kms, - MetaKmsUpdate *update) +static MetaKmsUpdate * +meta_kms_take_pending_update (MetaKms *kms, + MetaKmsDevice *device) { - meta_assert_in_kms_impl (kms); + GList *l; - g_list_foreach (kms->devices, - (GFunc) meta_kms_device_predict_states_in_impl, - update); -} - -static MetaKmsFeedback * -combine_feedbacks (MetaKmsFeedback *feedback, - MetaKmsFeedback *other_feedback) -{ - GList *failed_planes; - MetaKmsFeedback *new_feedback; - const GError *error; - - if (!feedback) - return other_feedback; - - failed_planes = - g_list_concat (meta_kms_feedback_get_failed_planes (feedback), - meta_kms_feedback_get_failed_planes (other_feedback)); - error = meta_kms_feedback_get_error (feedback); - if (!error) - error = meta_kms_feedback_get_error (other_feedback); - - if (error) + for (l = kms->pending_updates; l; l = l->next) { - new_feedback = meta_kms_feedback_new_failed (failed_planes, - g_error_copy (error)); - } - else - { - new_feedback = meta_kms_feedback_new_passed (); + MetaKmsUpdate *update = l->data; + + if (meta_kms_update_get_device (update) == device) + { + kms->pending_updates = g_list_delete_link (kms->pending_updates, l); + return update; + } } - meta_kms_feedback_free (feedback); - meta_kms_feedback_free (other_feedback); - - return new_feedback; + return NULL; } static gpointer -meta_kms_process_updates_in_impl (MetaKmsImpl *impl, - gpointer user_data, - GError **error) +meta_kms_process_update_in_impl (MetaKmsImpl *impl, + gpointer user_data, + GError **error) { - GList *updates = user_data; - MetaKmsFeedback *feedback = NULL; - GList *l; + MetaKmsFeedback *feedback; + MetaKmsUpdate *update = user_data; - for (l = updates; l; l = l->next) - { - MetaKmsUpdate *update = l->data; - MetaKmsFeedback *device_feedback; - - device_feedback = meta_kms_impl_process_update (impl, update); - feedback = combine_feedbacks (feedback, device_feedback); - meta_kms_predict_states_in_impl (meta_kms_impl_get_kms (impl), update); - } - - g_list_free_full (updates, (GDestroyNotify) meta_kms_update_free); + feedback = meta_kms_impl_process_update (impl, update); + meta_kms_device_predict_states_in_impl (meta_kms_update_get_device (update), + update); return feedback; } -static MetaKmsFeedback * -meta_kms_post_updates_sync (MetaKms *kms, - GList *updates) +MetaKmsFeedback * +meta_kms_post_pending_update_sync (MetaKms *kms, + MetaKmsDevice *device) { - g_list_foreach (updates, (GFunc) meta_kms_update_seal, NULL); + MetaKmsUpdate *update; + MetaKmsFeedback *feedback; COGL_TRACE_BEGIN_SCOPED (MetaKmsPostUpdateSync, "KMS (post update)"); - return meta_kms_run_impl_task_sync (kms, - meta_kms_process_updates_in_impl, - updates, - NULL); -} + update = meta_kms_take_pending_update (kms, device); + if (!update) + return NULL; -MetaKmsFeedback * -meta_kms_post_pending_updates_sync (MetaKms *kms) -{ - return meta_kms_post_updates_sync (kms, - g_steal_pointer (&kms->pending_updates)); + meta_kms_update_seal (update); + + feedback = meta_kms_run_impl_task_sync (kms, + meta_kms_process_update_in_impl, + update, + NULL); + + meta_kms_update_free (update); + + return feedback; } static gpointer @@ -584,6 +554,12 @@ meta_kms_get_backend (MetaKms *kms) return kms->backend; } +GList * +meta_kms_get_devices (MetaKms *kms) +{ + return kms->devices; +} + MetaKmsDevice * meta_kms_create_device (MetaKms *kms, const char *path, diff --git a/src/backends/native/meta-kms.h b/src/backends/native/meta-kms.h index 237ecbce9..97876d370 100644 --- a/src/backends/native/meta-kms.h +++ b/src/backends/native/meta-kms.h @@ -34,12 +34,15 @@ MetaKmsUpdate * meta_kms_ensure_pending_update (MetaKms *kms, MetaKmsUpdate * meta_kms_get_pending_update (MetaKms *kms, MetaKmsDevice *device); -MetaKmsFeedback * meta_kms_post_pending_updates_sync (MetaKms *kms); +MetaKmsFeedback * meta_kms_post_pending_update_sync (MetaKms *kms, + MetaKmsDevice *device); void meta_kms_discard_pending_page_flips (MetaKms *kms); MetaBackend * meta_kms_get_backend (MetaKms *kms); +GList * meta_kms_get_devices (MetaKms *kms); + MetaKmsDevice * meta_kms_create_device (MetaKms *kms, const char *path, MetaKmsDeviceFlag flags, diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c index d6a40688a..16e3423de 100644 --- a/src/backends/native/meta-monitor-manager-kms.c +++ b/src/backends/native/meta-monitor-manager-kms.c @@ -122,7 +122,6 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager, MetaKms *kms = meta_backend_native_get_kms (backend_native); uint64_t state; GList *l; - g_autoptr (MetaKmsFeedback) kms_feedback = NULL; switch (mode) { case META_POWER_SAVE_ON: @@ -146,16 +145,18 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager, MetaGpuKms *gpu_kms = l->data; MetaKmsDevice *kms_device = meta_gpu_kms_get_kms_device (gpu_kms); MetaKmsUpdate *kms_update; + g_autoptr (MetaKmsFeedback) kms_feedback = NULL; kms_update = meta_kms_ensure_pending_update (kms, kms_device); meta_gpu_kms_set_power_save_mode (gpu_kms, state, kms_update); - } - kms_feedback = meta_kms_post_pending_updates_sync (kms); - if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED) - { - g_warning ("Failed to set DPMS: %s", - meta_kms_feedback_get_error (kms_feedback)->message); + kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device); + if (meta_kms_feedback_get_result (kms_feedback) != + META_KMS_FEEDBACK_PASSED) + { + g_warning ("Failed to set DPMS: %s", + meta_kms_feedback_get_error (kms_feedback)->message); + } } } @@ -433,7 +434,7 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager, g_debug ("Setting CRTC (%" G_GUINT64_FORMAT ") gamma to %s", meta_crtc_get_id (crtc), gamma_ramp_string); - kms_feedback = meta_kms_post_pending_updates_sync (kms); + kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device); if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED) { g_warning ("Failed to set CRTC gamma: %s", diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index c32cea3d3..d49076303 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -1867,24 +1867,24 @@ ensure_crtc_modes (CoglOnscreen *onscreen) } } -static gboolean +static void unset_disabled_crtcs (MetaBackend *backend, MetaKms *kms) { - gboolean did_mode_set = FALSE; GList *l; for (l = meta_backend_get_gpus (backend); l; l = l->next) { MetaGpu *gpu = l->data; + MetaKmsDevice *kms_device = + meta_gpu_kms_get_kms_device (META_GPU_KMS (gpu)); GList *k; + gboolean did_mode_set = FALSE; + g_autoptr (MetaKmsFeedback) kms_feedback = NULL; for (k = meta_gpu_get_crtcs (gpu); k; k = k->next) { MetaCrtc *crtc = k->data; - MetaKmsCrtc *kms_crtc = - meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc)); - MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc); MetaKmsUpdate *kms_update; if (meta_crtc_get_config (crtc)) @@ -1895,23 +1895,20 @@ unset_disabled_crtcs (MetaBackend *backend, did_mode_set = TRUE; } - } - return did_mode_set; -} + if (!did_mode_set) + continue; -static void -post_pending_updates (MetaKms *kms) -{ - g_autoptr (MetaKmsFeedback) kms_feedback = NULL; + kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device); + if (meta_kms_feedback_get_result (kms_feedback) != + META_KMS_FEEDBACK_PASSED) + { + const GError *error = meta_kms_feedback_get_error (kms_feedback); - kms_feedback = meta_kms_post_pending_updates_sync (kms); - if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED) - { - const GError *error = meta_kms_feedback_get_error (kms_feedback); - - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED)) - g_warning ("Failed to post KMS update: %s", error->message); + if (!g_error_matches (error, G_IO_ERROR, + G_IO_ERROR_PERMISSION_DENIED)) + g_warning ("Failed to post KMS update: %s", error->message); + } } } @@ -1942,6 +1939,8 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, MetaPowerSave power_save_mode; g_autoptr (GError) error = NULL; MetaDrmBufferGbm *buffer_gbm; + MetaKmsCrtc *kms_crtc; + MetaKmsDevice *kms_device; g_autoptr (MetaKmsFeedback) kms_feedback = NULL; COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeSwapBuffers, @@ -2008,7 +2007,22 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, COGL_TRACE_BEGIN (MetaRendererNativePostKmsUpdate, "Onscreen (post pending update)"); - post_pending_updates (kms); + kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (onscreen_native->crtc)); + kms_device = meta_kms_crtc_get_device (kms_crtc); + kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device); + if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED) + { + const GError *error = meta_kms_feedback_get_error (kms_feedback); + MetaGpuKms *gpu_kms = + META_GPU_KMS (meta_crtc_get_gpu (onscreen_native->crtc)); + int64_t now_ns; + + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED)) + g_warning ("Failed to post KMS update: %s", error->message); + + now_ns = meta_gpu_kms_get_current_time_ns (gpu_kms); + notify_view_crtc_presented (onscreen_native->view, kms_crtc, now_ns); + } COGL_TRACE_END (MetaRendererNativePostKmsUpdate); } @@ -2157,6 +2171,8 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen, MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (backend); MetaPowerSave power_save_mode; + MetaKmsCrtc *kms_crtc; + MetaKmsDevice *kms_device; g_autoptr (MetaKmsFeedback) kms_feedback = NULL; power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager); @@ -2179,7 +2195,9 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen, meta_onscreen_native_flip_crtcs (onscreen, META_KMS_PAGE_FLIP_FLAG_NO_DISCARD_FEEDBACK); - kms_feedback = meta_kms_post_pending_updates_sync (kms); + kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (onscreen_native->crtc)); + kms_device = meta_kms_crtc_get_device (kms_crtc); + kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device); if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED) { const GError *feedback_error = meta_kms_feedback_get_error (kms_feedback); @@ -3010,16 +3028,12 @@ meta_renderer_native_finish_frame (MetaRendererNative *renderer_native) MetaBackend *backend = meta_renderer_get_backend (renderer); MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); MetaKms *kms = meta_backend_native_get_kms (backend_native); - gboolean did_mode_set = FALSE; if (renderer_native->pending_unset_disabled_crtcs) { - did_mode_set = unset_disabled_crtcs (backend, kms); + unset_disabled_crtcs (backend, kms); renderer_native->pending_unset_disabled_crtcs = FALSE; } - - if (did_mode_set) - post_pending_updates (kms); } static gboolean @@ -3603,8 +3617,7 @@ meta_renderer_native_reset_modes (MetaRendererNative *renderer_native) MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); MetaKms *kms = meta_backend_native_get_kms (backend_native); - if (unset_disabled_crtcs (backend, kms)) - post_pending_updates (kms); + unset_disabled_crtcs (backend, kms); } static MetaGpuKms *