[gtk+] wayland: Add a cursor cache



commit 62eb5d0358b4b753bf0902b2bb712ad3a36f25f3
Author: Kristian Høgsberg <krh bitplanet net>
Date:   Wed Mar 20 22:34:03 2013 -0400

    wayland: Add a cursor cache
    
    We avoid creating a new GdkCursor object every time
    _gdk_wayland_display_get_cursor_for_name/type() is called.

 gdk/wayland/gdkcursor-wayland.c  |   73 ++++++++++++++++++++++++++++++++++++++
 gdk/wayland/gdkdisplay-wayland.c |    2 +
 gdk/wayland/gdkdisplay-wayland.h |    1 +
 gdk/wayland/gdkprivate-wayland.h |    2 +
 4 files changed, 78 insertions(+), 0 deletions(-)
---
diff --git a/gdk/wayland/gdkcursor-wayland.c b/gdk/wayland/gdkcursor-wayland.c
index ce64565..198753e 100644
--- a/gdk/wayland/gdkcursor-wayland.c
+++ b/gdk/wayland/gdkcursor-wayland.c
@@ -65,6 +65,68 @@ G_DEFINE_TYPE (GdkWaylandCursor, _gdk_wayland_cursor, GDK_TYPE_CURSOR)
 
 static guint theme_serial = 0;
 
+struct cursor_cache_key
+{
+  GdkCursorType type;
+  const char *name;
+};
+
+static void
+add_to_cache (GdkWaylandDisplay *display, GdkWaylandCursor *cursor)
+{
+  display->cursor_cache = g_slist_prepend (display->cursor_cache, cursor);
+
+  g_object_ref (cursor);
+}
+
+static gint
+cache_compare_func (gconstpointer listelem,
+                    gconstpointer target)
+{
+  GdkWaylandCursor *cursor = (GdkWaylandCursor *) listelem;
+  struct cursor_cache_key* key = (struct cursor_cache_key *) target;
+
+  if (cursor->cursor.type != key->type)
+    return 1; /* No match */
+
+  /* Elements marked as pixmap must be named cursors
+   * (since we don't store normal pixmap cursors
+   */
+  if (key->type == GDK_CURSOR_IS_PIXMAP)
+    return strcmp (key->name, cursor->name);
+
+  return 0; /* Match */
+}
+
+static GdkWaylandCursor*
+find_in_cache (GdkWaylandDisplay *display,
+               GdkCursorType      type,
+               const char        *name)
+{
+  GSList* res;
+  struct cursor_cache_key key;
+
+  key.type = type;
+  key.name = name;
+
+  res = g_slist_find_custom (display->cursor_cache, &key, cache_compare_func);
+
+  if (res)
+    return (GdkWaylandCursor *) res->data;
+
+  return NULL;
+}
+
+/* Called by gdk_wayland_display_finalize to flush any cached cursors
+ * for a dead display.
+ */
+void
+_gdk_wayland_display_finalize_cursors (GdkWaylandDisplay *display)
+{
+  g_slist_foreach (display->cursor_cache, (GFunc) g_object_unref, NULL);
+  g_slist_free (display->cursor_cache);
+}
+
 static void
 gdk_wayland_cursor_finalize (GObject *object)
 {
@@ -281,6 +343,15 @@ _gdk_wayland_display_get_cursor_for_name (GdkDisplay  *display,
 
   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
 
+  private = find_in_cache (wayland_display, GDK_CURSOR_IS_PIXMAP, name);
+  if (private)
+    {
+      /* Cache had it, add a ref for this user */
+      g_object_ref (private);
+
+      return (GdkCursor*) private;
+    }
+
   private = g_object_new (GDK_TYPE_WAYLAND_CURSOR,
                           "cursor-type", GDK_CURSOR_IS_PIXMAP,
                           "display", display,
@@ -319,6 +390,8 @@ _gdk_wayland_display_get_cursor_for_name (GdkDisplay  *display,
 
   private->buffer = wl_cursor_image_get_buffer(cursor->images[0]);
 
+  add_to_cache (wayland_display, private);
+
   return GDK_CURSOR (private);
 }
 
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
index e244118..4193d53 100644
--- a/gdk/wayland/gdkdisplay-wayland.c
+++ b/gdk/wayland/gdkdisplay-wayland.c
@@ -204,6 +204,8 @@ gdk_wayland_display_finalize (GObject *object)
 {
   GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (object);
 
+  _gdk_wayland_display_finalize_cursors (display_wayland);
+
   /* Keymap */
   if (display_wayland->keymap)
     g_object_unref (display_wayland->keymap);
diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h
index fb284e3..ce2082d 100644
--- a/gdk/wayland/gdkdisplay-wayland.h
+++ b/gdk/wayland/gdkdisplay-wayland.h
@@ -65,6 +65,7 @@ struct _GdkWaylandDisplay
   struct wl_data_device_manager *data_device_manager;
 
   struct wl_cursor_theme *cursor_theme;
+  GSList *cursor_cache;
 
   GSource *event_source;
 
diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h
index 6f07059..480108e 100644
--- a/gdk/wayland/gdkprivate-wayland.h
+++ b/gdk/wayland/gdkprivate-wayland.h
@@ -53,6 +53,8 @@ GdkKeymap *_gdk_wayland_keymap_new_from_fd (uint32_t format,
                                             uint32_t fd, uint32_t size);
 struct xkb_state *_gdk_wayland_keymap_get_xkb_state (GdkKeymap *keymap);
 
+void       _gdk_wayland_display_finalize_cursors (GdkWaylandDisplay *display);
+
 GdkCursor *_gdk_wayland_display_get_cursor_for_type (GdkDisplay    *display,
                                                     GdkCursorType  cursor_type);
 GdkCursor *_gdk_wayland_display_get_cursor_for_name (GdkDisplay  *display,


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