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.

<div><br></div><div>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.</div><div><br>

</div><div>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):</div><div>
<a href="http://alumni.media.mit.edu/%7Eerikb/tmp/test.zip" target="_blank">http://alumni.media.mit.edu/~erikb/tmp/test.zip</a></div>

<div><br></div><div>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.<br>

<br><br><span style="font-family: courier new,monospace;">import gtk, gobject</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">import cairo</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">class DragTest( gtk.DrawingArea ):</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">    __gsignals__ = {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        "expose-event": "override",</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">        "on-mouse-move": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)),</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        "on-mouse-down": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)),</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">    }</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    def __init__(self):</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">        gtk.DrawingArea.__init__(self)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        self.set_events(gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.BUTTON_PRESS_MASK)</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">        self.connect("motion_notify_event", self.__on_mouse_move)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        self.connect("button_press_event", self.__on_button_press)</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        self.box_w = 1210</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        self.box_h = 910</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        self.box_type = 0</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        self.box_x = 0</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">        self.box_y = 0</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        self.cairo_img = cairo.ImageSurface( cairo.FORMAT_ARGB32, self.box_w, self.box_h )</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">        ctx = cairo.Context( self.cairo_img )</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        ctx.set_source_rgb( 0, 0, 1 )</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">        ctx.rectangle( 0, 0, self.box_w, self.box_h )</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        ctx.fill( )</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        self.cairo_file_img = cairo.ImageSurface.create_from_png( "bg.png" )</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        self.pixbuf = gtk.gdk.pixbuf_new_from_file( "bg.png" )</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    def __on_mouse_move(self, area, event):</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">        self.box_x, self.box_y, mods = self.get_window().get_pointer()</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        self.queue_draw( )</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    def __on_button_press(self, area, event):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        self.box_type += 1</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">        if (self.box_type > 3):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">            self.box_type = 0</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">        self.queue_draw( )</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">    def do_expose_event(self, event):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        context = self.window.cairo_create()</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        # clip to the visible part</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        context.rectangle(event.area.x, event.area.y,</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">                          event.area.width, event.area.height)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        context.clip()</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        if (self.box_type == 0):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">            context.set_source_rgb( 0, 1, 0 )</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        elif (self.box_type == 1):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">            context.set_source_surface( self.cairo_file_img, self.box_x, self.box_y )</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        elif (self.box_type == 2):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">            context.set_source_surface( self.cairo_img, self.box_x, self.box_y )</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        elif (self.box_type == 3):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">            context.set_source_pixbuf( self.pixbuf, self.box_x, self.box_y )</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        context.rectangle( self.box_x, self.box_y, self.box_w, self.box_h )</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">        context.fill( )</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">window = gtk.Window()</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">window.set_size_request( 1210, 910 )</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">window.connect( "delete_event", lambda *args: gtk.main_quit() )</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">window.add( DragTest() )</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">window.show_all()</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">gtk.main()</span><br style="font-family: courier new,monospace;">

<br></div>
<div><br></div>