using System; using sharpallegro5; using ALLEGRO_DISPLAY = System.IntPtr; using ALLEGRO_BITMAP = System.IntPtr; using clock_t = System.Int64; using System.Diagnostics; /* * Benchmark for memory blenders. */ public class ex_blend_bench : AllegroExample { /* 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. */ const int 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. */ const float TEST_TIME = 5.0f; enum Mode { ALL, PLAIN_BLIT, SCALED_BLIT, ROTATE_BLIT }; static string[] names = { "", "Plain blit", "Scaled blit", "Rotated blit" }; static ALLEGRO_DISPLAY display; static void step(Mode mode, ALLEGRO_BITMAP b2) { switch (mode) { case Mode.ALL: break; case Mode.PLAIN_BLIT: al_draw_bitmap(b2, 0, 0, 0); break; case Mode.SCALED_BLIT: al_draw_scaled_bitmap(b2, 0, 0, 320, 200, 0, 0, 640, 480, 0); break; case Mode.ROTATE_BLIT: al_draw_scaled_rotated_bitmap(b2, 10, 10, 10, 10, 2.0f, 2.0f, (float)(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() { clock_t c = DateTime.Now.Ticks; // clock(); return (double)c / TimeSpan.TicksPerSecond; //CLOCKS_PER_SEC; } static bool do_test(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 == IntPtr.Zero) { abort_example("Error loading data/mysha.pcx\n"); return false; } b2 = al_load_bitmap("data/allegro.pcx"); if (b2 == IntPtr.Zero) { 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(ref 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(ref state); log_printf("Benchmark: {0}\n", names[(int)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 = (int)(TEST_TIME * 100 / (t1 - t0)); /* Do the real test. */ t0 = current_clock(); for (i = 0; i < REPEAT; i++) { step(mode, b2); } t1 = current_clock(); // TODO: double numeric conversion/rounding to be fixed log_printf("Time = {0} s, {1} steps\n", t1 - t0, REPEAT); log_printf("{0}: {1} FPS\n", names[(int)mode], REPEAT / (t1 - t0)); al_destroy_bitmap(b1); al_destroy_bitmap(b2); return true; } static int Main(string[] argv) { Mode mode = Mode.ALL; int i; if (argv.Length > 1) { i = int.Parse(argv[1]); switch (i) { case 0: mode = Mode.PLAIN_BLIT; break; case 1: mode = Mode.SCALED_BLIT; break; case 2: mode = Mode.ROTATE_BLIT; break; } } if (!al_init()) return 1; open_log(); al_init_image_addon(); al_init_primitives_addon(); display = al_create_display(640, 480); if (display == IntPtr.Zero) { abort_example("Error creating display\n"); return 1; } if (mode == Mode.ALL) { for (mode = Mode.PLAIN_BLIT; mode <= Mode.ROTATE_BLIT; mode++) { do_test(mode); } } else { do_test(mode); } al_destroy_display(display); close_log(true); return 0; } }