/* * Benchmark for memory blenders. */ #include #include #include #include #include #include "common.c" /* Do a few un-timed runs to switch CPU to performance mode and cache * data and so on - seems to make the results more stable here. * Also used to guess the number of timed iterations. */ #define WARMUP 100 /* How many seconds the timing should approximately take - a fixed * number of iterations is not enough on very fast systems but takes * too long on slow systems. */ #define TEST_TIME 5.0 enum Mode { ALL, PLAIN_BLIT, SCALED_BLIT, ROTATE_BLIT }; static char const *names[] = { "", "Plain blit", "Scaled blit", "Rotated blit" }; ALLEGRO_DISPLAY *display; static void step(enum Mode mode, ALLEGRO_BITMAP *b2) { switch (mode) { case ALL: break; case PLAIN_BLIT: al_draw_bitmap(b2, 0, 0, 0); break; case SCALED_BLIT: al_draw_scaled_bitmap(b2, 0, 0, 320, 200, 0, 0, 640, 480, 0); break; case ROTATE_BLIT: al_draw_scaled_rotated_bitmap(b2, 10, 10, 10, 10, 2.0, 2.0, ALLEGRO_PI/30, 0); break; } } /* al_get_current_time() measures wallclock time - but for the benchmark * result we prefer CPU time so clock() is better. */ static double current_clock(void) { clock_t c = clock(); return (double)c / CLOCKS_PER_SEC; } static bool do_test(enum Mode mode) { ALLEGRO_STATE state; ALLEGRO_BITMAP *b1; ALLEGRO_BITMAP *b2; int REPEAT; double t0, t1; int i; al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); b1 = al_load_bitmap("data/mysha.pcx"); if (!b1) { abort_example("Error loading data/mysha.pcx\n"); return false; } b2 = al_load_bitmap("data/allegro.pcx"); if (!b2) { abort_example("Error loading data/mysha.pcx\n"); return false; } al_set_target_bitmap(b1); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); step(mode, b2); /* Display the blended bitmap to the screen so we can see something. */ al_store_state(&state, ALLEGRO_STATE_ALL); al_set_target_backbuffer(display); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_draw_bitmap(b1, 0, 0, 0); al_flip_display(); al_restore_state(&state); log_printf("Benchmark: %s\n", names[mode]); log_printf("Please wait...\n"); /* Do warmup run and estimate required runs for real test. */ t0 = current_clock(); for (i = 0; i < WARMUP; i++) { step(mode, b2); } t1 = current_clock(); REPEAT = TEST_TIME * 100 / (t1 - t0); /* Do the real test. */ t0 = current_clock(); for (i = 0; i < REPEAT; i++) { step(mode, b2); } t1 = current_clock(); log_printf("Time = %g s, %d steps\n", t1 - t0, REPEAT); log_printf("%s: %g FPS\n", names[mode], REPEAT / (t1 - t0)); log_printf("Done\n"); al_destroy_bitmap(b1); al_destroy_bitmap(b2); return true; } int main(int argc, char **argv) { enum Mode mode = ALL; int i; if (argc > 1) { i = strtol(argv[1], NULL, 10); switch (i) { case 0: mode = PLAIN_BLIT; break; case 1: mode = SCALED_BLIT; break; case 2: mode = ROTATE_BLIT; break; } } if (!al_init()) { abort_example("Could not init Allegro\n"); } open_log(); al_init_image_addon(); al_init_primitives_addon(); init_platform_specific(); display = al_create_display(640, 480); if (!display) { abort_example("Error creating display\n"); } if (mode == ALL) { for (mode = PLAIN_BLIT; mode <= ROTATE_BLIT; mode++) { do_test(mode); } } else { do_test(mode); } al_destroy_display(display); close_log(true); return 0; } /* vim: set sts=3 sw=3 et: */