How do I make my game render faster?

Hi,

I’m pretty new to sdl so I’m probably doing some basic mistakes.
Currently my game takes about 120ms to render a frame, which consists of
just a bunch of blit() calls. I want to get this to below 40ms,
hopefully way below.

I already about doubled the speed by calling SDL_DisplayFormat() for all
surfaces. What other pitfalls are there to avoid?

I tried setting my main window / surface to HWSURFACE but that slowed
things down. Is that because then I’m blitting from a SWSURFACE to a
HWSURFACE lots of times per frame?

MfG
Goswin

It may be good to keep track of which surfaces have been updated and which
haven’t - there may be cases where you don’t need to update something that
you are currently blitting.
-AlexOn Mon, May 7, 2012 at 1:19 PM, Goswin von Brederlow wrote:

Hi,

I’m pretty new to sdl so I’m probably doing some basic mistakes.
Currently my game takes about 120ms to render a frame, which consists of
just a bunch of blit() calls. I want to get this to below 40ms,
hopefully way below.

I already about doubled the speed by calling SDL_DisplayFormat() for all
surfaces. What other pitfalls are there to avoid?

I tried setting my main window / surface to HWSURFACE but that slowed
things down. Is that because then I’m blitting from a SWSURFACE to a
HWSURFACE lots of times per frame?

MfG
Goswin


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Is there any code to peruse? It would tell a lot more than we can guess.

Jonny D

Are you using alpha blending? If so that can be a high consumer of the CPU.
Use SDL_UpdateRects to only update parts of screen (requires more logic to
handle, and may not be worth it if the background changes)
Lower the bpp for your images i.e from 32 bpp to 16 bpp.
Switch to opengl if you platform can support it.
Profile your code________________________________
From: goswin-v-b@web.de (Goswin von Brederlow)
To: SDL Development List
Sent: Mon, May 7, 2012 1:19:46 PM
Subject: [SDL] How do I make my game render faster?

Hi,

I’m pretty new to sdl so I’m probably doing some basic mistakes.
Currently my game takes about 120ms to render a frame, which consists of
just a bunch of blit() calls. I want to get this to below 40ms,
hopefully way below.

I already about doubled the speed by calling SDL_DisplayFormat() for all
surfaces. What other pitfalls are there to avoid?

I tried setting my main window / surface to HWSURFACE but that slowed
things down. Is that because then I’m blitting from a SWSURFACE to a
HWSURFACE lots of times per frame?

MfG
Goswin


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Hi,

Are you using the latest version of SDL (SDL2)?
If so, then SDL_Surfaces(s) are usually not hardware accelerated.
Switch to using SDL_texture and SDL_Render instead.

Ignore my comments if using SDL 1.2.xx.

PallavOn 07-05-2012 22:49, Goswin von Brederlow wrote:

Hi,

I’m pretty new to sdl so I’m probably doing some basic mistakes.
Currently my game takes about 120ms to render a frame, which consists of
just a bunch of blit() calls. I want to get this to below 40ms,
hopefully way below.

I already about doubled the speed by calling SDL_DisplayFormat() for all
surfaces. What other pitfalls are there to avoid?

I tried setting my main window / surface to HWSURFACE but that slowed
things down. Is that because then I’m blitting from a SWSURFACE to a
HWSURFACE lots of times per frame?

MfG
Goswin


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Pallav Nawani
Game Designer/CEO
http://www.ironcode.com
Twitter: http://twitter.com/Ironcode_Gaming
Facebook: http://www.facebook.com/Ironcode.Gaming

Jonathan Dearborn writes:

Is there any code to peruse? ?It would tell a lot more than we can guess.

Jonny D

I’m not sure how much help that will be since I’m using ocaml. But here
we go:

http://mrvn.homeip.net/gitweb/?p=settler;a=tree
git clone http://mrvn.homeip.net/git/settler

MfG
Goswin

Scott Smith writes:

Are you using alpha blending? If so that can be a high consumer of the CPU.

I need transparency but I have considered using COLORKEY. I suspected
that alpha blending might be expensive but it is good to see it
confirmed. I will have to add some code to convert images to COLORKEY
after loading and compare the two. Alpha blending would allow better
graphics though.

Use SDL_UpdateRects to only update parts of screen (requires more logic to
handle, and may not be worth it if the background changes)

There is a minimap of 300x200 pixel that changes every frame and a main
map of (width - 200) * height that also changes every frame. What’s left
is a 200 * (height - 200) region for GUI elements that will change
ocasionaly (when the user switches tabs) or frequently (when the user
switches to a statistics tab), but probably less than every frame.

But the main map is where all the work is spend. I 'm using a hexagonal
grid so I’m blitting in a lots of triangles for the terrain, ontop each
another for terrain modification (rivers so far). After that it is
buildings, items and units as present on the tiles. That comes to up to
6 surfaces per tile (up+down triangle, up+down modifier, building | item

  • unit).

Idealy I want terrain to be animated. Wind going through the grass,
little waves on the ocean, … Then the terrain would change every
frame.

Units are to be animated even when stationary (cleaning their nose,
looking around, that kind of thing) and most certainly while moving. So
they often change between frames. And that means items and buildings
must be drawn too in case they overlap. Buildings can be animated too,
smoke in the chimeny or the like. Not that I have that yet but it should
be an option. Tracking where items or buildings overlap units or when
units change their look between frames would be complicated.

Lower the bpp for your images i.e from 32 bpp to 16 bpp.

Won’t that be slower when running on a 32 bpp display (as I usualy do)?

Switch to opengl if you platform can support it.
Profile your code

MfG
Goswin

Colorkey will be much better, especially if the image being copied is just
replacing the destination colors. It also shouldnt look any worse.
Based on the description on what your doing I think using opengl to accelerate
all of your blending and blits would be a huge speed increase. But of course
that requires a good rewrite on the rendering engine.________________________________
From: goswin-v-b@web.de (Goswin von Brederlow)
To: SDL Development List
Sent: Tue, May 8, 2012 11:54:24 AM
Subject: Re: [SDL] How do I make my game render faster?

Scott Smith <@Scott_Smith> writes:

Are you using alpha blending? If so that can be a high consumer of the CPU.

I need transparency but I have considered using COLORKEY. I suspected
that alpha blending might be expensive but it is good to see it
confirmed. I will have to add some code to convert images to COLORKEY
after loading and compare the two. Alpha blending would allow better
graphics though.

Use SDL_UpdateRects to only update parts of screen (requires more logic to
handle, and may not be worth it if the background changes)

There is a minimap of 300x200 pixel that changes every frame and a main
map of (width - 200) * height that also changes every frame. What’s left
is a 200 * (height - 200) region for GUI elements that will change
ocasionaly (when the user switches tabs) or frequently (when the user
switches to a statistics tab), but probably less than every frame.

But the main map is where all the work is spend. I 'm using a hexagonal
grid so I’m blitting in a lots of triangles for the terrain, ontop each
another for terrain modification (rivers so far). After that it is
buildings, items and units as present on the tiles. That comes to up to
6 surfaces per tile (up+down triangle, up+down modifier, building | item

  • unit).

Idealy I want terrain to be animated. Wind going through the grass,
little waves on the ocean, … Then the terrain would change every
frame.

Units are to be animated even when stationary (cleaning their nose,
looking around, that kind of thing) and most certainly while moving. So
they often change between frames. And that means items and buildings
must be drawn too in case they overlap. Buildings can be animated too,
smoke in the chimeny or the like. Not that I have that yet but it should
be an option. Tracking where items or buildings overlap units or when
units change their look between frames would be complicated.

Lower the bpp for your images i.e from 32 bpp to 16 bpp.

Won’t that be slower when running on a 32 bpp display (as I usualy do)?

Switch to opengl if you platform can support it.
Profile your code

MfG
Goswin


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

If you do want to make an easy transition to OpenGL (avoiding such a
rewrite as Scott mentions), I made a C library that has an API similar to
SDL’s surface API:
http://code.google.com/p/sdl-gpu/

It would be nice to have a wider usage base than just me. :slight_smile:

It has rotation, scaling, and other good stuff. The main difference
semantically is that it draws images at their center instead of at the
top-left corner. It also differentiates render targets from image sources.

There are a bunch of demo programs that show how to use it in lieu of
formal documentation.

Jonny D

Scott Smith writes:

Colorkey will be much better, especially if the image being copied is just
replacing the destination colors. It also shouldnt look any worse.

Rivers have a start and end point and there the rivers sandy edge
(didn’t blend the water itself unfortunaetly) blends smoothly into the
terrain [1]. Makes it look much better than having a hard edge as
required by colorkey. So there will be some drawbacks. Probably nothing
that can’t be solved by pre rendering tiles with river and then blitting
the combined tile with colorkey.

Based on the description on what your doing I think using opengl to accelerate
all of your blending and blits would be a huge speed increase. But of course
that requires a good rewrite on the rendering engine.

I’m afraid GL is not always an option. Not everyone has it and I don’t
have it everywhere myself. And software GL will be much slower. I will
probably provide a GL flavour but I want this to also run without.

MfG
Goswin–
1 http://mrvn.homeip.net/map/foo.png

I haven’t been following this thread closely (in fact, I’ve been completely
cut off from email for a few days), but if you have plenty of detail and/or
expensive operations (blending) on the maps, it might be an option to render
the background into an offscreen cache of some sort and update the screen from
that instead. This way, the per-frame fullscreen blits will be simple
rectangular opaque copy operations, whereas the heavy rendering only has to be
done for the areas exposed as the view scrolls across the map.On Wednesday 09 May 2012, at 11.13.00, Goswin von Brederlow wrote:

Scott Smith writes:

Colorkey will be much better, especially if the image being copied is
just replacing the destination colors. It also shouldnt look any worse.

Rivers have a start and end point and there the rivers sandy edge
(didn’t blend the water itself unfortunaetly) blends smoothly into the
terrain [1]. Makes it look much better than having a hard edge as
required by colorkey. So there will be some drawbacks. Probably nothing
that can’t be solved by pre rendering tiles with river and then blitting
the combined tile with colorkey.


//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.— Games, examples, libraries, scripting, sound, music, graphics —.
| http://consulting.olofson.net http://olofsonarcade.com |
’---------------------------------------------------------------------’

David Olofson writes:> On Wednesday 09 May 2012, at 11.13.00, Goswin von Brederlow wrote:

Scott Smith writes:

Colorkey will be much better, especially if the image being copied is
just replacing the destination colors. It also shouldnt look any worse.

Rivers have a start and end point and there the rivers sandy edge
(didn’t blend the water itself unfortunaetly) blends smoothly into the
terrain [1]. Makes it look much better than having a hard edge as
required by colorkey. So there will be some drawbacks. Probably nothing
that can’t be solved by pre rendering tiles with river and then blitting
the combined tile with colorkey.

I haven’t been following this thread closely (in fact, I’ve been completely
cut off from email for a few days), but if you have plenty of detail and/or
expensive operations (blending) on the maps, it might be an option to render
the background into an offscreen cache of some sort and update the screen from
that instead. This way, the per-frame fullscreen blits will be simple
rectangular opaque copy operations, whereas the heavy rendering only has to be
done for the areas exposed as the view scrolls across the map.

That idea has crossed my mind too.

Problem there comes when the background is animated. I would have to
render X copies covering a full animation cycle. And if the animation
cycles of individual tiles differ (river has 7 frames, ocean has 11 => X
= 77) then X can become rather large.

It is a possibility if nothing else helps and by picking the number of
frames per animation right the total number of frames needed could be
kept small.

MfG
Goswin

[…off-screen cache…]

That idea has crossed my mind too.

Problem there comes when the background is animated. I would have to
render X copies covering a full animation cycle. And if the animation
cycles of individual tiles differ (river has 7 frames, ocean has 11 => X
= 77) then X can become rather large.

It is a possibility if nothing else helps and by picking the number of
frames per animation right the total number of frames needed could be
kept small.

Are tiles aligned to a fixed grid, or can they be placed arbitrarily?

If you’re sticking with aligned tiles, multilayering is basically a form of
compression, and you might get away with “decompressing” at load time by pre-
rendering all combinations of tiles that will be used in the map.

Or, you can maintain a cache of prerendered combined tiles for the current
view only, so new sets/animation cycles only have to be rendered once as they
come into view.

All sorts of variants here - but of course, this stuff does complicate the
engine quite a bit. Can’t blame people for relying on hardware acceleration
and/or raw CPU power… :slight_smile:

BTW, you are using RLE acceleration, right…? That restricts the impact of
alpha blending to only the areas that actually need blending (opaque areas ore
copied and transparent areas are skipped), rather than forcing the blitter to
blend every pixel of RGBA surfaces.On Thursday 10 May 2012, at 14.03.52, Goswin von Brederlow wrote:


//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.— Games, examples, libraries, scripting, sound, music, graphics —.
| http://consulting.olofson.net http://olofsonarcade.com |
’---------------------------------------------------------------------’

David Olofson writes:> On Thursday 10 May 2012, at 14.03.52, Goswin von Brederlow <@Goswin_von_Brederlow> wrote:

[…off-screen cache…]

That idea has crossed my mind too.

Problem there comes when the background is animated. I would have to
render X copies covering a full animation cycle. And if the animation
cycles of individual tiles differ (river has 7 frames, ocean has 11 => X
= 77) then X can become rather large.

It is a possibility if nothing else helps and by picking the number of
frames per animation right the total number of frames needed could be
kept small.

Are tiles aligned to a fixed grid, or can they be placed arbitrarily?

If you’re sticking with aligned tiles, multilayering is basically a form of
compression, and you might get away with “decompressing” at load time by pre-
rendering all combinations of tiles that will be used in the map.

Or, you can maintain a cache of prerendered combined tiles for the current
view only, so new sets/animation cycles only have to be rendered once as they
come into view.

All sorts of variants here - but of course, this stuff does complicate the
engine quite a bit. Can’t blame people for relying on hardware acceleration
and/or raw CPU power… :slight_smile:

BTW, you are using RLE acceleration, right…? That restricts the impact of
alpha blending to only the areas that actually need blending (opaque areas ore
copied and transparent areas are skipped), rather than forcing the blitter to
blend every pixel of RGBA surfaces.

I havent a clue. I’m not specifically turning on RLE. In ocaml some
functions have it as optional argument and I just skipped it. No idea if
that means it is on or off but I suspect off. I didn’t see it in the
surface infos when I looked at specific surfaces.

Here are some surprising timings:

Alpha blending: 120ms/frame
Color key : 145ms/frame
Opaque : 100ms/frame

I would have expected color key to be faster than or at least equal to
alpha blending even if all but river tiles have only totaly transparent
or totaly opaque for now.

MfG
Goswin

Just out of curiosity: how long does it take to render frames if you
comment out the actual blit() calls?

It might be useful to see what the performance of your rendering logic is
before SDL enters the picture, especially if you’re traversing a bunch of
data structures or doing a lot of other bookkeeping in the middle of it.On Thu, May 10, 2012 at 11:34 AM, Goswin von Brederlow wrote:

David Olofson writes:

On Thursday 10 May 2012, at 14.03.52, Goswin von Brederlow < goswin-v-b at web.de> wrote:
[…off-screen cache…]

That idea has crossed my mind too.

Problem there comes when the background is animated. I would have to
render X copies covering a full animation cycle. And if the animation
cycles of individual tiles differ (river has 7 frames, ocean has 11 => X
= 77) then X can become rather large.

It is a possibility if nothing else helps and by picking the number of
frames per animation right the total number of frames needed could be
kept small.

Are tiles aligned to a fixed grid, or can they be placed arbitrarily?

If you’re sticking with aligned tiles, multilayering is basically a form
of
compression, and you might get away with “decompressing” at load time by
pre-
rendering all combinations of tiles that will be used in the map.

Or, you can maintain a cache of prerendered combined tiles for the
current
view only, so new sets/animation cycles only have to be rendered once as
they
come into view.

All sorts of variants here - but of course, this stuff does complicate
the
engine quite a bit. Can’t blame people for relying on hardware
acceleration
and/or raw CPU power… :slight_smile:

BTW, you are using RLE acceleration, right…? That restricts the impact
of
alpha blending to only the areas that actually need blending (opaque
areas ore
copied and transparent areas are skipped), rather than forcing the
blitter to
blend every pixel of RGBA surfaces.

I havent a clue. I’m not specifically turning on RLE. In ocaml some
functions have it as optional argument and I just skipped it. No idea if
that means it is on or off but I suspect off. I didn’t see it in the
surface infos when I looked at specific surfaces.

Here are some surprising timings:

Alpha blending: 120ms/frame
Color key : 145ms/frame
Opaque : 100ms/frame

I would have expected color key to be faster than or at least equal to
alpha blending even if all but river tiles have only totaly transparent
or totaly opaque for now.

MfG
Goswin


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

  • Ben S.

Benjamin Shadwick writes:

Just out of curiosity: how long does it take to render frames if you comment
out the actual blit() calls?

It might be useful to see what the performance of your rendering logic is
before SDL enters the picture, especially if you’re traversing a bunch of data
structures or doing a lot of other bookkeeping in the middle of it.

~12ms for the flip, ~8ms for the minimap, ~95ms for terrain, ~7ms for
buildings, items and units

MfG
Goswin

MfG
Goswin

So even without rendering terrain, you’d only be able to achieve 37 FPS
(1000 / (12 + 8 + 7)).On Fri, May 11, 2012 at 1:18 AM, Goswin von Brederlow wrote:

Benjamin Shadwick <@Benjamin_Shadwick> writes:

Just out of curiosity: how long does it take to render frames if you
comment
out the actual blit() calls?

It might be useful to see what the performance of your rendering logic is
before SDL enters the picture, especially if you’re traversing a bunch
of data
structures or doing a lot of other bookkeeping in the middle of it.

~12ms for the flip, ~8ms for the minimap, ~95ms for terrain, ~7ms for
buildings, items and units

MfG
Goswin

MfG
Goswin


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

  • Ben S.

You’re likely to get much better performance if you switch to SDL 2.0
and/or a 3D solution.On Fri, May 11, 2012 at 7:47 PM, Benjamin Shadwick wrote:

So even without rendering terrain, you’d only be able to achieve 37 FPS
(1000 / (12 + 8 + 7)).

On Fri, May 11, 2012 at 1:18 AM, Goswin von Brederlow wrote:

Benjamin Shadwick writes:

Just out of curiosity: how long does it take to render frames if you
comment
out the actual blit() calls?

It might be useful to see what the performance of your rendering logic
is
before SDL enters the picture, especially if you’re traversing a bunch
of data
structures or doing a lot of other bookkeeping in the middle of it.

~12ms for the flip, ~8ms for the minimap, ~95ms for terrain, ~7ms for
buildings, items and units

MfG
Goswin

MfG
Goswin


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

  • Ben S.

SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org