1/***************************************************************************** 2Copyright 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts. 3 4 All Rights Reserved 5 6Permission to use, copy, modify, and distribute this software and its 7documentation for any purpose and without fee is hereby granted, 8provided that the above copyright notice appear in all copies and that 9both that copyright notice and this permission notice appear in 10supporting documentation, and that the name of Digital not be 11used in advertising or publicity pertaining to distribution of the 12software without specific, written prior permission. 13 14DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 15ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 16DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 17ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 18WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 19ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 20SOFTWARE. 21 22******************************************************************************/ 23 24#include "x11perf.h" 25#include <stdio.h> 26 27#define NUMPOINTS 100 28 29static Pixmap pix; 30static XImage *image; 31static XPoint points[NUMPOINTS]; 32static XSegment *segsa, *segsb; 33static XSegment *segsa2, *segsb2; 34 35#define NegMod(x, y) ((y) - (((-x)-1) % (7)) - 1) 36 37static void 38InitBltLines(void) 39{ 40 int x, y; 41 42 points[0].x = points[0].y = y = 0; 43 for (int i = 1; i != NUMPOINTS/2; i++) { 44 if (i & 1) { 45 points[i].x = WIDTH-1; 46 } else { 47 points[i].x = 0; 48 } 49 y += HEIGHT / (NUMPOINTS/2); 50 points[i].y = y; 51 } 52 53 x = 0; 54 for (int i = NUMPOINTS/2; i!= NUMPOINTS; i++) { 55 if (i & 1) { 56 points[i].y = HEIGHT-1; 57 } else { 58 points[i].y = 0; 59 } 60 x += WIDTH / (NUMPOINTS/2); 61 points[i].x = x; 62 } 63} 64 65int 66InitScroll(XParms xp, Parms p, int64_t reps) 67{ 68 InitBltLines(); 69 XSetFunction(xp->d, xp->fggc, GXcopy); 70 XDrawLines(xp->d, xp->w, xp->fggc, points, NUMPOINTS, CoordModeOrigin); 71 XSetFunction(xp->d, xp->fggc, xp->func); 72 return reps; 73} 74 75void 76DoScroll(XParms xp, Parms p, int64_t reps) 77{ 78 int size, x, y, xorg, yorg, delta; 79 80 size = p->special; 81 xorg = 0; yorg = 0; 82 x = 0; y = 0; 83 if (xp->version == VERSION1_2) { 84 delta = 1; 85 } else { 86 /* Version 1.2 only scrolled up by 1 scanline, which made hardware 87 using page-mode access to VRAM look better on paper than it would 88 perform in a more realistic scroll. So we've changed to scroll by 89 the height of the 6x13 fonts. */ 90 delta = 13; 91 } 92 93 for (int i = 0; i != reps; i++) { 94 XCopyArea(xp->d, xp->w, xp->w, xp->fggc, x, y + delta, 95 size, size, x, y); 96 y += size; 97 if (y + size + delta > HEIGHT) { 98 yorg += delta; 99 if (yorg >= size || yorg + size + delta > HEIGHT) { 100 yorg = 0; 101 xorg++; 102 if (xorg >= size || xorg + size > WIDTH) { 103 xorg = 0; 104 } 105 } 106 y = yorg; 107 x += size; 108 if (x + size > WIDTH) { 109 x = xorg; 110 } 111 } 112 CheckAbort (); 113 } 114} 115 116void 117MidScroll(XParms xp, Parms p) 118{ 119 XClearWindow(xp->d, xp->w); 120 XDrawLines(xp->d, xp->w, xp->fggc, points, NUMPOINTS, CoordModeOrigin); 121} 122 123void 124EndScroll(XParms xp, Parms p) 125{ 126} 127 128static void 129InitCopyLocations(int size, int mul, int div, 130 int64_t reps, XSegment **ap, XSegment **bp) 131{ 132 int x1, y1, x2, y2; 133 int xinc, yinc; 134 int width, height; 135 XSegment *a, *b; 136 137 size = size * mul / div; 138 /* Try to exercise all alignments of src and destination equally, as well 139 as all 4 top-to-bottom/bottom-to-top, left-to-right, right-to-left 140 copying directions. Computation done here just to make sure slow 141 machines aren't measuring anything but the XCopyArea calls. 142 */ 143 xinc = (size & ~3) + 1; 144 yinc = xinc + 3; 145 146 width = (WIDTH - size) & ~31; 147 height = (HEIGHT - size) & ~31; 148 149 x1 = 0; 150 y1 = 0; 151 x2 = width; 152 y2 = height; 153 154 *ap = a = malloc(reps * sizeof(XSegment)); 155 *bp = b = malloc(reps * sizeof(XSegment)); 156 for (int i = 0; i != reps; i++) { 157 a[i].x1 = x1 * div / mul; 158 a[i].y1 = y1 * div / mul; 159 a[i].x2 = x2 * div / mul; 160 a[i].y2 = y2 * div / mul; 161 162 /* Move x2, y2, location backward */ 163 x2 -= xinc; 164 if (x2 < 0) { 165 x2 = NegMod(x2, width); 166 y2 -= yinc; 167 if (y2 < 0) { 168 y2 = NegMod(y2, height); 169 } 170 } 171 172 b[i].x1 = x1 * div / mul; 173 b[i].y1 = y1 * div / mul; 174 b[i].x2 = x2 * div / mul; 175 b[i].y2 = y2 * div / mul; 176 177 /* Move x1, y1 location forward */ 178 x1 += xinc; 179 if (x1 > width) { 180 x1 %= 32; 181 y1 += yinc; 182 if (y1 > height) { 183 y1 %= 32; 184 } 185 } 186 } /* end for */ 187} 188 189 190int 191InitCopyWin(XParms xp, Parms p, int64_t reps) 192{ 193 (void) InitScroll(xp, p, reps); 194 InitCopyLocations(p->special, 1, 1, reps, &segsa, &segsb); 195 return reps; 196} 197 198int 199InitCopyPix(XParms xp, Parms p, int64_t reps) 200{ 201 GC pixgc; 202 (void) InitCopyWin(xp, p, reps); 203 204 /* Create pixmap to write stuff into, and initialize it */ 205 pix = XCreatePixmap(xp->d, xp->w, WIDTH, HEIGHT, xp->vinfo.depth); 206 pixgc = XCreateGC(xp->d, pix, 0, NULL); 207 /* need a gc with GXcopy cos pixmaps contain junk on creation. mmm */ 208 XCopyArea(xp->d, xp->w, pix, pixgc, 0, 0, WIDTH, HEIGHT, 0, 0); 209 XFreeGC(xp->d, pixgc); 210 return reps; 211} 212 213static int 214InitImage(XParms xp, Parms p, int64_t reps, long pm) 215{ 216 (void) InitCopyWin(xp, p, reps); 217 218 /* Create image to stuff bits into */ 219 image = XGetImage(xp->d, xp->w, 0, 0, WIDTH, HEIGHT, pm, 220 p->font==NULL ? ZPixmap : (strcmp(p->font, "XY") == 0? XYPixmap : ZPixmap)); 221 if(image==NULL){ 222 printf("XGetImage failed\n"); 223 return False; 224 } 225 if (p->font && !strcmp(p->font, "XYBitmap")) { 226 int bytes_per_line = (WIDTH + 31) / 8; 227 char *data = malloc (bytes_per_line * HEIGHT); 228 XImage *new = XCreateImage(xp->d, xp->vinfo.visual, 1, XYBitmap, 0, 229 data, WIDTH, HEIGHT, 32, bytes_per_line); 230 int x, y; 231 unsigned long zero_pixel; 232 int has_zero = 0; 233 234 for (y = 0; y < HEIGHT; y++) 235 for (x = 0; x < WIDTH; x++) { 236 unsigned long src_pixel = XGetPixel(image, x, y); 237 unsigned long dst_pixel = 0; 238 if (!has_zero) { 239 zero_pixel = src_pixel; 240 has_zero = 1; 241 } 242 if (src_pixel == zero_pixel) 243 dst_pixel = 0; 244 else 245 dst_pixel = 1; 246 XPutPixel(new, x, y, dst_pixel); 247 } 248 XDestroyImage(image); 249 image = new; 250 } 251 return reps; 252} 253 254int 255InitGetImage(XParms xp, Parms p, int64_t reps) 256{ 257 return InitImage(xp, p, reps, xp->planemask); 258} 259 260int 261InitPutImage(XParms xp, Parms p, int64_t reps) 262{ 263 if(!InitImage(xp, p, reps, 0xffffffff))return False; 264 XClearWindow(xp->d, xp->w); 265 return reps; 266} 267 268static void 269CopyArea(XParms xp, Parms p, int64_t reps, Drawable src, Drawable dst) 270{ 271 int i, size; 272 XSegment *sa, *sb; 273 274 size = p->special; 275 for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) { 276 XCopyArea(xp->d, src, dst, xp->fggc, 277 sa->x1, sa->y1, size, size, sa->x2, sa->y2); 278 XCopyArea(xp->d, src, dst, xp->fggc, 279 sa->x2, sa->y2, size, size, sa->x1, sa->y1); 280 XCopyArea(xp->d, src, dst, xp->fggc, 281 sb->x2, sb->y2, size, size, sb->x1, sb->y1); 282 XCopyArea(xp->d, src, dst, xp->fggc, 283 sb->x1, sb->y1, size, size, sb->x2, sb->y2); 284 CheckAbort (); 285 } 286} 287 288void 289DoCopyWinWin(XParms xp, Parms p, int64_t reps) 290{ 291 CopyArea(xp, p, reps, xp->w, xp->w); 292} 293 294void 295DoCopyPixWin(XParms xp, Parms p, int64_t reps) 296{ 297 CopyArea(xp, p, reps, pix, xp->w); 298} 299 300void 301DoCopyWinPix(XParms xp, Parms p, int64_t reps) 302{ 303 CopyArea(xp, p, reps, xp->w, pix); 304 xp->p = pix; /* HardwareSync will now sync on pixmap */ 305} 306 307void 308DoCopyPixPix(XParms xp, Parms p, int64_t reps) 309{ 310 CopyArea(xp, p, reps, pix, pix); 311 xp->p = pix; /* HardwareSync will now sync on pixmap */ 312} 313 314void 315DoGetImage(XParms xp, Parms p, int64_t reps) 316{ 317 int i, size; 318 XSegment *sa, *sb; 319 int format; 320 321 size = p->special; 322 format = (p->font == NULL) ? ZPixmap : XYPixmap; 323 for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) { 324 XDestroyImage(image); 325 image = XGetImage(xp->d, xp->w, sa->x1, sa->y1, size, size, 326 xp->planemask, format); 327 if (image) XDestroyImage(image); 328 image = XGetImage(xp->d, xp->w, sa->x2, sa->y2, size, size, 329 xp->planemask, format); 330 if (image) XDestroyImage(image); 331 image = XGetImage(xp->d, xp->w, sb->x2, sb->y2, size, size, 332 xp->planemask, format); 333 if (image) XDestroyImage(image); 334 image = XGetImage(xp->d, xp->w, sb->x1, sb->y1, size, size, 335 xp->planemask, format); 336/* 337 338One might expect XGetSubImage to be slightly faster than XGetImage. Go look 339at the code in Xlib. MIT X11R3 ran approximately 30 times slower for a 500x500 340rectangle. 341 342 (void) XGetSubImage(xp->d, xp->w, sa->x1, sa->y1, size, size, 343 xp->planemask, ZPixmap, image, sa->x2, sa->y2); 344 (void) XGetSubImage(xp->d, xp->w, sa->x2, sa->y2, size, size, 345 xp->planemask, ZPixmap, image, sa->x1, sa->y1); 346 (void) XGetSubImage(xp->d, xp->w, sb->x2, sb->y2, size, size, 347 xp->planemask, ZPixmap, image, sb->x2, sb->y2); 348 (void) XGetSubImage(xp->d, xp->w, sb->x1, sb->y1, size, size, 349 xp->planemask, ZPixmap, image, sb->x2, sb->y2); 350*/ 351 CheckAbort (); 352 } 353} 354 355void 356DoPutImage(XParms xp, Parms p, int64_t reps) 357{ 358 int i, size; 359 XSegment *sa, *sb; 360 361 size = p->special; 362 for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) { 363 XPutImage(xp->d, xp->w, xp->fggc, image, 364 sa->x1, sa->y1, sa->x2, sa->y2, size, size); 365 XPutImage(xp->d, xp->w, xp->fggc, image, 366 sa->x2, sa->y2, sa->x1, sa->y1, size, size); 367 XPutImage(xp->d, xp->w, xp->fggc, image, 368 sb->x2, sb->y2, sb->x2, sb->y2, size, size); 369 XPutImage(xp->d, xp->w, xp->fggc, image, 370 sb->x1, sb->y1, sb->x2, sb->y2, size, size); 371 CheckAbort (); 372 } 373} 374 375#ifdef MITSHM 376 377#include <sys/types.h> 378#ifndef Lynx 379#include <sys/ipc.h> 380#include <sys/shm.h> 381#else 382#include <ipc.h> 383#include <shm.h> 384#endif 385#include <X11/extensions/XShm.h> 386 387static XImage shm_image; 388static XShmSegmentInfo shm_info; 389 390static int haderror; 391static int (*origerrorhandler)(Display *, XErrorEvent *); 392 393static int 394shmerrorhandler(Display *d, XErrorEvent *e) 395{ 396 haderror++; 397 if(e->error_code==BadAccess) { 398 fprintf(stderr,"failed to attach shared memory\n"); 399 return 0; 400 } else 401 return (*origerrorhandler)(d,e); 402} 403 404static int 405InitShmImage(XParms xp, Parms p, int64_t reps, Bool read_only) 406{ 407 int image_size; 408 409 if(!InitImage(xp, p, reps, 0xffffffff))return False; 410 if (!XShmQueryExtension(xp->d)) { 411 /* 412 * Clean up here because cleanup function is not called if this 413 * function fails 414 */ 415 if (image) 416 XDestroyImage(image); 417 image = NULL; 418 free(segsa); 419 free(segsb); 420 return False; 421 } 422 shm_image = *image; 423 image_size = image->bytes_per_line * image->height; 424 /* allow XYPixmap choice: */ 425 if(p->font && strcmp(p->font, "XYBitmap") != 0) image_size *= xp->vinfo.depth; 426 shm_info.shmid = shmget(IPC_PRIVATE, image_size, IPC_CREAT|0777); 427 if (shm_info.shmid < 0) 428 { 429 /* 430 * Clean up here because cleanup function is not called if this 431 * function fails 432 */ 433 if (image) 434 XDestroyImage(image); 435 image = NULL; 436 free(segsa); 437 free(segsb); 438 perror ("shmget"); 439 return False; 440 } 441 shm_info.shmaddr = (char *) shmat(shm_info.shmid, NULL, 0); 442 if (shm_info.shmaddr == ((char *) -1)) 443 { 444 /* 445 * Clean up here because cleanup function is not called if this 446 * function fails 447 */ 448 if (image) 449 XDestroyImage(image); 450 image = NULL; 451 free(segsa); 452 free(segsb); 453 perror ("shmat"); 454 shmctl (shm_info.shmid, IPC_RMID, NULL); 455 return False; 456 } 457 shm_info.readOnly = read_only; 458 XSync(xp->d,True); 459 haderror = False; 460 origerrorhandler = XSetErrorHandler(shmerrorhandler); 461 XShmAttach (xp->d, &shm_info); 462 XSync(xp->d,True); /* wait for error or ok */ 463 XSetErrorHandler(origerrorhandler); 464 if(haderror){ 465 /* 466 * Clean up here because cleanup function is not called if this 467 * function fails 468 */ 469 if (image) 470 XDestroyImage(image); 471 image = NULL; 472 free(segsa); 473 free(segsb); 474 if(shmdt (shm_info.shmaddr)==-1) 475 perror("shmdt:"); 476 if(shmctl (shm_info.shmid, IPC_RMID, NULL)==-1) 477 perror("shmctl rmid:"); 478 return False; 479 } 480 shm_image.data = shm_info.shmaddr; 481 memmove( shm_image.data, image->data, image_size); 482 shm_image.obdata = (char *) &shm_info; 483 return reps; 484} 485 486int 487InitShmPutImage(XParms xp, Parms p, int64_t reps) 488{ 489 if (!InitShmImage(xp, p, reps, True)) return False; 490 XClearWindow(xp->d, xp->w); 491 return reps; 492} 493 494int 495InitShmGetImage(XParms xp, Parms p, int64_t reps) 496{ 497 return InitShmImage(xp, p, reps, False); 498} 499 500void 501DoShmPutImage(XParms xp, Parms p, int64_t reps) 502{ 503 int i, size; 504 XSegment *sa, *sb; 505 506 size = p->special; 507 for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) { 508 XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image, 509 sa->x1, sa->y1, sa->x2, sa->y2, size, size, False); 510 XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image, 511 sa->x2, sa->y2, sa->x1, sa->y1, size, size, False); 512 XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image, 513 sb->x2, sb->y2, sb->x2, sb->y2, size, size, False); 514 XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image, 515 sb->x1, sb->y1, sb->x2, sb->y2, size, size, False); 516 CheckAbort (); 517 } 518} 519 520void 521DoShmGetImage(XParms xp, Parms p, int64_t reps) 522{ 523 int i, size; 524 XSegment *sa, *sb; 525 526 size = p->special; 527 528 shm_image.width = size; 529 shm_image.height = size; 530 531 for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) { 532 /* compute offsets into image data? */ 533 XShmGetImage(xp->d, xp->w, &shm_image, sa->x1, sa->y1, xp->planemask); 534 XShmGetImage(xp->d, xp->w, &shm_image, sa->x2, sa->y2, xp->planemask); 535 XShmGetImage(xp->d, xp->w, &shm_image, sb->x2, sb->y2, xp->planemask); 536 XShmGetImage(xp->d, xp->w, &shm_image, sb->x1, sb->y1, xp->planemask); 537 CheckAbort (); 538 } 539} 540 541static void 542EndShmImage(XParms xp, Parms p) 543{ 544 EndGetImage (xp, p); 545 XShmDetach (xp->d, &shm_info); 546 XSync(xp->d, False); /* need server to detach so can remove id */ 547 if(shmdt (shm_info.shmaddr)==-1) 548 perror("shmdt:"); 549 if(shmctl (shm_info.shmid, IPC_RMID, NULL)==-1) 550 perror("shmctl rmid:"); 551} 552 553void 554EndShmGetImage(XParms xp, Parms p) 555{ 556 EndShmImage(xp, p); 557} 558 559void 560EndShmPutImage(XParms xp, Parms p) 561{ 562 EndShmImage(xp, p); 563} 564#endif 565 566 567void 568MidCopyPix(XParms xp, Parms p) 569{ 570 XClearWindow(xp->d, xp->w); 571} 572 573void 574EndCopyWin(XParms xp, Parms p) 575{ 576 EndScroll(xp, p); 577 free(segsa); 578 free(segsb); 579 if (segsa2) 580 free (segsa2); 581 if (segsb2) 582 free (segsb2); 583 segsa = segsb = segsa2 = segsb2 = NULL; 584} 585 586void 587EndCopyPix(XParms xp, Parms p) 588{ 589 EndCopyWin(xp, p); 590 XFreePixmap(xp->d, pix); 591 /* 592 * Ensure that the next test doesn't try and sync on the pixmap 593 */ 594 xp->p = (Pixmap)0; 595} 596 597void 598EndGetImage(XParms xp, Parms p) 599{ 600 EndCopyWin(xp, p); 601 if (image) XDestroyImage(image); 602} 603 604int 605InitCopyPlane(XParms xp, Parms p, int64_t reps) 606{ 607 XGCValues gcv; 608 GC pixgc; 609 610 InitBltLines(); 611 InitCopyLocations(p->special, 1, 1, reps, &segsa, &segsb); 612 613 /* Create pixmap to write stuff into, and initialize it */ 614 pix = XCreatePixmap(xp->d, xp->w, WIDTH, HEIGHT, 615 p->font==NULL ? 1 : xp->vinfo.depth); 616 gcv.graphics_exposures = False; 617 gcv.foreground = 0; 618 gcv.background = 1; 619 pixgc = XCreateGC(xp->d, pix, 620 GCForeground | GCBackground | GCGraphicsExposures, &gcv); 621 XFillRectangle(xp->d, pix, pixgc, 0, 0, WIDTH, HEIGHT); 622 gcv.foreground = 1; 623 gcv.background = 0; 624 XChangeGC(xp->d, pixgc, GCForeground | GCBackground, &gcv); 625 XDrawLines(xp->d, pix, pixgc, points, NUMPOINTS, CoordModeOrigin); 626 XFreeGC(xp->d, pixgc); 627 628 return reps; 629} 630 631void 632DoCopyPlane(XParms xp, Parms p, int64_t reps) 633{ 634 int i, size; 635 XSegment *sa, *sb; 636 637 size = p->special; 638 for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) { 639 XCopyPlane(xp->d, pix, xp->w, xp->fggc, 640 sa->x1, sa->y1, size, size, sa->x2, sa->y2, 1); 641 XCopyPlane(xp->d, pix, xp->w, xp->fggc, 642 sa->x2, sa->y2, size, size, sa->x1, sa->y1, 1); 643 XCopyPlane(xp->d, pix, xp->w, xp->fggc, 644 sb->x2, sb->y2, size, size, sb->x1, sb->y1, 1); 645 XCopyPlane(xp->d, pix, xp->w, xp->fggc, 646 sb->x1, sb->y1, size, size, sb->x2, sb->y2, 1); 647 CheckAbort (); 648 } 649} 650 651#include <X11/extensions/Xrender.h> 652 653static Picture winPict, pixPict; 654 655int 656InitCompositeWin(XParms xp, Parms p, int64_t reps) 657{ 658 XRenderPictFormat *format; 659 660 (void) InitScroll (xp, p, reps); 661 InitCopyLocations(p->special, 1, 1, reps, &segsa, &segsb); 662 if (p->fillStyle) { 663 int mul = 0x10000; 664 int div = p->fillStyle; 665 InitCopyLocations (p->special, mul, div, reps, &segsa2, &segsb2); 666 } 667 format = XRenderFindVisualFormat (xp->d, xp->vinfo.visual); 668 winPict = XRenderCreatePicture (xp->d, xp->w, format, 0, NULL); 669 return reps; 670} 671 672int 673InitCompositePix(XParms xp, Parms p, int64_t reps) 674{ 675 XRenderPictFormat *format = NULL; 676 int depth; 677 static XRenderColor c = { 0xffff, 0x0000, 0xffff, 0xffff }; 678 679 (void) InitCompositeWin (xp, p, reps); 680 681 /* Create pixmap to write stuff into, and initialize it */ 682 switch (xp->planemask) { 683 case PictStandardNative: 684 depth = xp->vinfo.depth; 685 format = XRenderFindVisualFormat (xp->d, xp->vinfo.visual); 686 break; 687 case PictStandardRGB24: 688 depth = 24; 689 break; 690 case PictStandardARGB32: 691 depth = 32; 692 break; 693 case PictStandardA8: 694 depth = 8; 695 break; 696 case PictStandardA4: 697 depth = 4; 698 break; 699 case PictStandardA1: 700 depth = 1; 701 break; 702 default: 703 depth = 0; 704 break; 705 } 706 if (!format) 707 format = XRenderFindStandardFormat (xp->d, xp->planemask); 708 709 pix = XCreatePixmap(xp->d, xp->w, WIDTH, HEIGHT, depth); 710 pixPict = XRenderCreatePicture (xp->d, pix, format, 0, NULL); 711 712 XRenderComposite (xp->d, PictOpClear, 713 winPict, None, pixPict, 714 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 715 716 XRenderFillRectangle (xp->d, PictOpSrc, 717 pixPict, &c, 0, 0, WIDTH, HEIGHT); 718#if 1 719 XRenderComposite (xp->d, PictOpSrc, 720 winPict, None, pixPict, 721 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 722#endif 723 if (p->fillStyle) { 724 XTransform transform; 725 memset (&transform, '\0', sizeof (transform)); 726 transform.matrix[0][0] = ((long long) 0x10000 * 0x10000) / p->fillStyle; 727 transform.matrix[1][1] = ((long long) 0x10000 * 0x10000) / p->fillStyle; 728 transform.matrix[2][2] = 0x10000; 729 XRenderSetPictureTransform (xp->d, pixPict, &transform); 730 XRenderSetPictureFilter (xp->d, pixPict, FilterBilinear, NULL, 0); 731 } 732 return reps; 733} 734 735void 736EndCompositeWin (XParms xp, Parms p) 737{ 738 if (winPict) 739 { 740 XRenderFreePicture (xp->d, winPict); 741 winPict = None; 742 } 743 if (pixPict) 744 { 745 XRenderFreePicture (xp->d, pixPict); 746 pixPict = None; 747 } 748} 749 750static void 751CompositeArea(XParms xp, Parms p, int64_t reps, Picture src, Picture dst) 752{ 753 int size; 754 XSegment *sa, *sb; 755 XSegment *sa2, *sb2; 756 757 758 size = p->special; 759 sa = segsa; 760 sb = segsb; 761 sa2 = segsa2 ? segsa2 : segsa; 762 sb2 = segsb2 ? segsb2 : segsb; 763 for (int i = 0; i < reps; i++) { 764 XRenderComposite (xp->d, xp->func, 765 src, None, dst, 766 sa2->x1, sa2->y1, 0, 0, sa->x2, sa->y2, size, size); 767 XRenderComposite (xp->d, xp->func, 768 src, None, dst, 769 sa2->x2, sa2->y2, 0, 0, sa->x1, sa->y1, size, size); 770 XRenderComposite (xp->d, xp->func, 771 src, None, dst, 772 sb2->x2, sb2->y2, 0, 0, sb->x1, sb->y1, size, size); 773 XRenderComposite (xp->d, xp->func, 774 src, None, dst, 775 sb2->x1, sb2->y1, 0, 0, sb->x2, sb->y2, size, size); 776 CheckAbort (); 777 sa++; sb++; 778 sa2++; sb2++; 779 } 780} 781 782void 783DoCompositeWinWin (XParms xp, Parms p, int64_t reps) 784{ 785 CompositeArea (xp, p, reps, winPict, winPict); 786} 787 788void 789DoCompositePixWin (XParms xp, Parms p, int64_t reps) 790{ 791 CompositeArea (xp, p, reps, pixPict, winPict); 792} 793