test/testblitspeed.c
author Ryan C. Gordon <icculus@icculus.org>
Thu, 29 Sep 2005 09:43:00 +0000
changeset 1152 51a8702d8ecd
parent 1039 68f2b997758e
child 1231 cf59e7b91ed4
permissions -rw-r--r--
Updates to PocketPC (WinCE) support, thanks to Dmitry Yakimov at
activekitten.com.
     1 /*
     2  * Benchmarks surface-to-surface blits in various formats.
     3  *
     4  *  Written by Ryan C. Gordon.
     5  */
     6 
     7 #include <stdio.h>
     8 #include <stdlib.h>
     9 #include <string.h>
    10 
    11 #include "SDL.h"
    12 
    13 static SDL_Surface *dest = NULL;
    14 static SDL_Surface *src = NULL;
    15 static int testSeconds = 10;
    16 
    17 
    18 static int percent(int val, int total)
    19 {
    20     return((int) ((((float) val) / ((float) total)) * 100.0f));
    21 }
    22 
    23 static int randRange(int lo, int hi)
    24 {
    25     return(lo + (int) (((double) hi)*rand()/(RAND_MAX+1.0)));
    26 }
    27 
    28 static void copy_trunc_str(char *str, size_t strsize, const char *flagstr)
    29 {
    30     if ( (strlen(str) + strlen(flagstr)) >= (strsize - 1) )
    31         strcpy(str + (strsize - 5), " ...");
    32     else
    33         strcat(str, flagstr);
    34 }
    35 
    36 static void __append_sdl_surface_flag(SDL_Surface *_surface, char *str,
    37                                       size_t strsize, Uint32 flag,
    38                                       const char *flagstr)
    39 {
    40     if (_surface->flags & flag)
    41         copy_trunc_str(str, strsize, flagstr);
    42 } /* append_sdl_surface_flag */
    43 
    44 
    45 #define append_sdl_surface_flag(a, b, c, fl) __append_sdl_surface_flag(a, b, c, fl, " " #fl)
    46 #define print_tf_state(str, val) printf("%s: {%s}\n", str, (val) ? "true" : "false" )
    47 
    48 static void output_surface_details(const char *name, SDL_Surface *surface)
    49 {
    50     printf("Details for %s:\n", name);
    51 
    52     if (surface == NULL)
    53     {
    54         printf("-WARNING- You've got a NULL surface!");
    55     }
    56     else
    57     {
    58         char f[256];
    59         printf("  width  : %d\n", surface->w);
    60         printf("  height : %d\n", surface->h);
    61         printf("  depth  : %d bits per pixel\n", surface->format->BitsPerPixel);
    62         printf("  pitch  : %d\n", (int) surface->pitch);
    63 
    64         printf("  red    : 0x%08X mask, %d shift, %d loss\n",
    65                     (int) surface->format->Rmask,
    66                     (int) surface->format->Rshift,
    67                     (int) surface->format->Rloss);
    68         printf("  green  : 0x%08X mask, %d shift, %d loss\n",
    69                     (int) surface->format->Gmask,
    70                     (int) surface->format->Gshift,
    71                     (int) surface->format->Gloss);
    72         printf("  blue   : 0x%08X mask, %d shift, %d loss\n",
    73                     (int) surface->format->Bmask,
    74                     (int) surface->format->Bshift,
    75                     (int) surface->format->Bloss);
    76         printf("  alpha  : 0x%08X mask, %d shift, %d loss\n",
    77                     (int) surface->format->Amask,
    78                     (int) surface->format->Ashift,
    79                     (int) surface->format->Aloss);
    80 
    81         f[0] = '\0';
    82 
    83         /*append_sdl_surface_flag(surface, f, sizeof (f), SDL_SWSURFACE);*/
    84         if ((surface->flags & SDL_HWSURFACE) == 0)
    85             copy_trunc_str(f, sizeof (f), " SDL_SWSURFACE");
    86 
    87         append_sdl_surface_flag(surface, f, sizeof (f), SDL_HWSURFACE);
    88         append_sdl_surface_flag(surface, f, sizeof (f), SDL_ASYNCBLIT);
    89         append_sdl_surface_flag(surface, f, sizeof (f), SDL_ANYFORMAT);
    90         append_sdl_surface_flag(surface, f, sizeof (f), SDL_HWPALETTE);
    91         append_sdl_surface_flag(surface, f, sizeof (f), SDL_DOUBLEBUF);
    92         append_sdl_surface_flag(surface, f, sizeof (f), SDL_FULLSCREEN);
    93         append_sdl_surface_flag(surface, f, sizeof (f), SDL_OPENGL);
    94         append_sdl_surface_flag(surface, f, sizeof (f), SDL_OPENGLBLIT);
    95         append_sdl_surface_flag(surface, f, sizeof (f), SDL_RESIZABLE);
    96         append_sdl_surface_flag(surface, f, sizeof (f), SDL_NOFRAME);
    97         append_sdl_surface_flag(surface, f, sizeof (f), SDL_HWACCEL);
    98         append_sdl_surface_flag(surface, f, sizeof (f), SDL_SRCCOLORKEY);
    99         append_sdl_surface_flag(surface, f, sizeof (f), SDL_RLEACCELOK);
   100         append_sdl_surface_flag(surface, f, sizeof (f), SDL_RLEACCEL);
   101         append_sdl_surface_flag(surface, f, sizeof (f), SDL_SRCALPHA);
   102         append_sdl_surface_flag(surface, f, sizeof (f), SDL_PREALLOC);
   103 
   104         if (f[0] == '\0')
   105             strcpy(f, " (none)");
   106 
   107         printf("  flags  :%s\n", f);
   108 
   109         #if 0
   110         info = SDL_GetVideoInfo();
   111         assert(info != NULL);
   112 
   113         print_tf_state("hardware surface available", info->hw_available);
   114         print_tf_state("window manager available", info->wm_available);
   115         print_tf_state("accelerated hardware->hardware blits", info->blit_hw);
   116         print_tf_state("accelerated hardware->hardware colorkey blits", info->blit_hw_CC);
   117         print_tf_state("accelerated hardware->hardware alpha blits", info->blit_hw_A);
   118         print_tf_state("accelerated software->hardware blits", info->blit_sw);
   119         print_tf_state("accelerated software->hardware colorkey blits", info->blit_sw_CC);
   120         print_tf_state("accelerated software->hardware alpha blits", info->blit_sw_A);
   121         print_tf_state("accelerated color fills", info->blit_fill);
   122 
   123         printf("video memory: (%d)\n", info->video_mem);
   124         #endif
   125     } /* else */
   126 
   127     printf("\n");
   128 }
   129 
   130 static void output_details(void)
   131 {
   132     output_surface_details("Source Surface", src);
   133     output_surface_details("Destination Surface", dest);
   134 }
   135 
   136 static Uint32 blit(SDL_Surface *dst, SDL_Surface *src, int x, int y)
   137 {
   138     Uint32 start = 0;
   139     SDL_Rect srcRect;
   140     SDL_Rect dstRect;
   141 
   142     srcRect.x = 0;
   143     srcRect.y = 0;
   144     dstRect.x = x;
   145     dstRect.y = y;
   146     dstRect.w = srcRect.w = src->w;  /* SDL will clip as appropriate. */
   147     dstRect.h = srcRect.h = src->h;
   148 
   149     start = SDL_GetTicks();
   150     SDL_BlitSurface(src, &srcRect, dst, &dstRect);
   151     return(SDL_GetTicks() - start);
   152 }
   153 
   154 static void blitCentered(SDL_Surface *dst, SDL_Surface *src)
   155 {
   156     int x = (dst->w - src->w) / 2;
   157     int y = (dst->h - src->h) / 2;
   158     blit(dst, src, x, y);
   159 }
   160 
   161 static int atoi_hex(const char *str)
   162 {
   163     if (str == NULL)
   164         return 0;
   165 
   166     if (strlen(str) > 2)
   167     {
   168         int retval = 0;
   169         if ((str[0] == '0') && (str[1] == 'x'))
   170             sscanf(str + 2, "%X", &retval);
   171         return(retval);
   172     }
   173 
   174     return(atoi(str));
   175 }
   176 
   177 
   178 static int setup_test(int argc, char **argv)
   179 {
   180     const char *dumpfile = NULL;
   181     SDL_Surface *bmp = NULL;
   182     Uint32 dstbpp = 32;
   183     Uint32 dstrmask = 0x00FF0000;
   184     Uint32 dstgmask = 0x0000FF00;
   185     Uint32 dstbmask = 0x000000FF;
   186     Uint32 dstamask = 0x00000000;
   187     Uint32 dstflags = 0;
   188     int dstw = 640;
   189     int dsth = 480;
   190     Uint32 srcbpp = 32;
   191     Uint32 srcrmask = 0x00FF0000;
   192     Uint32 srcgmask = 0x0000FF00;
   193     Uint32 srcbmask = 0x000000FF;
   194     Uint32 srcamask = 0x00000000;
   195     Uint32 srcflags = 0;
   196     int srcw = 640;
   197     int srch = 480;
   198     int screenSurface = 0;
   199     int i;
   200 
   201     for (i = 1; i < argc; i++)
   202     {
   203         const char *arg = argv[i];
   204 
   205         if (strcmp(arg, "--dstbpp") == 0)
   206             dstbpp = atoi(argv[++i]);
   207         else if (strcmp(arg, "--dstrmask") == 0)
   208             dstrmask = atoi_hex(argv[++i]);
   209         else if (strcmp(arg, "--dstgmask") == 0)
   210             dstgmask = atoi_hex(argv[++i]);
   211         else if (strcmp(arg, "--dstbmask") == 0)
   212             dstbmask = atoi_hex(argv[++i]);
   213         else if (strcmp(arg, "--dstamask") == 0)
   214             dstamask = atoi_hex(argv[++i]);
   215         else if (strcmp(arg, "--dstwidth") == 0)
   216             dstw = atoi(argv[++i]);
   217         else if (strcmp(arg, "--dstheight") == 0)
   218             dsth = atoi(argv[++i]);
   219         else if (strcmp(arg, "--dsthwsurface") == 0)
   220             dstflags |= SDL_HWSURFACE;
   221         else if (strcmp(arg, "--srcbpp") == 0)
   222             srcbpp = atoi(argv[++i]);
   223         else if (strcmp(arg, "--srcrmask") == 0)
   224             srcrmask = atoi_hex(argv[++i]);
   225         else if (strcmp(arg, "--srcgmask") == 0)
   226             srcgmask = atoi_hex(argv[++i]);
   227         else if (strcmp(arg, "--srcbmask") == 0)
   228             srcbmask = atoi_hex(argv[++i]);
   229         else if (strcmp(arg, "--srcamask") == 0)
   230             srcamask = atoi_hex(argv[++i]);
   231         else if (strcmp(arg, "--srcwidth") == 0)
   232             srcw = atoi(argv[++i]);
   233         else if (strcmp(arg, "--srcheight") == 0)
   234             srch = atoi(argv[++i]);
   235         else if (strcmp(arg, "--srchwsurface") == 0)
   236             srcflags |= SDL_HWSURFACE;
   237         else if (strcmp(arg, "--seconds") == 0)
   238             testSeconds = atoi(argv[++i]);
   239         else if (strcmp(arg, "--screen") == 0)
   240             screenSurface = 1;
   241         else if (strcmp(arg, "--dumpfile") == 0)
   242             dumpfile = argv[++i];
   243         else
   244         {
   245             fprintf(stderr, "Unknown commandline option: %s\n", arg);
   246             return(0);
   247         }
   248     }
   249 
   250     if (SDL_Init(SDL_INIT_VIDEO) == -1)
   251     {
   252         fprintf(stderr, "SDL_Init failed: %s\n", SDL_GetError());
   253         return(0);
   254     }
   255 
   256     bmp = SDL_LoadBMP("sample.bmp");
   257     if (bmp == NULL)
   258     {
   259         fprintf(stderr, "SDL_LoadBMP failed: %s\n", SDL_GetError());
   260         SDL_Quit();
   261         return(0);
   262     }
   263 
   264     if ((dstflags & SDL_HWSURFACE) == 0) dstflags |= SDL_SWSURFACE;
   265     if ((srcflags & SDL_HWSURFACE) == 0) srcflags |= SDL_SWSURFACE;
   266 
   267     if (screenSurface)
   268         dest = SDL_SetVideoMode(dstw, dsth, dstbpp, dstflags);
   269     else
   270     {
   271         dest = SDL_CreateRGBSurface(dstflags, dstw, dsth, dstbpp,
   272                                     dstrmask, dstgmask, dstbmask, dstamask);
   273     }
   274 
   275     if (dest == NULL)
   276     {
   277         fprintf(stderr, "dest surface creation failed: %s\n", SDL_GetError());
   278         SDL_Quit();
   279         return(0);
   280     }
   281 
   282     src = SDL_CreateRGBSurface(srcflags, srcw, srch, srcbpp,
   283                                srcrmask, srcgmask, srcbmask, srcamask);
   284     if (src == NULL)
   285     {
   286         fprintf(stderr, "src surface creation failed: %s\n", SDL_GetError());
   287         SDL_Quit();
   288         return(0);
   289     }
   290 
   291     /* set some sane defaults so we can see if the blit code is broken... */
   292     SDL_FillRect(dest, NULL, SDL_MapRGB(dest->format, 0, 0, 0));
   293     SDL_FillRect(src, NULL, SDL_MapRGB(src->format, 0, 0, 0));
   294 
   295     blitCentered(src, bmp);
   296     SDL_FreeSurface(bmp);
   297 
   298     if (dumpfile)
   299         SDL_SaveBMP(src, dumpfile);  /* make sure initial convert is sane. */
   300 
   301     output_details();
   302 
   303     return(1);
   304 }
   305 
   306 
   307 static void test_blit_speed(void)
   308 {
   309     Uint32 clearColor = SDL_MapRGB(dest->format, 0, 0, 0);
   310     Uint32 iterations = 0;
   311     Uint32 elasped = 0;
   312     Uint32 end = 0;
   313     Uint32 now = 0;
   314     Uint32 last = 0;
   315     int testms = testSeconds * 1000;
   316     int wmax = (dest->w - src->w);
   317     int hmax = (dest->h - src->h);
   318     int isScreen = (SDL_GetVideoSurface() == dest);
   319     SDL_Event event;
   320 
   321     printf("Testing blit speed for %d seconds...\n", testSeconds);
   322 
   323     now = SDL_GetTicks();
   324     end = now + testms;
   325 
   326     do
   327     {
   328         /* pump the event queue occasionally to keep OS happy... */
   329         if (now - last > 1000)
   330         {
   331             last = now;
   332             while (SDL_PollEvent(&event)) { /* no-op. */ }
   333         }
   334 
   335         iterations++;
   336         elasped += blit(dest, src, randRange(0, wmax), randRange(0, hmax));
   337         if (isScreen)
   338         {
   339             SDL_Flip(dest);  /* show it! */
   340             SDL_FillRect(dest, NULL, clearColor); /* blank it for next time! */
   341         }
   342 
   343         now = SDL_GetTicks();
   344     } while (now < end);
   345 
   346     printf("Non-blitting crap accounted for %d percent of this run.\n",
   347             percent(testms - elasped, testms));
   348 
   349     printf("%d blits took %d ms (%d fps).\n",
   350             (int) iterations,
   351             (int) elasped,
   352             (int) (((float)iterations) / (((float)elasped) / 1000.0f)));
   353 }
   354 
   355 int main(int argc, char **argv)
   356 {
   357     int initialized = setup_test(argc, argv);
   358     if (initialized)
   359     {
   360         test_blit_speed();
   361         SDL_Quit();
   362     }
   363     return(!initialized);
   364 }
   365 
   366 /* end of testblitspeed.c ... */
   367