test/testblitspeed.c
author Holmes Futrell <hfutrell@umail.ucsb.edu>
Fri, 18 Jul 2008 19:23:13 +0000
branchgsoc2008_iphone
changeset 2377 e9a0bad0ea07
parent 2267 c785543d1843
child 2669 e27bdcc80744
permissions -rw-r--r--
Just renamed it...
     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 
    95         printf("  red bits   : 0x%08X mask, %d shift, %d loss\n",
    96                (int) surface->format->Rmask,
    97                (int) surface->format->Rshift, (int) surface->format->Rloss);
    98         printf("  green bits : 0x%08X mask, %d shift, %d loss\n",
    99                (int) surface->format->Gmask,
   100                (int) surface->format->Gshift, (int) surface->format->Gloss);
   101         printf("  blue bits  : 0x%08X mask, %d shift, %d loss\n",
   102                (int) surface->format->Bmask,
   103                (int) surface->format->Bshift, (int) surface->format->Bloss);
   104         printf("  alpha bits : 0x%08X mask, %d shift, %d loss\n",
   105                (int) surface->format->Amask,
   106                (int) surface->format->Ashift, (int) surface->format->Aloss);
   107 
   108         f[0] = '\0';
   109 
   110         /*append_sdl_surface_flag(surface, f, sizeof (f), SDL_SWSURFACE); */
   111         if ((surface->flags & SDL_HWSURFACE) == 0)
   112             copy_trunc_str(f, sizeof(f), " SDL_SWSURFACE");
   113 
   114         append_sdl_surface_flag(surface, f, sizeof(f), SDL_HWSURFACE);
   115         append_sdl_surface_flag(surface, f, sizeof(f), SDL_ASYNCBLIT);
   116         append_sdl_surface_flag(surface, f, sizeof(f), SDL_ANYFORMAT);
   117         append_sdl_surface_flag(surface, f, sizeof(f), SDL_HWPALETTE);
   118         append_sdl_surface_flag(surface, f, sizeof(f), SDL_DOUBLEBUF);
   119         append_sdl_surface_flag(surface, f, sizeof(f), SDL_FULLSCREEN);
   120         append_sdl_surface_flag(surface, f, sizeof(f), SDL_OPENGL);
   121         append_sdl_surface_flag(surface, f, sizeof(f), SDL_RESIZABLE);
   122         append_sdl_surface_flag(surface, f, sizeof(f), SDL_NOFRAME);
   123         append_sdl_surface_flag(surface, f, sizeof(f), SDL_HWACCEL);
   124         append_sdl_surface_flag(surface, f, sizeof(f), SDL_SRCCOLORKEY);
   125         append_sdl_surface_flag(surface, f, sizeof(f), SDL_RLEACCELOK);
   126         append_sdl_surface_flag(surface, f, sizeof(f), SDL_RLEACCEL);
   127         append_sdl_surface_flag(surface, f, sizeof(f), SDL_SRCALPHA);
   128         append_sdl_surface_flag(surface, f, sizeof(f), SDL_PREALLOC);
   129 
   130         if (f[0] == '\0')
   131             strcpy(f, " (none)");
   132 
   133         printf("  flags      :%s\n", f);
   134     }
   135 
   136     printf("\n");
   137 }
   138 
   139 static void
   140 output_details(void)
   141 {
   142     output_videoinfo_details();
   143     output_surface_details("Source Surface", src);
   144     output_surface_details("Destination Surface", dest);
   145 }
   146 
   147 static Uint32
   148 blit(SDL_Surface * dst, SDL_Surface * src, int x, int y)
   149 {
   150     Uint32 start = 0;
   151     SDL_Rect srcRect;
   152     SDL_Rect dstRect;
   153 
   154     srcRect.x = 0;
   155     srcRect.y = 0;
   156     dstRect.x = x;
   157     dstRect.y = y;
   158     dstRect.w = srcRect.w = src->w;     /* SDL will clip as appropriate. */
   159     dstRect.h = srcRect.h = src->h;
   160 
   161     start = SDL_GetTicks();
   162     SDL_BlitSurface(src, &srcRect, dst, &dstRect);
   163     return (SDL_GetTicks() - start);
   164 }
   165 
   166 static void
   167 blitCentered(SDL_Surface * dst, SDL_Surface * src)
   168 {
   169     int x = (dst->w - src->w) / 2;
   170     int y = (dst->h - src->h) / 2;
   171     blit(dst, src, x, y);
   172 }
   173 
   174 static int
   175 atoi_hex(const char *str)
   176 {
   177     if (str == NULL)
   178         return 0;
   179 
   180     if (strlen(str) > 2) {
   181         int retval = 0;
   182         if ((str[0] == '0') && (str[1] == 'x'))
   183             sscanf(str + 2, "%X", &retval);
   184         return (retval);
   185     }
   186 
   187     return (atoi(str));
   188 }
   189 
   190 
   191 static int
   192 setup_test(int argc, char **argv)
   193 {
   194     const char *dumpfile = NULL;
   195     SDL_Surface *bmp = NULL;
   196     Uint32 dstbpp = 32;
   197     Uint32 dstrmask = 0x00FF0000;
   198     Uint32 dstgmask = 0x0000FF00;
   199     Uint32 dstbmask = 0x000000FF;
   200     Uint32 dstamask = 0x00000000;
   201     Uint32 dstflags = 0;
   202     int dstw = 640;
   203     int dsth = 480;
   204     Uint32 srcbpp = 32;
   205     Uint32 srcrmask = 0x00FF0000;
   206     Uint32 srcgmask = 0x0000FF00;
   207     Uint32 srcbmask = 0x000000FF;
   208     Uint32 srcamask = 0x00000000;
   209     Uint32 srcflags = 0;
   210     int srcw = 640;
   211     int srch = 480;
   212     Uint32 origsrcalphaflags = 0;
   213     Uint32 origdstalphaflags = 0;
   214     Uint32 srcalphaflags = 0;
   215     Uint32 dstalphaflags = 0;
   216     Uint8 origsrcalpha = 255;
   217     Uint8 origdstalpha = 255;
   218     Uint8 srcalpha = 255;
   219     Uint8 dstalpha = 255;
   220     int screenSurface = 0;
   221     int i = 0;
   222 
   223     for (i = 1; i < argc; i++) {
   224         const char *arg = argv[i];
   225 
   226         if (strcmp(arg, "--dstbpp") == 0)
   227             dstbpp = atoi(argv[++i]);
   228         else if (strcmp(arg, "--dstrmask") == 0)
   229             dstrmask = atoi_hex(argv[++i]);
   230         else if (strcmp(arg, "--dstgmask") == 0)
   231             dstgmask = atoi_hex(argv[++i]);
   232         else if (strcmp(arg, "--dstbmask") == 0)
   233             dstbmask = atoi_hex(argv[++i]);
   234         else if (strcmp(arg, "--dstamask") == 0)
   235             dstamask = atoi_hex(argv[++i]);
   236         else if (strcmp(arg, "--dstwidth") == 0)
   237             dstw = atoi(argv[++i]);
   238         else if (strcmp(arg, "--dstheight") == 0)
   239             dsth = atoi(argv[++i]);
   240         else if (strcmp(arg, "--dsthwsurface") == 0)
   241             dstflags |= SDL_HWSURFACE;
   242         else if (strcmp(arg, "--srcbpp") == 0)
   243             srcbpp = atoi(argv[++i]);
   244         else if (strcmp(arg, "--srcrmask") == 0)
   245             srcrmask = atoi_hex(argv[++i]);
   246         else if (strcmp(arg, "--srcgmask") == 0)
   247             srcgmask = atoi_hex(argv[++i]);
   248         else if (strcmp(arg, "--srcbmask") == 0)
   249             srcbmask = atoi_hex(argv[++i]);
   250         else if (strcmp(arg, "--srcamask") == 0)
   251             srcamask = atoi_hex(argv[++i]);
   252         else if (strcmp(arg, "--srcwidth") == 0)
   253             srcw = atoi(argv[++i]);
   254         else if (strcmp(arg, "--srcheight") == 0)
   255             srch = atoi(argv[++i]);
   256         else if (strcmp(arg, "--srchwsurface") == 0)
   257             srcflags |= SDL_HWSURFACE;
   258         else if (strcmp(arg, "--seconds") == 0)
   259             testSeconds = atoi(argv[++i]);
   260         else if (strcmp(arg, "--screen") == 0)
   261             screenSurface = 1;
   262         else if (strcmp(arg, "--dumpfile") == 0)
   263             dumpfile = argv[++i];
   264         /* !!! FIXME: set colorkey. */
   265         else if (0) {           /* !!! FIXME: we handle some commandlines elsewhere now */
   266             fprintf(stderr, "Unknown commandline option: %s\n", arg);
   267             return (0);
   268         }
   269     }
   270 
   271     if (SDL_Init(SDL_INIT_VIDEO) == -1) {
   272         fprintf(stderr, "SDL_Init failed: %s\n", SDL_GetError());
   273         return (0);
   274     }
   275 
   276     bmp = SDL_LoadBMP("sample.bmp");
   277     if (bmp == NULL) {
   278         fprintf(stderr, "SDL_LoadBMP failed: %s\n", SDL_GetError());
   279         SDL_Quit();
   280         return (0);
   281     }
   282 
   283     if ((dstflags & SDL_HWSURFACE) == 0)
   284         dstflags |= SDL_SWSURFACE;
   285     if ((srcflags & SDL_HWSURFACE) == 0)
   286         srcflags |= SDL_SWSURFACE;
   287 
   288     if (screenSurface)
   289         dest = SDL_SetVideoMode(dstw, dsth, dstbpp, dstflags);
   290     else {
   291         dest = SDL_CreateRGBSurface(dstflags, dstw, dsth, dstbpp,
   292                                     dstrmask, dstgmask, dstbmask, dstamask);
   293     }
   294 
   295     if (dest == NULL) {
   296         fprintf(stderr, "dest surface creation failed: %s\n", SDL_GetError());
   297         SDL_Quit();
   298         return (0);
   299     }
   300 
   301     src = SDL_CreateRGBSurface(srcflags, srcw, srch, srcbpp,
   302                                srcrmask, srcgmask, srcbmask, srcamask);
   303     if (src == NULL) {
   304         fprintf(stderr, "src surface creation failed: %s\n", SDL_GetError());
   305         SDL_Quit();
   306         return (0);
   307     }
   308 
   309     /* handle alpha settings... */
   310     srcalphaflags = (src->flags & SDL_SRCALPHA) | (src->flags & SDL_RLEACCEL);
   311     dstalphaflags =
   312         (dest->flags & SDL_SRCALPHA) | (dest->flags & SDL_RLEACCEL);
   313     origsrcalphaflags = srcalphaflags;
   314     origdstalphaflags = dstalphaflags;
   315     SDL_GetSurfaceAlphaMod(src, &srcalpha);
   316     SDL_GetSurfaceAlphaMod(dest, &dstalpha);
   317     origsrcalpha = srcalpha;
   318     origdstalpha = dstalpha;
   319     for (i = 1; i < argc; i++) {
   320         const char *arg = argv[i];
   321 
   322         if (strcmp(arg, "--srcalpha") == 0)
   323             srcalpha = atoi(argv[++i]);
   324         else if (strcmp(arg, "--dstalpha") == 0)
   325             dstalpha = atoi(argv[++i]);
   326         else if (strcmp(arg, "--srcsrcalpha") == 0)
   327             srcalphaflags |= SDL_SRCALPHA;
   328         else if (strcmp(arg, "--srcnosrcalpha") == 0)
   329             srcalphaflags &= ~SDL_SRCALPHA;
   330         else if (strcmp(arg, "--srcrleaccel") == 0)
   331             srcalphaflags |= SDL_RLEACCEL;
   332         else if (strcmp(arg, "--srcnorleaccel") == 0)
   333             srcalphaflags &= ~SDL_RLEACCEL;
   334         else if (strcmp(arg, "--dstsrcalpha") == 0)
   335             dstalphaflags |= SDL_SRCALPHA;
   336         else if (strcmp(arg, "--dstnosrcalpha") == 0)
   337             dstalphaflags &= ~SDL_SRCALPHA;
   338         else if (strcmp(arg, "--dstrleaccel") == 0)
   339             dstalphaflags |= SDL_RLEACCEL;
   340         else if (strcmp(arg, "--dstnorleaccel") == 0)
   341             dstalphaflags &= ~SDL_RLEACCEL;
   342     }
   343     if ((dstalphaflags != origdstalphaflags) || (origdstalpha != dstalpha))
   344         SDL_SetAlpha(dest, dstalphaflags, dstalpha);
   345     if ((srcalphaflags != origsrcalphaflags) || (origsrcalpha != srcalpha))
   346         SDL_SetAlpha(src, srcalphaflags, srcalpha);
   347 
   348     /* set some sane defaults so we can see if the blit code is broken... */
   349     SDL_FillRect(dest, NULL, SDL_MapRGB(dest->format, 0, 0, 0));
   350     SDL_FillRect(src, NULL, SDL_MapRGB(src->format, 0, 0, 0));
   351 
   352     blitCentered(src, bmp);
   353     SDL_FreeSurface(bmp);
   354 
   355     if (dumpfile)
   356         SDL_SaveBMP(src, dumpfile);     /* make sure initial convert is sane. */
   357 
   358     output_details();
   359 
   360     return (1);
   361 }
   362 
   363 
   364 static void
   365 test_blit_speed(void)
   366 {
   367     Uint32 clearColor = SDL_MapRGB(dest->format, 0, 0, 0);
   368     Uint32 iterations = 0;
   369     Uint32 elasped = 0;
   370     Uint32 end = 0;
   371     Uint32 now = 0;
   372     Uint32 last = 0;
   373     int testms = testSeconds * 1000;
   374     int wmax = (dest->w - src->w);
   375     int hmax = (dest->h - src->h);
   376     int isScreen = (SDL_GetVideoSurface() == dest);
   377     SDL_Event event;
   378 
   379     printf("Testing blit speed for %d seconds...\n", testSeconds);
   380 
   381     now = SDL_GetTicks();
   382     end = now + testms;
   383 
   384     do {
   385         /* pump the event queue occasionally to keep OS happy... */
   386         if (now - last > 1000) {
   387             last = now;
   388             while (SDL_PollEvent(&event)) {     /* no-op. */
   389             }
   390         }
   391 
   392         iterations++;
   393         elasped += blit(dest, src, randRange(0, wmax), randRange(0, hmax));
   394         if (isScreen) {
   395             SDL_Flip(dest);     /* show it! */
   396             SDL_FillRect(dest, NULL, clearColor);       /* blank it for next time! */
   397         }
   398 
   399         now = SDL_GetTicks();
   400     }
   401     while (now < end);
   402 
   403     printf("Non-blitting crap accounted for %d percent of this run.\n",
   404            percent(testms - elasped, testms));
   405 
   406     printf("%d blits took %d ms (%d fps).\n",
   407            (int) iterations,
   408            (int) elasped,
   409            (int) (((float) iterations) / (((float) elasped) / 1000.0f)));
   410 }
   411 
   412 int
   413 main(int argc, char **argv)
   414 {
   415     int initialized = setup_test(argc, argv);
   416     if (initialized) {
   417         test_blit_speed();
   418         SDL_Quit();
   419     }
   420     return (!initialized);
   421 }
   422 
   423 /* end of testblitspeed.c ... */