[SDL] RLE blits

Mikael Thieme mikael.thieme at gmail.com
Sun Dec 30 13:59:20 PST 2007


Hi,

I have spent the last couple of days benchmarking SDL-blitting under 
various combinations of settings (hw vs sw surfaces, 16 vs 32 bpp, 
Colorkey/RLE etc.) on win32.

The results seem to indicate that 32bpp RLE blits are about ten (!) 
times faster than ordinary keyed blits. 16bpp RLE blits on the other 
hand are only about twice as fast (a much more reasonable difference?).

The benchmark blits 1000 circular-shaped sprites using software 
surfaces. The results are basically the same regardless of driver 
(windib vs directx). My laptop gives similar results...

Is there a reasonable explanation for this huge difference?

I have included key parts of the benchmarking code below, maybe I missed 
something?

Best regards.

Mikael


void Benchmark::keyBlit(){
	const int SPRITE_COUNT = 1000;
	
	const string filename = "KeySprite.bmp";
	SDL_Surface *bitmap = SDL_LoadBMP(filename.c_str());
	if(bitmap == NULL){
		mError = "Could not load bitmap (" + filename + ").";
		return;
	}
	if(SDL_SetColorKey(bitmap, SDL_SRCCOLORKEY, SDL_MapRGB(bitmap->format, 
0, 0, 0))){
		mError = "Could not set color key.";
		return;
	}
	SDL_Surface *sprite = SDL_DisplayFormat(bitmap);
	if(sprite == NULL){
		mError = "Could not convert bitmap to display format.";
		return;
	}
	const int SPRITE_WIDTH = sprite->w;
	const int SPRITE_HEIGHT = sprite->h;

	ostringstream output;
	output << SPRITE_COUNT << " " << SPRITE_WIDTH << "X" << SPRITE_HEIGHT 
<< " sprites.";
	mComment = output.str();

	SDL_Surface *display = SDL_GetVideoSurface();
	if(display == NULL){
		mError = "Could not retrieve display surface.";
		return;
	}
	const int DISPLAY_WIDTH = display->w;
	const int DISPLAY_HEIGHT = display->h;

	const double END = getTime() + mDuration;
	while(getTime() < END){
		const double BEFORE = getTime();
		for(int i = 0; i < SPRITE_COUNT; i++){
			const int SPRITE_X = getInt(0, DISPLAY_WIDTH - SPRITE_WIDTH);
			const int SPRITE_Y = getInt(0, DISPLAY_HEIGHT - SPRITE_HEIGHT);
			SDL_Rect destinationRectangle;
			destinationRectangle.x = SPRITE_X;
			destinationRectangle.y = SPRITE_Y;
			destinationRectangle.w = SPRITE_WIDTH;
			destinationRectangle.h = SPRITE_HEIGHT;
			if(SDL_BlitSurface(sprite, NULL, display, &destinationRectangle) < 0){
				mError = "Could not blit.";
				return;
			}
		}
		const double AFTER = getTime();
		const double SAMPLE = AFTER - BEFORE;
		mSamples.push_back(SAMPLE);
		if(SDL_Flip(display) < 0){
			mError = "Could not flip.";
			return;
		}
		SDL_Delay(100);
	}

	SDL_FreeSurface(sprite);
	SDL_FreeSurface(bitmap);
}

void Benchmark::rleBlit(){
	const int SPRITE_COUNT = 1000;
	
	const string filename = "KeySprite.bmp";
	SDL_Surface *bitmap = SDL_LoadBMP(filename.c_str());
	if(bitmap == NULL){
		mError = "Could not load bitmap (" + filename + ").";
		return;
	}
	if(SDL_SetColorKey(bitmap, SDL_SRCCOLORKEY | SDL_RLEACCEL, 
SDL_MapRGB(bitmap->format, 0, 0, 0))){
		mError = "Could not set color key and RLE.";
		return;
	}
	SDL_Surface *sprite = SDL_DisplayFormat(bitmap);
	if(sprite == NULL){
		mError = "Could not convert bitmap to display format.";
		return;
	}
	const int SPRITE_WIDTH = sprite->w;
	const int SPRITE_HEIGHT = sprite->h;

	ostringstream output;
	output << SPRITE_COUNT << " " << SPRITE_WIDTH << "X" << SPRITE_HEIGHT 
<< " sprites.";
	mComment = output.str();

	SDL_Surface *display = SDL_GetVideoSurface();
	if(display == NULL){
		mError = "Could not retrieve display surface.";
		return;
	}
	const int DISPLAY_WIDTH = display->w;
	const int DISPLAY_HEIGHT = display->h;

	const double END = getTime() + mDuration;
	while(getTime() < END){
		const double BEFORE = getTime();
		for(int i = 0; i < SPRITE_COUNT; i++){
			const int SPRITE_X = getInt(0, DISPLAY_WIDTH - SPRITE_WIDTH);
			const int SPRITE_Y = getInt(0, DISPLAY_HEIGHT - SPRITE_HEIGHT);
			SDL_Rect destinationRectangle;
			destinationRectangle.x = SPRITE_X;
			destinationRectangle.y = SPRITE_Y;
			destinationRectangle.w = SPRITE_WIDTH;
			destinationRectangle.h = SPRITE_HEIGHT;
			if(SDL_BlitSurface(sprite, NULL, display, &destinationRectangle) < 0){
				mError = "Could not blit.";
				return;
			}
		}
		const double AFTER = getTime();
		const double SAMPLE = AFTER - BEFORE;
		mSamples.push_back(SAMPLE);
		if(SDL_Flip(display) < 0){
			mError = "Could not flip.";
			return;
		}
		SDL_Delay(100);
	}

	SDL_FreeSurface(sprite);
	SDL_FreeSurface(bitmap);
}




More information about the SDL mailing list