Hi Rich Quoting Richard Drummond <evilrich@xxxxxxxxxxxxxx>: > Can you compare frame-rates on your system with and without this change? > Okay, I've done the tests playing one half of Kick Off 2: With patch: Average frame time: 19,579630 ms [frames: 19509 time: 381979] Without patch: Average frame time: 35,634270 ms [frames: 19066 time: 679403] As you can see there is a significant slowdown which basically makes the game unplayable. Kick Off 2 uses 8-way scrolling with a frame rate of 20ms, which is why I figured flushing the whole screen could never decrease performance (at not least in this special case). Seems like there must be some redundant calls to flush_block()! Here is what I get when turning debug on in 'flush_block' and 'flush_screen': Function: flush_screen Function: flush_block 32 32 Function: flush_block 34 34 Function: flush_block 36 36 Function: flush_block 38 38 ...[snip]... Function: flush_block 476 476 Function: flush_block 478 478 Function: flush_block 501 511 Function: flush_screen Apparently every other line gets flushed and SDL_UpdateRect must have an overhead, not present in the x11 implementation, which slows thing down. I should probadly note that I was using double resolution and scanlines. When swiching to lowres (without scanlines) I get this debug info: Function: flush_screen Function: flush_block 16 116 Function: flush_block 117 217 Function: flush_block 218 239 Function: flush_block 245 255 Function: flush_screen Which look more like what should happen. And now the game runs fine of course :) Anyway, I've done a fix which merges adjacent blocks (and those seperated by a scanline) in sucessive call to flush_block: --- sdlgfx.c 2004-10-26 07:42:20.000000000 +0200 +++ sdlgfx.c.new 2004-11-12 20:35:56.504922840 +0100 @@ -131,22 +131,40 @@ /* Not implemented for SDL output */ } +static int pending_flush = 0; +static int ystart_p, ystop_p; + void flush_block (int ystart, int ystop) { DEBUG_LOG ("Function: flush_block %d %d\n", ystart, ystop); - SDL_UnlockSurface (prSDLScreen); - SDL_UpdateRect (prSDLScreen, 0, ystart, current_width, ystop - ystart + 1); - SDL_LockSurface (prSDLScreen); + if (pending_flush) { + if (ystart <= ystop_p + 2) { + /* merge with pending flush */ + ystop_p = ystop; + } else { + /* do previous pending flush and make this flush pending */ + SDL_UpdateRect (prSDLScreen, 0, ystart_p, current_width, ystop_p - ystart_p + 1); + ystart_p = ystart; + ystop_p = ystop; + } + } else { + /* make this flush pending */ + ystart_p = ystart; + ystop_p = ystop; + pending_flush = 1; + } } void flush_screen (int ystart, int ystop) { DEBUG_LOG ("Function: flush_screen\n"); -#if 0 - SDL_UpdateRect(prSDLScreen, 0, 0, current_width, current_height); -#endif + if (prSDLScreen) { + SDL_Rect rect = { 0, 0, prSDLScreen->w, prSDLScreen->h }; + SDL_FillRect (prSDLScreen, &rect, SDL_MapRGB (prSDLScreen->format, 0,0,0)); + SDL_UpdateRect (prSDLScreen, 0, 0, rect.w, rect.h); + } } void flush_clear_screen (void) Whih this change everything runs fine for me, and it shouldn't slow down anything else. This code should really go in 'drawing.c' but that one seems a bit more difficult to mess with. Anyway I agree that the 100 line blocks look a bit arbitrary. If something changes does it really flush a whole 100 line block? Merging the blocks and only flushing what has changed seem like a better scheme to me. Corecting the scanline issue in stead of sidestepping it would be nice as well :) Cheers, Jesper