[gtk+] gdkwindow: Avoid list allocation and object refs during repaint
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] gdkwindow: Avoid list allocation and object refs during repaint
- Date: Mon, 14 Sep 2015 09:02:07 +0000 (UTC)
commit eafedfbaf8e080a1e444f46cde082fb2734552f9
Author: Alexander Larsson <alexl redhat com>
Date: Mon Sep 14 09:43:14 2015 +0200
gdkwindow: Avoid list allocation and object refs during repaint
There is no need to ref the windows we're ignoring, so collect and ref
only the affected child windows. Also, use a on-stack array rather
than allocating a linked list.
Also, we don't need to ref during the event emissions too, as we
already hold a ref.
https://bugzilla.gnome.org/show_bug.cgi?id=754687
gdk/gdkwindow.c | 35 +++++++++++++++++++++++++----------
1 files changed, 25 insertions(+), 10 deletions(-)
---
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index f21e30b..3298b8a 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -3541,7 +3541,10 @@ _gdk_window_process_updates_recurse_helper (GdkWindow *window,
{
GdkWindow *child;
cairo_region_t *clipped_expose_region;
- GList *l, *children;
+ GdkWindow **children;
+ GdkWindow **free_children = NULL;
+ int i, n_children;
+ GList *l;
if (window->destroyed)
return;
@@ -3575,23 +3578,23 @@ _gdk_window_process_updates_recurse_helper (GdkWindow *window,
GdkEvent event;
event.expose.type = GDK_EXPOSE;
- event.expose.window = g_object_ref (window);
+ event.expose.window = window; /* we already hold a ref */
event.expose.send_event = FALSE;
event.expose.count = 0;
event.expose.region = clipped_expose_region;
cairo_region_get_extents (clipped_expose_region, &event.expose.area);
_gdk_event_emit (&event);
-
- g_object_unref (window);
}
- /* Make this reentrancy safe for expose handlers freeing windows */
- children = g_list_copy (window->children);
- g_list_foreach (children, (GFunc)g_object_ref, NULL);
+ n_children = g_list_length (window->children);
+ children = g_newa (GdkWindow *, n_children);
+ if (children == NULL)
+ children = free_children = g_new (GdkWindow *, n_children);
+ n_children = 0;
/* Iterate over children, starting at bottommost */
- for (l = g_list_last (children); l != NULL; l = l->prev)
+ for (l = g_list_last (window->children); l != NULL; l = l->prev)
{
child = l->data;
@@ -3605,10 +3608,22 @@ _gdk_window_process_updates_recurse_helper (GdkWindow *window,
/* Client side child, expose */
if (child->impl == window->impl)
- _gdk_window_process_updates_recurse_helper ((GdkWindow *)child, clipped_expose_region);
+ {
+ /* ref the child to make this reentrancy safe for expose
+ handlers freeing other windows */
+ children[n_children++] = g_object_ref (child);
+ }
}
- g_list_free_full (children, g_object_unref);
+ for (i = 0; i < n_children; i++)
+ {
+ _gdk_window_process_updates_recurse_helper ((GdkWindow *)children[i],
+ clipped_expose_region);
+ g_object_unref (children[i]);
+ }
+
+
+ g_free (free_children);
out:
cairo_region_destroy (clipped_expose_region);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]