RLE blits

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);

}