lxdm-greeter-gtk excessive CPU usage

Bug #733912 reported by Andrey Bondarenko on 2011-03-12
14
This bug affects 2 people
Affects Status Importance Assigned to Milestone
LXDE
Unknown
Unknown
lxdm (Ubuntu)
Medium
Julien Lavergne

Bug Description

Binary package hint: lxdm

On my system with Celeron (P-III Tualatin) 1.4GHz (cpuinfo.txt) processor lxdm-greeter-gtk constantly uses about 20-30% of CPU power, it is too much.

The issue can only be reproduced if background image is set (bg=<path to file>) in /etc/lxdm/default.conf (pidstat-with-bg.txt). If there is no background image, lxdm-greeter-gtk consumes only about 2-3% of CPU (see pidstat-without-bg.txt).

I beleive the cause is poorly designed redrawing algorithm. Callgrind shows that on_expose function consumes about 50% of CPU instructions with background image (see callgrind-with-bg.txt). When background image is not set callgrind didn't show this function at all.

Related branches

Andrey Bondarenko (abone) wrote :
Andrey Bondarenko (abone) wrote :
Andrey Bondarenko (abone) wrote :
Andrey Bondarenko (abone) wrote :
Andrey Bondarenko (abone) wrote :
Andrey Bondarenko (abone) wrote :

I'm sorry, forgot to mention. I've found reported issue in Maverick package version lxdm-0.2.0-0ubuntu3.

Julien Lavergne (gilir) wrote :

Thank you for your bug report. Could you try with Ubuntu or Lubuntu Natty (11.04). There was some fixes regarding lxdm and the background rendering in lxdm 0.3.0.
You can also test lxdm 0.3.0 in LXDE PPA : https://launchpad.net/~lxde/+archive/ppa

Changed in lxdm (Ubuntu):
status: New → Incomplete
importance: Undecided → Medium
SteVe Cook (yorvyk) wrote :

High cpu usage still occurring in Natty with lxdm 0.3.0. 60% cpu with a 2 GHz P4.

Andrey Bondarenko (abone) wrote :

Both versions are affected because on_expose function was not changed. If you check serc/greeter.c::on_expose, you will see that this function redraws entire screen on each call:

    if( bg_img )
    {
        cairo_matrix_t matrix;
        double x = 0, y = 0, sx, sy;
        cairo_get_matrix(cr, &matrix);
        sx = (double)gdk_screen_width() / (double)gdk_pixbuf_get_width(bg_img);
        sy = (double)gdk_screen_height() / (double)gdk_pixbuf_get_height(bg_img);
        cairo_scale(cr, sx, sy);
        gdk_cairo_set_source_pixbuf(cr, bg_img, x, y);
        cairo_paint(cr);
        cairo_set_matrix(cr, &matrix);
    }

Witn src/greeter.c::on_timeout function which changes system time every second, it leads to full screen redraw every second. In my case it means to scale 800x800 pixels wallpaper image and put it on 1600x900 pixel screen. This algorithm just cannot work fast or consume ow CPU.

It need to use information from evt and redraw only affected area. Also, I think it should cache pre-scaled bitmap.

Sorry, I have no experience in GTK/Cairo programming and cannot provide a patch right now.

Julien Lavergne (gilir) wrote :

Thank your for the analysis. Deconnecting the on_expose function to expose-event fix the flickering and I suppose the CPU usage. IMO, background need only to be draw on creation of the window, it should not change during teh "life" of the window. I'll try to make a proper patch.

Changed in lxdm (Ubuntu):
status: Incomplete → In Progress
assignee: nobody → Julien Lavergne (gilir)
Julien Lavergne (gilir) wrote :

Could you test with the lxdm package in my PPA : https://launchpad.net/~gilir/+archive/lubuntu ?
There are still flickering in natty, but it seems to be another problem.

Andrey Bondarenko (abone) wrote :

PPA version lxdm_0.3.0-0ubuntu5~ppa3 still uses about 20-30% of CPU on my box.

Julien Lavergne (gilir) wrote :

Thanks for the testing. Unfortunatly, I was not enable to do a better solution to improve the drawing. I think the better solution is just to remove this on_expose function. I'm not even sure it's really necessary because the background should be managed by the theme.
I'll publish another package in the PPA with this fix (version ~ppa5).

Andrey Bondarenko (abone) wrote :

Version lxdm_0.3.0-0ubuntu5~ppa5 does not use CPU, but now it also ignores any background image settings, as if bg= was not set at all. Probably on_expose should be called at least once.

Also, there is on_screen_size_changed, function in greeter.c. I don't know what it is, but we probably should redraw on screen size changes as well. Can't imagine when screen size can change, may be on mobile devices because of rotation?

Julien Lavergne (gilir) wrote :

Upstream proposed another fix for this problem. Could you test version lxdm - 0.3.0-0ubuntu5~ppa8 in my PPA ?

Andrey Bondarenko (abone) wrote :

I'll test ppa8 version a bit later and get back with results, but I'm afraid it won't help.

I've tried to implement fix proposed by upstream myself based on ppa3 version (using gdk_cairo_rectangle + cairo_fill). Looks like it is cairo performance problem. The following implementation of on_expose function produces 20-30%CPU:

static gboolean on_expose(GtkWidget* widget, GdkEventExpose* evt, gpointer user_data)
{
    cairo_t *cr = gdk_cairo_create(evt->window);
    gdk_cairo_set_source_pixbuf (cr, bg_img, 0, 0);
    gdk_cairo_rectangle(cr, &evt->area);
    cairo_fill(cr);
    cairo_destroy(cr);
    return FALSE;
}

Falling back to deprecated api uses only 1-2% CPU (need -DGDK_ENABLE_DEPRECATED and -DGDK_PIXBUF_ENABLE_DEPRECATED compile flags):

static gboolean on_expose(GtkWidget* widget, GdkEventExpose* evt, gpointer user_data)
{
    GdkGC *gc = gdk_gc_new(evt->window);
    gdk_draw_pixbuf(evt->window,
                    gc,
                    bg_img,
                    evt->area.x, evt->area.y,
                    evt->area.x, evt->area.y,
                    evt->area.width, evt->area.height,
                    GDK_RGB_DITHER_NONE, 0, 0);
    g_object_unref(gc);
    return FALSE;
}

Looks like a new API 20-30 time slower than an old one. May be this was fixed in never versions of gdk. Here in maverick I have:

libgdk2.0-0 version 2.22.0-0ubuntu1
libgdk-pixbuf2.0-0 version 2.22.0-0ubuntu1
libcairo2 version 1.10.0-1ubuntu3

Julien Lavergne (gilir) wrote :

Yes, difficult to say where the bug is in the stack.

Steve, could you test the last version in my PPA and see if the CPU usage is still high on Natty ?

SteVe Cook (yorvyk) wrote :

3% CU usage with ppa10 version down from 27% with ppa8 version.
1 GHz Duron and ATI Rage 128.

Julien Lavergne (gilir) wrote :

Thanks Steve.
I'll upload upstream fix, and assume the other part of the performance problem is fixed in newer versions of gtk + cairo, available in Natty.

Launchpad Janitor (janitor) wrote :

This bug was fixed in the package lxdm - 0.3.0-0ubuntu5

---------------
lxdm (0.3.0-0ubuntu5) natty; urgency=low

  * debian/patches/90_simple_expose.patch
   - From upstream, rework the expose-event callback which have a high CPU
     usage (LP: #733912)
  * debian/patches/20_disable_resize_grip.patch
   - Disable resize grip which break the background drawing (LP: #703658)
 -- Julien Lavergne <email address hidden> Sun, 20 Mar 2011 00:31:24 +0100

Changed in lxdm (Ubuntu):
status: In Progress → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.