mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-26 05:31:07 +00:00
wayland: Add a cursor cache
We avoid creating a new GdkCursor object every time _gdk_wayland_display_get_cursor_for_name/type() is called.
This commit is contained in:
parent
0d9d808217
commit
62eb5d0358
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user