[mutter] kms: Use custom page flip function when retrying failed flips



commit 0aa4bab53931a0906dfabed1095afbd2ae705177
Author: Erik Kurzinger <ekurzinger nvidia com>
Date:   Fri Jul 17 13:38:55 2020 -0700

    kms: Use custom page flip function when retrying failed flips
    
    When using its EGLStream-based presentation path with the proprietary NVIDIA
    driver, mutter will use a different function to process page flips -
    custom_egl_stream_page_flip.  If that fails due to an EBUSY error, it will
    attempt to retry the flip.  However, when retrying, it unconditionally uses the
    libdrm-based path. In practice, this causes a segfault when attempting to
    access plane_assignments->fb_id, since plane_assignments will be NULL in the
    EGLStream case.  The issue can be reproduced reliably by VT-switching away from
    GNOME and back again while an EGL application is running.
    
    This patch has mutter also use the custom page flip function when retrying the
    failed flip.
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1375

 src/backends/native/meta-kms-impl-simple.c | 46 +++++++++++++++++++++---------
 1 file changed, 33 insertions(+), 13 deletions(-)
---
diff --git a/src/backends/native/meta-kms-impl-simple.c b/src/backends/native/meta-kms-impl-simple.c
index b5c7bb7424..5aa7adc08e 100644
--- a/src/backends/native/meta-kms-impl-simple.c
+++ b/src/backends/native/meta-kms-impl-simple.c
@@ -319,6 +319,8 @@ typedef struct _RetryPageFlipData
   MetaKmsPageFlipData *page_flip_data;
   float refresh_rate;
   uint64_t retry_time_us;
+  MetaKmsCustomPageFlipFunc custom_page_flip_func;
+  gpointer custom_page_flip_user_data;
 } RetryPageFlipData;
 
 static void
@@ -370,6 +372,7 @@ retry_page_flips (gpointer user_data)
       int fd;
       int ret;
       MetaKmsPageFlipData *page_flip_data;
+      MetaKmsCustomPageFlipFunc custom_page_flip_func;
 
       if (is_timestamp_earlier_than (now_us,
                                      retry_page_flip_data->retry_time_us))
@@ -378,12 +381,22 @@ retry_page_flips (gpointer user_data)
           continue;
         }
 
-      fd = meta_kms_impl_device_get_fd (impl_device);
-      ret = drmModePageFlip (fd,
-                             meta_kms_crtc_get_id (crtc),
-                             retry_page_flip_data->fb_id,
-                             DRM_MODE_PAGE_FLIP_EVENT,
-                             retry_page_flip_data->page_flip_data);
+      custom_page_flip_func = retry_page_flip_data->custom_page_flip_func;
+      if (custom_page_flip_func)
+        {
+          ret = custom_page_flip_func (retry_page_flip_data->custom_page_flip_user_data,
+                                       retry_page_flip_data->page_flip_data);
+        }
+      else
+        {
+          fd = meta_kms_impl_device_get_fd (impl_device);
+          ret = drmModePageFlip (fd,
+                                 meta_kms_crtc_get_id (crtc),
+                                 retry_page_flip_data->fb_id,
+                                 DRM_MODE_PAGE_FLIP_EVENT,
+                                 retry_page_flip_data->page_flip_data);
+        }
+
       if (ret == -EBUSY)
         {
           float refresh_rate;
@@ -451,11 +464,13 @@ retry_page_flips (gpointer user_data)
 }
 
 static void
-schedule_retry_page_flip (MetaKmsImplSimple   *impl_simple,
-                          MetaKmsCrtc         *crtc,
-                          uint32_t             fb_id,
-                          float                refresh_rate,
-                          MetaKmsPageFlipData *page_flip_data)
+schedule_retry_page_flip (MetaKmsImplSimple         *impl_simple,
+                          MetaKmsCrtc               *crtc,
+                          uint32_t                   fb_id,
+                          float                      refresh_rate,
+                          MetaKmsPageFlipData       *page_flip_data,
+                          MetaKmsCustomPageFlipFunc  custom_page_flip_func,
+                          gpointer                   custom_page_flip_user_data)
 {
   RetryPageFlipData *retry_page_flip_data;
   uint64_t now_us;
@@ -471,6 +486,8 @@ schedule_retry_page_flip (MetaKmsImplSimple   *impl_simple,
     .page_flip_data = meta_kms_page_flip_data_ref (page_flip_data),
     .refresh_rate = refresh_rate,
     .retry_time_us = retry_time_us,
+    .custom_page_flip_func = custom_page_flip_func,
+    .custom_page_flip_user_data = custom_page_flip_user_data,
   };
 
   if (!impl_simple->retry_page_flips_source)
@@ -677,9 +694,12 @@ process_page_flip (MetaKmsImpl    *impl,
           refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode);
           schedule_retry_page_flip (impl_simple,
                                     crtc,
-                                    plane_assignment->fb_id,
+                                    plane_assignment ?
+                                        plane_assignment->fb_id : 0,
                                     refresh_rate,
-                                    page_flip_data);
+                                    page_flip_data,
+                                    custom_page_flip_func,
+                                    page_flip->custom_page_flip_user_data);
         }
       else
         {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]