[mutter] MetaRendererNative: Flush all pending swap notifies on idle



commit cfafb0bfca5de86418f828bb8b39c1aa73f754b3
Author: Rui Matos <tiagomatos gmail com>
Date:   Mon Dec 5 19:18:24 2016 +0100

    MetaRendererNative: Flush all pending swap notifies on idle
    
    We need to do swap notifications asynchronously from flip events since
    these might be processed during swap buffers if we are waiting for the
    previous frame's flip to continue with the current.
    
    This means that we might have more than one swap notification queued
    to be delivered when the idle handler runs. In that case we must
    deliver all notifications for which we've already seen a flip event.
    
    Failing to do so means that if a new frame, that only swaps buffers on
    such a swap notification backlogged Onscreen, is started, when later
    we get its flip event, we'd notify only an old frame which would hit
    this MetaStageNative's frame_cb() early exit:
    
      if (global_frame_counter <= presented_frame_counter)
        return;
    
    and we'd never finish the new frame and thus clutter's master clock
    would be waiting forever stuck.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=774557

 src/backends/native/meta-renderer-native.c |   22 ++++++++++++++++------
 1 files changed, 16 insertions(+), 6 deletions(-)
---
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index b0845f4..740c1b5 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -98,6 +98,9 @@ typedef struct _MetaOnscreenNative
 
   gboolean pending_set_crtc;
 
+  int64_t pending_queue_swap_notify_frame_count;
+  int64_t pending_swap_notify_frame_count;
+
   MetaRendererView *view;
   int pending_flips;
 } MetaOnscreenNative;
@@ -166,16 +169,19 @@ flush_pending_swap_notify (CoglFramebuffer *framebuffer)
 
       if (onscreen_native->pending_swap_notify)
         {
-          CoglFrameInfo *info =
-            g_queue_pop_head (&onscreen->pending_frame_infos);
+          CoglFrameInfo *info;
 
-          _cogl_onscreen_notify_frame_sync (onscreen, info);
-          _cogl_onscreen_notify_complete (onscreen, info);
+          while ((info = g_queue_peek_head (&onscreen->pending_frame_infos)) &&
+                 info->global_frame_counter <= onscreen_native->pending_swap_notify_frame_count)
+            {
+              _cogl_onscreen_notify_frame_sync (onscreen, info);
+              _cogl_onscreen_notify_complete (onscreen, info);
+              cogl_object_unref (info);
+              g_queue_pop_head (&onscreen->pending_frame_infos);
+            }
 
           onscreen_native->pending_swap_notify = FALSE;
           cogl_object_unref (onscreen);
-
-          cogl_object_unref (info);
         }
     }
 }
@@ -242,6 +248,9 @@ meta_onscreen_native_queue_swap_notify (CoglOnscreen *onscreen)
   CoglRendererEGL *egl_renderer = cogl_renderer->winsys;
   MetaRendererNative *renderer_native = egl_renderer->platform;
 
+  onscreen_native->pending_swap_notify_frame_count =
+    onscreen_native->pending_queue_swap_notify_frame_count;
+
   if (onscreen_native->pending_swap_notify)
     return;
 
@@ -850,6 +859,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
       onscreen_native->pending_set_crtc = FALSE;
     }
 
+  onscreen_native->pending_queue_swap_notify_frame_count = renderer_native->frame_counter;
   meta_onscreen_native_flip_crtcs (onscreen);
 }
 


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