Mercurial > sdl-ios-xcode
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 |