/* * Fast Lines * ---------- * * How fast is line drawing using server-side * lines, compared with the portable * line-drawing algorithm which uses rectangles? * * This program draws many random lines and * times how long it takes to complete. * * On my 800MHz Pentium, lines 1 pixel thick * show the greatest speed improvment. Long lines * with lots of clipping can take only 10% the time * of portable lines drawn using rectangles. * Lines with less clipping use about 30% the time * when drawn on the server side. * Lines thicker than 1 pixel are about the same * speed whichever method is used to draw them. * Short lines seem to be faster using portable * rectangle code, rather than server-side lines. */ #include #include #include App *app; Window *w; unsigned int width = 1; unsigned int length = 800; long iterations = 1000; Colour colours[] = { {0,0,0,0}, {0,255,0,0}, {0,0,255,0}, {0,0,0,255}, {0,255,0,255}, {0,255,255,0}, {0,0,255,255}, {0,128,128,128} }; #define NUM_COLOURS (sizeof(colours)/sizeof(colours[0])) void go_now(Control *c) { long t1, t2; Point p1, p2; Graphics *g; long i, msec1, msec2; App *app; char buf[160]; app = w->app; g = get_window_graphics(w); set_line_width(g, width); /* First test. */ t1 = current_time(app); srand(t1); for (i=0; i < iterations; i++) { if (i % 128 == 0) set_colour(g, colours[(i/100)%NUM_COLOURS]); p1.x = (rand() % 1024) - 20; p1.y = (rand() % 1024) - 20; p2.x = p1.x + (rand() % length) - (length/2); p2.y = p1.y + (rand() % length) - (length/2); draw_line(g, p1, p2); } t2 = current_time(app); msec1 = t2 - t1; sprintf(buf, "It took %ld milliseconds to draw the fast lines.", msec1); ask_ok(app, "Results", buf); /* Clear the window. */ set_colour(g, WHITE); fill_rect(g, get_window_area(w)); set_colour(g, BLACK); /* Second test. */ t1 = current_time(app); srand(t1); for (i=0; i < iterations; i++) { if (i % 128 == 0) set_colour(g, colours[(i/100)%NUM_COLOURS]); p1.x = (rand() % 1024) - 20; p1.y = (rand() % 1024) - 20; p2.x = p1.x + (rand() % length) - (length/2); p2.y = p1.y + (rand() % length) - (length/2); portable_draw_line(g, p1, p2); } t2 = current_time(app); msec2 = t2 - t1; sprintf(buf, "It took %ld milliseconds to draw the portable lines.", msec2); ask_ok(app, "Results", buf); if (msec1 == msec2) sprintf(buf, "There was no measurable difference in speed."); else if (msec1 > msec2) sprintf(buf, "Portable lines took %ld%% as much time.", 100*msec2/msec1); else sprintf(buf, "Fast lines took %ld%% as much time.", 100*msec1/msec2); ask_ok(app, "Results", buf); del_graphics(g); } void clear_win(Control *c) { Graphics *g; g = get_window_graphics(w); set_colour(g, WHITE); fill_rect(g, get_window_area(w)); del_graphics(g); } void set_num(Control *c) { char *num; char buf[80]; sprintf(buf, "%ld", iterations); num = ask_string(app, "Question", "How many lines should the program draw?", buf); if (num == NULL) return; iterations = atol(num); free(num); } void set_width(Control *c) /* set line thickness */ { char *num; char buf[80]; sprintf(buf, "%d", width); num = ask_string(app, "Question", "Draw lines of what width?", buf); if (num == NULL) return; width = atoi(num); free(num); } void set_len(Control *c) /* set line length */ { char *num; char buf[80]; sprintf(buf, "%d", length); num = ask_string(app, "Question", "Draw lines of what approximate length?", buf); if (num == NULL) return; length = atoi(num); if (length == 0) length = 1; free(num); } void quit_now(Control *c) { exit(0); } int main(int argc, char *argv[]) { Control *btn[6]; app = new_app(argc, argv); w = new_window(app, rect(10,10,448,400), "Line Drawing Speed", STANDARD_WINDOW); btn[0] = new_button(w, rect(10,10,90,25), "Exit", quit_now); btn[1] = new_button(w, rect(10,40,90,25), "Set Number", set_num); btn[2] = new_button(w, rect(10,70,90,25), "Set Width", set_width); btn[3] = new_button(w, rect(10,100,90,25), "Set Length", set_len); btn[4] = new_button(w, rect(10,130,90,25), "Clear", clear_win); btn[5] = new_button(w, rect(10,160,90,25), "Go", go_now); show_window(w); main_loop(app); del_app(app); return 0; }