My little scroll app speeds up when I hit a key for no apparent reason

First off thanks to Sam Lantinga for explaining what SDL is clipping my
Rects, it makes since now so now I’m not too sore about SDL doing something I
didn’t expect.

Now to business: I've got a small sdl app that makes a tile make out of

a multidimential array that indexes a single dimention array of SDL_Surface
pointers. I then scroll the app by drawing the tiles over each other again and
again each time in a different spot. It’s pretty slow under X since it’s using
software surfaces and no real optimization tricks. But for reasons I don’t know
it speeds up if hit a key. The scrolling becomes noticable smother and takes
less time to complete (I used a simple while loop to do the scrolling as fast
as possible). There’s absolutly no code to receive input during the scroll. I
stole the while loop out of testsprite in the SDL sorce code and taged it at
the end, that’s the only place for input. Is this an issue with priorities or
something. Does the app get more CPU time when a key is being pressed. The
code’s pretty long (a good 200 lines, but most of that’s white space), but if
someone wants to see it let me know. I’ve implemented the exact same algorythm
in DirectX (without SDL) and this didn’t happen. If anyone has any clue I’d
sure appreciate it. I’m stumped. Thanks again.–
Jeremy Gregorio
jgreg at azstarnet.com

It’s pretty slow under X since it’s using
software surfaces and no real optimization tricks. But for reasons I don’t know
it speeds up if hit a key. The scrolling becomes noticable smother and takes
less time to complete (I used a simple while loop to do the scrolling as fast
as possible). There’s absolutly no code to receive input during the scroll. I
stole the while loop out of testsprite in the SDL sorce code and taged it at
the end, that’s the only place for input.

Interesting. Maybe it’s something in your environment — some background
application humming along, sucking up cpu or bothering the X server with
requests. Kill Netscape, always a good start. Look for silly applets
flashing pointless animations.

Is this an issue with priorities or

something. Does the app get more CPU time when a key is being pressed. The
code’s pretty long (a good 200 lines, but most of that’s white space), but if
someone wants to see it let me know.

Sure, post it here, or an url to it. Things like this have been observed
now and then on different historical machines, usually because of bogus
scheduling algorithms. Somehow it’s reassuring that the phenomenon can
still show up today :slight_smile:

Here’s the code:

/Here’s my little 'ol app. spot_tile.bmp and brick.bmp are just 64x48 bitmaps I use for tiles
A Word or two about how it (suppositly) works: A retangle representing the area of the TileMap
that is curently visableis maintaned. I call this the ViewRectangle or VRect for
short. The VRect can be passed to DrawTiles() and all tiles in the VRect will
be blitted to screen. By moving the VRect and calling DrawTiles() scrolling
can be done. This is a brute force method I’ll fix pretty soon
/

//includes
#include <stdio.h>
#include <stdlib.h>
#include “SDL.h”
//end includes

//typedefs
#define X_TILE_SIZE 64
#define Y_TILE_SIZE 48
#define SCREEN_EXTENT_X 640
#define SCREEN_EXTENT_Y 480
#define NUM_TILES_X 10
#define NUM_TILES_Y 40
#define WORLD_MAP_EXTENT_X (X_TILE_SIZE * NUM_TILES_X)
#define WORLD_MAP_EXTENT_Y (Y_TILE_SIZE * NUM_TILES_Y)
//end of typedefs

//function decs
Uint16 CreateHicolorPixel( SDL_PixelFormat fmt, Uint8 red, Uint8 green, Uint8 blue );
SDL_Surface
LoadImage( char* file );
int DrawTiles(SDL_Rect* WorldCoordsRect);
//end function decs

//globals
SDL_Surface screen;
int done = 0;
SDL_Event event;
char TileMap[NUM_TILES_X][NUM_TILES_Y];
SDL_Surface
Tiles[2];
SDL_Rect VRect;
//end globals

int main(){

VRect.x = 0;
VRect.y = WORLD_MAP_EXTENT_Y - 640;
    VRect.w = 640;
VRect.h = WORLD_MAP_EXTENT_Y;

/* Initialize SDL */
if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
	fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
	exit(1);
}

if ( (screen=SDL_SetVideoMode(640,480, 16,SDL_FULLSCREEN | SDL_ANYFORMAT )) == NULL ) {
	fprintf(stderr, "Couldn't set 640x480 video mode: %s\n",
							SDL_GetError());
	exit(2);
}


//load the tiles
Tiles[0] = LoadImage( "spot_tile.bmp" );
    Tiles[1] = LoadImage( "brick.bmp" );

for(int j = 0; j < 40; j++){

	for(int i = 0; i < 10; i++){

		TileMap[i][j] = i % 2;

	}//end for loop i

}//end for loop j
int loopcount = 0;
    int initial_ticks = SDL_GetTicks();

while ( VRect.y > 0 ){

    	DrawTiles(&VRect);
	VRect.y -= 5;
	VRect.h -= 5;
	loopcount++;

}

    int final_ticks = SDL_GetTicks();

printf("Time to do a DrawTiles(): %d\n", (final_ticks-initial_ticks) );
printf("loopcount: %d\n", loopcount);
SDL_UpdateRect(screen, 0,0,640,480);

while ( !done ) {

	/* Check for events */

	while ( SDL_PollEvent(&event) ) {
		switch (event.type) {
			case SDL_KEYDOWN:
				/* Any keypress quits the app... */
			case SDL_QUIT:
				done = 1;
				break;
			default:
				break;
		}//end switch

	}//end while ( SDL_PollEvent(&event) )
}//end while (!done)

SDL_Quit();

return 0;

}//end main

SDL_Surface* LoadImage( char* file ){

SDL_Surface* temp = NULL;

/* Load an image */
temp = SDL_LoadBMP(file);
if ( temp == NULL ) {
fprintf(stderr, “Couldn’t load %s: %s\n”, file, SDL_GetError());////////
exit(1);
}

/* Convert image to video format */
temp = SDL_DisplayFormat(temp);

if ( temp == NULL ) {
	fprintf(stderr, "Couldn't convert background: %s\n",
						SDL_GetError());
	exit(1);
}

return temp;

}//end methond LoadImage

Uint16 CreateHicolorPixel( SDL_PixelFormat *fmt, Uint8 red, Uint8 green, Uint8 blue ){
Uint16 value;

       /* This series of bit shifts uses the information from the SDL_Format
       structure to correctly compose a 16-bit pixel value from 8-bit red,
            green, and blue data. */
         value = ((red >> fmt->Rloss) << fmt->Rshift) +
             ((green >> fmt->Gloss) << fmt->Gshift) +
             ((blue >> fmt->Bloss) << fmt->Bshift);
          return value;

}//end method CreateHicolorPixel

int DrawTiles(SDL_Rect* WorldCoordsRect){

SDL_Rect destpts, Blit_Tiles_Extents, SDL_Blit_Rect;
int first_destpts_x;

destpts.x = -(WorldCoordsRect->x % X_TILE_SIZE);
destpts.y = -(WorldCoordsRect->y % Y_TILE_SIZE);
destpts.w = WorldCoordsRect->w - WorldCoordsRect->x;
destpts.h = WorldCoordsRect->h - WorldCoordsRect->y;	

first_destpts_x = destpts.x;

Blit_Tiles_Extents.x = WorldCoordsRect->x / X_TILE_SIZE;
Blit_Tiles_Extents.y = WorldCoordsRect->y / Y_TILE_SIZE;

// The following lines of code make sure that when Blit_Tiles_Extents’ members are use to form
//Tile map indexes those indexes don’t overrun the bounds of the array
if ( Blit_Tiles_Extents.x < 0 )
Blit_Tiles_Extents.x = 0;
if ( Blit_Tiles_Extents.y < 0 )
Blit_Tiles_Extents.y = 0;
if ( Blit_Tiles_Extents.w > (NUM_TILES_X) )
Blit_Tiles_Extents.w = (NUM_TILES_X-1);
if ( Blit_Tiles_Extents.h > (NUM_TILES_Y) )
Blit_Tiles_Extents.h = (NUM_TILES_Y-1);

// The following lines of code make sure that partial tile get blited, SDL handles the clipping here
if( Blit_Tiles_Extents.x > 0 )
Blit_Tiles_Extents.x–;
if( Blit_Tiles_Extents.y > 0 )
Blit_Tiles_Extents.y–;
if( Blit_Tiles_Extents.w < (NUM_TILES_X) )
Blit_Tiles_Extents.w++;
if( Blit_Tiles_Extents.h < (NUM_TILES_Y) )
Blit_Tiles_Extents.h++;
for( int j = Blit_Tiles_Extents.y; j < Blit_Tiles_Extents.h; j++){

	for( int i = Blit_Tiles_Extents.x; i < Blit_Tiles_Extents.w; i++){
		SDL_Blit_Rect.x = destpts.x;
		SDL_Blit_Rect.y = destpts.y;	
		SDL_BlitSurface(Tiles[ TileMap[i][j] ], NULL, screen, &SDL_Blit_Rect );
		destpts.x += X_TILE_SIZE;

	}//end for loop i

	destpts.y += Y_TILE_SIZE;
	destpts.x = first_destpts_x;

}//end for loop j

//right now I’m just redrawing the whole screen, I’ll fix that when I start optimizing
SDL_UpdateRect(screen, 0,0,640,480);

return 0;

}–
Jeremy Gregorio
jgreg at azstarnet.com

I had a similar problem - it turns out that one of the default Gnome applets
(I believe it’s the desktop viewer) takes a screenshot every few seconds!
This dropped the performance of my application by 20-30% and made it look
choppy. I just started by killing off processes one by one until my app was
smooth again.

“Mattias Engdeg?rd” wrote in message
news:200011081121.MAA27799 at my.nada.kth.se

It’s pretty slow under X since it’s using
software surfaces and no real optimization tricks. But for reasons I
don’t know

it speeds up if hit a key. The scrolling becomes noticable smother and
takes

less time to complete (I used a simple while loop to do the scrolling as
fast

as possible). There’s absolutly no code to receive input during the
scroll. I

stole the while loop out of testsprite in the SDL sorce code and taged it
at

the end, that’s the only place for input.

Interesting. Maybe it’s something in your environment — some background
application humming along, sucking up cpu or bothering the X server with
requests. Kill Netscape, always a good start. Look for silly applets
flashing pointless animations.

Is this an issue with priorities or

something. Does the app get more CPU time when a key is being pressed.
The

code’s pretty long (a good 200 lines, but most of that’s white space),
but if> >someone wants to see it let me know.

Sure, post it here, or an url to it. Things like this have been observed
now and then on different historical machines, usually because of bogus
scheduling algorithms. Somehow it’s reassuring that the phenomenon can
still show up today :slight_smile:

Unfortunately that doesn’t seem to be my problem. I started a simple X
session with no window manager (just exec xterm), and I still get the problem.
It’s weird.On Wed, 08 Nov 2000, you wrote:

I had a similar problem - it turns out that one of the default Gnome applets
(I believe it’s the desktop viewer) takes a screenshot every few seconds!
This dropped the performance of my application by 20-30% and made it look
choppy. I just started by killing off processes one by one until my app was
smooth again.


Jeremy Gregorio
jgreg at azstarnet.com

Just a little update on my troubles with SDL. I modified testsprite.c
from the sdl examples that came with the library. So now the executable dies
with a mousedown event. What that means is I’m free to press any key I wish. If
I do press and hold a key the app’s drawing speeds up significantly with the
animation looking much smoother. I’ve been able to replicate this behavior with
just a basic X server running only an xterm. At any rate here’s the output of a
top command when I’ve got kde running:

872 PrincePh 19 0 4504 4504 3068 R 0 87.0 7.5 77:43 x11amp
1330 root 9 0 1032 1032 840 R 0 15.2 1.7 0:00 top
1 root 0 0 112 56 40 S 0 0.0 0.0 0:04 init
2 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 kflushd
3 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 kpiod
4 root 0 0 0 0 0 SW 0 0.0 0.0 0:01 kswapd
5 root -20 -20 0 0 0 SW< 0 0.0 0.0 0:00 mdrecoveryd
132 root 0 0 64 0 0 SW 0 0.0 0.0 0:00 apmd
221 bin 0 0 76 0 0 SW 0 0.0 0.0 0:00 portmap
268 root 0 0 216 160 120 S 0 0.0 0.2 0:00 syslogd
279 root 0 0 500 168 120 S 0 0.0 0.2 0:00 klogd
293 daemon 0 0 144 112 84 S 0 0.0 0.1 0:00 atd
307 root 0 0 248 192 136 S 0 0.0 0.3 0:00 crond
325 root 0 0 216 172 140 S 0 0.0 0.2 0:00 inetd
339 root 0 0 80 0 0 SW 0 0.0 0.0 0:00 lpd
357 root 0 0 124 0 0 SW 0 0.0 0.0 0:00 rpc.statd
368 root 0 0 72 0 0 SW 0 0.0 0.0 0:00 rpc.rquotad
379 root 0 0 92 0 0 SW 0 0.0 0.0 0:00 rpc.mountd
394 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 nfsd
395 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 nfsd
396 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 nfsd
397 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 nfsd
398 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 nfsd
399 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 nfsd
400 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 nfsd
401 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 nfsd
402 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 lockd
403 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 rpciod
438 root 0 0 524 312 232 S 0 0.0 0.5 0:00 sendmail
453 root 0 0 108 60 40 S 0 0.0 0.1 0:00 gpm
476 xfs 0 0 520 60 28 S 0 0.0 0.1 0:00 xfs
510 root 0 0 272 0 0 SW 0 0.0 0.0 0:00 login
511 root 0 0 68 0 0 SW 0 0.0 0.0 0:00 mingetty
512 root 0 0 68 0 0 SW 0 0.0 0.0 0:00 mingetty
513 root 0 0 68 0 0 SW 0 0.0 0.0 0:00 mingetty
514 root 0 0 68 0 0 SW 0 0.0 0.0 0:00 mingetty
515 root 0 0 68 0 0 SW 0 0.0 0.0 0:00 mingetty
517 root 0 0 76 32 16 S 0 0.0 0.0 0:00 update
519 PrincePh 0 0 772 736 564 S 0 0.0 1.2 0:00 bash
742 PrincePh 0 0 788 788 648 S 0 0.0 1.3 0:00 startx
743 PrincePh 0 0 760 760 636 S 0 0.0 1.2 0:00 xinit
744 root 0 0 233M 230M 1088 S 0 0.0 395.2 4:59 X
752 PrincePh 0 0 784 784 648 S 0 0.0 1.3 0:00 sh
753 PrincePh 0 0 3712 3096 2116 S 0 0.0 5.1 0:13 kwm
765 PrincePh 0 0 1384 696 612 S 0 0.0 1.1 0:00 kaudioserver
766 PrincePh 0 0 3256 3256 2356 S 0 0.0 5.4 0:01 kwmsound
767 PrincePh 0 0 1984 1056 852 S 0 0.0 1.7 0:04 kfm
768 PrincePh 0 0 3476 3476 2560 S 0 0.0 5.8 0:01 krootwm
769 PrincePh 0 0 2448 1712 1304 S 0 0.0 2.8 0:06 kpanel
770 PrincePh 0 0 3608 3552 2676 S 0 0.0 5.9 0:04 kbgndwm
774 PrincePh 0 0 2420 2420 1644 S 0 0.0 4.0 0:03 maudio
778 PrincePh 0 0 1880 1144 848 S 0 0.0 1.9 0:02 knotes
780 PrincePh 0 0 3408 3408 2480 S 0 0.0 5.7 0:01 khotkeys
781 PrincePh 0 0 740 740 644 S 0 0.0 1.2 0:00 rclock
782 PrincePh 0 0 2592 1892 1512 S 0 0.0 3.1 0:04 kvt
783 PrincePh 0 0 980 980 780 S 0 0.0 1.6 0:00 bash
785 root 0 0 892 892 676 S 0 0.0 1.4 0:00 su
787 root 0 0 1060 1060 796 S 0 0.0 1.7 0:00 bash
792 root 0 0 5264 5264 1692 S 0 0.0 8.8 0:01 xawtv
805 PrincePh 0 0 1556 792 576 S 0 0.0 1.3 0:08 kppp
806 root 0 0 1640 1032 940 S 0 0.0 1.7 0:00 kppp
808 root 0 0 928 928 748 S 0 0.0 1.5 0:00 pppd
875 PrincePh 0 0 4504 4504 3068 S 0 0.0 7.5 0:00 x11amp
1012 PrincePh 0 0 4504 4504 3068 S 0 0.0 7.5 0:01 x11amp
1013 PrincePh 0 0 4504 4504 3068 S 0 0.0 7.5 0:00 x11amp
1197 root 0 0 4120 4120 3032 S 0 0.0 6.8 0:02 kwrite
1233 root 0 0 4136 4136 3032 S 0 0.0 6.9 0:02 kwrite
1268 PrincePh 0 0 5924 5924 4268 S 0 0.0 9.9 0:06 kmail
1270 PrincePh 0 0 12424 12M 7908 S 0 0.0 20.8 0:11 netscape-commun
1280 PrincePh 0 0 3664 3664 3096 S 0 0.0 6.1 0:00 netscape-commun

quite a lot of processes. I’ve tried this with and without netscape as well
when kde is running. At this point I’m lost. SDL’s Testver tells me I’ve got
v1.1.6. I’m running redhat6.1 with kernel 2.2.5-15. If anyone’s got any ideas
I’d be really grateful. Thanks again.–
Jeremy Gregorio
jgreg at azstarnet.com

I had a similar problem - it turns out that one of the default Gnome applets
(I believe it’s the desktop viewer) takes a screenshot every few seconds!
This dropped the performance of my application by 20-30% and made it look
choppy. I just started by killing off processes one by one until my app was
smooth again.

UHHH!!!,
I have a better one.

I create a Console application in Visual C and if get over 30 fps when running
it from a dos box.
Yesterday I ran it from the Explorer and it only got 0.8 fps. I expend the whole
evening trying to find the problem, until totally tired I run it again from a
dos box and voila: 30 fps.