This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
testblitspeed.c
433 lines (374 loc) · 13.8 KB
1
2
3
4
5
6
7
8
9
10
11
/*
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely.
*/
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*
* Benchmarks surface-to-surface blits in various formats.
*
* Written by Ryan C. Gordon.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SDL.h"
static SDL_Surface *dest = NULL;
static SDL_Surface *src = NULL;
static int testSeconds = 10;
29
30
static int
percent(int val, int total)
31
{
32
return ((int) ((((float) val) / ((float) total)) * 100.0f));
33
34
}
35
36
static int
randRange(int lo, int hi)
37
{
38
return (lo + (int) (((double) hi) * rand() / (RAND_MAX + 1.0)));
39
40
}
41
42
static void
copy_trunc_str(char *str, size_t strsize, const char *flagstr)
43
{
44
if ((strlen(str) + strlen(flagstr)) >= (strsize - 1))
45
46
47
48
49
strcpy(str + (strsize - 5), " ...");
else
strcat(str, flagstr);
}
50
51
52
static void
__append_sdl_surface_flag(SDL_Surface * _surface, char *str,
size_t strsize, Uint32 flag, const char *flagstr)
53
54
55
{
if (_surface->flags & flag)
copy_trunc_str(str, strsize, flagstr);
56
}
57
58
59
60
61
#define append_sdl_surface_flag(a, b, c, fl) __append_sdl_surface_flag(a, b, c, fl, " " #fl)
#define print_tf_state(str, val) printf("%s: {%s}\n", str, (val) ? "true" : "false" )
62
63
static void
output_videoinfo_details(void)
64
65
66
67
68
{
const SDL_VideoInfo *info = SDL_GetVideoInfo();
printf("SDL_GetVideoInfo():\n");
if (info == NULL)
printf(" (null.)\n");
69
else {
70
71
print_tf_state(" hardware surface available", info->hw_available);
print_tf_state(" window manager available", info->wm_available);
72
73
74
75
76
77
78
79
80
81
82
83
print_tf_state(" accelerated hardware->hardware blits",
info->blit_hw);
print_tf_state(" accelerated hardware->hardware colorkey blits",
info->blit_hw_CC);
print_tf_state(" accelerated hardware->hardware alpha blits",
info->blit_hw_A);
print_tf_state(" accelerated software->hardware blits",
info->blit_sw);
print_tf_state(" accelerated software->hardware colorkey blits",
info->blit_sw_CC);
print_tf_state(" accelerated software->hardware alpha blits",
info->blit_sw_A);
84
85
86
87
88
89
90
print_tf_state(" accelerated color fills", info->blit_fill);
printf(" video memory: (%d)\n", info->video_mem);
}
printf("\n");
}
91
92
static void
output_surface_details(const char *name, SDL_Surface * surface)
93
94
95
{
printf("Details for %s:\n", name);
96
if (surface == NULL) {
97
printf("-WARNING- You've got a NULL surface!");
98
} else {
99
char f[256];
100
101
printf(" width : %d\n", surface->w);
printf(" height : %d\n", surface->h);
102
103
printf(" depth : %d bits per pixel\n",
surface->format->BitsPerPixel);
104
105
106
printf(" pitch : %d\n", (int) surface->pitch);
printf(" red bits : 0x%08X mask, %d shift, %d loss\n",
107
108
(int) surface->format->Rmask,
(int) surface->format->Rshift, (int) surface->format->Rloss);
109
printf(" green bits : 0x%08X mask, %d shift, %d loss\n",
110
111
(int) surface->format->Gmask,
(int) surface->format->Gshift, (int) surface->format->Gloss);
112
printf(" blue bits : 0x%08X mask, %d shift, %d loss\n",
113
114
(int) surface->format->Bmask,
(int) surface->format->Bshift, (int) surface->format->Bloss);
115
printf(" alpha bits : 0x%08X mask, %d shift, %d loss\n",
116
117
(int) surface->format->Amask,
(int) surface->format->Ashift, (int) surface->format->Aloss);
118
119
120
f[0] = '\0';
121
/*append_sdl_surface_flag(surface, f, sizeof (f), SDL_SWSURFACE); */
122
if ((surface->flags & SDL_HWSURFACE) == 0)
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
copy_trunc_str(f, sizeof(f), " SDL_SWSURFACE");
append_sdl_surface_flag(surface, f, sizeof(f), SDL_HWSURFACE);
append_sdl_surface_flag(surface, f, sizeof(f), SDL_ASYNCBLIT);
append_sdl_surface_flag(surface, f, sizeof(f), SDL_ANYFORMAT);
append_sdl_surface_flag(surface, f, sizeof(f), SDL_HWPALETTE);
append_sdl_surface_flag(surface, f, sizeof(f), SDL_DOUBLEBUF);
append_sdl_surface_flag(surface, f, sizeof(f), SDL_FULLSCREEN);
append_sdl_surface_flag(surface, f, sizeof(f), SDL_OPENGL);
append_sdl_surface_flag(surface, f, sizeof(f), SDL_RESIZABLE);
append_sdl_surface_flag(surface, f, sizeof(f), SDL_NOFRAME);
append_sdl_surface_flag(surface, f, sizeof(f), SDL_HWACCEL);
append_sdl_surface_flag(surface, f, sizeof(f), SDL_SRCCOLORKEY);
append_sdl_surface_flag(surface, f, sizeof(f), SDL_RLEACCELOK);
append_sdl_surface_flag(surface, f, sizeof(f), SDL_RLEACCEL);
append_sdl_surface_flag(surface, f, sizeof(f), SDL_SRCALPHA);
append_sdl_surface_flag(surface, f, sizeof(f), SDL_PREALLOC);
140
141
142
143
if (f[0] == '\0')
strcpy(f, " (none)");
144
145
printf(" flags :%s\n", f);
}
146
147
148
149
printf("\n");
}
150
151
static void
output_details(void)
152
{
153
output_videoinfo_details();
154
155
156
157
output_surface_details("Source Surface", src);
output_surface_details("Destination Surface", dest);
}
158
159
static Uint32
blit(SDL_Surface * dst, SDL_Surface * src, int x, int y)
160
161
162
163
164
165
166
167
168
{
Uint32 start = 0;
SDL_Rect srcRect;
SDL_Rect dstRect;
srcRect.x = 0;
srcRect.y = 0;
dstRect.x = x;
dstRect.y = y;
169
dstRect.w = srcRect.w = src->w; /* SDL will clip as appropriate. */
170
171
172
173
dstRect.h = srcRect.h = src->h;
start = SDL_GetTicks();
SDL_BlitSurface(src, &srcRect, dst, &dstRect);
174
return (SDL_GetTicks() - start);
175
176
}
177
178
static void
blitCentered(SDL_Surface * dst, SDL_Surface * src)
179
180
181
182
183
184
{
int x = (dst->w - src->w) / 2;
int y = (dst->h - src->h) / 2;
blit(dst, src, x, y);
}
185
186
static int
atoi_hex(const char *str)
187
188
189
190
{
if (str == NULL)
return 0;
191
if (strlen(str) > 2) {
192
193
194
int retval = 0;
if ((str[0] == '0') && (str[1] == 'x'))
sscanf(str + 2, "%X", &retval);
195
return (retval);
196
197
}
198
return (atoi(str));
199
200
201
}
202
203
static int
setup_test(int argc, char **argv)
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
{
const char *dumpfile = NULL;
SDL_Surface *bmp = NULL;
Uint32 dstbpp = 32;
Uint32 dstrmask = 0x00FF0000;
Uint32 dstgmask = 0x0000FF00;
Uint32 dstbmask = 0x000000FF;
Uint32 dstamask = 0x00000000;
Uint32 dstflags = 0;
int dstw = 640;
int dsth = 480;
Uint32 srcbpp = 32;
Uint32 srcrmask = 0x00FF0000;
Uint32 srcgmask = 0x0000FF00;
Uint32 srcbmask = 0x000000FF;
Uint32 srcamask = 0x00000000;
Uint32 srcflags = 0;
int srcw = 640;
int srch = 480;
223
224
225
226
Uint32 origsrcalphaflags = 0;
Uint32 origdstalphaflags = 0;
Uint32 srcalphaflags = 0;
Uint32 dstalphaflags = 0;
227
228
229
230
Uint8 origsrcalpha = 255;
Uint8 origdstalpha = 255;
Uint8 srcalpha = 255;
Uint8 dstalpha = 255;
231
int screenSurface = 0;
232
int i = 0;
233
234
for (i = 1; i < argc; i++) {
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
const char *arg = argv[i];
if (strcmp(arg, "--dstbpp") == 0)
dstbpp = atoi(argv[++i]);
else if (strcmp(arg, "--dstrmask") == 0)
dstrmask = atoi_hex(argv[++i]);
else if (strcmp(arg, "--dstgmask") == 0)
dstgmask = atoi_hex(argv[++i]);
else if (strcmp(arg, "--dstbmask") == 0)
dstbmask = atoi_hex(argv[++i]);
else if (strcmp(arg, "--dstamask") == 0)
dstamask = atoi_hex(argv[++i]);
else if (strcmp(arg, "--dstwidth") == 0)
dstw = atoi(argv[++i]);
else if (strcmp(arg, "--dstheight") == 0)
dsth = atoi(argv[++i]);
else if (strcmp(arg, "--dsthwsurface") == 0)
dstflags |= SDL_HWSURFACE;
else if (strcmp(arg, "--srcbpp") == 0)
srcbpp = atoi(argv[++i]);
else if (strcmp(arg, "--srcrmask") == 0)
srcrmask = atoi_hex(argv[++i]);
else if (strcmp(arg, "--srcgmask") == 0)
srcgmask = atoi_hex(argv[++i]);
else if (strcmp(arg, "--srcbmask") == 0)
srcbmask = atoi_hex(argv[++i]);
else if (strcmp(arg, "--srcamask") == 0)
srcamask = atoi_hex(argv[++i]);
else if (strcmp(arg, "--srcwidth") == 0)
srcw = atoi(argv[++i]);
else if (strcmp(arg, "--srcheight") == 0)
srch = atoi(argv[++i]);
else if (strcmp(arg, "--srchwsurface") == 0)
srcflags |= SDL_HWSURFACE;
else if (strcmp(arg, "--seconds") == 0)
testSeconds = atoi(argv[++i]);
else if (strcmp(arg, "--screen") == 0)
screenSurface = 1;
else if (strcmp(arg, "--dumpfile") == 0)
dumpfile = argv[++i];
275
/* !!! FIXME: set colorkey. */
276
else if (0) { /* !!! FIXME: we handle some commandlines elsewhere now */
277
fprintf(stderr, "Unknown commandline option: %s\n", arg);
278
return (0);
279
280
281
}
}
282
if (SDL_Init(SDL_INIT_VIDEO) == -1) {
283
fprintf(stderr, "SDL_Init failed: %s\n", SDL_GetError());
284
return (0);
285
286
287
}
bmp = SDL_LoadBMP("sample.bmp");
288
if (bmp == NULL) {
289
290
fprintf(stderr, "SDL_LoadBMP failed: %s\n", SDL_GetError());
SDL_Quit();
291
return (0);
292
293
}
294
295
296
297
if ((dstflags & SDL_HWSURFACE) == 0)
dstflags |= SDL_SWSURFACE;
if ((srcflags & SDL_HWSURFACE) == 0)
srcflags |= SDL_SWSURFACE;
298
299
300
if (screenSurface)
dest = SDL_SetVideoMode(dstw, dsth, dstbpp, dstflags);
301
else {
302
303
304
305
dest = SDL_CreateRGBSurface(dstflags, dstw, dsth, dstbpp,
dstrmask, dstgmask, dstbmask, dstamask);
}
306
if (dest == NULL) {
307
308
fprintf(stderr, "dest surface creation failed: %s\n", SDL_GetError());
SDL_Quit();
309
return (0);
310
311
312
313
}
src = SDL_CreateRGBSurface(srcflags, srcw, srch, srcbpp,
srcrmask, srcgmask, srcbmask, srcamask);
314
if (src == NULL) {
315
316
fprintf(stderr, "src surface creation failed: %s\n", SDL_GetError());
SDL_Quit();
317
return (0);
318
319
}
320
/* handle alpha settings... */
321
322
323
srcalphaflags = (src->flags & SDL_SRCALPHA) | (src->flags & SDL_RLEACCEL);
dstalphaflags =
(dest->flags & SDL_SRCALPHA) | (dest->flags & SDL_RLEACCEL);
324
325
origsrcalphaflags = srcalphaflags;
origdstalphaflags = dstalphaflags;
326
327
328
329
SDL_GetSurfaceAlphaMod(src, &srcalpha);
SDL_GetSurfaceAlphaMod(dest, &dstalpha);
origsrcalpha = srcalpha;
origdstalpha = dstalpha;
330
for (i = 1; i < argc; i++) {
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
const char *arg = argv[i];
if (strcmp(arg, "--srcalpha") == 0)
srcalpha = atoi(argv[++i]);
else if (strcmp(arg, "--dstalpha") == 0)
dstalpha = atoi(argv[++i]);
else if (strcmp(arg, "--srcsrcalpha") == 0)
srcalphaflags |= SDL_SRCALPHA;
else if (strcmp(arg, "--srcnosrcalpha") == 0)
srcalphaflags &= ~SDL_SRCALPHA;
else if (strcmp(arg, "--srcrleaccel") == 0)
srcalphaflags |= SDL_RLEACCEL;
else if (strcmp(arg, "--srcnorleaccel") == 0)
srcalphaflags &= ~SDL_RLEACCEL;
else if (strcmp(arg, "--dstsrcalpha") == 0)
dstalphaflags |= SDL_SRCALPHA;
else if (strcmp(arg, "--dstnosrcalpha") == 0)
dstalphaflags &= ~SDL_SRCALPHA;
else if (strcmp(arg, "--dstrleaccel") == 0)
dstalphaflags |= SDL_RLEACCEL;
else if (strcmp(arg, "--dstnorleaccel") == 0)
dstalphaflags &= ~SDL_RLEACCEL;
}
354
355
356
357
if ((dstalphaflags != origdstalphaflags) || (origdstalpha != dstalpha))
SDL_SetAlpha(dest, dstalphaflags, dstalpha);
if ((srcalphaflags != origsrcalphaflags) || (origsrcalpha != srcalpha))
SDL_SetAlpha(src, srcalphaflags, srcalpha);
358
359
360
361
362
363
364
365
366
/* set some sane defaults so we can see if the blit code is broken... */
SDL_FillRect(dest, NULL, SDL_MapRGB(dest->format, 0, 0, 0));
SDL_FillRect(src, NULL, SDL_MapRGB(src->format, 0, 0, 0));
blitCentered(src, bmp);
SDL_FreeSurface(bmp);
if (dumpfile)
367
SDL_SaveBMP(src, dumpfile); /* make sure initial convert is sane. */
368
369
370
output_details();
371
return (1);
372
373
374
}
375
376
static void
test_blit_speed(void)
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
{
Uint32 clearColor = SDL_MapRGB(dest->format, 0, 0, 0);
Uint32 iterations = 0;
Uint32 elasped = 0;
Uint32 end = 0;
Uint32 now = 0;
Uint32 last = 0;
int testms = testSeconds * 1000;
int wmax = (dest->w - src->w);
int hmax = (dest->h - src->h);
int isScreen = (SDL_GetVideoSurface() == dest);
SDL_Event event;
printf("Testing blit speed for %d seconds...\n", testSeconds);
now = SDL_GetTicks();
end = now + testms;
395
do {
396
/* pump the event queue occasionally to keep OS happy... */
397
if (now - last > 1000) {
398
last = now;
399
400
while (SDL_PollEvent(&event)) { /* no-op. */
}
401
402
403
404
}
iterations++;
elasped += blit(dest, src, randRange(0, wmax), randRange(0, hmax));
405
406
407
if (isScreen) {
SDL_Flip(dest); /* show it! */
SDL_FillRect(dest, NULL, clearColor); /* blank it for next time! */
408
409
410
}
now = SDL_GetTicks();
411
} while (now < end);
412
413
printf("Non-blitting crap accounted for %d percent of this run.\n",
414
percent(testms - elasped, testms));
415
416
printf("%d blits took %d ms (%d fps).\n",
417
418
419
(int) iterations,
(int) elasped,
(int) (((float) iterations) / (((float) elasped) / 1000.0f)));
420
421
}
422
423
int
main(int argc, char **argv)
424
425
{
int initialized = setup_test(argc, argv);
426
if (initialized) {
427
428
429
test_blit_speed();
SDL_Quit();
}
430
return (!initialized);
431
432
433
}
/* end of testblitspeed.c ... */