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