test/testvidinfo.c
author Patrice Mandin <patmandin@gmail.com>
Thu, 19 Jan 2006 21:28:52 +0000
changeset 1257 448a9a64537b
parent 886 05c551e5bc64
child 1545 8d9bb0cf2c2a
permissions -rw-r--r--
[PATCH] SDL_GetVideoMode() does not find best mode, part 2

Following commit 1.51, I come accross a problem when SDL must choose between
several video modes that could suit the one asked.

If I ask 320x240 with this list:
768x480 768x240 640x400 640x200 384x480 384x240 320x400 320x200

The smallest selectables modes are 384x240 and 320x400. And SDL choose the later
in this list, but 384x240 is more suitable. So I added a check to compare
the pixel count (surface) of modes, and select the one which has the smallest
pixel count.

In my example, 384x240 has 92160 pixels, and 320x400 has 128000 pixels. So now
SDL will choose 384x240 for the asked 320x240 mode.
     1 
     2 /* Simple program -- figure out what kind of video display we have */
     3 
     4 #include <stdlib.h>
     5 #include <stdio.h>
     6 #include <stdlib.h>
     7 #include <string.h>
     8 
     9 #include "SDL.h"
    10 
    11 #define NUM_BLITS	10
    12 #define NUM_UPDATES	500
    13 
    14 #define FLAG_MASK	(SDL_HWSURFACE | SDL_FULLSCREEN | SDL_DOUBLEBUF | \
    15                          SDL_SRCCOLORKEY | SDL_SRCALPHA | SDL_RLEACCEL  | \
    16                          SDL_RLEACCELOK)
    17 
    18 void PrintFlags(Uint32 flags)
    19 {
    20 	printf("0x%8.8x", (flags & FLAG_MASK));
    21 	if ( flags & SDL_HWSURFACE ) {
    22 		printf(" SDL_HWSURFACE");
    23 	} else {
    24 		printf(" SDL_SWSURFACE");
    25 	}
    26 	if ( flags & SDL_FULLSCREEN ) {
    27 		printf(" | SDL_FULLSCREEN");
    28 	}
    29 	if ( flags & SDL_DOUBLEBUF ) {
    30 		printf(" | SDL_DOUBLEBUF");
    31 	}
    32 	if ( flags & SDL_SRCCOLORKEY ) {
    33 		printf(" | SDL_SRCCOLORKEY");
    34 	}
    35 	if ( flags & SDL_SRCALPHA ) {
    36 		printf(" | SDL_SRCALPHA");
    37 	}
    38 	if ( flags & SDL_RLEACCEL ) {
    39 		printf(" | SDL_RLEACCEL");
    40 	}
    41 	if ( flags & SDL_RLEACCELOK ) {
    42 		printf(" | SDL_RLEACCELOK");
    43 	}
    44 }
    45 
    46 int RunBlitTests(SDL_Surface *screen, SDL_Surface *bmp, int blitcount)
    47 {
    48 	int i, j;
    49 	int maxx;
    50 	int maxy;
    51 	SDL_Rect dst;
    52 
    53 	maxx = (int)screen->w - bmp->w + 1;
    54 	maxy = (int)screen->h - bmp->h + 1;
    55 	for ( i = 0; i < NUM_UPDATES; ++i ) {
    56 		for ( j = 0; j < blitcount; ++j ) {
    57 			if ( maxx ) {
    58 				dst.x = rand() % maxx;
    59 			} else {
    60 				dst.x = 0;
    61 			}
    62 			if ( maxy ) {
    63 				dst.y = rand() % maxy;
    64 			} else {
    65 				dst.y = 0;
    66 			}
    67 			dst.w = bmp->w;
    68 			dst.h = bmp->h;
    69 			SDL_BlitSurface(bmp, NULL, screen, &dst);
    70 		}
    71 		SDL_Flip(screen);
    72 	}
    73 
    74 	return i;
    75 }
    76 
    77 int RunModeTests(SDL_Surface *screen)
    78 {
    79 	Uint32 then, now;
    80 	Uint32 frames;
    81 	float seconds;
    82 	int i;
    83 	Uint8 r, g, b;
    84 	SDL_Surface *bmp, *bmpcc, *tmp;
    85 	SDL_Event event;
    86 
    87 	while ( SDL_PollEvent(&event) ) {
    88 		if ( event.type == SDL_KEYDOWN )
    89 			return 0;
    90 	}
    91 
    92 	/* First test fills and screen update speed */
    93 	printf("Running color fill and fullscreen update test\n");
    94 	then = SDL_GetTicks();
    95 	frames = 0;
    96 	for ( i = 0; i < 256; ++i ) {
    97 		r = i;
    98 		g = 0;
    99 		b = 0;
   100 		SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, g, b));
   101 		SDL_Flip(screen);
   102 		++frames;
   103 	}
   104 	for ( i = 0; i < 256; ++i ) {
   105 		r = 0;
   106 		g = i;
   107 		b = 0;
   108 		SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, g, b));
   109 		SDL_Flip(screen);
   110 		++frames;
   111 	}
   112 	for ( i = 0; i < 256; ++i ) {
   113 		r = 0;
   114 		g = 0;
   115 		b = i;
   116 		SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, g, b));
   117 		SDL_Flip(screen);
   118 		++frames;
   119 	}
   120 	now = SDL_GetTicks();
   121 	seconds = (float)(now - then) / 1000.0f;
   122 	if ( seconds > 0.0f ) {
   123 		printf("%d fills and flips in %2.2f seconds, %2.2f FPS\n", frames, seconds, (float)frames / seconds);
   124 	} else {
   125 		printf("%d fills and flips in zero seconds!n", frames);
   126 	}
   127 
   128         /* clear the screen after fill test */
   129         SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
   130 	SDL_Flip(screen);
   131 
   132 	while ( SDL_PollEvent(&event) ) {
   133 		if ( event.type == SDL_KEYDOWN )
   134 			return 0;
   135 	}
   136 
   137         /* run the generic blit test */
   138 	bmp = SDL_LoadBMP("sample.bmp");
   139 	if ( ! bmp ) {
   140 		printf("Couldn't load sample.bmp: %s\n", SDL_GetError());
   141 		return 0;
   142 	}
   143 	printf("Running freshly loaded blit test: %dx%d at %d bpp, flags: ",
   144 		bmp->w, bmp->h, bmp->format->BitsPerPixel);
   145 	PrintFlags(bmp->flags);
   146 	printf("\n");
   147 	then = SDL_GetTicks();
   148 	frames = RunBlitTests(screen, bmp, NUM_BLITS);
   149 	now = SDL_GetTicks();
   150 	seconds = (float)(now - then) / 1000.0f;
   151 	if ( seconds > 0.0f ) {
   152 		printf("%d blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS*frames, frames, seconds, (float)frames / seconds);
   153 	} else {
   154 		printf("%d blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames);
   155 	}
   156 
   157         /* clear the screen after blit test */
   158         SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
   159 	SDL_Flip(screen);
   160 
   161 	while ( SDL_PollEvent(&event) ) {
   162 		if ( event.type == SDL_KEYDOWN )
   163 			return 0;
   164 	}
   165 
   166         /* run the colorkeyed blit test */
   167 	bmpcc = SDL_LoadBMP("sample.bmp");
   168 	if ( ! bmpcc ) {
   169 		printf("Couldn't load sample.bmp: %s\n", SDL_GetError());
   170 		return 0;
   171 	}
   172 	printf("Running freshly loaded cc blit test: %dx%d at %d bpp, flags: ",
   173 		bmpcc->w, bmpcc->h, bmpcc->format->BitsPerPixel);
   174         SDL_SetColorKey(bmpcc, SDL_SRCCOLORKEY | SDL_RLEACCEL, *(Uint8 *)bmpcc->pixels);
   175 
   176 	PrintFlags(bmpcc->flags);
   177 	printf("\n");
   178 	then = SDL_GetTicks();
   179 	frames = RunBlitTests(screen, bmpcc, NUM_BLITS);
   180 	now = SDL_GetTicks();
   181 	seconds = (float)(now - then) / 1000.0f;
   182 	if ( seconds > 0.0f ) {
   183 		printf("%d cc blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS*frames, frames, seconds, (float)frames / seconds);
   184 	} else {
   185 		printf("%d cc blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames);
   186 	}
   187 
   188         /* clear the screen after cc blit test */
   189         SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
   190 	SDL_Flip(screen);
   191 
   192 	while ( SDL_PollEvent(&event) ) {
   193 		if ( event.type == SDL_KEYDOWN )
   194 			return 0;
   195 	}
   196 
   197         /* run the generic blit test */
   198 	tmp = bmp;
   199 	bmp = SDL_DisplayFormat(bmp);
   200 	SDL_FreeSurface(tmp);
   201 	if ( ! bmp ) {
   202 		printf("Couldn't convert sample.bmp: %s\n", SDL_GetError());
   203 		return 0;
   204 	}
   205 	printf("Running display format blit test: %dx%d at %d bpp, flags: ",
   206 		bmp->w, bmp->h, bmp->format->BitsPerPixel);
   207 	PrintFlags(bmp->flags);
   208 	printf("\n");
   209 	then = SDL_GetTicks();
   210 	frames = RunBlitTests(screen, bmp, NUM_BLITS);
   211 	now = SDL_GetTicks();
   212 	seconds = (float)(now - then) / 1000.0f;
   213 	if ( seconds > 0.0f ) {
   214 		printf("%d blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS*frames, frames, seconds, (float)frames / seconds);
   215 	} else {
   216 		printf("%d blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames);
   217 	}
   218 
   219         /* clear the screen after blit test */
   220         SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
   221 	SDL_Flip(screen);
   222 
   223 	while ( SDL_PollEvent(&event) ) {
   224 		if ( event.type == SDL_KEYDOWN )
   225 			return 0;
   226 	}
   227 
   228         /* run the colorkeyed blit test */
   229 	tmp = bmpcc;
   230 	bmpcc = SDL_DisplayFormat(bmpcc);
   231 	SDL_FreeSurface(tmp);
   232 	if ( ! bmpcc ) {
   233 		printf("Couldn't convert sample.bmp: %s\n", SDL_GetError());
   234 		return 0;
   235 	}
   236 	printf("Running display format cc blit test: %dx%d at %d bpp, flags: ",
   237 		bmpcc->w, bmpcc->h, bmpcc->format->BitsPerPixel);
   238 	PrintFlags(bmpcc->flags);
   239 	printf("\n");
   240 	then = SDL_GetTicks();
   241 	frames = RunBlitTests(screen, bmpcc, NUM_BLITS);
   242 	now = SDL_GetTicks();
   243 	seconds = (float)(now - then) / 1000.0f;
   244 	if ( seconds > 0.0f ) {
   245 		printf("%d cc blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS*frames, frames, seconds, (float)frames / seconds);
   246 	} else {
   247 		printf("%d cc blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames);
   248 	}
   249 
   250         /* clear the screen after cc blit test */
   251         SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
   252 	SDL_Flip(screen);
   253 
   254 	while ( SDL_PollEvent(&event) ) {
   255 		if ( event.type == SDL_KEYDOWN )
   256 			return 0;
   257 	}
   258 
   259         /* run the alpha blit test only if screen bpp>8 */
   260         if (bmp->format->BitsPerPixel>8)
   261         {
   262 		SDL_FreeSurface(bmp);
   263                 bmp = SDL_LoadBMP("sample.bmp");
   264 		SDL_SetAlpha(bmp, SDL_SRCALPHA, 85); /* 85 - 33% alpha */
   265 		tmp = bmp;
   266 		bmp = SDL_DisplayFormat(bmp);
   267 		SDL_FreeSurface(tmp);
   268 		if ( ! bmp ) {
   269 			printf("Couldn't convert sample.bmp: %s\n", SDL_GetError());
   270 			return 0;
   271 		}
   272 		printf("Running display format alpha blit test: %dx%d at %d bpp, flags: ",
   273 			bmp->w, bmp->h, bmp->format->BitsPerPixel);
   274 		PrintFlags(bmp->flags);
   275 		printf("\n");
   276 		then = SDL_GetTicks();
   277 		frames = RunBlitTests(screen, bmp, NUM_BLITS);
   278 		now = SDL_GetTicks();
   279 		seconds = (float)(now - then) / 1000.0f;
   280 		if ( seconds > 0.0f ) {
   281 			printf("%d alpha blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS*frames, frames, seconds, (float)frames / seconds);
   282 		} else {
   283 			printf("%d alpha blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames);
   284 		}
   285 	}
   286 
   287         /* clear the screen after alpha blit test */
   288         SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
   289 	SDL_Flip(screen);
   290 
   291 	while ( SDL_PollEvent(&event) ) {
   292 		if ( event.type == SDL_KEYDOWN )
   293 			return 0;
   294 	}
   295 
   296         /* run the cc+alpha blit test only if screen bpp>8 */
   297         if (bmp->format->BitsPerPixel>8)
   298         {
   299 		SDL_FreeSurface(bmpcc);
   300                 bmpcc = SDL_LoadBMP("sample.bmp");
   301 		SDL_SetAlpha(bmpcc, SDL_SRCALPHA, 85); /* 85 - 33% alpha */
   302                 SDL_SetColorKey(bmpcc, SDL_SRCCOLORKEY | SDL_RLEACCEL, *(Uint8 *)bmpcc->pixels);
   303 		tmp = bmpcc;
   304 		bmpcc = SDL_DisplayFormat(bmpcc);
   305 		SDL_FreeSurface(tmp);
   306 		if ( ! bmpcc ) {
   307 			printf("Couldn't convert sample.bmp: %s\n", SDL_GetError());
   308 			return 0;
   309 		}
   310 		printf("Running display format cc+alpha blit test: %dx%d at %d bpp, flags: ",
   311 			bmpcc->w, bmpcc->h, bmpcc->format->BitsPerPixel);
   312 		PrintFlags(bmpcc->flags);
   313 		printf("\n");
   314 		then = SDL_GetTicks();
   315 		frames = RunBlitTests(screen, bmpcc, NUM_BLITS);
   316 		now = SDL_GetTicks();
   317 		seconds = (float)(now - then) / 1000.0f;
   318 		if ( seconds > 0.0f ) {
   319 			printf("%d cc+alpha blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS*frames, frames, seconds, (float)frames / seconds);
   320 		} else {
   321 			printf("%d cc+alpha blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames);
   322 		}
   323 	}
   324 
   325 	SDL_FreeSurface(bmpcc);
   326 	SDL_FreeSurface(bmp);
   327 
   328 	while ( SDL_PollEvent(&event) ) {
   329 		if ( event.type == SDL_KEYDOWN )
   330 			return 0;
   331 	}
   332 	return 1;
   333 }
   334 
   335 void RunVideoTests()
   336 {
   337 	static const struct {
   338 		int w, h, bpp;
   339 	} mode_list[] = {
   340 		{ 640, 480, 8 }, { 640, 480, 16 }, { 640, 480, 32 },
   341 		{ 800, 600, 8 }, { 800, 600, 16 }, { 800, 600, 32 },
   342 		{ 1024, 768, 8 }, { 1024, 768, 16 }, { 1024, 768, 32 }
   343 	};
   344 	static const Uint32 flags[] = {
   345 		(SDL_SWSURFACE),
   346 		(SDL_SWSURFACE | SDL_FULLSCREEN),
   347 		(SDL_HWSURFACE | SDL_FULLSCREEN),
   348 		(SDL_HWSURFACE | SDL_FULLSCREEN | SDL_DOUBLEBUF)
   349 	};
   350 	int i, j;
   351 	SDL_Surface *screen;
   352 
   353 	/* Test out several different video mode combinations */
   354 	SDL_WM_SetCaption("SDL Video Benchmark", "vidtest");
   355 	SDL_ShowCursor(0);
   356 	for ( i = 0; i < SDL_TABLESIZE(mode_list); ++i ) {
   357 		for ( j = 0; j < SDL_TABLESIZE(flags); ++j ) {
   358 			printf("===================================\n");
   359 			printf("Setting video mode: %dx%d at %d bpp, flags: ",
   360 			                          mode_list[i].w,
   361 			                          mode_list[i].h,
   362 			                          mode_list[i].bpp);
   363 			PrintFlags(flags[j]);
   364 			printf("\n");
   365 			screen = SDL_SetVideoMode(mode_list[i].w,
   366 			                          mode_list[i].h,
   367 			                          mode_list[i].bpp,
   368 			                          flags[j]);
   369 			if ( ! screen ) {
   370 				printf("Setting video mode failed: %s\n", SDL_GetError());
   371 				continue;
   372 			}
   373 			if ( (screen->flags & FLAG_MASK) != flags[j] ) {
   374 				printf("Flags didn't match: ");
   375 				PrintFlags(screen->flags);
   376 				printf("\n");
   377 				continue;
   378 			}
   379 			if ( ! RunModeTests(screen) ) {
   380 				return;
   381 			}
   382 		}
   383 	}
   384 }
   385 
   386 int main(int argc, char *argv[])
   387 {
   388 	const SDL_VideoInfo *info;
   389 	int i;
   390 	SDL_Rect **modes;
   391 	char driver[128];
   392 
   393 	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
   394 		fprintf(stderr,
   395 			"Couldn't initialize SDL: %s\n", SDL_GetError());
   396 		exit(1);
   397 	}
   398 	if ( SDL_VideoDriverName(driver, sizeof(driver)) ) {
   399 		printf("Video driver: %s\n", driver);
   400 	}
   401 	info = SDL_GetVideoInfo();
   402 	printf(
   403 "Current display: %d bits-per-pixel\n",info->vfmt->BitsPerPixel);
   404 	if ( info->vfmt->palette == NULL ) {
   405 		printf("	Red Mask = 0x%.8x\n", info->vfmt->Rmask);
   406 		printf("	Green Mask = 0x%.8x\n", info->vfmt->Gmask);
   407 		printf("	Blue Mask = 0x%.8x\n", info->vfmt->Bmask);
   408 	}
   409 	/* Print available fullscreen video modes */
   410 	modes = SDL_ListModes(NULL, SDL_FULLSCREEN);
   411 	if ( modes == (SDL_Rect **)0 ) {
   412 		printf("No available fullscreen video modes\n");
   413 	} else
   414 	if ( modes == (SDL_Rect **)-1 ) {
   415 		printf("No special fullscreen video modes\n");
   416 	} else {
   417 		printf("Fullscreen video modes:\n");
   418 		for ( i=0; modes[i]; ++i ) {
   419 			printf("\t%dx%dx%d\n", modes[i]->w, modes[i]->h, info->vfmt->BitsPerPixel);
   420 		}
   421 	}
   422 	if ( info->wm_available ) {
   423 		printf("A window manager is available\n");
   424 	}
   425 	if ( info->hw_available ) {
   426 		printf("Hardware surfaces are available (%dK video memory)\n",
   427 			info->video_mem);
   428 	}
   429 	if ( info->blit_hw ) {
   430 		printf(
   431 "Copy blits between hardware surfaces are accelerated\n");
   432 	}
   433 	if ( info->blit_hw_CC ) {
   434 		printf(
   435 "Colorkey blits between hardware surfaces are accelerated\n");
   436 	}
   437 	if ( info->blit_hw_A ) {
   438 		printf(
   439 "Alpha blits between hardware surfaces are accelerated\n");
   440 	}
   441 	if ( info->blit_sw ) {
   442 		printf(
   443 "Copy blits from software surfaces to hardware surfaces are accelerated\n");
   444 	}
   445 	if ( info->blit_sw_CC ) {
   446 		printf(
   447 "Colorkey blits from software surfaces to hardware surfaces are accelerated\n");
   448 	}
   449 	if ( info->blit_sw_A ) {
   450 		printf(
   451 "Alpha blits from software surfaces to hardware surfaces are accelerated\n");
   452 	}
   453 	if ( info->blit_fill ) {
   454 		printf(
   455 "Color fills on hardware surfaces are accelerated\n");
   456 	}
   457 
   458 	if ( argv[1] && (strcmp(argv[1], "-benchmark") == 0) ) {
   459 		RunVideoTests();
   460 	}
   461 
   462 	SDL_Quit();
   463 	return(0);
   464 }