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