test/testblitspeed.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 28 May 2006 13:04:16 +0000
branchSDL-1.3
changeset 1662 782fd950bd46
parent 1658 e49147870aac
child 1668 4da1ee79c9af
permissions -rw-r--r--
Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API.

WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid.

The code is now run through a consistent indent format:
indent -i4 -nut -nsc -br -ce

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