1 /*
2  * Copyright © 2005 Eric Anholt
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of Eric Anholt not be used in
9  * advertising or publicity pertaining to distribution of the software without
10  * specific, written prior permission.  Eric Anholt makes no
11  * representations about the suitability of this software for any purpose.  It
12  * is provided "as is" without express or implied warranty.
13  *
14  * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  */
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 
26 #include "rendercheck.h"
27 
28 /* Test a composite of a given operation, source, and destination picture.  */
29 Bool
blend_test(Display * dpy,picture_info * win,picture_info * dst,const int * op,int num_op,const picture_info ** src_color,int num_src,const picture_info ** dst_color,int num_dst)30 blend_test(Display *dpy, picture_info *win, picture_info *dst,
31 	   const int *op, int num_op,
32 	   const picture_info **src_color, int num_src,
33 	   const picture_info **dst_color, int num_dst)
34 {
35 	color4d expected, tested, tdst;
36 	char testname[20];
37 	int i, j, k, y, iter;
38 	int page, num_pages;
39 
40 	/* If the window is smaller than the number of sources to test,
41 	 * we need to break the sources up into pages.
42 	 *
43 	 * We however assume that the window will always be wider than num_ops.
44 	 */
45 	num_pages = num_src / win_height + 1;
46 
47 	k = y = 0;
48 	while (k < num_dst) {
49 	    XImage *image;
50 	    int k0 = k, k1 = k;
51 	    int this_src, rem_src;
52 
53 	    rem_src = num_src;
54 	    for (page = 0; page < num_pages; page++) {
55 		    this_src = rem_src / (num_pages - page);
56 		    for (iter = 0; iter < pixmap_move_iter; iter++) {
57 			    k1 = k0;
58 			    y = 0;
59 			    while (k1 < num_dst && y + this_src <= win_height) {
60 				    XRenderComposite(dpy, PictOpSrc,
61 						     dst_color[k1++]->pict, 0, dst->pict,
62 						     0, 0,
63 						     0, 0,
64 						     0, y,
65 						     num_op, this_src);
66 				    for (j = 0; j < this_src; j++) {
67 					    for (i = 0; i < num_op; i++) {
68 						    XRenderComposite(dpy, ops[op[i]].op,
69 								     src_color[j]->pict, 0, dst->pict,
70 								     0, 0,
71 								     0, 0,
72 								     i, y,
73 								     1, 1);
74 					    }
75 					    y++;
76 				    }
77 			    }
78 		    }
79 
80 		    image = XGetImage(dpy, dst->d,
81 				      0, 0, num_ops, y,
82 				      0xffffffff, ZPixmap);
83 		    copy_pict_to_win(dpy, dst, win, win_width, win_height);
84 
85 		    y = 0;
86 		    for (k = k0; k < k1; k++) {
87 			    XRenderDirectFormat dst_acc;
88 
89 			    accuracy(&dst_acc,
90 				     &dst->format->direct,
91 				     &dst_color[k]->format->direct);
92 
93 			    tdst = dst_color[k]->color;
94 			    color_correct(dst, &tdst);
95 
96 			    for (j = 0; j < this_src; j++) {
97 				    XRenderDirectFormat acc;
98 
99 				    accuracy(&acc, &src_color[j]->format->direct, &dst_acc);
100 
101 				    for (i = 0; i < num_op; i++) {
102 					    get_pixel_from_image(image, dst, i, y, &tested);
103 
104 					    do_composite(ops[op[i]].op,
105 							 &src_color[j]->color,
106 							 NULL,
107 							 &tdst,
108 							 &expected,
109 							 FALSE);
110 					    color_correct(dst, &expected);
111 
112 					    if (eval_diff(&acc, &expected, &tested) > 3.) {
113 						    char *srcformat;
114 
115 						    snprintf(testname, 20, "%s blend", ops[op[i]].name);
116 						    describe_format(&srcformat, NULL, src_color[j]->format);
117 						    print_fail(testname, &expected, &tested, 0, 0,
118 							       eval_diff(&acc, &expected, &tested));
119 						    printf("src color: %.2f %.2f %.2f %.2f (%s)\n"
120 							   "dst color: %.2f %.2f %.2f %.2f\n",
121 							   src_color[j]->color.r, src_color[j]->color.g,
122 							   src_color[j]->color.b, src_color[j]->color.a,
123 							   srcformat,
124 							   dst_color[k]->color.r,
125 							   dst_color[k]->color.g,
126 							   dst_color[k]->color.b,
127 							   dst_color[k]->color.a);
128 						    printf("src: %s, dst: %s\n", src_color[j]->name, dst->name);
129 						    free(srcformat);
130 						    return FALSE;
131 					    }
132 				    }
133 				    y++;
134 			    }
135 		    }
136 
137 		    XDestroyImage(image);
138 		    rem_src -= this_src;
139 	    }
140 	}
141 
142 	return TRUE;
143 }
144