I was wondering if anybody could explain this to me, I’m running under
X11 and I don’t know if Win32 would show much difference, but here goes:
I’ve been trying to get my application to draw as fast as possible, as
I’m a hobbyist programmer/learn-as-I-go and I’ve had to rewrite some
pretty crappy code from the past, and I’m sure I’ll rewrite it again.
But I’ve been going through various methods of blitting and I was
wondering if somebody could explain the results to me:
ORIGINAL METHOD:
My original method consisted of a simple double buffer. I had a
software surface the size of the window, I’d blit and scratch pixels
there. It was divided into tiles, and if any pixel within a tile (they
were about 30x25 or something like that) was drawn to, that pixel became
dirty, and when all the drawing as done, my flip function would go
through and flip all the tiles that were dirtied. gprof showed that
function to be slow, so I tried speeding it up and to reduce blits I
wrote some code to detect blocks of tiles and such. Okay, that’s my
original method, a simple double buffer. It took about 50% cpu during
normal gameplay and 85% during heavy action.
SECOND METHOD:
My second method was taken from the programmer of LGames. I asked the
maker of lbreakout2 how he got this application to draw, and so I took
his advice and avoided SDL_Flip(). I simply drew directly to the window
surface, writing code to wait for a lock for scratching and got all that
done. I then had a large array of SDL_Rects which I kept track of all
blits, and when it came time to flip, I used SDL_UpdateRects() and
updated them all. This was a major performance increase. 20-30% cpu
during gameplay and 45% during normal gameplay. All these benchmarks are
under X11.
THIRD METHOD:
I thought I’d try and be smart and combine both methods, so I could
blit and scratch around in memory, arguably faster, right? The only
different between this and my original method, is I’d use a large array
of SDL_Rects() from my second method. So I blit/scartch to the
backbuffer, remember the exact rects I did this in, then
SDL_UpdateRects() on all those. This method proved to be slightly faster
than my original, method, but no where near as fast as the second
method. This method was about 20% slower in everything from my second
method.
Can anybody explain why the third method wasn’t faster? I’m not entirely
sure. I think maybe there’s a huge slowdown in calling SDL_BlitSurface()
a bazillion times, but shouldn’t the original backbuffer method be the
fastest anyway? Don’t most games use a simple dobule buffer? Why is the
second method, literally just blitting as I need to draw/erase and then
calling SDL_UpdateRects() on a large array the fastest way to do it?
Does anybody know why maybe the double buffer method wasn’t the fastest?
Thanks for your thought, I’m not sure why it wouldn’t be the fastest.
Thanks.–
Chris Thielen <@Christopher_Thielen>