test/testblitspeed.c
changeset 1039 68f2b997758e
child 1231 cf59e7b91ed4
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/test/testblitspeed.c	Tue Feb 15 11:50:33 2005 +0000
     1.3 @@ -0,0 +1,367 @@
     1.4 +/*
     1.5 + * Benchmarks surface-to-surface blits in various formats.
     1.6 + *
     1.7 + *  Written by Ryan C. Gordon.
     1.8 + */
     1.9 +
    1.10 +#include <stdio.h>
    1.11 +#include <stdlib.h>
    1.12 +#include <string.h>
    1.13 +
    1.14 +#include "SDL.h"
    1.15 +
    1.16 +static SDL_Surface *dest = NULL;
    1.17 +static SDL_Surface *src = NULL;
    1.18 +static int testSeconds = 10;
    1.19 +
    1.20 +
    1.21 +static int percent(int val, int total)
    1.22 +{
    1.23 +    return((int) ((((float) val) / ((float) total)) * 100.0f));
    1.24 +}
    1.25 +
    1.26 +static int randRange(int lo, int hi)
    1.27 +{
    1.28 +    return(lo + (int) (((double) hi)*rand()/(RAND_MAX+1.0)));
    1.29 +}
    1.30 +
    1.31 +static void copy_trunc_str(char *str, size_t strsize, const char *flagstr)
    1.32 +{
    1.33 +    if ( (strlen(str) + strlen(flagstr)) >= (strsize - 1) )
    1.34 +        strcpy(str + (strsize - 5), " ...");
    1.35 +    else
    1.36 +        strcat(str, flagstr);
    1.37 +}
    1.38 +
    1.39 +static void __append_sdl_surface_flag(SDL_Surface *_surface, char *str,
    1.40 +                                      size_t strsize, Uint32 flag,
    1.41 +                                      const char *flagstr)
    1.42 +{
    1.43 +    if (_surface->flags & flag)
    1.44 +        copy_trunc_str(str, strsize, flagstr);
    1.45 +} /* append_sdl_surface_flag */
    1.46 +
    1.47 +
    1.48 +#define append_sdl_surface_flag(a, b, c, fl) __append_sdl_surface_flag(a, b, c, fl, " " #fl)
    1.49 +#define print_tf_state(str, val) printf("%s: {%s}\n", str, (val) ? "true" : "false" )
    1.50 +
    1.51 +static void output_surface_details(const char *name, SDL_Surface *surface)
    1.52 +{
    1.53 +    printf("Details for %s:\n", name);
    1.54 +
    1.55 +    if (surface == NULL)
    1.56 +    {
    1.57 +        printf("-WARNING- You've got a NULL surface!");
    1.58 +    }
    1.59 +    else
    1.60 +    {
    1.61 +        char f[256];
    1.62 +        printf("  width  : %d\n", surface->w);
    1.63 +        printf("  height : %d\n", surface->h);
    1.64 +        printf("  depth  : %d bits per pixel\n", surface->format->BitsPerPixel);
    1.65 +        printf("  pitch  : %d\n", (int) surface->pitch);
    1.66 +
    1.67 +        printf("  red    : 0x%08X mask, %d shift, %d loss\n",
    1.68 +                    (int) surface->format->Rmask,
    1.69 +                    (int) surface->format->Rshift,
    1.70 +                    (int) surface->format->Rloss);
    1.71 +        printf("  green  : 0x%08X mask, %d shift, %d loss\n",
    1.72 +                    (int) surface->format->Gmask,
    1.73 +                    (int) surface->format->Gshift,
    1.74 +                    (int) surface->format->Gloss);
    1.75 +        printf("  blue   : 0x%08X mask, %d shift, %d loss\n",
    1.76 +                    (int) surface->format->Bmask,
    1.77 +                    (int) surface->format->Bshift,
    1.78 +                    (int) surface->format->Bloss);
    1.79 +        printf("  alpha  : 0x%08X mask, %d shift, %d loss\n",
    1.80 +                    (int) surface->format->Amask,
    1.81 +                    (int) surface->format->Ashift,
    1.82 +                    (int) surface->format->Aloss);
    1.83 +
    1.84 +        f[0] = '\0';
    1.85 +
    1.86 +        /*append_sdl_surface_flag(surface, f, sizeof (f), SDL_SWSURFACE);*/
    1.87 +        if ((surface->flags & SDL_HWSURFACE) == 0)
    1.88 +            copy_trunc_str(f, sizeof (f), " SDL_SWSURFACE");
    1.89 +
    1.90 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_HWSURFACE);
    1.91 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_ASYNCBLIT);
    1.92 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_ANYFORMAT);
    1.93 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_HWPALETTE);
    1.94 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_DOUBLEBUF);
    1.95 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_FULLSCREEN);
    1.96 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_OPENGL);
    1.97 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_OPENGLBLIT);
    1.98 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_RESIZABLE);
    1.99 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_NOFRAME);
   1.100 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_HWACCEL);
   1.101 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_SRCCOLORKEY);
   1.102 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_RLEACCELOK);
   1.103 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_RLEACCEL);
   1.104 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_SRCALPHA);
   1.105 +        append_sdl_surface_flag(surface, f, sizeof (f), SDL_PREALLOC);
   1.106 +
   1.107 +        if (f[0] == '\0')
   1.108 +            strcpy(f, " (none)");
   1.109 +
   1.110 +        printf("  flags  :%s\n", f);
   1.111 +
   1.112 +        #if 0
   1.113 +        info = SDL_GetVideoInfo();
   1.114 +        assert(info != NULL);
   1.115 +
   1.116 +        print_tf_state("hardware surface available", info->hw_available);
   1.117 +        print_tf_state("window manager available", info->wm_available);
   1.118 +        print_tf_state("accelerated hardware->hardware blits", info->blit_hw);
   1.119 +        print_tf_state("accelerated hardware->hardware colorkey blits", info->blit_hw_CC);
   1.120 +        print_tf_state("accelerated hardware->hardware alpha blits", info->blit_hw_A);
   1.121 +        print_tf_state("accelerated software->hardware blits", info->blit_sw);
   1.122 +        print_tf_state("accelerated software->hardware colorkey blits", info->blit_sw_CC);
   1.123 +        print_tf_state("accelerated software->hardware alpha blits", info->blit_sw_A);
   1.124 +        print_tf_state("accelerated color fills", info->blit_fill);
   1.125 +
   1.126 +        printf("video memory: (%d)\n", info->video_mem);
   1.127 +        #endif
   1.128 +    } /* else */
   1.129 +
   1.130 +    printf("\n");
   1.131 +}
   1.132 +
   1.133 +static void output_details(void)
   1.134 +{
   1.135 +    output_surface_details("Source Surface", src);
   1.136 +    output_surface_details("Destination Surface", dest);
   1.137 +}
   1.138 +
   1.139 +static Uint32 blit(SDL_Surface *dst, SDL_Surface *src, int x, int y)
   1.140 +{
   1.141 +    Uint32 start = 0;
   1.142 +    SDL_Rect srcRect;
   1.143 +    SDL_Rect dstRect;
   1.144 +
   1.145 +    srcRect.x = 0;
   1.146 +    srcRect.y = 0;
   1.147 +    dstRect.x = x;
   1.148 +    dstRect.y = y;
   1.149 +    dstRect.w = srcRect.w = src->w;  /* SDL will clip as appropriate. */
   1.150 +    dstRect.h = srcRect.h = src->h;
   1.151 +
   1.152 +    start = SDL_GetTicks();
   1.153 +    SDL_BlitSurface(src, &srcRect, dst, &dstRect);
   1.154 +    return(SDL_GetTicks() - start);
   1.155 +}
   1.156 +
   1.157 +static void blitCentered(SDL_Surface *dst, SDL_Surface *src)
   1.158 +{
   1.159 +    int x = (dst->w - src->w) / 2;
   1.160 +    int y = (dst->h - src->h) / 2;
   1.161 +    blit(dst, src, x, y);
   1.162 +}
   1.163 +
   1.164 +static int atoi_hex(const char *str)
   1.165 +{
   1.166 +    if (str == NULL)
   1.167 +        return 0;
   1.168 +
   1.169 +    if (strlen(str) > 2)
   1.170 +    {
   1.171 +        int retval = 0;
   1.172 +        if ((str[0] == '0') && (str[1] == 'x'))
   1.173 +            sscanf(str + 2, "%X", &retval);
   1.174 +        return(retval);
   1.175 +    }
   1.176 +
   1.177 +    return(atoi(str));
   1.178 +}
   1.179 +
   1.180 +
   1.181 +static int setup_test(int argc, char **argv)
   1.182 +{
   1.183 +    const char *dumpfile = NULL;
   1.184 +    SDL_Surface *bmp = NULL;
   1.185 +    Uint32 dstbpp = 32;
   1.186 +    Uint32 dstrmask = 0x00FF0000;
   1.187 +    Uint32 dstgmask = 0x0000FF00;
   1.188 +    Uint32 dstbmask = 0x000000FF;
   1.189 +    Uint32 dstamask = 0x00000000;
   1.190 +    Uint32 dstflags = 0;
   1.191 +    int dstw = 640;
   1.192 +    int dsth = 480;
   1.193 +    Uint32 srcbpp = 32;
   1.194 +    Uint32 srcrmask = 0x00FF0000;
   1.195 +    Uint32 srcgmask = 0x0000FF00;
   1.196 +    Uint32 srcbmask = 0x000000FF;
   1.197 +    Uint32 srcamask = 0x00000000;
   1.198 +    Uint32 srcflags = 0;
   1.199 +    int srcw = 640;
   1.200 +    int srch = 480;
   1.201 +    int screenSurface = 0;
   1.202 +    int i;
   1.203 +
   1.204 +    for (i = 1; i < argc; i++)
   1.205 +    {
   1.206 +        const char *arg = argv[i];
   1.207 +
   1.208 +        if (strcmp(arg, "--dstbpp") == 0)
   1.209 +            dstbpp = atoi(argv[++i]);
   1.210 +        else if (strcmp(arg, "--dstrmask") == 0)
   1.211 +            dstrmask = atoi_hex(argv[++i]);
   1.212 +        else if (strcmp(arg, "--dstgmask") == 0)
   1.213 +            dstgmask = atoi_hex(argv[++i]);
   1.214 +        else if (strcmp(arg, "--dstbmask") == 0)
   1.215 +            dstbmask = atoi_hex(argv[++i]);
   1.216 +        else if (strcmp(arg, "--dstamask") == 0)
   1.217 +            dstamask = atoi_hex(argv[++i]);
   1.218 +        else if (strcmp(arg, "--dstwidth") == 0)
   1.219 +            dstw = atoi(argv[++i]);
   1.220 +        else if (strcmp(arg, "--dstheight") == 0)
   1.221 +            dsth = atoi(argv[++i]);
   1.222 +        else if (strcmp(arg, "--dsthwsurface") == 0)
   1.223 +            dstflags |= SDL_HWSURFACE;
   1.224 +        else if (strcmp(arg, "--srcbpp") == 0)
   1.225 +            srcbpp = atoi(argv[++i]);
   1.226 +        else if (strcmp(arg, "--srcrmask") == 0)
   1.227 +            srcrmask = atoi_hex(argv[++i]);
   1.228 +        else if (strcmp(arg, "--srcgmask") == 0)
   1.229 +            srcgmask = atoi_hex(argv[++i]);
   1.230 +        else if (strcmp(arg, "--srcbmask") == 0)
   1.231 +            srcbmask = atoi_hex(argv[++i]);
   1.232 +        else if (strcmp(arg, "--srcamask") == 0)
   1.233 +            srcamask = atoi_hex(argv[++i]);
   1.234 +        else if (strcmp(arg, "--srcwidth") == 0)
   1.235 +            srcw = atoi(argv[++i]);
   1.236 +        else if (strcmp(arg, "--srcheight") == 0)
   1.237 +            srch = atoi(argv[++i]);
   1.238 +        else if (strcmp(arg, "--srchwsurface") == 0)
   1.239 +            srcflags |= SDL_HWSURFACE;
   1.240 +        else if (strcmp(arg, "--seconds") == 0)
   1.241 +            testSeconds = atoi(argv[++i]);
   1.242 +        else if (strcmp(arg, "--screen") == 0)
   1.243 +            screenSurface = 1;
   1.244 +        else if (strcmp(arg, "--dumpfile") == 0)
   1.245 +            dumpfile = argv[++i];
   1.246 +        else
   1.247 +        {
   1.248 +            fprintf(stderr, "Unknown commandline option: %s\n", arg);
   1.249 +            return(0);
   1.250 +        }
   1.251 +    }
   1.252 +
   1.253 +    if (SDL_Init(SDL_INIT_VIDEO) == -1)
   1.254 +    {
   1.255 +        fprintf(stderr, "SDL_Init failed: %s\n", SDL_GetError());
   1.256 +        return(0);
   1.257 +    }
   1.258 +
   1.259 +    bmp = SDL_LoadBMP("sample.bmp");
   1.260 +    if (bmp == NULL)
   1.261 +    {
   1.262 +        fprintf(stderr, "SDL_LoadBMP failed: %s\n", SDL_GetError());
   1.263 +        SDL_Quit();
   1.264 +        return(0);
   1.265 +    }
   1.266 +
   1.267 +    if ((dstflags & SDL_HWSURFACE) == 0) dstflags |= SDL_SWSURFACE;
   1.268 +    if ((srcflags & SDL_HWSURFACE) == 0) srcflags |= SDL_SWSURFACE;
   1.269 +
   1.270 +    if (screenSurface)
   1.271 +        dest = SDL_SetVideoMode(dstw, dsth, dstbpp, dstflags);
   1.272 +    else
   1.273 +    {
   1.274 +        dest = SDL_CreateRGBSurface(dstflags, dstw, dsth, dstbpp,
   1.275 +                                    dstrmask, dstgmask, dstbmask, dstamask);
   1.276 +    }
   1.277 +
   1.278 +    if (dest == NULL)
   1.279 +    {
   1.280 +        fprintf(stderr, "dest surface creation failed: %s\n", SDL_GetError());
   1.281 +        SDL_Quit();
   1.282 +        return(0);
   1.283 +    }
   1.284 +
   1.285 +    src = SDL_CreateRGBSurface(srcflags, srcw, srch, srcbpp,
   1.286 +                               srcrmask, srcgmask, srcbmask, srcamask);
   1.287 +    if (src == NULL)
   1.288 +    {
   1.289 +        fprintf(stderr, "src surface creation failed: %s\n", SDL_GetError());
   1.290 +        SDL_Quit();
   1.291 +        return(0);
   1.292 +    }
   1.293 +
   1.294 +    /* set some sane defaults so we can see if the blit code is broken... */
   1.295 +    SDL_FillRect(dest, NULL, SDL_MapRGB(dest->format, 0, 0, 0));
   1.296 +    SDL_FillRect(src, NULL, SDL_MapRGB(src->format, 0, 0, 0));
   1.297 +
   1.298 +    blitCentered(src, bmp);
   1.299 +    SDL_FreeSurface(bmp);
   1.300 +
   1.301 +    if (dumpfile)
   1.302 +        SDL_SaveBMP(src, dumpfile);  /* make sure initial convert is sane. */
   1.303 +
   1.304 +    output_details();
   1.305 +
   1.306 +    return(1);
   1.307 +}
   1.308 +
   1.309 +
   1.310 +static void test_blit_speed(void)
   1.311 +{
   1.312 +    Uint32 clearColor = SDL_MapRGB(dest->format, 0, 0, 0);
   1.313 +    Uint32 iterations = 0;
   1.314 +    Uint32 elasped = 0;
   1.315 +    Uint32 end = 0;
   1.316 +    Uint32 now = 0;
   1.317 +    Uint32 last = 0;
   1.318 +    int testms = testSeconds * 1000;
   1.319 +    int wmax = (dest->w - src->w);
   1.320 +    int hmax = (dest->h - src->h);
   1.321 +    int isScreen = (SDL_GetVideoSurface() == dest);
   1.322 +    SDL_Event event;
   1.323 +
   1.324 +    printf("Testing blit speed for %d seconds...\n", testSeconds);
   1.325 +
   1.326 +    now = SDL_GetTicks();
   1.327 +    end = now + testms;
   1.328 +
   1.329 +    do
   1.330 +    {
   1.331 +        /* pump the event queue occasionally to keep OS happy... */
   1.332 +        if (now - last > 1000)
   1.333 +        {
   1.334 +            last = now;
   1.335 +            while (SDL_PollEvent(&event)) { /* no-op. */ }
   1.336 +        }
   1.337 +
   1.338 +        iterations++;
   1.339 +        elasped += blit(dest, src, randRange(0, wmax), randRange(0, hmax));
   1.340 +        if (isScreen)
   1.341 +        {
   1.342 +            SDL_Flip(dest);  /* show it! */
   1.343 +            SDL_FillRect(dest, NULL, clearColor); /* blank it for next time! */
   1.344 +        }
   1.345 +
   1.346 +        now = SDL_GetTicks();
   1.347 +    } while (now < end);
   1.348 +
   1.349 +    printf("Non-blitting crap accounted for %d percent of this run.\n",
   1.350 +            percent(testms - elasped, testms));
   1.351 +
   1.352 +    printf("%d blits took %d ms (%d fps).\n",
   1.353 +            (int) iterations,
   1.354 +            (int) elasped,
   1.355 +            (int) (((float)iterations) / (((float)elasped) / 1000.0f)));
   1.356 +}
   1.357 +
   1.358 +int main(int argc, char **argv)
   1.359 +{
   1.360 +    int initialized = setup_test(argc, argv);
   1.361 +    if (initialized)
   1.362 +    {
   1.363 +        test_blit_speed();
   1.364 +        SDL_Quit();
   1.365 +    }
   1.366 +    return(!initialized);
   1.367 +}
   1.368 +
   1.369 +/* end of testblitspeed.c ... */
   1.370 +