[pygtk] Animation performance - limitation or my code?

Tomeu Vizoso tomeu at sugarlabs.org
Tue Sep 1 17:22:47 WST 2009


On Tue, Sep 1, 2009 at 11:10, Kim Adil<kadil at proactiveindustrial.net> wrote:
> Hi Tomeu
>
> Maybe you could help me interpret the results? Nothing really stands out to
> me.

Those results imply that the python side of things does very little
work at all. So this profiler won't be of use for you from now on and
you should profile the C side.

For a first quick try, sysprof has worked well for me in the past.
systemtap is good as well but has a steeper learning curve.

HTHs,

Tomeu

> Thanks,
> Kim
>
> Tomeu Vizoso wrote:
>>
>> On Tue, Sep 1, 2009 at 07:34, Kim Adil<kadil at proactiveindustrial.net>
>> wrote:
>>
>>>
>>> I once wrote a gtk program in C that displayed about 30 animations on a
>>> drawing area and they moved around the screen, and performance was
>>> excellent. The drawingarea size was 1600x1200 and the animations were
>>> very smooth.
>>>
>>> I have started to write a similar app using pygtk in a more object
>>> oriented way, and the drawing area size really seems to have a large
>>> impact on performance. When the drawing area is 100x100, anims are
>>> smooth. If the drawing area is dragged to 1000x1000 the frame rate drops
>>> very quickly. Is this to be expected with the python being interpreted,
>>> or is it just that my code is inefficient. See sample below (requires 2
>>> animated gif files a.gif and a2.gif, just substitute any from the web for
>>> demonstartion, and a glade file attached):
>>>
>>
>> I recommend you that take the time to profile it with a tool such as this
>> one:
>>
>> http://www.vrplumber.com/programming/runsnakerun/
>>
>> That will tell which part of your program is taking most of the cpu
>> and you won't need to guess.
>>
>> Regards,
>>
>> Tomeu
>>
>>
>>>
>>> #!/usr/bin/env python
>>> import sys
>>> import pygtk
>>> import glib
>>> import gtk
>>> import gtk.glade
>>> # main window to display objects in motion
>>>
>>> i=1
>>> class MainWin:
>>>   def __init__(self):
>>>       self.gladefile = "hv.glade"
>>>       self.wTree = gtk.glade.XML(self.gladefile, "main_win")
>>>       dic = {"on_drawingarea1_expose_event" : self.expose,
>>>              "on_drawingarea1_configure_event": self.configure,
>>>              }
>>>       self.wTree.signal_autoconnect(dic)
>>>       self.window = self.wTree.get_widget("main_win")
>>>       self.da = self.wTree.get_widget("drawingarea1")
>>>       self.window.show_all()
>>>       x, y, width, height = self.da.get_allocation()
>>>       self.pixmap = gtk.gdk.Pixmap(self.da.window, width, height)
>>>       self.machlist = []
>>>       self.setup_objects()
>>>       glib.timeout_add(30, self.draw_objects)
>>>
>>>   def setup_objects(self):
>>>       self.machlist.append(Object('t1','v','stopped',10,10,'a.gif'))
>>>       self.machlist.append(Object('t2','v','travelling',300,10,'a2.gif'))
>>>       self.machlist.append(Object('t3','v','stopped',100,300,'a.gif'))
>>>       self.machlist.append(Object('t4','v','stopped',600,600,'a2.gif'))
>>>       self.machlist.append(Object('t5','v','stopped',100,60,'a.gif'))
>>>       self.machlist.append(Object('t6','f','stopped',60,100,'a.gif'))
>>>       self.machlist.append(Object('t7','f','travelling',100,100,'a.gif'))
>>>
>>>   def draw_objects(self):
>>>       x, y, width, height = self.da.get_allocation()
>>>       self.pixmap = gtk.gdk.Pixmap(self.da.window, width, height)
>>>       self.pixmap.draw_rectangle(self.da.get_style().white_gc,True, 0,
>>> 0, width, height)
>>>       for object in self.machlist:
>>>
>>>
>>> self.pixmap.draw_pixbuf(self.da.get_style().fg_gc[gtk.STATE_NORMAL],object.pb,
>>> 0, 0, object.x,object.y)
>>>       return True
>>>   def expose(self,a,b):
>>>       x, y, width, height = self.da.get_allocation()
>>>
>>>
>>> self.da.window.draw_drawable(self.da.get_style().fg_gc[gtk.STATE_NORMAL],self.pixmap,
>>> x, y, x, y, width, height)
>>>       self.da.queue_draw_area(x, y, width, height)
>>>       return False
>>>
>>>   def configure(self,a,b):
>>>       x, y, width, height = self.da.get_allocation()
>>>
>>>
>>> self.da.window.draw_drawable(self.da.get_style().fg_gc[gtk.STATE_NORMAL],self.pixmap,
>>> x, y, x, y, width, height)
>>>       return False
>>>
>>>   def cleanup(self):
>>>       for object in self.machlist:
>>>           glib.source_remove(object.timeout)
>>>
>>>   def list_objects(self):
>>>       self.draw_objects()
>>>       for object in self.machlist:
>>>
>>>
>>> self.pixmap.draw_pixbuf(self.da.get_style().fg_gc[gtk.STATE_NORMAL],object.pb,
>>> 0, 0, 0, 0)
>>>       #self.da.queue_draw()
>>> class Object:
>>>   def __init__(self,name,model,state,x,y,anim):
>>>       self.name=name
>>>       self.model=model
>>>       self.state=state
>>>       self.x=x
>>>       self.y=y
>>>       self.anim=anim
>>>       self.image='l'
>>>       self.frame=0
>>>       self.imagef = gtk.Image()
>>>       self.pixbufanim = gtk.gdk.PixbufAnimation(anim)
>>>       print 'width %d - height
>>> %d'%(self.pixbufanim.get_width(),self.pixbufanim.get_height())
>>>       self.pbiter = self.pixbufanim.get_iter()
>>>       print 'delay time %d'%(self.pbiter.get_delay_time())
>>>       self.pb=self.pbiter.get_pixbuf()
>>>       self.t=glib.timeout_add(self.pbiter.get_delay_time(),
>>> self.update_pb)
>>>
>>>   def update_pb(self):
>>>       self.pbiter.advance()
>>>       self.pb=self.pbiter.get_pixbuf()
>>>       self.t=glib.timeout_add(self.pbiter.get_delay_time(),
>>> self.update_pb)
>>>       return False
>>>
>>>
>>> print 'create mainwin'
>>> m=MainWin()
>>> gtk.main()
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> pygtk mailing list   pygtk at daa.com.au
>>> http://www.daa.com.au/mailman/listinfo/pygtk
>>> Read the PyGTK FAQ: http://faq.pygtk.org/
>>>
>>>
>>
>>
>>
>>
>
>



-- 
«Sugar Labs is anyone who participates in improving and using Sugar.
What Sugar Labs does is determined by the participants.» - David
Farning


More information about the pygtk mailing list