do_blt.c revision 533545b5
1264fa531Smrg/***************************************************************************** 2264fa531SmrgCopyright 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts. 3264fa531Smrg 4264fa531Smrg All Rights Reserved 5264fa531Smrg 6264fa531SmrgPermission to use, copy, modify, and distribute this software and its 7264fa531Smrgdocumentation for any purpose and without fee is hereby granted, 8264fa531Smrgprovided that the above copyright notice appear in all copies and that 9264fa531Smrgboth that copyright notice and this permission notice appear in 10264fa531Smrgsupporting documentation, and that the name of Digital not be 11264fa531Smrgused in advertising or publicity pertaining to distribution of the 12264fa531Smrgsoftware without specific, written prior permission. 13264fa531Smrg 14264fa531SmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 15264fa531SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 16264fa531SmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 17264fa531SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 18264fa531SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 19264fa531SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 20264fa531SmrgSOFTWARE. 21264fa531Smrg 22264fa531Smrg******************************************************************************/ 23264fa531Smrg 24264fa531Smrg#include "x11perf.h" 25264fa531Smrg#include <stdio.h> 26264fa531Smrg 27264fa531Smrg#define NUMPOINTS 100 28264fa531Smrg 29264fa531Smrgstatic Pixmap pix; 30264fa531Smrgstatic XImage *image; 31264fa531Smrgstatic XPoint points[NUMPOINTS]; 32264fa531Smrgstatic XSegment *segsa, *segsb; 33533545b5Smrgstatic XSegment *segsa2, *segsb2; 34264fa531Smrg 35264fa531Smrg#define NegMod(x, y) ((y) - (((-x)-1) % (7)) - 1) 36264fa531Smrg 37264fa531Smrgstatic void 38264fa531SmrgInitBltLines(void) 39264fa531Smrg{ 40264fa531Smrg int i, x, y; 41264fa531Smrg 42264fa531Smrg points[0].x = points[0].y = y = 0; 43264fa531Smrg for (i = 1; i != NUMPOINTS/2; i++) { 44264fa531Smrg if (i & 1) { 45264fa531Smrg points[i].x = WIDTH-1; 46264fa531Smrg } else { 47264fa531Smrg points[i].x = 0; 48264fa531Smrg } 49264fa531Smrg y += HEIGHT / (NUMPOINTS/2); 50264fa531Smrg points[i].y = y; 51264fa531Smrg } 52264fa531Smrg 53264fa531Smrg x = 0; 54264fa531Smrg for (i = NUMPOINTS/2; i!= NUMPOINTS; i++) { 55264fa531Smrg if (i & 1) { 56264fa531Smrg points[i].y = HEIGHT-1; 57264fa531Smrg } else { 58264fa531Smrg points[i].y = 0; 59264fa531Smrg } 60264fa531Smrg x += WIDTH / (NUMPOINTS/2); 61264fa531Smrg points[i].x = x; 62264fa531Smrg } 63264fa531Smrg} 64264fa531Smrg 65264fa531Smrgint 66533545b5SmrgInitScroll(XParms xp, Parms p, int64_t reps) 67264fa531Smrg{ 68264fa531Smrg InitBltLines(); 69264fa531Smrg XDrawLines(xp->d, xp->w, xp->fggc, points, NUMPOINTS, CoordModeOrigin); 70264fa531Smrg return reps; 71264fa531Smrg} 72264fa531Smrg 73264fa531Smrgvoid 74533545b5SmrgDoScroll(XParms xp, Parms p, int64_t reps) 75264fa531Smrg{ 76264fa531Smrg int i, size, x, y, xorg, yorg, delta; 77264fa531Smrg 78264fa531Smrg size = p->special; 79264fa531Smrg xorg = 0; yorg = 0; 80264fa531Smrg x = 0; y = 0; 81264fa531Smrg if (xp->version == VERSION1_2) { 82264fa531Smrg delta = 1; 83264fa531Smrg } else { 84264fa531Smrg /* Version 1.2 only scrolled up by 1 scanline, which made hardware 85264fa531Smrg using page-mode access to VRAM look better on paper than it would 86264fa531Smrg perform in a more realistic scroll. So we've changed to scroll by 87264fa531Smrg the height of the 6x13 fonts. */ 88264fa531Smrg delta = 13; 89264fa531Smrg } 90264fa531Smrg 91264fa531Smrg for (i = 0; i != reps; i++) { 92264fa531Smrg XCopyArea(xp->d, xp->w, xp->w, xp->fggc, x, y + delta, 93264fa531Smrg size, size, x, y); 94264fa531Smrg y += size; 95264fa531Smrg if (y + size + delta > HEIGHT) { 96264fa531Smrg yorg += delta; 97264fa531Smrg if (yorg >= size || yorg + size + delta > HEIGHT) { 98264fa531Smrg yorg = 0; 99264fa531Smrg xorg++; 100264fa531Smrg if (xorg >= size || xorg + size > WIDTH) { 101264fa531Smrg xorg = 0; 102264fa531Smrg } 103264fa531Smrg } 104264fa531Smrg y = yorg; 105264fa531Smrg x += size; 106264fa531Smrg if (x + size > WIDTH) { 107264fa531Smrg x = xorg; 108264fa531Smrg } 109264fa531Smrg } 110264fa531Smrg CheckAbort (); 111264fa531Smrg } 112264fa531Smrg} 113264fa531Smrg 114264fa531Smrgvoid 115264fa531SmrgMidScroll(XParms xp, Parms p) 116264fa531Smrg{ 117264fa531Smrg XClearWindow(xp->d, xp->w); 118264fa531Smrg XDrawLines(xp->d, xp->w, xp->fggc, points, NUMPOINTS, CoordModeOrigin); 119264fa531Smrg} 120264fa531Smrg 121264fa531Smrgvoid 122264fa531SmrgEndScroll(XParms xp, Parms p) 123264fa531Smrg{ 124264fa531Smrg} 125264fa531Smrg 126264fa531Smrgstatic void 127533545b5SmrgInitCopyLocations(int size, int mul, int div, 128533545b5Smrg int64_t reps, XSegment **ap, XSegment **bp) 129264fa531Smrg{ 130533545b5Smrg int x1, y1, x2, y2, i; 131264fa531Smrg int xinc, yinc; 132264fa531Smrg int width, height; 133533545b5Smrg XSegment *a, *b; 134264fa531Smrg 135533545b5Smrg size = size * mul / div; 136264fa531Smrg /* Try to exercise all alignments of src and destination equally, as well 137264fa531Smrg as all 4 top-to-bottom/bottom-to-top, left-to-right, right-to-left 138264fa531Smrg copying directions. Computation done here just to make sure slow 139264fa531Smrg machines aren't measuring anything but the XCopyArea calls. 140264fa531Smrg */ 141264fa531Smrg xinc = (size & ~3) + 1; 142264fa531Smrg yinc = xinc + 3; 143264fa531Smrg 144264fa531Smrg width = (WIDTH - size) & ~31; 145264fa531Smrg height = (HEIGHT - size) & ~31; 146264fa531Smrg 147264fa531Smrg x1 = 0; 148264fa531Smrg y1 = 0; 149264fa531Smrg x2 = width; 150264fa531Smrg y2 = height; 151264fa531Smrg 152533545b5Smrg *ap = a = (XSegment *)malloc(reps * sizeof(XSegment)); 153533545b5Smrg *bp = b = (XSegment *)malloc(reps * sizeof(XSegment)); 154264fa531Smrg for (i = 0; i != reps; i++) { 155533545b5Smrg a[i].x1 = x1 * div / mul; 156533545b5Smrg a[i].y1 = y1 * div / mul; 157533545b5Smrg a[i].x2 = x2 * div / mul; 158533545b5Smrg a[i].y2 = y2 * div / mul; 159264fa531Smrg 160264fa531Smrg /* Move x2, y2, location backward */ 161264fa531Smrg x2 -= xinc; 162264fa531Smrg if (x2 < 0) { 163264fa531Smrg x2 = NegMod(x2, width); 164264fa531Smrg y2 -= yinc; 165264fa531Smrg if (y2 < 0) { 166264fa531Smrg y2 = NegMod(y2, height); 167264fa531Smrg } 168264fa531Smrg } 169264fa531Smrg 170533545b5Smrg b[i].x1 = x1 * div / mul; 171533545b5Smrg b[i].y1 = y1 * div / mul; 172533545b5Smrg b[i].x2 = x2 * div / mul; 173533545b5Smrg b[i].y2 = y2 * div / mul; 174264fa531Smrg 175264fa531Smrg /* Move x1, y1 location forward */ 176264fa531Smrg x1 += xinc; 177264fa531Smrg if (x1 > width) { 178264fa531Smrg x1 %= 32; 179264fa531Smrg y1 += yinc; 180264fa531Smrg if (y1 > height) { 181264fa531Smrg y1 %= 32; 182264fa531Smrg } 183264fa531Smrg } 184264fa531Smrg } /* end for */ 185264fa531Smrg} 186264fa531Smrg 187264fa531Smrg 188264fa531Smrgint 189533545b5SmrgInitCopyWin(XParms xp, Parms p, int64_t reps) 190264fa531Smrg{ 191264fa531Smrg (void) InitScroll(xp, p, reps); 192533545b5Smrg InitCopyLocations(p->special, 1, 1, reps, &segsa, &segsb); 193264fa531Smrg return reps; 194264fa531Smrg} 195264fa531Smrg 196264fa531Smrgint 197533545b5SmrgInitCopyPix(XParms xp, Parms p, int64_t reps) 198264fa531Smrg{ 199264fa531Smrg GC pixgc; 200264fa531Smrg (void) InitCopyWin(xp, p, reps); 201264fa531Smrg 202264fa531Smrg /* Create pixmap to write stuff into, and initialize it */ 203264fa531Smrg pix = XCreatePixmap(xp->d, xp->w, WIDTH, HEIGHT, xp->vinfo.depth); 204c37a63b8Smrg pixgc = XCreateGC(xp->d, pix, 0, NULL); 205264fa531Smrg /* need a gc with GXcopy cos pixmaps contain junk on creation. mmm */ 206264fa531Smrg XCopyArea(xp->d, xp->w, pix, pixgc, 0, 0, WIDTH, HEIGHT, 0, 0); 207264fa531Smrg XFreeGC(xp->d, pixgc); 208264fa531Smrg return reps; 209264fa531Smrg} 210264fa531Smrg 211264fa531Smrgint 212533545b5SmrgInitGetImage(XParms xp, Parms p, int64_t reps) 213264fa531Smrg{ 214264fa531Smrg (void) InitCopyWin(xp, p, reps); 215264fa531Smrg 216264fa531Smrg /* Create image to stuff bits into */ 217264fa531Smrg image = XGetImage(xp->d, xp->w, 0, 0, WIDTH, HEIGHT, xp->planemask, 218c37a63b8Smrg p->font==NULL?ZPixmap:XYPixmap); 219c37a63b8Smrg if(image==NULL){ 220264fa531Smrg printf("XGetImage failed\n"); 221264fa531Smrg return False; 222264fa531Smrg } 223264fa531Smrg return reps; 224264fa531Smrg} 225264fa531Smrg 226264fa531Smrgint 227533545b5SmrgInitPutImage(XParms xp, Parms p, int64_t reps) 228264fa531Smrg{ 229264fa531Smrg if(!InitGetImage(xp, p, reps))return False; 230264fa531Smrg XClearWindow(xp->d, xp->w); 231264fa531Smrg return reps; 232264fa531Smrg} 233264fa531Smrg 234264fa531Smrgstatic void 235533545b5SmrgCopyArea(XParms xp, Parms p, int64_t reps, Drawable src, Drawable dst) 236264fa531Smrg{ 237264fa531Smrg int i, size; 238264fa531Smrg XSegment *sa, *sb; 239264fa531Smrg 240264fa531Smrg size = p->special; 241264fa531Smrg for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) { 242264fa531Smrg XCopyArea(xp->d, src, dst, xp->fggc, 243264fa531Smrg sa->x1, sa->y1, size, size, sa->x2, sa->y2); 244264fa531Smrg XCopyArea(xp->d, src, dst, xp->fggc, 245264fa531Smrg sa->x2, sa->y2, size, size, sa->x1, sa->y1); 246264fa531Smrg XCopyArea(xp->d, src, dst, xp->fggc, 247264fa531Smrg sb->x2, sb->y2, size, size, sb->x1, sb->y1); 248264fa531Smrg XCopyArea(xp->d, src, dst, xp->fggc, 249264fa531Smrg sb->x1, sb->y1, size, size, sb->x2, sb->y2); 250264fa531Smrg CheckAbort (); 251264fa531Smrg } 252264fa531Smrg} 253264fa531Smrg 254264fa531Smrgvoid 255533545b5SmrgDoCopyWinWin(XParms xp, Parms p, int64_t reps) 256264fa531Smrg{ 257264fa531Smrg CopyArea(xp, p, reps, xp->w, xp->w); 258264fa531Smrg} 259264fa531Smrg 260264fa531Smrgvoid 261533545b5SmrgDoCopyPixWin(XParms xp, Parms p, int64_t reps) 262264fa531Smrg{ 263264fa531Smrg CopyArea(xp, p, reps, pix, xp->w); 264264fa531Smrg} 265264fa531Smrg 266264fa531Smrgvoid 267533545b5SmrgDoCopyWinPix(XParms xp, Parms p, int64_t reps) 268264fa531Smrg{ 269264fa531Smrg CopyArea(xp, p, reps, xp->w, pix); 270264fa531Smrg xp->p = pix; /* HardwareSync will now sync on pixmap */ 271264fa531Smrg} 272264fa531Smrg 273264fa531Smrgvoid 274533545b5SmrgDoCopyPixPix(XParms xp, Parms p, int64_t reps) 275264fa531Smrg{ 276264fa531Smrg CopyArea(xp, p, reps, pix, pix); 277264fa531Smrg xp->p = pix; /* HardwareSync will now sync on pixmap */ 278264fa531Smrg} 279264fa531Smrg 280264fa531Smrgvoid 281533545b5SmrgDoGetImage(XParms xp, Parms p, int64_t reps) 282264fa531Smrg{ 283264fa531Smrg int i, size; 284264fa531Smrg XSegment *sa, *sb; 285264fa531Smrg int format; 286264fa531Smrg 287264fa531Smrg size = p->special; 288c37a63b8Smrg format = (p->font == NULL) ? ZPixmap : XYPixmap; 289264fa531Smrg for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) { 290264fa531Smrg XDestroyImage(image); 291264fa531Smrg image = XGetImage(xp->d, xp->w, sa->x1, sa->y1, size, size, 292264fa531Smrg xp->planemask, format); 293264fa531Smrg if (image) XDestroyImage(image); 294264fa531Smrg image = XGetImage(xp->d, xp->w, sa->x2, sa->y2, size, size, 295264fa531Smrg xp->planemask, format); 296264fa531Smrg if (image) XDestroyImage(image); 297264fa531Smrg image = XGetImage(xp->d, xp->w, sb->x2, sb->y2, size, size, 298264fa531Smrg xp->planemask, format); 299264fa531Smrg if (image) XDestroyImage(image); 300264fa531Smrg image = XGetImage(xp->d, xp->w, sb->x1, sb->y1, size, size, 301264fa531Smrg xp->planemask, format); 302264fa531Smrg/* 303264fa531Smrg 304264fa531SmrgOne might expect XGetSubImage to be slightly faster than XGetImage. Go look 305264fa531Smrgat the code in Xlib. MIT X11R3 ran approximately 30 times slower for a 500x500 306264fa531Smrgrectangle. 307264fa531Smrg 308264fa531Smrg (void) XGetSubImage(xp->d, xp->w, sa->x1, sa->y1, size, size, 309264fa531Smrg xp->planemask, ZPixmap, image, sa->x2, sa->y2); 310264fa531Smrg (void) XGetSubImage(xp->d, xp->w, sa->x2, sa->y2, size, size, 311264fa531Smrg xp->planemask, ZPixmap, image, sa->x1, sa->y1); 312264fa531Smrg (void) XGetSubImage(xp->d, xp->w, sb->x2, sb->y2, size, size, 313264fa531Smrg xp->planemask, ZPixmap, image, sb->x2, sb->y2); 314264fa531Smrg (void) XGetSubImage(xp->d, xp->w, sb->x1, sb->y1, size, size, 315264fa531Smrg xp->planemask, ZPixmap, image, sb->x2, sb->y2); 316264fa531Smrg*/ 317264fa531Smrg CheckAbort (); 318264fa531Smrg } 319264fa531Smrg} 320264fa531Smrg 321264fa531Smrgvoid 322533545b5SmrgDoPutImage(XParms xp, Parms p, int64_t reps) 323264fa531Smrg{ 324264fa531Smrg int i, size; 325264fa531Smrg XSegment *sa, *sb; 326264fa531Smrg 327264fa531Smrg size = p->special; 328264fa531Smrg for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) { 329264fa531Smrg XPutImage(xp->d, xp->w, xp->fggc, image, 330264fa531Smrg sa->x1, sa->y1, sa->x2, sa->y2, size, size); 331264fa531Smrg XPutImage(xp->d, xp->w, xp->fggc, image, 332264fa531Smrg sa->x2, sa->y2, sa->x1, sa->y1, size, size); 333264fa531Smrg XPutImage(xp->d, xp->w, xp->fggc, image, 334264fa531Smrg sb->x2, sb->y2, sb->x2, sb->y2, size, size); 335264fa531Smrg XPutImage(xp->d, xp->w, xp->fggc, image, 336264fa531Smrg sb->x1, sb->y1, sb->x2, sb->y2, size, size); 337264fa531Smrg CheckAbort (); 338264fa531Smrg } 339264fa531Smrg} 340264fa531Smrg 341264fa531Smrg#ifdef MITSHM 342264fa531Smrg 343264fa531Smrg#include <sys/types.h> 344264fa531Smrg#ifndef Lynx 345264fa531Smrg#include <sys/ipc.h> 346264fa531Smrg#include <sys/shm.h> 347264fa531Smrg#else 348264fa531Smrg#include <ipc.h> 349264fa531Smrg#include <shm.h> 350264fa531Smrg#endif 351264fa531Smrg#include <X11/extensions/XShm.h> 352264fa531Smrg 353264fa531Smrgstatic XImage shm_image; 354264fa531Smrgstatic XShmSegmentInfo shm_info; 355264fa531Smrg 356264fa531Smrgstatic int haderror; 357264fa531Smrgstatic int (*origerrorhandler)(Display *, XErrorEvent *); 358264fa531Smrg 359264fa531Smrgstatic int 360264fa531Smrgshmerrorhandler(Display *d, XErrorEvent *e) 361264fa531Smrg{ 362264fa531Smrg haderror++; 363264fa531Smrg if(e->error_code==BadAccess) { 364264fa531Smrg fprintf(stderr,"failed to attach shared memory\n"); 365264fa531Smrg return 0; 366264fa531Smrg } else 367264fa531Smrg return (*origerrorhandler)(d,e); 368264fa531Smrg} 369264fa531Smrg 370e4ee1255Smrgstatic int 371533545b5SmrgInitShmImage(XParms xp, Parms p, int64_t reps, Bool read_only) 372264fa531Smrg{ 373264fa531Smrg int image_size; 374264fa531Smrg 375264fa531Smrg if(!InitGetImage(xp, p, reps))return False; 376264fa531Smrg if (!XShmQueryExtension(xp->d)) { 377264fa531Smrg /* 378264fa531Smrg * Clean up here because cleanup function is not called if this 379264fa531Smrg * function fails 380264fa531Smrg */ 381264fa531Smrg if (image) 382264fa531Smrg XDestroyImage(image); 383264fa531Smrg image = NULL; 384264fa531Smrg free(segsa); 385264fa531Smrg free(segsb); 386264fa531Smrg return False; 387264fa531Smrg } 388264fa531Smrg shm_image = *image; 389264fa531Smrg image_size = image->bytes_per_line * image->height; 390264fa531Smrg /* allow XYPixmap choice: */ 391264fa531Smrg if(p->font)image_size *= xp->vinfo.depth; 392264fa531Smrg shm_info.shmid = shmget(IPC_PRIVATE, image_size, IPC_CREAT|0777); 393264fa531Smrg if (shm_info.shmid < 0) 394264fa531Smrg { 395264fa531Smrg /* 396264fa531Smrg * Clean up here because cleanup function is not called if this 397264fa531Smrg * function fails 398264fa531Smrg */ 399264fa531Smrg if (image) 400264fa531Smrg XDestroyImage(image); 401264fa531Smrg image = NULL; 402264fa531Smrg free(segsa); 403264fa531Smrg free(segsb); 404264fa531Smrg perror ("shmget"); 405264fa531Smrg return False; 406264fa531Smrg } 407c37a63b8Smrg shm_info.shmaddr = (char *) shmat(shm_info.shmid, NULL, 0); 408264fa531Smrg if (shm_info.shmaddr == ((char *) -1)) 409264fa531Smrg { 410264fa531Smrg /* 411264fa531Smrg * Clean up here because cleanup function is not called if this 412264fa531Smrg * function fails 413264fa531Smrg */ 414264fa531Smrg if (image) 415264fa531Smrg XDestroyImage(image); 416264fa531Smrg image = NULL; 417264fa531Smrg free(segsa); 418264fa531Smrg free(segsb); 419264fa531Smrg perror ("shmat"); 420c37a63b8Smrg shmctl (shm_info.shmid, IPC_RMID, NULL); 421264fa531Smrg return False; 422264fa531Smrg } 423e4ee1255Smrg shm_info.readOnly = read_only; 424264fa531Smrg XSync(xp->d,True); 425264fa531Smrg haderror = False; 426264fa531Smrg origerrorhandler = XSetErrorHandler(shmerrorhandler); 427264fa531Smrg XShmAttach (xp->d, &shm_info); 428264fa531Smrg XSync(xp->d,True); /* wait for error or ok */ 429264fa531Smrg XSetErrorHandler(origerrorhandler); 430264fa531Smrg if(haderror){ 431264fa531Smrg /* 432264fa531Smrg * Clean up here because cleanup function is not called if this 433264fa531Smrg * function fails 434264fa531Smrg */ 435264fa531Smrg if (image) 436264fa531Smrg XDestroyImage(image); 437264fa531Smrg image = NULL; 438264fa531Smrg free(segsa); 439264fa531Smrg free(segsb); 440264fa531Smrg if(shmdt (shm_info.shmaddr)==-1) 441264fa531Smrg perror("shmdt:"); 442c37a63b8Smrg if(shmctl (shm_info.shmid, IPC_RMID, NULL)==-1) 443264fa531Smrg perror("shmctl rmid:"); 444264fa531Smrg return False; 445264fa531Smrg } 446264fa531Smrg shm_image.data = shm_info.shmaddr; 447264fa531Smrg memmove( shm_image.data, image->data, image_size); 448264fa531Smrg shm_image.obdata = (char *) &shm_info; 449264fa531Smrg return reps; 450264fa531Smrg} 451264fa531Smrg 452e4ee1255Smrgint 453533545b5SmrgInitShmPutImage(XParms xp, Parms p, int64_t reps) 454e4ee1255Smrg{ 455e4ee1255Smrg if (!InitShmImage(xp, p, reps, True)) return False; 456e4ee1255Smrg XClearWindow(xp->d, xp->w); 457e4ee1255Smrg return reps; 458e4ee1255Smrg} 459e4ee1255Smrg 460e4ee1255Smrgint 461533545b5SmrgInitShmGetImage(XParms xp, Parms p, int64_t reps) 462e4ee1255Smrg{ 463e4ee1255Smrg return InitShmImage(xp, p, reps, False); 464e4ee1255Smrg} 465e4ee1255Smrg 466533545b5Smrgvoid 467533545b5SmrgDoShmPutImage(XParms xp, Parms p, int64_t reps) 468264fa531Smrg{ 469264fa531Smrg int i, size; 470264fa531Smrg XSegment *sa, *sb; 471264fa531Smrg 472264fa531Smrg size = p->special; 473264fa531Smrg for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) { 474264fa531Smrg XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image, 475264fa531Smrg sa->x1, sa->y1, sa->x2, sa->y2, size, size, False); 476264fa531Smrg XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image, 477264fa531Smrg sa->x2, sa->y2, sa->x1, sa->y1, size, size, False); 478264fa531Smrg XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image, 479264fa531Smrg sb->x2, sb->y2, sb->x2, sb->y2, size, size, False); 480264fa531Smrg XShmPutImage(xp->d, xp->w, xp->fggc, &shm_image, 481264fa531Smrg sb->x1, sb->y1, sb->x2, sb->y2, size, size, False); 482264fa531Smrg CheckAbort (); 483264fa531Smrg } 484264fa531Smrg} 485264fa531Smrg 486e4ee1255Smrgvoid 487533545b5SmrgDoShmGetImage(XParms xp, Parms p, int64_t reps) 488264fa531Smrg{ 489e4ee1255Smrg int i, size; 490e4ee1255Smrg XSegment *sa, *sb; 491e4ee1255Smrg 492e4ee1255Smrg size = p->special; 493e4ee1255Smrg 494e4ee1255Smrg shm_image.width = size; 495e4ee1255Smrg shm_image.height = size; 496e4ee1255Smrg 497e4ee1255Smrg for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) { 498e4ee1255Smrg /* compute offsets into image data? */ 499e4ee1255Smrg XShmGetImage(xp->d, xp->w, &shm_image, sa->x1, sa->y1, xp->planemask); 500e4ee1255Smrg XShmGetImage(xp->d, xp->w, &shm_image, sa->x2, sa->y2, xp->planemask); 501e4ee1255Smrg XShmGetImage(xp->d, xp->w, &shm_image, sb->x2, sb->y2, xp->planemask); 502e4ee1255Smrg XShmGetImage(xp->d, xp->w, &shm_image, sb->x1, sb->y1, xp->planemask); 503e4ee1255Smrg CheckAbort (); 504e4ee1255Smrg } 505e4ee1255Smrg} 506264fa531Smrg 507e4ee1255Smrgstatic void 508e4ee1255SmrgEndShmImage(XParms xp, Parms p) 509e4ee1255Smrg{ 510264fa531Smrg EndGetImage (xp, p); 511264fa531Smrg XShmDetach (xp->d, &shm_info); 512264fa531Smrg XSync(xp->d, False); /* need server to detach so can remove id */ 513264fa531Smrg if(shmdt (shm_info.shmaddr)==-1) 514264fa531Smrg perror("shmdt:"); 515c37a63b8Smrg if(shmctl (shm_info.shmid, IPC_RMID, NULL)==-1) 516264fa531Smrg perror("shmctl rmid:"); 517264fa531Smrg} 518264fa531Smrg 519e4ee1255Smrgvoid 520e4ee1255SmrgEndShmGetImage(XParms xp, Parms p) 521e4ee1255Smrg{ 522e4ee1255Smrg EndShmImage(xp, p); 523e4ee1255Smrg} 524e4ee1255Smrg 525e4ee1255Smrgvoid 526e4ee1255SmrgEndShmPutImage(XParms xp, Parms p) 527e4ee1255Smrg{ 528e4ee1255Smrg EndShmImage(xp, p); 529e4ee1255Smrg} 530264fa531Smrg#endif 531264fa531Smrg 532264fa531Smrg 533264fa531Smrgvoid 534264fa531SmrgMidCopyPix(XParms xp, Parms p) 535264fa531Smrg{ 536264fa531Smrg XClearWindow(xp->d, xp->w); 537264fa531Smrg} 538264fa531Smrg 539264fa531Smrgvoid 540264fa531SmrgEndCopyWin(XParms xp, Parms p) 541264fa531Smrg{ 542264fa531Smrg EndScroll(xp, p); 543264fa531Smrg free(segsa); 544264fa531Smrg free(segsb); 545533545b5Smrg if (segsa2) 546533545b5Smrg free (segsa2); 547533545b5Smrg if (segsb2) 548533545b5Smrg free (segsb2); 549533545b5Smrg segsa = segsb = segsa2 = segsb2 = NULL; 550264fa531Smrg} 551264fa531Smrg 552264fa531Smrgvoid 553264fa531SmrgEndCopyPix(XParms xp, Parms p) 554264fa531Smrg{ 555264fa531Smrg EndCopyWin(xp, p); 556264fa531Smrg XFreePixmap(xp->d, pix); 557264fa531Smrg /* 558264fa531Smrg * Ensure that the next test doesn't try and sync on the pixmap 559264fa531Smrg */ 560264fa531Smrg xp->p = (Pixmap)0; 561264fa531Smrg} 562264fa531Smrg 563264fa531Smrgvoid 564264fa531SmrgEndGetImage(XParms xp, Parms p) 565264fa531Smrg{ 566264fa531Smrg EndCopyWin(xp, p); 567264fa531Smrg if (image) XDestroyImage(image); 568264fa531Smrg} 569264fa531Smrg 570264fa531Smrgint 571533545b5SmrgInitCopyPlane(XParms xp, Parms p, int64_t reps) 572264fa531Smrg{ 573264fa531Smrg XGCValues gcv; 574264fa531Smrg GC pixgc; 575264fa531Smrg 576264fa531Smrg InitBltLines(); 577533545b5Smrg InitCopyLocations(p->special, 1, 1, reps, &segsa, &segsb); 578264fa531Smrg 579264fa531Smrg /* Create pixmap to write stuff into, and initialize it */ 580264fa531Smrg pix = XCreatePixmap(xp->d, xp->w, WIDTH, HEIGHT, 581c37a63b8Smrg p->font==NULL ? 1 : xp->vinfo.depth); 582264fa531Smrg gcv.graphics_exposures = False; 583264fa531Smrg gcv.foreground = 0; 584264fa531Smrg gcv.background = 1; 585264fa531Smrg pixgc = XCreateGC(xp->d, pix, 586264fa531Smrg GCForeground | GCBackground | GCGraphicsExposures, &gcv); 587264fa531Smrg XFillRectangle(xp->d, pix, pixgc, 0, 0, WIDTH, HEIGHT); 588264fa531Smrg gcv.foreground = 1; 589264fa531Smrg gcv.background = 0; 590264fa531Smrg XChangeGC(xp->d, pixgc, GCForeground | GCBackground, &gcv); 591264fa531Smrg XDrawLines(xp->d, pix, pixgc, points, NUMPOINTS, CoordModeOrigin); 592264fa531Smrg XFreeGC(xp->d, pixgc); 593264fa531Smrg 594264fa531Smrg return reps; 595264fa531Smrg} 596264fa531Smrg 597264fa531Smrgvoid 598533545b5SmrgDoCopyPlane(XParms xp, Parms p, int64_t reps) 599264fa531Smrg{ 600264fa531Smrg int i, size; 601264fa531Smrg XSegment *sa, *sb; 602264fa531Smrg 603264fa531Smrg size = p->special; 604264fa531Smrg for (sa = segsa, sb = segsb, i = 0; i != reps; i++, sa++, sb++) { 605264fa531Smrg XCopyPlane(xp->d, pix, xp->w, xp->fggc, 606264fa531Smrg sa->x1, sa->y1, size, size, sa->x2, sa->y2, 1); 607264fa531Smrg XCopyPlane(xp->d, pix, xp->w, xp->fggc, 608264fa531Smrg sa->x2, sa->y2, size, size, sa->x1, sa->y1, 1); 609264fa531Smrg XCopyPlane(xp->d, pix, xp->w, xp->fggc, 610264fa531Smrg sb->x2, sb->y2, size, size, sb->x1, sb->y1, 1); 611264fa531Smrg XCopyPlane(xp->d, pix, xp->w, xp->fggc, 612264fa531Smrg sb->x1, sb->y1, size, size, sb->x2, sb->y2, 1); 613264fa531Smrg CheckAbort (); 614264fa531Smrg } 615264fa531Smrg} 616264fa531Smrg 617c37a63b8Smrg#include <X11/extensions/Xrender.h> 618c37a63b8Smrg 619c37a63b8Smrgstatic Picture winPict, pixPict; 620c37a63b8Smrg 621c37a63b8Smrgint 622533545b5SmrgInitCompositeWin(XParms xp, Parms p, int64_t reps) 623c37a63b8Smrg{ 624c37a63b8Smrg XRenderPictFormat *format; 625533545b5Smrg 626c37a63b8Smrg (void) InitScroll (xp, p, reps); 627533545b5Smrg InitCopyLocations(p->special, 1, 1, reps, &segsa, &segsb); 628533545b5Smrg if (p->fillStyle) { 629533545b5Smrg int mul = 0x10000; 630533545b5Smrg int div = p->fillStyle; 631533545b5Smrg InitCopyLocations (p->special, mul, div, reps, &segsa2, &segsb2); 632533545b5Smrg } 633c37a63b8Smrg format = XRenderFindVisualFormat (xp->d, xp->vinfo.visual); 634c37a63b8Smrg winPict = XRenderCreatePicture (xp->d, xp->w, format, 0, NULL); 635c37a63b8Smrg return reps; 636c37a63b8Smrg} 637c37a63b8Smrg 638c37a63b8Smrgint 639533545b5SmrgInitCompositePix(XParms xp, Parms p, int64_t reps) 640c37a63b8Smrg{ 641c37a63b8Smrg XRenderPictFormat *format = NULL; 642c37a63b8Smrg int depth; 643533545b5Smrg static XRenderColor c = { 0xffff, 0x0000, 0xffff, 0xffff }; 644c37a63b8Smrg 645c37a63b8Smrg (void) InitCompositeWin (xp, p, reps); 646c37a63b8Smrg 647c37a63b8Smrg /* Create pixmap to write stuff into, and initialize it */ 648c37a63b8Smrg switch (xp->planemask) { 649c37a63b8Smrg case PictStandardNative: 650c37a63b8Smrg depth = xp->vinfo.depth; 651c37a63b8Smrg format = XRenderFindVisualFormat (xp->d, xp->vinfo.visual); 652c37a63b8Smrg break; 653c37a63b8Smrg case PictStandardRGB24: 654c37a63b8Smrg depth = 24; 655c37a63b8Smrg break; 656c37a63b8Smrg case PictStandardARGB32: 657c37a63b8Smrg depth = 32; 658c37a63b8Smrg break; 659c37a63b8Smrg case PictStandardA8: 660c37a63b8Smrg depth = 8; 661c37a63b8Smrg break; 662c37a63b8Smrg case PictStandardA4: 663c37a63b8Smrg depth = 4; 664c37a63b8Smrg break; 665c37a63b8Smrg case PictStandardA1: 666c37a63b8Smrg depth = 1; 667c37a63b8Smrg break; 668c37a63b8Smrg default: 669c37a63b8Smrg depth = 0; 670c37a63b8Smrg break; 671c37a63b8Smrg } 672c37a63b8Smrg if (!format) 673c37a63b8Smrg format = XRenderFindStandardFormat (xp->d, xp->planemask); 674c37a63b8Smrg 675c37a63b8Smrg pix = XCreatePixmap(xp->d, xp->w, WIDTH, HEIGHT, depth); 676c37a63b8Smrg pixPict = XRenderCreatePicture (xp->d, pix, format, 0, NULL); 677c37a63b8Smrg 678c37a63b8Smrg XRenderComposite (xp->d, PictOpClear, 679c37a63b8Smrg winPict, None, pixPict, 680c37a63b8Smrg 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 681c37a63b8Smrg 682533545b5Smrg XRenderFillRectangle (xp->d, PictOpSrc, 683533545b5Smrg pixPict, &c, 0, 0, WIDTH, HEIGHT); 684c37a63b8Smrg#if 1 685533545b5Smrg XRenderComposite (xp->d, PictOpSrc, 686c37a63b8Smrg winPict, None, pixPict, 687c37a63b8Smrg 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 688c37a63b8Smrg#endif 689533545b5Smrg if (p->fillStyle) { 690533545b5Smrg XTransform transform; 691533545b5Smrg memset (&transform, '\0', sizeof (transform)); 692533545b5Smrg transform.matrix[0][0] = ((long long) 0x10000 * 0x10000) / p->fillStyle; 693533545b5Smrg transform.matrix[1][1] = ((long long) 0x10000 * 0x10000) / p->fillStyle; 694533545b5Smrg transform.matrix[2][2] = 0x10000; 695533545b5Smrg XRenderSetPictureTransform (xp->d, pixPict, &transform); 696533545b5Smrg XRenderSetPictureFilter (xp->d, pixPict, FilterBilinear, NULL, 0); 697533545b5Smrg } 698c37a63b8Smrg return reps; 699c37a63b8Smrg} 700c37a63b8Smrg 701c37a63b8Smrgvoid 702c37a63b8SmrgEndCompositeWin (XParms xp, Parms p) 703c37a63b8Smrg{ 704c37a63b8Smrg if (winPict) 705c37a63b8Smrg { 706c37a63b8Smrg XRenderFreePicture (xp->d, winPict); 707c37a63b8Smrg winPict = None; 708c37a63b8Smrg } 709c37a63b8Smrg if (pixPict) 710c37a63b8Smrg { 711c37a63b8Smrg XRenderFreePicture (xp->d, pixPict); 712c37a63b8Smrg pixPict = None; 713c37a63b8Smrg } 714c37a63b8Smrg} 715c37a63b8Smrg 716c37a63b8Smrgstatic void 717533545b5SmrgCompositeArea(XParms xp, Parms p, int64_t reps, Picture src, Picture dst) 718c37a63b8Smrg{ 719c37a63b8Smrg int i, size; 720c37a63b8Smrg XSegment *sa, *sb; 721533545b5Smrg XSegment *sa2, *sb2; 722533545b5Smrg 723c37a63b8Smrg 724c37a63b8Smrg size = p->special; 725533545b5Smrg sa = segsa; 726533545b5Smrg sb = segsb; 727533545b5Smrg sa2 = segsa2 ? segsa2 : segsa; 728533545b5Smrg sb2 = segsb2 ? segsb2 : segsb; 729533545b5Smrg for (i = 0; i < reps; i++) { 730c37a63b8Smrg XRenderComposite (xp->d, xp->func, 731c37a63b8Smrg src, None, dst, 732533545b5Smrg sa2->x1, sa2->y1, 0, 0, sa->x2, sa->y2, size, size); 733c37a63b8Smrg XRenderComposite (xp->d, xp->func, 734c37a63b8Smrg src, None, dst, 735533545b5Smrg sa2->x2, sa2->y2, 0, 0, sa->x1, sa->y1, size, size); 736c37a63b8Smrg XRenderComposite (xp->d, xp->func, 737c37a63b8Smrg src, None, dst, 738533545b5Smrg sb2->x2, sb2->y2, 0, 0, sb->x1, sb->y1, size, size); 739c37a63b8Smrg XRenderComposite (xp->d, xp->func, 740c37a63b8Smrg src, None, dst, 741533545b5Smrg sb2->x1, sb2->y1, 0, 0, sb->x2, sb->y2, size, size); 742c37a63b8Smrg CheckAbort (); 743533545b5Smrg sa++; sb++; 744533545b5Smrg sa2++; sb2++; 745c37a63b8Smrg } 746c37a63b8Smrg} 747c37a63b8Smrg 748c37a63b8Smrgvoid 749533545b5SmrgDoCompositeWinWin (XParms xp, Parms p, int64_t reps) 750c37a63b8Smrg{ 751c37a63b8Smrg CompositeArea (xp, p, reps, winPict, winPict); 752c37a63b8Smrg} 753c37a63b8Smrg 754c37a63b8Smrgvoid 755533545b5SmrgDoCompositePixWin (XParms xp, Parms p, int64_t reps) 756c37a63b8Smrg{ 757c37a63b8Smrg CompositeArea (xp, p, reps, pixPict, winPict); 758c37a63b8Smrg} 759