After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 314616 - Desktop very slow with image background.
Desktop very slow with image background.
Product: nautilus
Classification: Core
Component: Desktop
Other All
: Normal blocker
: 2.12.x
Assigned To: Nautilus Maintainers
Nautilus Maintainers
Depends on:
Blocks: 314617
Reported: 2005-08-26 20:50 UTC by Pat Suwalski
Modified: 2006-02-07 16:22 UTC
See Also:
GNOME target: 2.12.x
GNOME version: 2.11/2.12

Fix excessive redrawind on desktop (eel canvas) focus change (825 bytes, patch)
2005-08-29 20:33 UTC, Christophe Saout
none Details | Review
Patch for gtk+ which works around this (1.99 KB, patch)
2006-02-02 19:40 UTC, Federico Mena Quintero
none Details | Review
Updated gtk2-117163-cairo-repeat-pattern-workaround.diff (6.19 KB, patch)
2006-02-03 21:22 UTC, Federico Mena Quintero
committed Details | Review

Description Pat Suwalski 2005-08-26 20:50:20 UTC
Version details: garnome 2.11.92
Distribution/Version: Gentoo

Set background with an image, as opposed to solid colour. Grabbing an icon and
dragging it is severely lagged. Works properly with no background image.

Likely cairo-related?

The hardware is ATI Radeon M9 with all acceleration working properly.
Comment 1 Pat Suwalski 2005-08-26 20:55:29 UTC
I should also include that everything else desktop-related is slow, such as
opening the context menu: there is a very noticable delay from click to show.
Comment 2 Christophe Saout 2005-08-27 16:12:26 UTC
I'm also seeing this.

When changing focus from the desktop to another window, the X server is busy for
a third of a second. Most of the time this goes away after starting a fullscreen
OpenGL game and often comes back some hours later.

The X Server is stuck in fbblabla.o in a CopyArea operation. I couldn't figure
out what exactly was happening.

But when using a broken X server (where you get that funky repeat bug with cairo
that screws up your desktop) I'm seeing, that every time this happens the system
is busy to redraw the whole desktop.

It looks like there's an unnecessary expensive operation going on when drawing
the desktop. And he redraws the complete desktop every time it's getting or
losing focus (especially noticable and sucking with focus-follows-mousepointer).

I'm considering this a gnome 2.12 blocker.

If you need more information or help on debugging this, please tell me.
Comment 3 Pat Suwalski 2005-08-28 00:30:58 UTC
Seeing now that you are correct. The desktop is sluggish as I reported until I
started glxgears (note: no need for fullscreen). After that the desktop was as
snappy as ever.

I agree, this is a blocker. There is a serious redraw bug somewhere.
Comment 4 Luis Villa 2005-08-28 00:35:47 UTC
Hrm. I'm not seeing this at all. Cristophe, what X server are you seeing this on?
Comment 5 Pat Suwalski 2005-08-28 02:50:01 UTC
My xserver version string is as follows:

Gentoo (The X.Org Foundation, revision r0-0.1.2)
Comment 6 Christophe Saout 2005-08-28 10:50:57 UTC
I'm using the latest modular release (7.0rc0), but I saw the same with too. Also on Gentoo, but at least the modular release is pretty

I'm also using the ATI driver, on a Radeon Mobility and Radeon 8500. This might
have something to do with the ATI driver, some fallback to non-hardware
acceleration. I'm not sure. As I said, sometimes after starting certain programs
the problem goes away for some time. But when I'm switching between desktop and
programs very quickly, the CPU consumption is still high.
Comment 7 Christophe Saout 2005-08-28 14:39:30 UTC
I managed to get a gdb backtrace from nautilus while X was pausing:

(gdb) bt
  • #0 ??
  • #1 ??
  • #2 ??
  • #3 ??
  • #4 poll
    from /lib/
  • #5 _XWaitForReadable
    from /usr/lib/
  • #6 _XRead
    from /usr/lib/
  • #7 _XReply
    from /usr/lib/
  • #8 XSync
    from /usr/lib/
  • #9 _XSyncFunction
    from /usr/lib/
  • #10 XRenderComposite
    from /usr/lib/
  • #11 _cairo_xlib_surface_composite
    from /usr/lib/
  • #12 _cairo_surface_composite
    from /usr/lib/
  • #13 _cairo_surface_clip_and_composite_trapezoids
    from /usr/lib
  • #14 _cairo_gstate_clip_and_composite_trapezoids
    from /usr/lib/
  • #15 _cairo_gstate_fill
    from /usr/lib/
  • #16 cairo_fill_preserve
    from /usr/lib/
  • #17 cairo_fill
    from /usr/lib/
  • #18 gdk_window_clear_backing_rect
    from /usr/lib/libgdk-x11-2.0
  • #19 gdk_window_begin_paint_region
    from /usr/lib/libgdk-x11-2.0
  • #20 gtk_main_do_event
    from /usr/lib/
  • #21 gdk_window_process_updates_internal
    from /usr/lib/libgdk-x
  • #22 gdk_window_process_all_updates
    from /usr/lib/libgdk-x11-2.
  • #23 gdk_window_update_idle
    from /usr/lib/
  • #24 g_idle_dispatch
    from /usr/lib/
  • #25 g_main_context_dispatch
    from /usr/lib/
  • #26 g_main_context_iterate
    from /usr/lib/
  • #27 g_main_loop_run
    from /usr/lib/
  • #28 gtk_main
    from /usr/lib/

Comment 8 Christophe Saout 2005-08-28 15:30:10 UTC
With debug info. It's the

XRenderComposite (dpy=0x80fe5b0, op=3, src=..., mask=..., dst=..., src_x=0,
src_y=0, mask_x=0, mask_y=0, dst_x=0, dst_y=0, width=1024, height=768);

that is taking so much time. The gdb arguments are sometimes bogus, don't know
why (I checked using debug output, the arguments are actually ok)

(gdb) bt
  • #0 __kernel_vsyscall
  • #1 poll
    from /lib/
  • #2 _XWaitForReadable
    at XlibInt.c line 498
  • #3 _XRead
    at XlibInt.c line 1080
  • #4 _XReply
    at XlibInt.c line 1712
  • #5 XSync
    at Sync.c line 48
  • #6 _XSyncFunction
    at Synchro.c line 37
  • #7 XRenderComposite
    at Composite.c line 66
  • #8 _cairo_xlib_surface_composite
    at cairo-xlib-surface.c line 1131
  • #9 _cairo_surface_composite
    at cairo-surface.c line 841
  • #10 _cairo_surface_clip_and_composite_trapezoids
    at cairo-gstate.c line 1336
  • #11 _cairo_gstate_clip_and_composite_trapezoids
    at cairo-gstate.c line 1544
  • #12 _cairo_gstate_fill
    at cairo-gstate.c line 1590
  • #13 *INT_cairo_fill_preserve
    at cairo.c line 1598
  • #14 cairo_fill
    at cairo.c line 1576
  • #15 gdk_window_clear_backing_rect
    at gdkwindow.c line 1790
  • #16 IA__gdk_window_begin_paint_region
    at gdkwindow.c line 991
  • #17 IA__gtk_main_do_event
    at gtkmain.c line 1354
  • #18 gdk_window_process_updates_internal
    at gdkwindow.c line 2218
  • #19 IA__gdk_window_process_all_updates
    at gdkwindow.c line 2275
  • #20 gdk_window_update_idle
    at gdkwindow.c line 2137
  • #21 g_idle_dispatch
    at gmain.c line 3813
  • #22 IA__g_main_context_dispatch
    at gmain.c line 1934
  • #23 g_main_context_iterate
    at gmain.c line 2565
  • #24 IA__g_main_loop_run
    at gmain.c line 2769
  • #25 IA__gtk_main
    at gtkmain.c line 976
  • #26 main

Comment 9 Christophe Saout 2005-08-28 22:16:15 UTC
And the Xserver:

  • #0 fbCopyAreammx
    at fbmmx.c line 2241
  • #1 fbCompositeCopyAreammx
    at fbmmx.c line 2283
  • #2 fbComposite
    at fbpict.c line 1297
  • #3 XAAComposite
    at xaaPict.c line 529
  • #4 damageComposite
    at damage.c line 539
  • #5 CompositePicture
    at picture.c line 1667
  • #6 ProcRenderComposite
    at render.c line 755
  • #7 ProcRenderDispatch
    at render.c line 1995
  • #8 Dispatch
    at dispatch.c line 459
  • #9 main
    at main.c line 450

Comment 10 Arthur Taylor 2005-08-29 00:08:33 UTC
Noticed that it doesn't even have to be a graphical glx app to 'speed up' the
desktop, as running glxinfo will temporarily stop the slow performance. Also
noticed that this performace slowdown happens after starting nautilus, after
changing the background and after changing the gtk-theme.

I believe this might be a radeon-driver-xrender-acceleration related issue, as
there is no strange slowdown if you run an xserver with no acceleration at all.
Comment 11 Christophe Saout 2005-08-29 00:39:47 UTC
The more I am debugging this the more I' coming to the conclusion that this
massive slowdown is actually some weird Xorg bug. I mean, why are these simple
1024x768 copy operations in memory so damn slow?!

Well, but still. Why does nautilus redraw the whole desktop when it gets or
loses the focus? There isn't any actual visible change.

Can someone try to figure out what the old GTK+/Nautilus did different and why
there was no slowdown?
Comment 12 Pat Suwalski 2005-08-29 01:43:18 UTC
If by old you mean 2.10.x, then it's simply the lack of cairo.
Comment 13 Christian Neumair 2005-08-29 10:06:29 UTC
Maybe you could check whether nautilus_icon_container_set_margins and/or
nautilus_file_background_read_desktop_settings is invoked when the excessive
redraws take place?
Comment 14 Christophe Saout 2005-08-29 14:32:05 UTC

But I just set a breakpoint at gdk_window_schedule_update and it looks fairly
obvious (or is that just my impression?):

  • #0 gdk_window_schedule_update
    at gdkwindow.c line 2146
  • #1 IA__gdk_window_invalidate_maybe_recurse
  • #2 IA__gdk_window_invalidate_maybe_recurse
  • #3 IA__gdk_window_invalidate_region
  • #4 IA__gdk_window_invalidate_rect
  • #5 IA__gtk_widget_queue_draw_area
  • #6 IA__gtk_widget_queue_draw
    at gtkwidget.c line 2536
  • #7 handle_focus_in_event
    from /usr/lib/
  • #8 _gtk_marshal_BOOLEAN__BOXED
  • #9 g_closure_invoke
    from /usr/lib/
  • #10 signal_emit_unlocked_R
    from /usr/lib/
  • #11 g_signal_emit_valist
    from /usr/lib/
  • #12 g_signal_emit
    from /usr/lib/
  • #13 gtk_widget_event_internal
    at gtkwidget.c line 3735
  • #14 do_focus_change
    at gtkwindow.c line 4608
  • #15 _gtk_window_set_is_active
  • #16 gtk_window_focus_in_event
    at gtkwindow.c line 4630
  • #17 _gtk_marshal_BOOLEAN__BOXED
  • #18 g_type_class_meta_marshal
    from /usr/lib/
  • #19 g_closure_invoke
    from /usr/lib/
  • #20 signal_emit_unlocked_R
    from /usr/lib/
  • #21 g_signal_emit_valist
    from /usr/lib/
  • #22 g_signal_emit
    from /usr/lib/
  • #23 gtk_widget_event_internal
    at gtkwidget.c line 3735
  • #24 IA__gtk_main_do_event
    at gtkmain.c line 1375
  • #25 gdk_event_dispatch
    at gdkevents-x11.c line 2291
  • #26 g_main_context_dispatch
    from /usr/lib/
  • #27 g_main_context_iterate
    from /usr/lib/
  • #28 g_main_loop_run
    from /usr/lib/
  • #29 IA__gtk_main
    at gtkmain.c line 976
  • #30 main

static gboolean
handle_focus_in_event (GtkWidget *widget, GdkEventFocus *event, gpointer user_data)
        update_selected (NAUTILUS_ICON_CONTAINER (widget));
        gtk_widget_queue_draw (widget);

        return FALSE;
Comment 15 Christophe Saout 2005-08-29 14:35:55 UTC
Ok, sorry. This should of course only update the selected icons. Investigating...
Comment 16 Christophe Saout 2005-08-29 16:06:04 UTC
Well, something is going wrong in the clipping logic.

I just added some debug output to cairo_rectangle, cairo_clip and cairo_fill.
And I'm always getting this sequence when focussing/unfocussing the desktop:

rectangle: 0:0 1024x768
rectangle: 0:0 1024x768

It doesn't matter whether icons are selected or not, it's always this sequence. 

While selecting/deselecting icons the clipping/redrawing operations are normal.
Comment 17 Christian Neumair 2005-08-29 17:12:47 UTC
Christophe: When a redraw of the whole widget is queued, the whole area is
invalidated, meaning that your whole desktop is redrawn. The diff of the
original functionality is available under [1]. The rationale was obviously that
different colors may be used for the selected items depending on whether the
canvas has focus or not.
Why this redraw is additionally requested by Nautilus, although
eel_canvas_item_request_redraw in update_selected already invalidates the icon
rectangles stays dubious.
Dave, do you remember why exactly you added this call?

Comment 18 Christophe Saout 2005-08-29 20:33:53 UTC
Created attachment 51523 [details] [review]
Fix excessive redrawind on desktop (eel canvas) focus change

The actual fix seems easy. I just removed the calls to gtk_widget_queue_draw()
and it still works. eel_canvas_item_request_update() schedules the correct
redrawing procedure using gdk_window_invalidate_rect() itself.
Comment 19 Alexander Larsson 2005-08-31 13:42:30 UTC
Most Gtk+ widgets typically queue a full redraw on focus in/out. Even GtkWidget
itself does this, which is likely why dave added that code when he overrode the
parent handle_focus_in_event. This is generally needed because colors can change
when focus changes.

However, for the nautilus icon container the only things that change on focus is
the color of the selection in a rename editor and the icon + text color of the
selection. These are redrawn separately, and indeed work with the patch applied,
so it should be safe.

Even so, the copying of a full-screen pixmap to another pixmap should not take
so long time, so someone should try to figure out the X server bug and report that.
Comment 20 Frederic Crozat 2005-08-31 14:06:06 UTC
this problem is a bug in Radeon acceleration code in 6.9, triggered by
Cairo, when it is using XRenderComposite to render background. On older X
server, Cairo is using XCopyArea because of a bug in Render in old X servers.

This bug can be workaround by running glxinfo (seems to reset Radeon
acceleration code) or adding Options NoAccel "true" in xorg.conf.

Mandriva bug :
Comment 21 Frederic Crozat 2005-08-31 14:17:17 UTC
I've opened a bug on :
Comment 22 Alexander Larsson 2005-09-01 09:32:15 UTC
I've commited the focus redraw fix. I'm not sure there is much more we can do
from the gnome side. We just need to get the Xserver fixed. I'm closing this but
as NOTGNOME. Please follow up in the bug.
Comment 23 Federico Mena Quintero 2006-02-02 19:40:07 UTC
Created attachment 58604 [details] [review]
Patch for gtk+ which works around this

This is a bug in Cairo/XRENDER.  They get slow if one uses CAIRO_EXTEND_REPEAT for a source pixmap pattern with a pixmap surface as the destination.

GTK+ always turns on CAIRO_EXTEND_REPEAT when clearing the double-buffer pixmap for windows which have a pixmap background set on them.  With this patch, we detect whether the pixmap background is smaller than the window, and only turn on CAIRO_EXTEND_REPEAT in that case.  This makes Nautilus draw the desktop quickly again.
Comment 24 Federico Mena Quintero 2006-02-03 21:22:45 UTC
Created attachment 58673 [details] [review]
Updated gtk2-117163-cairo-repeat-pattern-workaround.diff

This patch fixes the offsetting bug in the previous patch.  It is what I've committed to GTK+ HEAD and gtk-2-8.

2006-02-03  Federico Mena Quintero  <>

	Work around,
	which used to be our own  If one uses a
	pixmap for a pattern in Cairo, and sets the pattern to
	CAIRO_EXTEND_REPEAT; and if the destination surface is also a
	pixmap, Cairo does a slow copy instead of using XCopyArea().  So,
	we use the same code that we used in GTK+ 2.6 (pre-cairo), by
	filling the double-buffer pixmap with a tiled GC and

	* gdk/gdkwindow.c (BackingRectMethod): New structure with a
	cairo_t and a GdkGC field.  Depending on which of these fields
	gets filled in, we'll use Cairo or GDK to clear the double-buffer
	pixmap when painting a window.
	(setup_backing_rect_method): Fill a BackingRectMethod as
	appropriate, depending on the window's configuration and our
	knowledge of whether Cairo is fast or slow when doing repeating
	(gdk_window_clear_backing_rect): Call
	setup_backing_rect_method().  Depending on what it returns, use
	Cairo to clear the double-buffer pixmap, or plain GDK.
Comment 25 Pat Suwalski 2006-02-06 22:12:12 UTC
I applied the patch to the gtk+2.8.11 in Gentoo and it seems to work as advertised. The desktop certainly feels snappier.