[mutter] kms: Make GSource ready by default



commit 6e0cfd3e55d554360b7e6963b39bcf996121847b
Author: Pekka Paalanen <pekka paalanen collabora com>
Date:   Fri Apr 17 14:50:13 2020 +0300

    kms: Make GSource ready by default
    
    When testing a laptop with intel and DisplayLink devices, attempting to set the
    DL output as the only active output resulted in GNOME/Wayland freezing. The
    main event loop was running fine, but nothing on screen would get updated once
    the DL output become the only one. This patch fixes that issue.
    
    DisplayLink USB 3 devices use an out-of-tree kernel DRM driver called EVDI.
    EVDI can sometimes fail drmModePageFlip(). For me, the flip fails reliably when
    hotplugging the DL dock and when changing display configuration to DL only.
    Mutter has a workaround for failing flips, it just calls drmModeSetCrtc() and
    that succeeds.
    
    What does not work reliably in the fallback path is Mutter keeping track of the
    pageflip. Since drmModePageFlip() failed, there will not be a pageflip event
    coming and instead Mutter queues a callback in its stead. When you have more
    than one output, some other output repainting will attempt to swap buffers and
    calls wait_for_pending_flips() which has the side-effect of dispatching any
    queued flip callbacks. With multiple outputs, you don't get stuck (unless they
    all fail the exact same way at the same time?). When you have only one output,
    it cannot proceed to repaint and buffer swap because the pageflip is not marked
    complete yet. Nothing dispatches the flip callback, leading to the freeze.
    
    The flip callback is intended to be an idle callback, implemented with a
    GSource. It is supposed to be called as soon as execution returns to the main
    event loop. The setup of the GSource is incomplete, so it will never dispatch.
    
    Fix the GSource setup by setting its ready-time to be always in the past. That
    gets it dispatched on the next cycle of the main event loop. This is now the
    default behavior for all sources created by meta_kms_add_source_in_impl().
    Sources that need a delay continue to do that by overriding the ready-time
    explicitly.
    
    An alternative solution could have been to implement GSource prepare and check
    callbacks returning TRUE. However, since meta_kms_add_source_in_impl() is used
    by flip retry code as well, and that code needs a delay through the ready-time,
    I was afraid I might break the flip retry code. Hence I decided to use
    ready-time instead.
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1209

 src/backends/native/meta-kms.c | 2 ++
 1 file changed, 2 insertions(+)
---
diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c
index f48ce9abd..80ce4e3c2 100644
--- a/src/backends/native/meta-kms.c
+++ b/src/backends/native/meta-kms.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2018 Red Hat
+ * Copyright 2020 DisplayLink (UK) Ltd.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -383,6 +384,7 @@ meta_kms_add_source_in_impl (MetaKms        *kms,
   simple_impl_source->kms = kms;
 
   g_source_set_callback (source, func, user_data, user_data_destroy);
+  g_source_set_ready_time (source, 0);
   g_source_attach (source, g_main_context_get_thread_default ());
 
   return source;


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