Monday, December 9, 2013

PyGame CFFI

One of the RaspberryPi's goals is to be a fun toolkit for school children (and adults!) to learn programming and electronics with. Python and pygame are part of this toolkit. Recently the RaspberryPi Foundation funded parts of the effort of porting of pypy to the Pi -- making Python programs on the Pi faster!

Unfortunately pygame is written as a Python C extension that wraps SDL which means performance of pygame under pypy remains mediocre. To fix this pygame needs to be rewritten using cffi to wrap SDL instead.

RaspberryPi sponsored a CTPUG (Cape Town Python User Group) hackathon to put together a proof-of-concept pygame-cffi. The day was quite successful - we got a basic version of the bub'n'bros client working on pygame-cffi (and on PyPy). The results can be found on github with contributions from the five people present at the sprint.

While far from complete, the proof of concept does show that there are no major obstacles to porting pygame to cffi and that cffi is a great way to bind your Python package to C libraries.

Amazingly, we managed to have machines running all three major platforms (OS X, Linux and Windows) at the hackathon so the code runs on all of them!

We would like to thank the Praekelt foundation for providing the venue and The Raspberry Pi foundation for providing food and drinks!

Cheers,
Simon Cross, Jeremy Thurgood, Neil Muller, David Sharpe and fijal.


12 comments:

  1. first of all pygame depends on SDL 1. Second ctypes kinda suck and I don't quite buy it's stability (especially with changing APIs, though it can be less of an issue with SDL). It's also slow on pypy

    ReplyDelete
  2. Ah, ok. Very nice work anyway. It's impressive what you all managed to get done in the sprint :)

    Here's some information from pygame land about where the project is heading.

    SDL 1 is the past, and the SDL developers are no longer putting out releases. However, I think many people will continue to patch it up for many years. SDL 2 is the future and after many years finally has a release out (2 now). pysdl2 is part of the future of pygame. pysdl2 matches the SDL 2 API as closely as possible. A pygame API ontop of pysdl2 is the future of pygame.

    ctypes is no good for some platforms like iOS, and the web and pypy apparently. Although note, that pysdl2 already 'works' on top of pypy.

    https://bitbucket.org/marcusva/py-sdl2/
    http://pysdl2.readthedocs.org/en/latest/


    Happy hacking :)

    ReplyDelete
  3. Amazing - you consider a messy cffi implementation (sometimes it builds on platform X, sometimes it does not, sometimes it works, sometimes it does not) a better choice over ctypes?

    ReplyDelete
  4. @Anonymous - your comment is pretty loaded, but we do think cffi is better than ctypes on all platforms, that's why we came up with cffi in the first place. I think cffi FAQ contains an answer to that.

    ReplyDelete
  5. @Rene: if pysdl2 is a bare-metal ctypes wrapper, writing a similar cffi wrapper instead should be very straightforward (even more than the current pygame-cffi). But do you know if pygame is really going that route, and if so, how soon?

    ReplyDelete
  6. I've been looking at cffi since it was first mentioned on our Pygame mailing list. It does look promising. I see only two, buffer related, issues that need to be resolved.

    First, PyPy lacks an array export mechanism comparable to the CPython PEP 3113 buffer protocol. Instead, only the NumPy Array Interface, version: 3 is available. Though Pygame supports both the Python and C sides of the interface, it relies on CPython's reference counting for timely buffer release [1]. Periodic garbage collection is too unpredictable.

    Second, the cffi module does not support CPython api function calls. So a cffi Pygame could not support the buffer protocol on CPython.

    A possible solution to the first issue is for PyPy to use an extended array interface that includes a PEP 3118 like buffer release callback. I am working to resolve the second issue: [Issue13797] Allow objects implemented in pure Python to export PEP 3118 buffers.

    [1] Add PEP 3118 (new) buffer support to Pygame surfaces

    ReplyDelete
  7. Hm, I can't get this to work on Ubuntu 12.04 doing the following

    virtualenv -p /usr/bin/pypy pypy
    cd pypy
    source bin/activate
    pip install git+https://github.com/eliben/pycparser.git
    pip install hg+https://github.com/eliben/pycparser.git
    pip install hg+https://bitbucket.org/cffi/cffi
    git clone https://github.com/CTPUG/pygame_cffi.git
    cd pygame_cffi/
    pypy
    import pygame

    >>>> import pygame
    Traceback (most recent call last):
    File "", line 1, in
    File "pygame/__init__.py", line 9, in
    from pygame.color import Color
    File "pygame/color.py", line 3, in
    from pygame._sdl import ffi, sdl
    File "pygame/_sdl.py", line 6, in
    ffi = cffi.FFI()
    File "/home/me/Documents/python/pygame/pypy/site-packages/cffi/api.py", line 56, in __init__
    import _cffi_backend as backend
    ImportError: No module named _cffi_backend


    dpkg -l pypy
    ...
    ii pypy 1.8+dfsg-2 fast alternative implementation of Python - PyPy interpreter


    Do I need a newer pypy? Am I missing something else?

    ReplyDelete
  8. I am +1 on porting PySDL2 to CFFI instead of pygame.

    ReplyDelete

  9. great! what's current status of it? I really can't wait to use Pygame on a PI through pypy.

    ReplyDelete
  10. Development occurs at https://github.com/CTPUG/pygame_cffi nowadays.

    ReplyDelete

See also PyPy's IRC channel: #pypy at freenode.net, or the pypy-dev mailing list.
If the blog post is old, it is pointless to ask questions here about it---you're unlikely to get an answer.