[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Speed up image.tostring with OpenGL ?



I know nothing of toonloop, so I'm guessing here, but I think your problem is not what you think it is, and from your problem description, it's likely you are not using openGL in the way it is meant to be used.

pygame.image.tostring is plenty fast, as fast as a pygame blit it's extremely unlikely it represents any kind of bottleneck whatsoever. If you want to test this yourself, temporarily hack your app to just keep sending the same string up to the card over and over again (i.e. eliminate the tostring call), and check your frame rate. I expect you'll see no difference at all.

Your slowness is probably caused by either uploading textures to opengl being a relatively slow operation (this is true no matter how you got the bytes to send to it) and/or your program being blocked by the OpenGL queue processing when you try to change a texture which there are pending operations on. (you aren't reusing the same single texture over and over again, are you?)

The speed of hardware acceleration really comes from 2 specific things - first is that you do complex operations on a set of textures which have already been uploaded to the card (meaning you make a lot of pixels draw with a relatively small set of vertex data being sent each frame), second is that you are taking advantage of parallelism by making the graphics card do work independently of your CPU (meaning you send commands that the graphics card can do on it's own time and won't block the rest of what your program does).

If you upload a new image every frame, you are not able to take advantage of the first way in which hardware acceleration speeds things up (you are basically sending all the pixels over to the card). If you are changing the content of textures as the graphics card is trying to draw them, you are not able to take advantage of the second way (the cpu ends up having to wait on the card being done with the texture before it can change it)

you are probably right to think the whole thing should be done in pygame, but there are probably ways you could speed stuff up if there is a good reason to stick with opengl.

The best way to do this in opengl, would be to load all the distinct frames into textures ahead of time, and then draw through them.

Barring that, you could probably make the routine at least twice as fast by rotating through a pool of textures (so that you are never waiting to change a texture as it's being drawn)

Also, you should probably use RGB instead of RGBX (should take 3/4ths the bandwidth to the card), there's no point in sending a dummy byte to the graphics card, when it comes to uploading textures, total bytes sent is generally much much more important than alignment issues.


On Sun, Jan 3, 2010 at 8:06 PM, Alexandre Quessy <alexandre@xxxxxxxxxx> wrote:
Hello Pygame users and developers !

Is there a way I can speed up the transfert from a surface to an
OpenGL texture ? Right now, I use the pygame.image.tostring function,
but it seems like converting the pixels to a Python str creates a
serious bottle neck in my stop motion application...

I think that it should either be implemented directly in Pygame, (best
option) or done using something like ctypes in my application. If none
of these option is not easy enough, I am thinking about switching to
Gstreamer+GTK with the GdkPixBuf, instead of Pygame surfaces. An other
option would be to rewrite the whole application in C++...

Any suggestion to fix this in a way that is not too long ?
My frame rate drops to 4 FPS when there are more than a few surfaces in my list.
Please try Toonloop to test this out. It works well on Linux. If
someone get it to work on Mac or Windows, I would need hints for
packaging it for those OS too. I convert the surfaces to OpenGL
texture in texture_from_image from the file
http://bitbucket.org/aalex/toonloop1/src/tip/toon/draw.py on what is
currently the line 42.
--