[mutter/wip/frame-synchronization: 58/69] Move sync alarms to be per-window and permanent



commit 44bd0c8db15befe62c1e34624588c68f18450254
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Wed Jun 8 11:26:03 2011 -0400

    Move sync alarms to be per-window and permanent
    
    Instead of creating a new alarm each time we resize a window
    interactively, create an alarm the first time we resize a window
    and keep it around permanently until we unmanage the window.
    Doing it this way will be useful when we allow the application to
    spontaneously generate sync request updates to indicate
    frames it is drawing.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=685463

 src/core/display-private.h |   14 ++++--
 src/core/display.c         |  122 ++++++++++++++++++-------------------------
 src/core/window-private.h  |    4 ++
 src/core/window-props.c    |    2 +
 src/core/window.c          |   80 ++++++++++++++++++++++++++++-
 5 files changed, 144 insertions(+), 78 deletions(-)
---
diff --git a/src/core/display-private.h b/src/core/display-private.h
index b03fffd..797cb95 100644
--- a/src/core/display-private.h
+++ b/src/core/display-private.h
@@ -221,10 +221,6 @@ struct _MetaDisplay
   int         xkb_base_event_type;
   guint32     last_bell_time;
 #endif
-#ifdef HAVE_XSYNC
-  /* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */
-  XSyncAlarm  grab_sync_request_alarm;
-#endif
   int	      grab_resize_timeout_id;
 
   /* Keybindings stuff */
@@ -366,6 +362,16 @@ void        meta_display_register_x_window   (MetaDisplay *display,
 void        meta_display_unregister_x_window (MetaDisplay *display,
                                               Window       xwindow);
 
+#ifdef HAVE_XSYNC
+MetaWindow* meta_display_lookup_sync_alarm     (MetaDisplay *display,
+                                                XSyncAlarm   alarm);
+void        meta_display_register_sync_alarm   (MetaDisplay *display,
+                                                XSyncAlarm  *alarmp,
+                                                MetaWindow  *window);
+void        meta_display_unregister_sync_alarm (MetaDisplay *display,
+                                                XSyncAlarm   alarm);
+#endif /* HAVE_XSYNC */
+
 void        meta_display_notify_window_created (MetaDisplay  *display,
                                                 MetaWindow   *window);
 
diff --git a/src/core/display.c b/src/core/display.c
index 42cf7b4..0747049 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -534,10 +534,6 @@ meta_display_open (void)
   the_display->allow_terminal_deactivation = TRUE; /* Only relevant for when a
                                                   terminal has the focus */
 
-#ifdef HAVE_XSYNC
-  the_display->grab_sync_request_alarm = None;
-#endif
-  
   /* FIXME copy the checks from GDK probably */
   the_display->static_gravity_works = g_getenv ("MUTTER_USE_STATIC_GRAVITY") != NULL;
   
@@ -1874,16 +1870,21 @@ event_callback (XEvent   *event,
     }
 
 #ifdef HAVE_XSYNC
-  if (META_DISPLAY_HAS_XSYNC (display) && 
-      event->type == (display->xsync_event_base + XSyncAlarmNotify) &&
-      ((XSyncAlarmNotifyEvent*)event)->alarm == display->grab_sync_request_alarm)
+  if (META_DISPLAY_HAS_XSYNC (display) &&
+      event->type == (display->xsync_event_base + XSyncAlarmNotify))
     {
-      filter_out_event = TRUE; /* GTK doesn't want to see this really */
-      
-      if (display->grab_op != META_GRAB_OP_NONE &&
-          display->grab_window != NULL &&
-          grab_op_is_mouse (display->grab_op))
-	meta_window_handle_mouse_grab_op_event (display->grab_window, event);
+      MetaWindow *alarm_window = meta_display_lookup_sync_alarm (display,
+                                                                 ((XSyncAlarmNotifyEvent*)event)->alarm);
+
+      if (alarm_window != NULL)
+        {
+          filter_out_event = TRUE; /* our own alarm, GTK doesn't want to see this */
+
+          if (display->grab_op != META_GRAB_OP_NONE &&
+              display->grab_window == alarm_window &&
+              grab_op_is_mouse (display->grab_op))
+            meta_window_handle_mouse_grab_op_event (display->grab_window, event);
+        }
     }
 #endif /* HAVE_XSYNC */
 
@@ -3468,6 +3469,39 @@ meta_display_unregister_x_window (MetaDisplay *display,
   remove_pending_pings_for_window (display, xwindow);
 }
 
+#ifdef HAVE_XSYNC
+/* We store sync alarms in the window ID hash table, because they are
+ * just more types of XIDs in the same global space, but we have
+ * typesafe functions to register/unregister for readability.
+ */
+
+MetaWindow*
+meta_display_lookup_sync_alarm (MetaDisplay *display,
+                                XSyncAlarm   alarm)
+{
+  return g_hash_table_lookup (display->window_ids, &alarm);
+}
+
+void
+meta_display_register_sync_alarm (MetaDisplay *display,
+                                  XSyncAlarm  *alarmp,
+                                  MetaWindow  *window)
+{
+  g_return_if_fail (g_hash_table_lookup (display->window_ids, alarmp) == NULL);
+
+  g_hash_table_insert (display->window_ids, alarmp, window);
+}
+
+void
+meta_display_unregister_sync_alarm (MetaDisplay *display,
+                                    XSyncAlarm   alarm)
+{
+  g_return_if_fail (g_hash_table_lookup (display->window_ids, &alarm) != NULL);
+
+  g_hash_table_remove (display->window_ids, &alarm);
+}
+#endif /* HAVE_XSYNC */
+
 void
 meta_display_notify_window_created (MetaDisplay  *display,
                                     MetaWindow   *window)
@@ -3805,7 +3839,6 @@ meta_display_begin_grab_op (MetaDisplay *display,
   display->grab_motion_notify_time = 0;
   display->grab_old_window_stacking = NULL;
 #ifdef HAVE_XSYNC
-  display->grab_sync_request_alarm = None;
   display->grab_last_user_action_was_snap = FALSE;
 #endif
   display->grab_frame_action = frame_action;
@@ -3825,55 +3858,11 @@ meta_display_begin_grab_op (MetaDisplay *display,
 
 #ifdef HAVE_XSYNC
       if ( meta_grab_op_is_resizing (display->grab_op) &&
-          display->grab_window->sync_request_counter != None)
+           display->grab_window->sync_request_counter != None)
         {
-          XSyncAlarmAttributes values;
-	  XSyncValue init;
-
-          meta_error_trap_push_with_return (display);
-
-	  /* Set the counter to 0, so we know that the application's
-	   * responses to the client messages will always trigger
-	   * a PositiveTransition
-	   */
-	  
-	  XSyncIntToValue (&init, 0);
-	  XSyncSetCounter (display->xdisplay,
-			   display->grab_window->sync_request_counter, init);
-	  
-	  display->grab_window->sync_request_serial = 0;
-	  display->grab_window->sync_request_time.tv_sec = 0;
-	  display->grab_window->sync_request_time.tv_usec = 0;
-	  
-          values.trigger.counter = display->grab_window->sync_request_counter;
-          values.trigger.value_type = XSyncAbsolute;
-          values.trigger.test_type = XSyncPositiveTransition;
-          XSyncIntToValue (&values.trigger.wait_value,
-			   display->grab_window->sync_request_serial + 1);
-	  
-          /* After triggering, increment test_value by this.
-           * (NOT wait_value above)
-           */
-          XSyncIntToValue (&values.delta, 1);
-	  
-          /* we want events (on by default anyway) */
-          values.events = True;
-          
-          display->grab_sync_request_alarm = XSyncCreateAlarm (display->xdisplay,
-                                                         XSyncCACounter |
-                                                         XSyncCAValueType |
-                                                         XSyncCAValue |
-                                                         XSyncCATestType |
-                                                         XSyncCADelta |
-                                                         XSyncCAEvents,
-                                                         &values);
-
-          if (meta_error_trap_pop_with_return (display) != Success)
-	    display->grab_sync_request_alarm = None;
-
-          meta_topic (META_DEBUG_RESIZING,
-                      "Created update alarm 0x%lx\n",
-                      display->grab_sync_request_alarm);
+          meta_window_create_sync_request_alarm (display->grab_window);
+          window->sync_request_time.tv_sec = 0;
+          window->sync_request_time.tv_usec = 0;
         }
 #endif
     }
@@ -3986,15 +3975,6 @@ meta_display_end_grab_op (MetaDisplay *display,
         meta_screen_ungrab_all_keys (display->grab_screen, timestamp);
     }
 
-#ifdef HAVE_XSYNC
-  if (display->grab_sync_request_alarm != None)
-    {
-      XSyncDestroyAlarm (display->xdisplay,
-                         display->grab_sync_request_alarm);
-      display->grab_sync_request_alarm = None;
-    }
-#endif /* HAVE_XSYNC */
-  
   display->grab_window = NULL;
   display->grab_screen = NULL;
   display->grab_xwindow = None;
diff --git a/src/core/window-private.h b/src/core/window-private.h
index d07c14b..fc4c986 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -347,6 +347,8 @@ struct _MetaWindow
   XSyncCounter sync_request_counter;
   guint sync_request_serial;
   GTimeVal sync_request_time;
+  /* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */
+  XSyncAlarm sync_request_alarm;
 #endif
   
   /* Number of UnmapNotify that are caused by us, if
@@ -619,6 +621,8 @@ void meta_window_refresh_resize_popup (MetaWindow *window);
 
 void meta_window_free_delete_dialog (MetaWindow *window);
 
+void meta_window_create_sync_request_alarm  (MetaWindow *window);
+void meta_window_destroy_sync_request_alarm (MetaWindow *window);
 
 void meta_window_update_keyboard_resize (MetaWindow *window,
                                          gboolean    update_cursor);
diff --git a/src/core/window-props.c b/src/core/window-props.c
index 68e14fd..e3473e8 100644
--- a/src/core/window-props.c
+++ b/src/core/window-props.c
@@ -882,6 +882,8 @@ reload_update_counter (MetaWindow    *window,
 {
   if (value->type != META_PROP_VALUE_INVALID)
     {
+      meta_window_destroy_sync_request_alarm (window);
+
 #ifdef HAVE_XSYNC
       XSyncCounter counter = value->v.xcounter;
 
diff --git a/src/core/window.c b/src/core/window.c
index 3ca1085..a0a09c4 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -1005,6 +1005,7 @@ meta_window_new_with_attrs (MetaDisplay       *display,
   window->sync_request_serial = 0;
   window->sync_request_time.tv_sec = 0;
   window->sync_request_time.tv_usec = 0;
+  window->sync_request_alarm = None;
 #endif
 
   window->screen = screen;
@@ -1808,6 +1809,8 @@ meta_window_unmanage (MetaWindow  *window,
   if (!window->override_redirect)
     meta_stack_remove (window->screen->stack, window);
 
+  meta_window_destroy_sync_request_alarm (window);
+
   if (window->frame)
     meta_window_destroy_frame (window);
 
@@ -4389,6 +4392,76 @@ static_gravity_works (MetaDisplay *display)
   return display->static_gravity_works;
 }
 
+void
+meta_window_create_sync_request_alarm (MetaWindow *window)
+{
+#ifdef HAVE_XSYNC
+  XSyncAlarmAttributes values;
+  XSyncValue init;
+
+  if (window->sync_request_counter == None ||
+      window->sync_request_alarm != None)
+    return;
+
+  meta_error_trap_push_with_return (window->display);
+
+  /* Set the counter to 0, so we know that the application's
+   * responses to the client messages will always trigger
+   * a PositiveTransition
+   */
+  XSyncIntToValue (&init, 0);
+  XSyncSetCounter (window->display->xdisplay,
+                   window->sync_request_counter, init);
+  window->sync_request_serial = 0;
+
+  values.trigger.counter = window->sync_request_counter;
+  values.trigger.test_type = XSyncPositiveTransition;
+
+  /* Initialize to one greater than the current value */
+  values.trigger.value_type = XSyncRelative;
+  XSyncIntToValue (&values.trigger.wait_value, 1);
+
+  /* After triggering, increment test_value by this until
+   * until the test condition is false */
+  XSyncIntToValue (&values.delta, 1);
+
+  /* we want events (on by default anyway) */
+  values.events = True;
+
+  window->sync_request_alarm = XSyncCreateAlarm (window->display->xdisplay,
+                                                 XSyncCACounter |
+                                                 XSyncCAValueType |
+                                                 XSyncCAValue |
+                                                 XSyncCATestType |
+                                                 XSyncCADelta |
+                                                 XSyncCAEvents,
+                                                 &values);
+
+  if (meta_error_trap_pop_with_return (window->display) == Success)
+    meta_display_register_sync_alarm (window->display, &window->sync_request_alarm, window);
+  else
+    {
+      window->sync_request_alarm = None;
+      window->sync_request_counter = None;
+    }
+#endif
+}
+
+void
+meta_window_destroy_sync_request_alarm (MetaWindow *window)
+{
+#ifdef HAVE_XSYNC
+  if (window->sync_request_alarm != None)
+    {
+      /* Has to be unregistered _before_ clearing the structure field */
+      meta_display_unregister_sync_alarm (window->display, window->sync_request_alarm);
+      XSyncDestroyAlarm (window->display->xdisplay,
+                         window->sync_request_alarm);
+      window->sync_request_alarm = None;
+    }
+#endif /* HAVE_XSYNC */
+}
+
 #ifdef HAVE_XSYNC
 static void
 send_sync_request (MetaWindow *window)
@@ -4949,8 +5022,9 @@ meta_window_move_resize_internal (MetaWindow          *window,
       meta_error_trap_push (window->display);
 
 #ifdef HAVE_XSYNC
-      if (window->sync_request_counter != None &&
-	  window->display->grab_sync_request_alarm != None &&
+      if (window == window->display->grab_window &&
+          window->sync_request_counter != None &&
+	  window->sync_request_alarm != None &&
 	  window->sync_request_time.tv_usec == 0 &&
 	  window->sync_request_time.tv_sec == 0)
 	{
@@ -8508,7 +8582,7 @@ check_moveresize_frequency (MetaWindow *window,
 
 #ifdef HAVE_XSYNC
   if (!window->disable_sync &&
-      window->display->grab_sync_request_alarm != None)
+      window->sync_request_alarm != None)
     {
       if (window->sync_request_time.tv_sec != 0 ||
 	  window->sync_request_time.tv_usec != 0)



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