Added testblitspeed to aid in profiling of SDL's blitters.
authorRyan C. Gordon <icculus@icculus.org>
Tue, 15 Feb 2005 11:50:33 +0000
changeset 103968f2b997758e
parent 1038 29d7db09776e
child 1040 c6ed27c7d47d
Added testblitspeed to aid in profiling of SDL's blitters.
test/Makefile.am
test/README
test/testblitspeed.c
     1.1 --- a/test/Makefile.am	Sun Feb 13 07:10:02 2005 +0000
     1.2 +++ b/test/Makefile.am	Tue Feb 15 11:50:33 2005 +0000
     1.3 @@ -5,7 +5,8 @@
     1.4  	testhread testlock testerror testsem testtimer \
     1.5  	loopwave testcdrom testkeys testvidinfo checkkeys testwin graywin \
     1.6  	testsprite testbitmap testalpha testgamma testpalette testwm \
     1.7 -	threadwin testoverlay testoverlay2 testgl testdyngl testjoystick
     1.8 +	threadwin testoverlay testoverlay2 testgl testdyngl testjoystick \
     1.9 +	testblitspeed
    1.10  
    1.11  testalpha_SOURCES = testalpha.c
    1.12  testalpha_LDADD = @MATHLIB@
     2.1 --- a/test/README	Sun Feb 13 07:10:02 2005 +0000
     2.2 +++ b/test/README	Tue Feb 15 11:50:33 2005 +0000
     2.3 @@ -24,3 +24,5 @@
     2.4  	testjoystick	List joysticks and watch joystick events
     2.5  	testoverlay	Tests the software/hardware overlay functionality.
     2.6  	testoverlay2	Tests the overlay flickering/scaling during playback.
     2.7 +	testblitspeed	Tests performance of SDL's blitters and converters.
     2.8 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/test/testblitspeed.c	Tue Feb 15 11:50:33 2005 +0000
     3.3 @@ -0,0 +1,367 @@
     3.4 +/*
     3.5 + * Benchmarks surface-to-surface blits in various formats.
     3.6 + *
     3.7 + *  Written by Ryan C. Gordon.
     3.8 + */
     3.9 +
    3.10 +#include <stdio.h>
    3.11 +#include <stdlib.h>
    3.12 +#include <string.h>
    3.13 +
    3.14 +#include "SDL.h"
    3.15 +
    3.16 +static SDL_Surface *dest = NULL;
    3.17 +static SDL_Surface *src = NULL;
    3.18 +static int testSeconds = 10;
    3.19 +
    3.20 +
    3.21 +static int percent(int val, int total)
    3.22 +{
    3.23 +    return((int) ((((float) val) / ((float) total)) * 100.0f));
    3.24 +}
    3.25 +
    3.26 +static int randRange(int lo, int hi)
    3.27 +{
    3.28 +    return(lo + (int) (((double) hi)*rand()/(RAND_MAX+1.0)));
    3.29 +}
    3.30 +
    3.31 +static void copy_trunc_str(char *str, size_t strsize, const char *flagstr)
    3.32 +{
    3.33 +    if ( (strlen(str) + strlen(flagstr)) >= (strsize - 1) )
    3.34 +        strcpy(str + (strsize - 5), " ...");
    3.35 +    else
    3.36 +        strcat(str, flagstr);
    3.37 +}
    3.38 +
    3.39 +static void __append_sdl_surface_flag(SDL_Surface *_surface, char *str,
    3.40 +                                      size_t strsize, Uint32 flag,
    3.41 +                                      const char *flagstr)
    3.42 +{
    3.43 +    if (_surface->flags & flag)
    3.44 +        copy_trunc_str(str, strsize, flagstr);
    3.45 +} /* append_sdl_surface_flag */
    3.46 +
    3.47 +
    3.48 +#define append_sdl_surface_flag(a, b, c, fl) __append_sdl_surface_flag(a, b, c, fl, " " #fl)
    3.49 +#define print_tf_state(str, val) printf("%s: {%s}\n", str, (val) ? "true" : "false" )
    3.50 +
    3.51 +static void output_surface_details(const char *name, SDL_Surface *surface)
    3.52 +{
    3.53 +    printf("Details for %s:\n", name);
    3.54 +
    3.55 +    if (surface == NULL)
    3.56 +    {
    3.57 +        printf("-WARNING- You've got a NULL surface!");
    3.58 +    }
    3.59 +    else
    3.60 +    {
    3.61 +        char f[256];
    3.62 +        printf("  width  : %d\n", surface->w);
    3.63 +        printf("  height : %d\n", surface->h);
    3.64 +        printf("  depth  : %d bits per pixel\n", surface->format->BitsPerPixel);
    3.65 +        printf("  pitch  : %d\n", (int) surface->pitch);
    3.66 +
    3.67 +        printf("  red    : 0x%08X mask, %d shift, %d loss\n",
    3.68 +                    (int) surface->format->Rmask,
    3.69 +                    (int) surface->format->Rshift,
    3.70 +                    (int) surface->format->Rloss);
    3.71 +        printf("  green  : 0x%08X mask, %d shift, %d loss\n",
    3.72 +                    (int) surface->format->Gmask,
    3.73 +                    (int) surface->format->Gshift,
    3.74 +                    (int) surface->format->Gloss);
    3.75 +        printf("  blue   : 0x%08X mask, %d shift, %d loss\n",
    3.76 +                    (int) surface->format->Bmask,
    3.77 +                    (int) surface->format->Bshift,
    3.78 +                    (int) surface->format->Bloss);
    3.79 +        printf("  alpha  : 0x%08X mask, %d shift, %d loss\n",
    3.80 +                    (int) surface->format->Amask,
    3.81 +                    (int) surface->format->Ashift,
    3.82 +                    (int) surface->format->Aloss);
    3.83 +
    3.84 +        f[0] = '\0';
    3.85 +
    3.86 +        /*append_sdl_surface_flag(surface, f, sizeof (f), SDL_SWSURFACE);*/
    3.87 +        if ((surface->flags & SDL_HWSURFACE) == 0)
    3.88 +            copy_trunc_str(f, sizeof (f), " SDL_SWSURFACE");
    3.89 +
    3.90 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_HWSURFACE);
    3.91 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_ASYNCBLIT);
    3.92 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_ANYFORMAT);
    3.93 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_HWPALETTE);
    3.94 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_DOUBLEBUF);
    3.95 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_FULLSCREEN);
    3.96 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_OPENGL);
    3.97 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_OPENGLBLIT);
    3.98 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_RESIZABLE);
    3.99 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_NOFRAME);
   3.100 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_HWACCEL);
   3.101 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_SRCCOLORKEY);
   3.102 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_RLEACCELOK);
   3.103 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_RLEACCEL);
   3.104 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_SRCALPHA);
   3.105 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_PREALLOC);
   3.106 +
   3.107 +        if (f[0] == '\0')
   3.108 +            strcpy(f, " (none)");
   3.109 +
   3.110 +        printf("  flags  :%s\n", f);
   3.111 +
   3.112 +        #if 0
   3.113 +        info = SDL_GetVideoInfo();
   3.114 +        assert(info != NULL);
   3.115 +
   3.116 +        print_tf_state("hardware surface available", info->hw_available);
   3.117 +        print_tf_state("window manager available", info->wm_available);
   3.118 +        print_tf_state("accelerated hardware->hardware blits", info->blit_hw);
   3.119 +        print_tf_state("accelerated hardware->hardware colorkey blits", info->blit_hw_CC);
   3.120 +        print_tf_state("accelerated hardware->hardware alpha blits", info->blit_hw_A);
   3.121 +        print_tf_state("accelerated software->hardware blits", info->blit_sw);
   3.122 +        print_tf_state("accelerated software->hardware colorkey blits", info->blit_sw_CC);
   3.123 +        print_tf_state("accelerated software->hardware alpha blits", info->blit_sw_A);
   3.124 +        print_tf_state("accelerated color fills", info->blit_fill);
   3.125 +
   3.126 +        printf("video memory: (%d)\n", info->video_mem);
   3.127 +        #endif
   3.128 +    } /* else */
   3.129 +
   3.130 +    printf("\n");
   3.131 +}
   3.132 +
   3.133 +static void output_details(void)
   3.134 +{
   3.135 +    output_surface_details("Source Surface", src);
   3.136 +    output_surface_details("Destination Surface", dest);
   3.137 +}
   3.138 +
   3.139 +static Uint32 blit(SDL_Surface *dst, SDL_Surface *src, int x, int y)
   3.140 +{
   3.141 +    Uint32 start = 0;
   3.142 +    SDL_Rect srcRect;
   3.143 +    SDL_Rect dstRect;
   3.144 +
   3.145 +    srcRect.x = 0;
   3.146 +    srcRect.y = 0;
   3.147 +    dstRect.x = x;
   3.148 +    dstRect.y = y;
   3.149 +    dstRect.w = srcRect.w = src->w;  /* SDL will clip as appropriate. */
   3.150 +    dstRect.h = srcRect.h = src->h;
   3.151 +
   3.152 +    start = SDL_GetTicks();
   3.153 +    SDL_BlitSurface(src, &srcRect, dst, &dstRect);
   3.154 +    return(SDL_GetTicks() - start);
   3.155 +}
   3.156 +
   3.157 +static void blitCentered(SDL_Surface *dst, SDL_Surface *src)
   3.158 +{
   3.159 +    int x = (dst->w - src->w) / 2;
   3.160 +    int y = (dst->h - src->h) / 2;
   3.161 +    blit(dst, src, x, y);
   3.162 +}
   3.163 +
   3.164 +static int atoi_hex(const char *str)
   3.165 +{
   3.166 +    if (str == NULL)
   3.167 +        return 0;
   3.168 +
   3.169 +    if (strlen(str) > 2)
   3.170 +    {
   3.171 +        int retval = 0;
   3.172 +        if ((str[0] == '0') && (str[1] == 'x'))
   3.173 +            sscanf(str + 2, "%X", &retval);
   3.174 +        return(retval);
   3.175 +    }
   3.176 +
   3.177 +    return(atoi(str));
   3.178 +}
   3.179 +
   3.180 +
   3.181 +static int setup_test(int argc, char **argv)
   3.182 +{
   3.183 +    const char *dumpfile = NULL;
   3.184 +    SDL_Surface *bmp = NULL;
   3.185 +    Uint32 dstbpp = 32;
   3.186 +    Uint32 dstrmask = 0x00FF0000;
   3.187 +    Uint32 dstgmask = 0x0000FF00;
   3.188 +    Uint32 dstbmask = 0x000000FF;
   3.189 +    Uint32 dstamask = 0x00000000;
   3.190 +    Uint32 dstflags = 0;
   3.191 +    int dstw = 640;
   3.192 +    int dsth = 480;
   3.193 +    Uint32 srcbpp = 32;
   3.194 +    Uint32 srcrmask = 0x00FF0000;
   3.195 +    Uint32 srcgmask = 0x0000FF00;
   3.196 +    Uint32 srcbmask = 0x000000FF;
   3.197 +    Uint32 srcamask = 0x00000000;
   3.198 +    Uint32 srcflags = 0;
   3.199 +    int srcw = 640;
   3.200 +    int srch = 480;
   3.201 +    int screenSurface = 0;
   3.202 +    int i;
   3.203 +
   3.204 +    for (i = 1; i < argc; i++)
   3.205 +    {
   3.206 +        const char *arg = argv[i];
   3.207 +
   3.208 +        if (strcmp(arg, "--dstbpp") == 0)
   3.209 +            dstbpp = atoi(argv[++i]);
   3.210 +        else if (strcmp(arg, "--dstrmask") == 0)
   3.211 +            dstrmask = atoi_hex(argv[++i]);
   3.212 +        else if (strcmp(arg, "--dstgmask") == 0)
   3.213 +            dstgmask = atoi_hex(argv[++i]);
   3.214 +        else if (strcmp(arg, "--dstbmask") == 0)
   3.215 +            dstbmask = atoi_hex(argv[++i]);
   3.216 +        else if (strcmp(arg, "--dstamask") == 0)
   3.217 +            dstamask = atoi_hex(argv[++i]);
   3.218 +        else if (strcmp(arg, "--dstwidth") == 0)
   3.219 +            dstw = atoi(argv[++i]);
   3.220 +        else if (strcmp(arg, "--dstheight") == 0)
   3.221 +            dsth = atoi(argv[++i]);
   3.222 +        else if (strcmp(arg, "--dsthwsurface") == 0)
   3.223 +            dstflags |= SDL_HWSURFACE;
   3.224 +        else if (strcmp(arg, "--srcbpp") == 0)
   3.225 +            srcbpp = atoi(argv[++i]);
   3.226 +        else if (strcmp(arg, "--srcrmask") == 0)
   3.227 +            srcrmask = atoi_hex(argv[++i]);
   3.228 +        else if (strcmp(arg, "--srcgmask") == 0)
   3.229 +            srcgmask = atoi_hex(argv[++i]);
   3.230 +        else if (strcmp(arg, "--srcbmask") == 0)
   3.231 +            srcbmask = atoi_hex(argv[++i]);
   3.232 +        else if (strcmp(arg, "--srcamask") == 0)
   3.233 +            srcamask = atoi_hex(argv[++i]);
   3.234 +        else if (strcmp(arg, "--srcwidth") == 0)
   3.235 +            srcw = atoi(argv[++i]);
   3.236 +        else if (strcmp(arg, "--srcheight") == 0)
   3.237 +            srch = atoi(argv[++i]);
   3.238 +        else if (strcmp(arg, "--srchwsurface") == 0)
   3.239 +            srcflags |= SDL_HWSURFACE;
   3.240 +        else if (strcmp(arg, "--seconds") == 0)
   3.241 +            testSeconds = atoi(argv[++i]);
   3.242 +        else if (strcmp(arg, "--screen") == 0)
   3.243 +            screenSurface = 1;
   3.244 +        else if (strcmp(arg, "--dumpfile") == 0)
   3.245 +            dumpfile = argv[++i];
   3.246 +        else
   3.247 +        {
   3.248 +            fprintf(stderr, "Unknown commandline option: %s\n", arg);
   3.249 +            return(0);
   3.250 +        }
   3.251 +    }
   3.252 +
   3.253 +    if (SDL_Init(SDL_INIT_VIDEO) == -1)
   3.254 +    {
   3.255 +        fprintf(stderr, "SDL_Init failed: %s\n", SDL_GetError());
   3.256 +        return(0);
   3.257 +    }
   3.258 +
   3.259 +    bmp = SDL_LoadBMP("sample.bmp");
   3.260 +    if (bmp == NULL)
   3.261 +    {
   3.262 +        fprintf(stderr, "SDL_LoadBMP failed: %s\n", SDL_GetError());
   3.263 +        SDL_Quit();
   3.264 +        return(0);
   3.265 +    }
   3.266 +
   3.267 +    if ((dstflags & SDL_HWSURFACE) == 0) dstflags |= SDL_SWSURFACE;
   3.268 +    if ((srcflags & SDL_HWSURFACE) == 0) srcflags |= SDL_SWSURFACE;
   3.269 +
   3.270 +    if (screenSurface)
   3.271 +        dest = SDL_SetVideoMode(dstw, dsth, dstbpp, dstflags);
   3.272 +    else
   3.273 +    {
   3.274 +        dest = SDL_CreateRGBSurface(dstflags, dstw, dsth, dstbpp,
   3.275 +                                    dstrmask, dstgmask, dstbmask, dstamask);
   3.276 +    }
   3.277 +
   3.278 +    if (dest == NULL)
   3.279 +    {
   3.280 +        fprintf(stderr, "dest surface creation failed: %s\n", SDL_GetError());
   3.281 +        SDL_Quit();
   3.282 +        return(0);
   3.283 +    }
   3.284 +
   3.285 +    src = SDL_CreateRGBSurface(srcflags, srcw, srch, srcbpp,
   3.286 +                               srcrmask, srcgmask, srcbmask, srcamask);
   3.287 +    if (src == NULL)
   3.288 +    {
   3.289 +        fprintf(stderr, "src surface creation failed: %s\n", SDL_GetError());
   3.290 +        SDL_Quit();
   3.291 +        return(0);
   3.292 +    }
   3.293 +
   3.294 +    /* set some sane defaults so we can see if the blit code is broken... */
   3.295 +    SDL_FillRect(dest, NULL, SDL_MapRGB(dest->format, 0, 0, 0));
   3.296 +    SDL_FillRect(src, NULL, SDL_MapRGB(src->format, 0, 0, 0));
   3.297 +
   3.298 +    blitCentered(src, bmp);
   3.299 +    SDL_FreeSurface(bmp);
   3.300 +
   3.301 +    if (dumpfile)
   3.302 +        SDL_SaveBMP(src, dumpfile);  /* make sure initial convert is sane. */
   3.303 +
   3.304 +    output_details();
   3.305 +
   3.306 +    return(1);
   3.307 +}
   3.308 +
   3.309 +
   3.310 +static void test_blit_speed(void)
   3.311 +{
   3.312 +    Uint32 clearColor = SDL_MapRGB(dest->format, 0, 0, 0);
   3.313 +    Uint32 iterations = 0;
   3.314 +    Uint32 elasped = 0;
   3.315 +    Uint32 end = 0;
   3.316 +    Uint32 now = 0;
   3.317 +    Uint32 last = 0;
   3.318 +    int testms = testSeconds * 1000;
   3.319 +    int wmax = (dest->w - src->w);
   3.320 +    int hmax = (dest->h - src->h);
   3.321 +    int isScreen = (SDL_GetVideoSurface() == dest);
   3.322 +    SDL_Event event;
   3.323 +
   3.324 +    printf("Testing blit speed for %d seconds...\n", testSeconds);
   3.325 +
   3.326 +    now = SDL_GetTicks();
   3.327 +    end = now + testms;
   3.328 +
   3.329 +    do
   3.330 +    {
   3.331 +        /* pump the event queue occasionally to keep OS happy... */
   3.332 +        if (now - last > 1000)
   3.333 +        {
   3.334 +            last = now;
   3.335 +            while (SDL_PollEvent(&event)) { /* no-op. */ }
   3.336 +        }
   3.337 +
   3.338 +        iterations++;
   3.339 +        elasped += blit(dest, src, randRange(0, wmax), randRange(0, hmax));
   3.340 +        if (isScreen)
   3.341 +        {
   3.342 +            SDL_Flip(dest);  /* show it! */
   3.343 +            SDL_FillRect(dest, NULL, clearColor); /* blank it for next time! */
   3.344 +        }
   3.345 +
   3.346 +        now = SDL_GetTicks();
   3.347 +    } while (now < end);
   3.348 +
   3.349 +    printf("Non-blitting crap accounted for %d percent of this run.\n",
   3.350 +            percent(testms - elasped, testms));
   3.351 +
   3.352 +    printf("%d blits took %d ms (%d fps).\n",
   3.353 +            (int) iterations,
   3.354 +            (int) elasped,
   3.355 +            (int) (((float)iterations) / (((float)elasped) / 1000.0f)));
   3.356 +}
   3.357 +
   3.358 +int main(int argc, char **argv)
   3.359 +{
   3.360 +    int initialized = setup_test(argc, argv);
   3.361 +    if (initialized)
   3.362 +    {
   3.363 +        test_blit_speed();
   3.364 +        SDL_Quit();
   3.365 +    }
   3.366 +    return(!initialized);
   3.367 +}
   3.368 +
   3.369 +/* end of testblitspeed.c ... */
   3.370 +