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