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.


10 comments:

Rene Dudfield said...

Why not use the ctypes based pysdl2?

Maciej Fijalkowski said...

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

Rene Dudfield said...

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 :)

Anonymous said...

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?

Maciej Fijalkowski said...

@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.

Armin Rigo said...

@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?

Lenard Lindstrom said...

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

Anonymous said...

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?

Maciej Fijalkowski said...

yes, you need a vastly newer pypy

anatoly techtonik said...

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