[gtk/wip/chergert/macos-iosurface: 6/6] macos: delay showing window until buffer is received




commit 6f592a98a106c9f7b23a913dad662b035ec86937
Author: Christian Hergert <christian hergert me>
Date:   Fri Feb 11 22:36:29 2022 -0800

    macos: delay showing window until buffer is received
    
    Being mapped doesn't mean we have to be displaying to the user invalid
    buffer contents. So we can wait until the next buffer is received to
    actually display the window (hopefully with valid buffer contents).

 gdk/macos/gdkmacossurface-private.h |  1 +
 gdk/macos/gdkmacossurface.c         | 24 +++++++++++++++++++++---
 2 files changed, 22 insertions(+), 3 deletions(-)
---
diff --git a/gdk/macos/gdkmacossurface-private.h b/gdk/macos/gdkmacossurface-private.h
index 637cc2ebfb..3cfcf1076a 100644
--- a/gdk/macos/gdkmacossurface-private.h
+++ b/gdk/macos/gdkmacossurface-private.h
@@ -67,6 +67,7 @@ struct _GdkMacosSurface
   guint did_initial_present : 1;
   guint geometry_dirty : 1;
   guint next_frame_set : 1;
+  guint show_on_next_swap : 1;
 };
 
 struct _GdkMacosSurfaceClass
diff --git a/gdk/macos/gdkmacossurface.c b/gdk/macos/gdkmacossurface.c
index caebed5c56..49e11e43c0 100644
--- a/gdk/macos/gdkmacossurface.c
+++ b/gdk/macos/gdkmacossurface.c
@@ -124,6 +124,8 @@ gdk_macos_surface_hide (GdkSurface *surface)
 
   g_assert (GDK_IS_MACOS_SURFACE (self));
 
+  self->show_on_next_swap = FALSE;
+
   _gdk_macos_display_remove_frame_callback (GDK_MACOS_DISPLAY (surface->display), self);
 
   was_mapped = GDK_SURFACE_IS_MAPPED (GDK_SURFACE (self));
@@ -818,7 +820,7 @@ _gdk_macos_surface_show (GdkMacosSurface *self)
 
   _gdk_macos_display_clear_sorting (GDK_MACOS_DISPLAY (GDK_SURFACE (self)->display));
 
-  [self->window showAndMakeKey:YES];
+  self->show_on_next_swap = TRUE;
 
   if (!was_mapped)
     {
@@ -829,8 +831,6 @@ _gdk_macos_surface_show (GdkMacosSurface *self)
           gdk_surface_thaw_updates (GDK_SURFACE (self));
         }
     }
-
-  [[self->window contentView] setNeedsDisplay:YES];
 }
 
 void
@@ -1127,6 +1127,16 @@ _gdk_macos_surface_get_buffer (GdkMacosSurface *self)
   return self->buffer;
 }
 
+static void
+_gdk_macos_surface_do_delayed_show (GdkMacosSurface *self)
+{
+  g_assert (GDK_IS_MACOS_SURFACE (self));
+
+  self->show_on_next_swap = FALSE;
+  [self->window showAndMakeKey:YES];
+  gdk_surface_request_motion (GDK_SURFACE (self));
+}
+
 void
 _gdk_macos_surface_swap_buffers (GdkMacosSurface      *self,
                                  const cairo_region_t *damage)
@@ -1134,6 +1144,14 @@ _gdk_macos_surface_swap_buffers (GdkMacosSurface      *self,
   g_return_if_fail (GDK_IS_MACOS_SURFACE (self));
   g_return_if_fail (damage != NULL);
 
+  /* We might have delayed actually showing the window until the buffer
+   * contents are ready to be displayed. Doing so ensures that we don't
+   * get a point where we might have invalid buffer contents before we
+   * have content to display to the user.
+   */
+  if G_UNLIKELY (self->show_on_next_swap)
+    _gdk_macos_surface_do_delayed_show (self);
+
   /* This code looks like it swaps buffers, but since the IOSurfaceRef
    * appears to be retained on the other side, we really just ask all
    * of the GdkMacosTile CALayer's to update their contents.


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