1 /*
2 * Benchmark for memory blenders.
3 */
4
5 #include <stdio.h>
6 #include <allegro5/allegro.h>
7 #include <allegro5/allegro_image.h>
8 #include <allegro5/allegro_primitives.h>
9 #include <time.h>
10
11 #include "common.c"
12
13 /* Do a few un-timed runs to switch CPU to performance mode and cache
14 * data and so on - seems to make the results more stable here.
15 * Also used to guess the number of timed iterations.
16 */
17 #define WARMUP 100
18 /* How many seconds the timing should approximately take - a fixed
19 * number of iterations is not enough on very fast systems but takes
20 * too long on slow systems.
21 */
22 #define TEST_TIME 5.0
23
24 enum Mode {
25 ALL,
26 PLAIN_BLIT,
27 SCALED_BLIT,
28 ROTATE_BLIT
29 };
30
31 static char const *names[] = {
32 "", "Plain blit", "Scaled blit", "Rotated blit"
33 };
34
35 ALLEGRO_DISPLAY *display;
36
step(enum Mode mode,ALLEGRO_BITMAP * b2)37 static void step(enum Mode mode, ALLEGRO_BITMAP *b2)
38 {
39 switch (mode) {
40 case ALL: break;
41 case PLAIN_BLIT:
42 al_draw_bitmap(b2, 0, 0, 0);
43 break;
44 case SCALED_BLIT:
45 al_draw_scaled_bitmap(b2, 0, 0, 320, 200, 0, 0, 640, 480, 0);
46 break;
47 case ROTATE_BLIT:
48 al_draw_scaled_rotated_bitmap(b2, 10, 10, 10, 10, 2.0, 2.0,
49 ALLEGRO_PI/30, 0);
50 break;
51 }
52 }
53
54 /* al_get_current_time() measures wallclock time - but for the benchmark
55 * result we prefer CPU time so clock() is better.
56 */
current_clock(void)57 static double current_clock(void)
58 {
59 clock_t c = clock();
60 return (double)c / CLOCKS_PER_SEC;
61 }
62
do_test(enum Mode mode)63 static bool do_test(enum Mode mode)
64 {
65 ALLEGRO_STATE state;
66 ALLEGRO_BITMAP *b1;
67 ALLEGRO_BITMAP *b2;
68 int REPEAT;
69 double t0, t1;
70 int i;
71
72 al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
73
74 b1 = al_load_bitmap("data/mysha.pcx");
75 if (!b1) {
76 abort_example("Error loading data/mysha.pcx\n");
77 return false;
78 }
79
80 b2 = al_load_bitmap("data/allegro.pcx");
81 if (!b2) {
82 abort_example("Error loading data/mysha.pcx\n");
83 return false;
84 }
85
86 al_set_target_bitmap(b1);
87 al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA);
88 step(mode, b2);
89
90 /* Display the blended bitmap to the screen so we can see something. */
91 al_store_state(&state, ALLEGRO_STATE_ALL);
92 al_set_target_backbuffer(display);
93 al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
94 al_draw_bitmap(b1, 0, 0, 0);
95 al_flip_display();
96 al_restore_state(&state);
97
98 log_printf("Benchmark: %s\n", names[mode]);
99 log_printf("Please wait...\n");
100
101 /* Do warmup run and estimate required runs for real test. */
102 t0 = current_clock();
103 for (i = 0; i < WARMUP; i++) {
104 step(mode, b2);
105 }
106 t1 = current_clock();
107 REPEAT = TEST_TIME * 100 / (t1 - t0);
108
109 /* Do the real test. */
110 t0 = current_clock();
111 for (i = 0; i < REPEAT; i++) {
112 step(mode, b2);
113 }
114 t1 = current_clock();
115
116 log_printf("Time = %g s, %d steps\n",
117 t1 - t0, REPEAT);
118 log_printf("%s: %g FPS\n", names[mode], REPEAT / (t1 - t0));
119 log_printf("Done\n");
120
121 al_destroy_bitmap(b1);
122 al_destroy_bitmap(b2);
123
124 return true;
125 }
126
main(int argc,char ** argv)127 int main(int argc, char **argv)
128 {
129 enum Mode mode = ALL;
130 int i;
131
132 if (argc > 1) {
133 i = strtol(argv[1], NULL, 10);
134 switch (i) {
135 case 0:
136 mode = PLAIN_BLIT;
137 break;
138 case 1:
139 mode = SCALED_BLIT;
140 break;
141 case 2:
142 mode = ROTATE_BLIT;
143 break;
144 }
145 }
146
147 if (!al_init()) {
148 abort_example("Could not init Allegro\n");
149 }
150
151 open_log();
152
153 al_init_image_addon();
154 al_init_primitives_addon();
155 init_platform_specific();
156
157 display = al_create_display(640, 480);
158 if (!display) {
159 abort_example("Error creating display\n");
160 }
161
162 if (mode == ALL) {
163 for (mode = PLAIN_BLIT; mode <= ROTATE_BLIT; mode++) {
164 do_test(mode);
165 }
166 }
167 else {
168 do_test(mode);
169 }
170
171 al_destroy_display(display);
172
173 close_log(true);
174
175 return 0;
176 }
177
178 /* vim: set sts=3 sw=3 et: */
179