macos: use display id when creating CVDisplayLink
authorChristian Hergert <christian@hergert.me>
Fri, 25 Feb 2022 21:09:31 +0000 (13:09 -0800)
committerChristian Hergert <chergert@redhat.com>
Wed, 16 Mar 2022 19:24:11 +0000 (12:24 -0700)
Currently we're using a display link that is for all active displays which
is just the display server trying to find some timings that try to overlap
as many as possible.

That was fine for a prototype, but we really need to do better for
situations with mixed frame rate (such as 60hz and 120hz promotion
displays). Additionally, the 144hz external monitor I have will never
reach 144hz using the current design.

This is just the first step in changing this, but the goal is to have
one of these attached to each GdkMacosMonitor which we can then use to
thaw surfaces specific to that monitor.

gdk/macos/gdkdisplaylinksource.c
gdk/macos/gdkdisplaylinksource.h
gdk/macos/gdkmacosdisplay.c

index 292b8be5195677a938fb5cabc620750960be274c..8b2f1a013fd7856bd603bab305aad7a80a4d0ee0 100644 (file)
@@ -147,6 +147,7 @@ gdk_display_link_source_frame_cb (CVDisplayLinkRef   display_link,
 
 /**
  * gdk_display_link_source_new:
+ * @display_id: the identifier of the monitor
  *
  * Creates a new `GSource` that will activate the dispatch function upon
  * notification from a CVDisplayLink that a new frame should be drawn.
@@ -159,7 +160,7 @@ gdk_display_link_source_frame_cb (CVDisplayLinkRef   display_link,
  * Returns: (transfer full): A newly created `GSource`
  */
 GSource *
-gdk_display_link_source_new (void)
+gdk_display_link_source_new (CGDirectDisplayID display_id)
 {
   GdkDisplayLinkSource *impl;
   GSource *source;
@@ -168,15 +169,13 @@ gdk_display_link_source_new (void)
 
   source = g_source_new (&gdk_display_link_source_funcs, sizeof *impl);
   impl = (GdkDisplayLinkSource *)source;
+  impl->display_id = display_id;
 
-  /*
-   * Create our link based on currently connected displays.
-   * If there are multiple displays, this will be something that tries
-   * to work for all of them. In the future, we may want to explore multiple
-   * links based on the connected displays.
+  /* Create DisplayLink for timing information for the display in
+   * question so that we can produce graphics for that display at whatever
+   * rate it can provide.
    */
-  ret = CVDisplayLinkCreateWithActiveCGDisplays (&impl->display_link);
-  if (ret != kCVReturnSuccess)
+  if (CVDisplayLinkCreateWithCGDisplay (display_id, &impl->display_link) != kCVReturnSuccess)
     {
       g_warning ("Failed to initialize CVDisplayLink!");
       return source;
index ed769b59f81422cc6f47141083cb1f51beabfc3f..bff1c91475295ff88445276262680fcf78da93d1 100644 (file)
@@ -30,17 +30,18 @@ G_BEGIN_DECLS
 
 typedef struct
 {
-  GSource          source;
+  GSource           source;
 
-  CVDisplayLinkRef display_link;
-  gint64           refresh_interval;
-  guint            refresh_rate;
+  CGDirectDisplayID display_id;
+  CVDisplayLinkRef  display_link;
+  gint64            refresh_interval;
+  guint             refresh_rate;
 
-  volatile gint64  presentation_time;
-  volatile guint   needs_dispatch;
+  volatile gint64   presentation_time;
+  volatile guint    needs_dispatch;
 } GdkDisplayLinkSource;
 
-GSource *gdk_display_link_source_new     (void);
+GSource *gdk_display_link_source_new     (CGDirectDisplayID     display_id);
 void     gdk_display_link_source_pause   (GdkDisplayLinkSource *source);
 void     gdk_display_link_source_unpause (GdkDisplayLinkSource *source);
 
index bc44eb3e93df5b59a3503903a69d151b91c7644d..5501a163183afedc3dc4106da911ad6340c8e4ac 100644 (file)
@@ -273,7 +273,7 @@ gdk_macos_display_frame_cb (gpointer data)
 static void
 gdk_macos_display_load_display_link (GdkMacosDisplay *self)
 {
-  self->frame_source = gdk_display_link_source_new ();
+  self->frame_source = gdk_display_link_source_new (CGMainDisplayID ());
   g_source_set_callback (self->frame_source,
                          gdk_macos_display_frame_cb,
                          self,