Why my simple scene run too slow ?

10 views
Skip to first unread message

Juan Jose Alonso

unread,
Mar 6, 2008, 7:00:30 PM3/6/08
to pyglet-users
Hi guys, have a problem on my game, here extract a little version of
my game that also have the fps problem.
also i can see the pink tinted, alpha channel of the ,png images about
one second at window startup.

Here a link with my simple example for run it.
http://dump.no/files/ccaffc285aeb/test.zip

And here the code for see without download it. (without images)

http://rafb.net/p/79RQlB27.html


Someone can help me? on my two machines i get 13fps aprox. (And i dont
have problems running others pyglet stuff)
I test on WindowsXP and Ubuntu Linux, with pyglet 1.0.


Happy hacking and blessed :)

Txema Vicente

unread,
Mar 6, 2008, 8:26:49 PM3/6/08
to pyglet...@googlegroups.com
I don't understand too much this engine class, but if you do this:

scenes.py
+from pyglet import image
-self.tile = engine.resource.load('grass1.png')
+self.tile = image.load('grass1.png')

It works at 96FPS (I also removed fps limit and vsync), so I bet the problem
is related to your resource loader. Anyway, with pyglet I get far more FPS,
so there is something wrong.

Besides, may be pyglet 1.1 has what you need:
http://pyglet.org/doc/1.1/api/pyglet.resource-module.html

> --
> No virus found in this incoming message.
> Checked by AVG Free Edition.
> Version: 7.5.516 / Virus Database: 269.21.5/1314 - Release Date:
> 05/03/2008 18:38
>
>

Drew Smathers

unread,
Mar 6, 2008, 8:38:14 PM3/6/08
to pyglet...@googlegroups.com

I only took a few seconds to look at your code, but I'm pretty sure
it's because you're calling blit 247 times per frame. The first
optimization is to use a display list (it will at least save you all
those excess function calls). I think there is `batch' feature in
pyglet which might help, but I haven't looked into it much yet - so
take my advice with a grain salt there. There is another much more
involved optimization that entails ordering your renderable objects by
driver state - but that would require overriding or monkey-patching
blit on Texture.

Cheers,
--
\\\\\/\"/\\\\\\\\\\\
\\\\/ // //\/\\\\\\\
\\\/ \\// /\ \/\\\\
\\/ /\/ / /\/ /\ \\\
\/ / /\/ /\ /\\\ \\
/ /\\\ /\\\ \\\\\/\
\/\\\\\/\\\\\/\\\\\\
d.p.s

Txema Vicente

unread,
Mar 6, 2008, 9:38:01 PM3/6/08
to pyglet...@googlegroups.com
> I only took a few seconds to look at your code, but I'm pretty sure
> it's because you're calling blit 247 times per frame. The first
> optimization is to use a display list (it will at least save you all
> those excess function calls). I think there is `batch' feature in
> pyglet which might help, but I haven't looked into it much yet - so
> take my advice with a grain salt there. There is another much more
> involved optimization that entails ordering your renderable objects by
> driver state - but that would require overriding or monkey-patching
> blit on Texture.

Yes, it seems the 247 blits are killing fps, too.
I did say that something was wrong, but I get the same 96 FPS with this
simple test code, and reducing the range increases drastically fps:

#Grass Test
#------------------------------------------

from pyglet import window,clock,image
from pyglet.gl import *

test=image.load('grass1.png')
win = window.Window(width=800,height=600,vsync=False)
clo = clock.Clock()
clo.set_fps_limit(0)

def render():
global test
for x in range(13):
for y in range(19):
test.blit(x*60,y*30)

glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

while not win.has_exit:
glClear(GL_COLOR_BUFFER_BIT)
win.dispatch_events()
dt=clo.tick()
render()
win.flip()
win.set_caption("FPS="+str(int(clo.get_fps())))

Richard Jones

unread,
Mar 6, 2008, 10:06:01 PM3/6/08
to pyglet...@googlegroups.com
On Fri, Mar 7, 2008 at 1:38 PM, Txema Vicente <tx...@nabla.net> wrote:
Yes, it seems the 247 blits are killing fps, too.
I did say that something was wrong, but I get the same 96 FPS with this
simple test code, and reducing the range increases drastically fps:

blit() is definitely not designed for high performance. The new graphics batch and related sprite functionality in pyglet 1.1 *is*.

I thought the performance of blit() was mentioned in the programming guide, but it's not. I'll add a note now (though it won't be on the website until an update is pushed out).


    Richard

Message has been deleted

Juan Jose Alonso

unread,
Mar 7, 2008, 6:56:51 AM3/7/08
to pyglet-users
I get only 14 fps with your example code.

:-/ same that with my code.

Txema Vicente

unread,
Mar 7, 2008, 8:55:53 AM3/7/08
to pyglet...@googlegroups.com
OK, I found the reason.

I always use -O, that makes the difference.

It is due to opengl error checking.


Txema Vicente

unread,
Mar 7, 2008, 9:05:23 AM3/7/08
to pyglet...@googlegroups.com
options['gl_error_check'] = False

> is related to your resource loader.

I was wrong, I tried your original code without optimization, and my
version with it.

Drew Smathers

unread,
Mar 7, 2008, 10:57:51 AM3/7/08
to pyglet...@googlegroups.com
On Fri, Mar 7, 2008 at 6:56 AM, Juan Jose Alonso
<kernel....@gmail.com> wrote:
>
> I get only 14 fps with your example code.
>
> :-/ same that with my code.
>

Consider the differences between your hw specs and use something as a
benchmark - what kind of framerates are you getting on the examples,
etc.

Juan Jose Alonso

unread,
Mar 7, 2008, 12:04:20 PM3/7/08
to pyglet-users
then i dont understand where are the problem, why my code dont run
fine in my two machines qand yes other pyglet code users.

On Mar 7, 4:57 pm, "Drew Smathers" <drew.smath...@gmail.com> wrote:
> On Fri, Mar 7, 2008 at 6:56 AM, Juan Jose Alonso
>

Ben Sizer

unread,
Mar 8, 2008, 12:37:30 PM3/8/08
to pyglet-users
On Mar 7, 3:06 am, "Richard Jones" <r1chardj0...@gmail.com> wrote:
> blit() is definitely not designed for high performance. The new graphics
> batch and related sprite functionality in pyglet 1.1 *is*.

How is blit() implemented? Even a very trivial implementation of
glBegin/2 triangles/glEnd per sprite should still do far better than
13fps with under 300 sprites. I'd be wary about putting performance
concerns into the documentation when this is unlikely to be the source
of the problem. It looks like this was just the error-checking anyway.

--
Ben Sizer

Richard Jones

unread,
Mar 8, 2008, 5:07:50 PM3/8/08
to pyglet...@googlegroups.com
On Sun, 9 Mar 2008, Ben Sizer wrote:
> On Mar 7, 3:06 am, "Richard Jones" <r1chardj0...@gmail.com> wrote:
> > blit() is definitely not designed for high performance. The new graphics
> > batch and related sprite functionality in pyglet 1.1 *is*.
>
> How is blit() implemented?

The code is remarkably short and easy to find in the pyglet.image module.


> Even a very trivial implementation of
> glBegin/2 triangles/glEnd per sprite should still do far better than
> 13fps with under 300 sprites.

Not when you're running Python code through ctypes.


Richard

Ben Sizer

unread,
Mar 10, 2008, 8:34:44 AM3/10/08
to pyglet-users
This doesn't change the fact that there's nothing intrinsically wrong
with blit(). It may not be the fastest performer available, but for
most people it will suffice. All I'm worried about is giving people
the false impression that they can't expect blit() to perform
reasonably, when it's clear that if you just run with the -O flag set,
it'll more than likely be fine. (I get about 120fps with 250 blits per
frame.)

--
Ben Sizer

Drew Smathers

unread,
Mar 10, 2008, 2:19:53 PM3/10/08
to pyglet...@googlegroups.com
On Mon, Mar 10, 2008 at 8:34 AM, Ben Sizer <kyl...@gmail.com> wrote:
>
> On Mar 8, 10:07 pm, Richard Jones <r1chardj0...@gmail.com> wrote:
> > On Sun, 9 Mar 2008, Ben Sizer wrote:
> >
>
> > > Even a very trivial implementation of
> > > glBegin/2 triangles/glEnd per sprite should still do far better than
> > > 13fps with under 300 sprites.
> >
> > Not when you're running Python code through ctypes.
>
> This doesn't change the fact that there's nothing intrinsically wrong
> with blit(). It may not be the fastest performer available, but for
> most people it will suffice.

There's nothing wrong with blit if you're blitting one thing. The
reason it's inefficient for 100s of things on the other hand, is for
two reasons:

1. Redundant driver state enabling/disabling for textures
2. Functional call overhead

I worked around 1 before new features now available in pyglet by
monkey patching blit and grouping blittable objects. This brought me
from <100fps to around 200fps with a few hundred objects. Driver
state enabling/disabling is expensive.

Regarding 2, if you have a large group of N objects that don't move
relative to one another, the easiest optimization is to use a display
list, reducing N function calls to 1. I applied this to the Juan's
code and increased the framerate from ~12FPS to ~100FPS on my system:

> All I'm worried about is giving people
> the false impression that they can't expect blit() to perform
> reasonably, when it's clear that if you just run with the -O flag set,
> it'll more than likely be fine.

You are really expecting too much out of the -O flag.

> (I get about 120fps with 250 blits per
> frame.)

Are you claiming that the demo ran at ~13FPS on your machine and then
you enabled the -O flag and it runs ~120FPS?

Richard Jones

unread,
Mar 10, 2008, 4:38:02 PM3/10/08
to pyglet...@googlegroups.com

Sure, my intention is simply to inform programmers that if performance is an
issue then blit() isn't the best way to go about things.


> (I get about 120fps with 250 blits per frame.)

That's considerably different from the 13FPS for 300 sprites you quoted
above :)


Richard

Richard Jones

unread,
Mar 10, 2008, 4:54:59 PM3/10/08
to pyglet...@googlegroups.com, Drew Smathers

Please don't forget that pyglet's speed changes pretty dramatically with -O
turned on due to the removal of glGetError() after every OpenGL call.


Richard

Ben Sizer

unread,
Mar 11, 2008, 1:31:28 PM3/11/08
to pyglet-users
On Mar 10, 6:19 pm, "Drew Smathers" <drew.smath...@gmail.com> wrote:
> On Mon, Mar 10, 2008 at 8:34 AM, Ben Sizer <kylo...@gmail.com> wrote:
>
> > This doesn't change the fact that there's nothing intrinsically wrong
> > with blit(). It may not be the fastest performer available, but for
> > most people it will suffice.
>
> There's nothing wrong with blit if you're blitting one thing. The
> reason it's inefficient for 100s of things on the other hand, is for
> two reasons:
>
> 1. Redundant driver state enabling/disabling for textures
> 2. Functional call overhead

The thing is, people have been using simple blitting, or some
equivalent of it, for well over a decade now, and it has always
performed reasonably for a certain kind of game or application.
DirectDraw examples from the mid to late 90s would have typically had
you making 400-800 blit calls per frame, and you could still expect
well over the typically cited baseline of 30FPS. Function call
overhead would be irrelevant compared to the other overheads (though
this is in C++). Of course, you wouldn't be able to do any rotations
or alpha blending with that, because the hardware acceleration
available didn't provide that for 2D operations.

So essentially, if we now take CPUs that are typically at least 32
times more powerful, and additionally leverage the benefit of using
OpenGL on GPUs that have progressed even faster than that, and yet
tell people that they either have to make fewer blit calls than they
did in 1997 or start worrying about driver state changes, then we have
done something horrifically wrong.

I'm not particularly interested in discussing the different ways of
optimising OpenGL at this point, because I know all that. What matters
to me is that we don't force the typical guy who just wants to draw
some sprites down into display list/VBO hell. If we can merge textures
or do some silent sorting behind the scenes to cut down on changes,
then that's a better approach. I think pyglet does some of this
already, which is great. If they still need extra performance, then
sure, they can get their hands dirty with the details. But I'd hate to
see people think that they're forced to do that, when most of the time
they're probably not.

I can't comment on how much complexity using 1.1's batching stuff
adds, because I still can't resolve www.pyglet.org here, and the
migration doc isn't up on code.google.com from what I can tell. From
what I remember though, they'd still have to manually think about
which image used which texture and batch them accordingly, which is
not all that friendly.

> > All I'm worried about is giving people
> > the false impression that they can't expect blit() to perform
> > reasonably, when it's clear that if you just run with the -O flag set,
> > it'll more than likely be fine.
>
> You are really expecting too much out of the -O flag.
>
> > (I get about 120fps with 250 blits per
> > frame.)
>
> Are you claiming that the demo ran at ~13FPS on your machine and then
> you enabled the -O flag and it runs ~120FPS?

I think my stats were that it went from 30FPS to 120FPS. I expect, as
Richard said, that this came from the error checking being disabled.

--
Ben Sizer

Richard Jones

unread,
Mar 11, 2008, 4:40:25 PM3/11/08
to pyglet...@googlegroups.com
On Wed, 12 Mar 2008, Ben Sizer wrote:
> The thing is, people have been using simple blitting, or some
> equivalent of it, for well over a decade now, and it has always
> performed reasonably for a certain kind of game or application.
> [snip]

You are comparing apples with oranges here.


> I'm not particularly interested in discussing the different ways of
> optimising OpenGL at this point, because I know all that. What matters
> to me is that we don't force the typical guy who just wants to draw
> some sprites down into display list/VBO hell.

Please don't describe pyglet.sprite as "VBO hell" until you've looked at it.


Richard

Brian Fisher

unread,
Mar 11, 2008, 4:47:58 PM3/11/08
to pyglet...@googlegroups.com
On Tue, Mar 11, 2008 at 1:40 PM, Richard Jones <r1char...@gmail.com> wrote:
> > I'm not particularly interested in discussing the different ways of
> > optimising OpenGL at this point, because I know all that. What matters
> > to me is that we don't force the typical guy who just wants to draw
> > some sprites down into display list/VBO hell.
>
> Please don't describe pyglet.sprite as "VBO hell" until you've looked at it.
>
He didn't describe pyglet.sprite as such. He just said that he
wouldn't like it if people had to go into display list/VBO Hell to get
fast blits. There was no implication in what he wrote that
pyglet.sprite forces that at all. He was just stating a criteria by
which he would judge the quality of blit routines.

Richard Jones

unread,
Mar 11, 2008, 4:54:42 PM3/11/08
to pyglet...@googlegroups.com
On Wed, 12 Mar 2008, Brian Fisher wrote:
> On Tue, Mar 11, 2008 at 1:40 PM, Richard Jones <r1char...@gmail.com>
wrote:
> > > I'm not particularly interested in discussing the different ways of
> > > optimising OpenGL at this point, because I know all that. What matters
> > > to me is that we don't force the typical guy who just wants to draw
> > > some sprites down into display list/VBO hell.
> >
> > Please don't describe pyglet.sprite as "VBO hell" until you've looked at
> > it.
>
> He didn't describe pyglet.sprite as such.

Yes, I'm aware of that ;)

I guess I was just trying to point out that tarring all VBO usage with the
brush of "it's hell" is not giving the nice Pythonic interfaces that Alex has
written (both pyglet.graphics and pyglet.sprite) a fair go :)


Richard

Juan Jose Alonso

unread,
Mar 12, 2008, 10:06:58 AM3/12/08
to pyglet-users
what is a display list? o_O

Thanks.

On Mar 10, 7:19 pm, "Drew Smathers" <drew.smath...@gmail.com> wrote:

Ben Sizer

unread,
Mar 12, 2008, 10:10:04 AM3/12/08
to pyglet-users
On Mar 11, 8:40 pm, Richard Jones <r1chardj0...@gmail.com> wrote:
> On Wed, 12 Mar 2008, Ben Sizer wrote:
> > The thing is, people have been using simple blitting, or some
> > equivalent of it, for well over a decade now, and it has always
> > performed reasonably for a certain kind of game or application.
> > [snip]
>
> You are comparing apples with oranges here.

Behind the scenes, yes. For the end user, not at all. They want to put
a graphic on the screen at a given position. That's why we still call
it blit() now, even though it blatantly is not 'blitting' the graphic
at all.

> > I'm not particularly interested in discussing the different ways of
> > optimising OpenGL at this point, because I know all that. What matters
> > to me is that we don't force the typical guy who just wants to draw
> > some sprites down into display list/VBO hell.
>
> Please don't describe pyglet.sprite as "VBO hell" until you've looked at it.

I have looked at it. Sadly I can't recite it from memory. It did look
however like you would need to have some knowledge of texture
management and so on to make the most of it for performance purposes,
as opposed to simply batching things up to make fewer calls. It might
support your point if you wanted to cite how it would be used. If I'm
wrong and it's not a big deal to get it properly sorting by texture
and so on, perhaps you could show a quick example?

--
Ben Sizer

Drew Smathers

unread,
Mar 12, 2008, 10:32:02 AM3/12/08
to pyglet...@googlegroups.com
On Wed, Mar 12, 2008 at 10:06 AM, Juan Jose Alonso
<kernel....@gmail.com> wrote:
>
> what is a display list? o_O
>


http://www.lighthouse3d.com/opengl/displaylists/

Alex Holkner

unread,
Mar 13, 2008, 6:42:43 AM3/13/08
to pyglet...@googlegroups.com

This is my fault, I haven't written new chapters in the Programming
Guide covering sprites and the new graphics API. Sprites are batched
and grouped according to the order you want them drawn in. That is,
all sprites in a given group in a batch will be drawn in an
indeterminate order. To have some sprites drawn in front of some
other sprites, these two groups of sprites would need to belong to
separate groups (or batches). A batch groups drawing operations
(calling batch.draw() draws all sprites/graphics in all groups in that
batch). Texture and other state sorting is handled automatically, and
small images are automatically bundled into larger textures (to
minimise state changes) when using the new resource API.

For examples, see examples/noisy/noisy.py for a simple use (one batch,
no groups), and examples/astraea/astraea.py for a more complex use
(using multiple groups and batches).

Alex.

Reply all
Reply to author
Forward
0 new messages