question about bad cairo performance on the olpc xo

Erik Blankinship erikb at
Fri Sep 3 01:49:27 EDT 2010

I need help understanding why I am getting very poor frame rates when I use
pycairo to move a large image around the screen on an olpc XO.  When I use
pycairo to draw a rectangle of the same size on an XO, I get great
performance!  This is confusing to me because in my experience on other
platforms, redrawing vector graphics is much, much slower than blitzing
bitmaps to the screen.

Is there something particular about the XO hardware, its software stack, or
cairo which retards the performance of displaying images?  The same test
case runs fine on my desktop machine.

Thank you!  Below is testing code and here is a link if you'd like to try it
yourself in the gnome desktop on an XO (the same performance problems also
occur when run as part of a sugar activity):<>

software notes: click to change the rectangle paint mode.   Green is a cairo
vector rectangle.  Red-1 is a cairo image surface created by loading a png.
 Blue is a cairo generated image_surface.  Red-1 is a gdk pixbuf created by
loading a png.

import gtk, gobject

import cairo

class DragTest( gtk.DrawingArea ):

    __gsignals__ = {
        "expose-event": "override",
        "on-mouse-move": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
        "on-mouse-down": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,

    def __init__(self):
        self.set_events(gtk.gdk.POINTER_MOTION_MASK |
        self.connect("motion_notify_event", self.__on_mouse_move)
        self.connect("button_press_event", self.__on_button_press)

        self.box_w = 1210
        self.box_h = 910

        self.box_type = 0
        self.box_x = 0
        self.box_y = 0
        self.cairo_img = cairo.ImageSurface( cairo.FORMAT_ARGB32,
self.box_w, self.box_h )
        ctx = cairo.Context( self.cairo_img )
        ctx.set_source_rgb( 0, 0, 1 )
        ctx.rectangle( 0, 0, self.box_w, self.box_h )
        ctx.fill( )

        self.cairo_file_img = cairo.ImageSurface.create_from_png( "bg.png" )

        self.pixbuf = gtk.gdk.pixbuf_new_from_file( "bg.png" )

    def __on_mouse_move(self, area, event):
        self.box_x, self.box_y, mods = self.get_window().get_pointer()
        self.queue_draw( )

    def __on_button_press(self, area, event):
        self.box_type += 1
        if (self.box_type > 3):
            self.box_type = 0
        self.queue_draw( )

    def do_expose_event(self, event):
        context = self.window.cairo_create()

        # clip to the visible part
        context.rectangle(event.area.x, event.area.y,
                          event.area.width, event.area.height)

        if (self.box_type == 0):
            context.set_source_rgb( 0, 1, 0 )

        elif (self.box_type == 1):
            context.set_source_surface( self.cairo_file_img, self.box_x,
self.box_y )

        elif (self.box_type == 2):
            context.set_source_surface( self.cairo_img, self.box_x,
self.box_y )

        elif (self.box_type == 3):
            context.set_source_pixbuf( self.pixbuf, self.box_x, self.box_y )

        context.rectangle( self.box_x, self.box_y, self.box_w, self.box_h )
        context.fill( )

window = gtk.Window()
window.set_size_request( 1210, 910 )
window.connect( "delete_event", lambda *args: gtk.main_quit() )
window.add( DragTest() )
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the Devel mailing list