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>