8

I am programming a raycasting game using SDL2. When drawing the floor, I need to call SDL_RenderCopy pixelwise. This leads to a bottleneck which drops the framerate below 10 fps. I am looking for performance boosts but can't seem to find some.

Here's a rough overview of the performance drop:

int main() {
  while(true) {
        for(x=0; x<800; x++) {
            for(y=0; y<600; y++) {
                SDL_Rect src = { 0, 0, 1, 1 };
                SDL_Rect dst = { x, y, 1, 1 };
                SDL_RenderCopy(ren, tx, &src, &dst); // this drops the framerate below 10
            }
        }
        SDL_RenderPresent(ren);
    }
 }
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Marius Anderie
  • 23
  • 1
  • 2
  • 12
  • 1
    You might need to do profiling to determine exactly the bottleneck area. It seems for every for loop, you are creating arrays and allocating memory. You are doing this 600 times for every outer for loop. Is it possible, for you to reuse the same array over and over, instead of creating new arrays. If you can reuse your array, this will ensure that the CPU will be fetching the data from the same memory location rather than looking it in the entire memory. – Juniar Aug 09 '14 at 04:44
  • Do you really have a separate texture for each pixel? You really should not be doing that. – Fsmv Aug 11 '14 at 13:34
  • @Fsmv why do you think that? He only has one texture - `tx` he is just rendering it a pixel at a time although not really sure why. – TPS Aug 20 '14 at 09:28
  • @Zammalad oh you're right, my bad. I guess I didn't read his code very closely and thought that was the only reason someone would be calling RenderCopy 800*600 times with 1x1 rectangles. It is really weird to be copying each pixel individually though. – Fsmv Aug 20 '14 at 13:20

2 Answers2

11

You should probably be using texture streaming for this. Basically you will create an SDL_Texture of type SDL_TEXTUREACCESS_STREAMING and then each frame you 'lock' the texture, update the pixels that you require then 'unlock' the texture again. The texture is then rendered in a single SDL_RenderCopy call.

Other than that calling SDL_RenderCopy 480,000 times a frame is always going to kill your framerate.

TPS
  • 2,067
  • 3
  • 23
  • 32
  • 1
    Is it even necessary to use a texture for these manual pixel-wise operations? Isn't it faster to use an `SDL_Surface` temporarily? Also, you don't need to call `SDL_RenderCopy` anymore as the pixels are "integrated" when unlocking the texture, do you? – Timmos Aug 23 '15 at 11:13
  • Not sure I understand what you mean @Timmos – TPS Aug 23 '15 at 11:46
  • Well wouldnt' an SDL_Surface be more efficient for all these pixel-wise operations, instead of an SDL_Texture? – Timmos Aug 25 '15 at 08:04
  • @Timmos I don't think so although I could be wrong. But assuming OP is using SDL2 which is what it is tagged as then an `SDL_Texture` is hardware accelerated where as `SDL_Surface` would be using software rendering (unless you create a new texture each frame from the modified surface which is not as efficient anyway). Using the `SDL_Texture` in steaming mode you have access to the pixels and only need to create it once as well as it taking advantage of hardware accelleration – TPS Aug 25 '15 at 08:18
  • And official example at: http://hg.libsdl.org/SDL/file/e12c38730512/test/teststreaming.c – Ciro Santilli OurBigBook.com Apr 08 '16 at 12:05
4

You are calling SDL_RenderCopy() in each frame so 600 * 800 = 480 000 times! It is normal for performance to drop.

Soma
  • 861
  • 2
  • 17
  • 32
frkk
  • 59
  • 3