tests.c revision 9aa2a2b5
1/* 2** 3*/ 4 5#include <X11/Intrinsic.h> 6#include <X11/StringDefs.h> 7#include <X11/Xaw/AsciiText.h> 8#include <X11/Xos.h> 9#include <stdio.h> 10#include <stdlib.h> 11#include <math.h> 12#include "xgc.h" 13#ifdef SVR4 14#define SYSV 15#endif 16#if !defined(SYSV) && !defined(QNX4) 17#include <sys/timeb.h> 18#include <sys/resource.h> 19#endif 20 21#ifndef PI 22#define PI 3.14159265 23#endif 24 25#ifdef SYSV 26#define random lrand48 27#endif 28 29 30/* timer(flag) 31** ----------- 32** When called with StartTimer, starts the stopwatch and returns nothing. 33** When called with EndTimer, stops the stopwatch and returns the time 34** in microseconds since it started. 35** 36** Uses rusage() so we can subtract the time used by the system and user 37** from our timer, and just concentrate on the time used in the X calls. 38*/ 39 40static long 41timer(int flag) 42{ 43#if !defined(SYSV) 44 static struct timeval starttime; /* starting time for gettimeofday() */ 45 struct timeval endtime; /* ending time for gettimeofday() */ 46#if !defined(__UNIXOS2__) && !defined(QNX4) 47 static struct rusage startusage; /* starting time for getrusage() */ 48 struct rusage endusage; /* ending time for getrusage() */ 49#endif 50 struct timezone tz; /* to make gettimeofday() happy */ 51 52 long elapsedtime; /* how long since we started the timer */ 53 54 switch (flag) { 55 case StartTimer: /* store initial values */ 56 gettimeofday(&starttime,&tz); 57#if !defined(__UNIXOS2__) && !defined(QNX4) 58 getrusage(RUSAGE_SELF,&startusage); 59#endif 60 return((long) NULL); 61 case EndTimer: 62 gettimeofday(&endtime,&tz); /* store final values */ 63#if !defined(__UNIXOS2__) && !defined(QNX4) 64 getrusage(RUSAGE_SELF,&endusage); 65#endif 66 67 /* all the following line does is use the formula 68 elapsed time = ending time - starting time, but there are three 69 different timers and two different units of time, ack... */ 70 71#if !defined(__UNIXOS2__) && !defined(QNX4) 72 elapsedtime = (long) ((long) 73 ((endtime.tv_sec - endusage.ru_utime.tv_sec - endusage.ru_stime.tv_sec 74 - starttime.tv_sec + startusage.ru_utime.tv_sec 75 + startusage.ru_stime.tv_sec)) * 1000000) + (long) 76 ((endtime.tv_usec - endusage.ru_utime.tv_usec - endusage.ru_stime.tv_usec 77 - starttime.tv_usec + startusage.ru_utime.tv_usec 78 + startusage.ru_stime.tv_usec)); 79#else 80 elapsedtime = (long)( ((long)endtime.tv_sec-(long)starttime.tv_sec)*1000000 81 +((long)endtime.tv_usec-(long)starttime.tv_usec)); 82#endif 83 return(elapsedtime); 84 85 default: 86 fprintf(stderr,"Invalid flag in timer()\n"); 87 return((long) NULL); 88 } 89#else 90 static time_t starttime; 91 92 switch (flag) { 93 case StartTimer: 94 time(&starttime); 95 return((long) NULL); 96 case EndTimer: 97 return( (time(NULL) - starttime) * 1000000); 98 default: 99 fprintf(stderr,"Invalid flag in timer()\n"); 100 return((long) NULL); 101 } 102#endif 103} 104 105 106void 107copyarea_test(void) 108{ 109 int num_copies = 200; 110 int i; 111 long totaltime; 112 char buf[80]; 113 114 num_copies *= X.percent; 115 116 XSetFillStyle(X.dpy,X.miscgc,FillTiled); 117 XFillRectangle(X.dpy,X.win,X.miscgc,0,0,400,400); 118 119 XSync(X.dpy,0); 120 timer(StartTimer); 121 for (i=0;i<num_copies;++i) 122 XCopyArea(X.dpy,X.win,X.win,X.gc,i,200-i, 123 200,200,200-i,i); 124 XSync(X.dpy,0); 125 totaltime = timer(EndTimer); 126 127 snprintf(buf,sizeof buf,"%.2f seconds.",(double)totaltime/1000000.); 128 show_result(buf); 129} 130 131void 132copyplane_test(void) 133{ 134 int num_copies = 200; 135 int i; 136 long totaltime; 137 char buf[80]; 138 139 if(!X.gcv.plane_mask || (X.gcv.plane_mask & (X.gcv.plane_mask - 1))) { 140 show_result("exactly one bit in plane mask must be set for this test"); 141 return; 142 } 143 144 145 num_copies *= X.percent; 146 147 XSetPlaneMask(X.dpy, X.gc, ~0L); 148 XSetFillStyle(X.dpy,X.miscgc,FillTiled); 149 XFillRectangle(X.dpy,X.win,X.miscgc,0,0,400,400); 150 151 XSync(X.dpy,0); 152 timer(StartTimer); 153 for (i=0;i<num_copies;++i) 154 XCopyPlane(X.dpy,X.win,X.win,X.gc,i,200-i, 155 200,200,200-i,i,X.gcv.plane_mask); 156 XSync(X.dpy,0); 157 totaltime = timer(EndTimer); 158 XSetPlaneMask(X.dpy, X.gc, X.gcv.plane_mask); 159 160 snprintf(buf,sizeof buf,"%.2f seconds.",(double)totaltime/1000000.); 161 show_result(buf); 162} 163 164void 165circle_line_test(int num_vertices, int radius) 166{ 167 double theta, delta; 168 int length, centerx, centery, i; 169 int relative_angle; 170 long totaltime; 171 char buf[80]; 172 XPoint *coord; 173 174 relative_angle = num_vertices*5/12+1; 175 delta = (double) relative_angle / (double) num_vertices * 2 * PI; 176 centerx = centery = 200; 177 178 coord = (XPoint *) malloc (sizeof(XPoint)*(num_vertices+1)); 179 180 length = (int) (2 * radius * (float) atan(delta/2.)); 181 182 for (i=0;i<=num_vertices;++i) { 183 theta = (double) i * delta; 184 coord[i].x = centerx + (int) (radius * cos(theta)); 185 coord[i].y = centery + (int) (radius * sin(theta)); 186 } 187 188 XSync(X.dpy,0); 189 timer(StartTimer); 190 XDrawLines(X.dpy,X.win,X.gc,coord,num_vertices+1,CoordModeOrigin); 191 XSync(X.dpy,0); 192 totaltime = timer(EndTimer); 193 194 snprintf(buf,sizeof buf,"%d lines of length %d in %.3f seconds.",num_vertices, 195 length,(double)totaltime/1000000.); 196 show_result(buf); 197 198 free(coord); 199} 200 201 202 203void 204polyline_test(void) 205{ 206 circle_line_test((int)(601*X.percent),190); 207} 208 209void 210polysegment_test(void) 211{ 212 XSegment *segments; 213 int num_segments = 600; 214 long totaltime; 215 char buf[80]; 216 int i; 217 218 num_segments *= X.percent; 219 220 segments = (XSegment *) malloc(sizeof(XSegment) * num_segments); 221 222 segments[0].x1 = random()%400; segments[0].y1 = random()%400; 223 segments[0].x2 = random()%400; segments[0].y2 = random()%400; 224 225 for(i=1;i<num_segments;++i) { 226 segments[i].x1 = (segments[i-1].x1-segments[i-1].y2+400+i)%400; 227 segments[i].y1 = (segments[i-1].y1+segments[i-1].x2+i)%400; 228 segments[i].x2 = (segments[i-1].x1-segments[i-1].y1+400+i)%400; 229 segments[i].y2 = (segments[i-1].x2+segments[i-1].y2+i)%400; 230 } 231 232 XSync(X.dpy,0); 233 start_timer(); 234 XDrawSegments(X.dpy,X.win,X.gc,segments,num_segments); 235 XSync(X.dpy,0); 236 totaltime = end_timer(); 237 238 snprintf(buf,sizeof buf,"%d segments in %.3f seconds.",num_segments, 239 (double)totaltime/1000000.); 240 show_result(buf); 241 242 free(segments); 243} 244 245void 246polypoint_test(void) 247{ 248 XPoint *points; 249 int num_points = 100000; 250 long totaltime; 251 char buf[80]; 252 int i; 253 254 num_points *= X.percent; 255 256 points = (XPoint *) malloc(sizeof(XPoint) * num_points); 257 258 points[0].x = random()%400; points[0].y = random()%400; 259 points[1].x = random()%400; points[1].y = random()%400; 260 261 for (i=2;i<num_points;++i) { 262 points[i].x = (points[i-1].x+points[i-2].y+i*3/200)%400; 263 points[i].y = (points[i-1].y+points[i-2].x+i*5/200)%400; 264 } 265 266 XSync(X.dpy,0); 267 start_timer(); 268 XDrawPoints(X.dpy,X.win,X.gc,points,num_points,CoordModeOrigin); 269 XSync(X.dpy,0); 270 totaltime = end_timer(); 271 272 snprintf(buf,sizeof buf,"%d points in %.3f seconds.",num_points, 273 (double)totaltime/1000000.); 274 show_result(buf); 275 276 free(points); 277} 278 279void 280genericrectangle_test(Boolean fill) 281{ 282 XRectangle *rects; 283 int num_rects = 200; 284 int perimeter = 0, area = 0; 285 int i; 286 long totaltime; 287 char buf[80]; 288 289 num_rects *= X.percent; 290 291 rects = (XRectangle *) malloc(sizeof(XRectangle) * num_rects); 292 293 for (i=0;i<num_rects;++i) { 294 rects[i].x = rects[i].y = 200 - i; 295 rects[i].width = rects[i].height = 2 * i; 296 perimeter += rects[i].width * 2 + rects[i].height * 2; 297 area += rects[i].width * rects[i].height; 298 } 299 300 XSync(X.dpy,0); 301 start_timer(); 302 if (fill) XFillRectangles(X.dpy,X.win,X.gc,rects,num_rects); 303 else XDrawRectangles(X.dpy,X.win,X.gc,rects,num_rects); 304 XSync(X.dpy,0); 305 totaltime = end_timer(); 306 307 if (fill) 308 snprintf(buf,sizeof buf,"%d pixels in %.2f seconds.",area,(double)totaltime/1000000.); 309 else 310 snprintf(buf,sizeof buf,"Total line length %d in %.3f seconds.",perimeter, 311 (double)totaltime/1000000.); 312 show_result(buf); 313 314 free(rects); 315} 316 317void 318polyrectangle_test(void) 319{ 320 genericrectangle_test(FALSE); 321} 322 323void 324polyfillrectangle_test(void) 325{ 326 genericrectangle_test(TRUE); 327} 328 329/*****************************/ 330 331void 332fillpolygon_test(void) 333{ 334 int i; 335 int points_per_side = 40; 336 int spacing; 337 XPoint *points; 338 XPoint polypoints[3]; 339 340 points = (XPoint *) malloc (sizeof(XPoint) * points_per_side * 4); 341 spacing = 400 / points_per_side; 342 343 for (i = 0; i < points_per_side; ++i) { 344 points[i].x = i * spacing; 345 points[i].y = 0; 346 347 points[i + points_per_side].x = 400; 348 points[i + points_per_side].y = i * spacing; 349 350 points[i + 2 * points_per_side].x = 400 - i * spacing; 351 points[i + 2 * points_per_side].y = 400; 352 353 points[i + 3 * points_per_side].x = 0; 354 points[i + 3 * points_per_side].y = 400 - i * spacing; 355 } 356 357 for (i = 0; i < 2 * points_per_side; i += 2) { 358 polypoints[0].x = points[i].x; 359 polypoints[0].y = points[i].y; 360 361 polypoints[1].x = points[i + 2 * points_per_side].x; 362 polypoints[1].y = points[i + 2 * points_per_side].y; 363 364 polypoints[2].x = points[i + 2 * points_per_side + 1].x; 365 polypoints[2].y = points[i + 2 * points_per_side + 1].y; 366 367 XFillPolygon (X.dpy, X.win, X.gc, polypoints, 3, Convex, CoordModeOrigin); 368 } 369 free(points); 370} 371 372/*****************************/ 373 374void 375genericarc_test(Boolean fill) 376{ 377 XArc *arcs; 378 int num_arcs = 180; 379 int i; 380 long totaltime; 381 char buf[80]; 382 383 num_arcs *= X.percent; 384 385 arcs = (XArc *) malloc(sizeof(XArc) * num_arcs); 386 387 for (i=0;i<num_arcs;++i) { 388 arcs[i].x = i; 389 arcs[i].y = i; 390 arcs[i].width = i; 391 arcs[i].height = i; 392 arcs[i].angle1 = i * 128; 393 arcs[i].angle2 = i * 128; 394 } 395 396 XSync(X.dpy,0); 397 start_timer(); 398 if (fill) XFillArcs(X.dpy,X.win,X.gc,arcs,num_arcs); 399 else XDrawArcs(X.dpy,X.win,X.gc,arcs,num_arcs); 400 XSync(X.dpy,0); 401 totaltime = end_timer(); 402 403 snprintf(buf,sizeof buf,"An uncounted number of pixels in %.3f seconds.", 404 (double)totaltime/1000000.); 405 show_result(buf); 406 407 free(arcs); 408} 409 410void 411polyarc_test(void) 412{ 413 genericarc_test(FALSE); 414} 415 416void 417polyfillarc_test(void) 418{ 419 genericarc_test(TRUE); 420} 421 422static const char string8[] = "pack my box with five dozen liquor jugs"; 423 424void 425polytext8_test(void) 426{ 427 int num_strings = 200; 428 int i; 429 long totaltime; 430 char buf[80]; 431 432 num_strings *= X.percent; 433 434 XSync(X.dpy,0); 435 start_timer(); 436 for (i=0;i<num_strings;++i) { 437 XDrawString(X.dpy,X.win,X.gc,(i%2 ? i : num_strings - i),i, 438 string8,sizeof(string8)-1); 439 } 440 XSync(X.dpy,0); 441 totaltime = end_timer(); 442 443 snprintf(buf,sizeof buf,"%d strings in %.2f seconds.",num_strings, 444 (double) totaltime/1000000.); 445 show_result(buf); 446} 447 448void 449imagetext8_test(void) 450{ 451 int num_strings = 200; 452 int i; 453 long totaltime; 454 char buf[80]; 455 456 num_strings *= X.percent; 457 458 XSync(X.dpy,0); 459 start_timer(); 460 for (i=0;i<num_strings;++i) { 461 XDrawImageString(X.dpy,X.win,X.gc,(i%2 ? i : num_strings - i),i, 462 string8,sizeof(string8)-1); 463 } 464 XSync(X.dpy,0); 465 totaltime = end_timer(); 466 467 snprintf(buf,sizeof buf,"%d strings in %.2f seconds.",num_strings, 468 (double) totaltime/1000000.); 469 show_result(buf); 470} 471 472static char unicode_font[] = 473 "-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1"; 474 475static const XChar2b string16[] = { 476 { 0x00, 0x20 }, { 0x00, 0x20 }, { 0x22, 0x2E }, { 0x00, 0x20 }, 477 { 0x00, 0x45 }, { 0x22, 0xC5 }, { 0x00, 0x64 }, { 0x00, 0x61 }, 478 { 0x00, 0x20 }, { 0x00, 0x3D }, { 0x00, 0x20 }, { 0x00, 0x51 }, 479 { 0x00, 0x2C }, { 0x00, 0x20 }, { 0x00, 0x20 }, { 0x00, 0x6E }, 480 { 0x00, 0x20 }, { 0x21, 0x92 }, { 0x00, 0x20 }, { 0x22, 0x1E }, 481 { 0x00, 0x2C }, { 0x00, 0x20 }, { 0x22, 0x11 }, { 0x00, 0x20 }, 482 { 0x00, 0x66 }, { 0x00, 0x28 }, { 0x00, 0x69 }, { 0x00, 0x29 }, 483 { 0x00, 0x20 }, { 0x00, 0x3D }, { 0x00, 0x20 }, { 0x22, 0x0F }, 484 { 0x00, 0x20 }, { 0x00, 0x67 }, { 0x00, 0x28 }, { 0x00, 0x69 }, 485 { 0x00, 0x29 }, { 0x00, 0x2C }, { 0x00, 0x20 }, { 0x22, 0x00 }, 486 { 0x00, 0x78 }, { 0x22, 0x08 }, { 0x21, 0x1D }, { 0x00, 0x3A }, 487 { 0x00, 0x20 }, { 0x23, 0x08 }, { 0x00, 0x78 }, { 0x23, 0x09 }, 488 { 0x00, 0x20 }, { 0x00, 0x3D }, { 0x00, 0x20 }, { 0x22, 0x12 }, 489 { 0x23, 0x0A }, { 0x22, 0x12 }, { 0x00, 0x78 }, { 0x23, 0x0B }, 490 { 0x00, 0x2C }, { 0x00, 0x20 }, { 0x03, 0xB1 }, { 0x00, 0x20 }, 491 { 0x22, 0x27 }, { 0x00, 0x20 }, { 0x00, 0xAC }, { 0x03, 0xB2 }, 492 { 0x00, 0x20 }, { 0x00, 0x3D }, { 0x00, 0x20 }, { 0x00, 0xAC }, 493 { 0x00, 0x28 }, { 0x00, 0xAC }, { 0x03, 0xB1 }, { 0x00, 0x20 }, 494 { 0x22, 0x28 }, { 0x00, 0x20 }, { 0x03, 0xB2 }, { 0x00, 0x29 }, 495 { 0x00, 0x2C } 496}; 497 498void 499polytext16_test(void) 500{ 501 int num_strings = 50; 502 int i; 503 long totaltime; 504 char buf[80]; 505 506 num_strings *= X.percent; 507 508 GC_change_font(unicode_font,FALSE); 509 510 XSync(X.dpy,0); 511 start_timer(); 512 for (i=0;i<num_strings;++i) { 513 XDrawString16(X.dpy,X.win,X.gc,(i%2 ? i : num_strings - i),10*i, 514 string16,sizeof(string16)/sizeof(XChar2b)); 515 } 516 XSync(X.dpy,0); 517 totaltime = end_timer(); 518 519 GC_change_font(X.fontname,FALSE); 520 521 snprintf(buf,sizeof buf,"%d strings in %.2f seconds.",num_strings, 522 (double) totaltime/1000000.); 523 show_result(buf); 524} 525 526void 527imagetext16_test(void) 528{ 529 int num_strings = 50; 530 int i; 531 long totaltime; 532 char buf[80]; 533 534 num_strings *= X.percent; 535 536 GC_change_font(unicode_font,FALSE); 537 538 XSync(X.dpy,0); 539 start_timer(); 540 for (i=0;i<num_strings;++i) { 541 XDrawImageString16(X.dpy,X.win,X.gc,(i%2 ? i : num_strings - i),10*i, 542 string16,sizeof(string16)/sizeof(XChar2b)); 543 } 544 XSync(X.dpy,0); 545 totaltime = end_timer(); 546 547 GC_change_font(X.fontname,FALSE); 548 549 snprintf(buf,sizeof buf,"%d strings in %.2f seconds.",num_strings, 550 (double) totaltime/1000000.); 551 show_result(buf); 552} 553 554void 555putimage_test(void) 556{ 557 int num_copies = 200; 558 int i; 559 long totaltime; 560 char buf[80]; 561 562 num_copies *= X.percent; 563 564 XSetFillStyle(X.dpy,X.miscgc,FillTiled); 565 XFillRectangle(X.dpy,X.win,X.miscgc,0,0,400,400); 566 567 X.image = XGetImage(X.dpy,X.win,0,0,200,200,~0,XYPixmap); 568 569 XSync(X.dpy,0); 570 timer(StartTimer); 571 for (i=0;i<num_copies;++i) 572 XPutImage(X.dpy,X.win,X.gc,X.image,0,0,i,i,200,200); 573 XSync(X.dpy,0); 574 totaltime = timer(EndTimer); 575 576 snprintf(buf,sizeof buf,"%.2f seconds.",(double)totaltime/1000000.); 577 show_result(buf); 578} 579 580 581/*****************************/ 582/*****************************/ 583 584void 585run_test(void) 586{ 587 XClearWindow(X.dpy,X.win); 588 589 print_if_recording("run\n"); 590 591 switch (X.test) { 592 case CopyArea: copyarea_test(); break; 593 case CopyPlane: copyplane_test(); break; 594 case PolyPoint: polypoint_test(); break; 595 case PolyLine: polyline_test(); break; 596 case PolySegment: polysegment_test(); break; 597 case PolyRectangle: polyrectangle_test(); break; 598 case PolyArc: polyarc_test(); break; 599 case FillPolygon: fillpolygon_test(); break; 600 case PolyFillRect: polyfillrectangle_test(); break; 601 case PolyFillArc: polyfillarc_test(); break; 602 case PolyText8: polytext8_test(); break; 603 case ImageText8: imagetext8_test(); break; 604 case PolyText16: polytext16_test(); break; 605 case ImageText16: imagetext16_test(); break; 606 case PutImage: putimage_test(); break; 607 default: fprintf(stderr,"That test doesn't exist yet.\n"); 608 } 609} 610 611/*****************************/ 612 613/* set_text(w,string) 614** ------------------ 615** Sets the text in a read-only text widget to the specified string. 616*/ 617 618void 619set_text(Widget w, char *string) 620{ 621 static Arg args[2]; 622 623 XtSetArg(args[0], XtNstring, string); 624 XtSetArg(args[1], XtNlength, strlen(string)); 625 XtSetValues(w, args, (Cardinal) 2 ); 626} 627 628void 629show_result(char *string) 630{ 631 char buf[80]; 632 633 set_text(result,string); 634 635 strcpy(buf,"# "); 636 strncat(buf,string,sizeof(buf) - 3); 637 buf[sizeof(buf) - 3] = '\0'; 638 strcat(buf,"\n"); 639 print_if_recording(buf); 640} 641