comparison test/testblitspeed.c @ 1039:68f2b997758e

Added testblitspeed to aid in profiling of SDL's blitters.
author Ryan C. Gordon <icculus@icculus.org>
date Tue, 15 Feb 2005 11:50:33 +0000
parents
children cf59e7b91ed4
comparison
equal deleted inserted replaced
1038:29d7db09776e 1039:68f2b997758e
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