take two
[profile/ivi/xorg-x11-drv-intel.git] / test / render-fill.c
1 #include <stdint.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4
5 #include <X11/Xutil.h> /* for XDestroyImage */
6 #include <pixman.h> /* for pixman blt functions */
7
8 #include "test.h"
9
10 static const uint8_t ops[] = {
11         PictOpClear,
12         PictOpSrc,
13         PictOpDst,
14 };
15
16 static void fill_rect(struct test_display *dpy, Picture p, uint8_t op,
17                       int x, int y, int w, int h,
18                       uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
19 {
20         XRenderColor render_color;
21
22         render_color.red   = red * alpha;
23         render_color.green = green * alpha;
24         render_color.blue  = blue * alpha;
25         render_color.alpha = alpha << 8;
26
27         XRenderFillRectangle(dpy->dpy, op, p, &render_color, x, y, w,h);
28 }
29
30 static void pixel_tests(struct test *t, int reps, int sets, enum target target)
31 {
32         struct test_target tt;
33         XImage image;
34         uint32_t *cells = malloc(t->real.width*t->real.height*4);
35         struct {
36                 uint16_t x, y;
37         } *pixels = malloc(reps*sizeof(*pixels));
38         int r, s;
39
40         test_target_create_render(&t->real, target, &tt);
41
42         printf("Testing setting of single pixels (%s): ",
43                test_target_name(target));
44         fflush(stdout);
45
46         for (s = 0; s < sets; s++) {
47                 for (r = 0; r < reps; r++) {
48                         int x = rand() % (tt.width - 1);
49                         int y = rand() % (tt.height - 1);
50                         int red = rand() % 0xff;
51                         int green = rand() % 0xff;
52                         int blue = rand() % 0xff;
53                         int alpha = rand() % 0xff;
54
55                         fill_rect(&t->real, tt.picture, PictOpSrc,
56                                   x, y, 1, 1,
57                                   red, green, blue, alpha);
58
59                         pixels[r].x = x;
60                         pixels[r].y = y;
61                         cells[y*tt.width+x] = color(red, green, blue, alpha);
62                 }
63
64                 test_init_image(&image, &t->real.shm, tt.format, 1, 1);
65
66                 for (r = 0; r < reps; r++) {
67                         uint32_t result;
68                         uint32_t x = pixels[r].x;
69                         uint32_t y = pixels[r].y;
70
71                         XShmGetImage(t->real.dpy, tt.draw, &image,
72                                      x, y, AllPlanes);
73
74                         result = *(uint32_t *)image.data;
75                         if (!pixel_equal(image.depth, result,
76                                          cells[y*tt.width+x])) {
77                                 uint32_t mask = depth_mask(image.depth);
78                                 die("failed to set pixel (%d,%d) to %08x [%08x], found %08x [%08x] instead\n",
79                                     x, y,
80                                     cells[y*tt.width+x] & mask,
81                                     cells[y*tt.width+x],
82                                     result & mask);
83                         }
84                 }
85         }
86         printf("passed [%d iterations x %d]\n", reps, sets);
87
88         test_target_destroy_render(&t->real, &tt);
89         free(pixels);
90         free(cells);
91 }
92
93 static void clear(struct test_display *dpy, struct test_target *tt)
94 {
95         XRenderColor render_color = {0};
96         XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color,
97                              0, 0, tt->width, tt->height);
98 }
99
100 static void area_tests(struct test *t, int reps, int sets, enum target target)
101 {
102         struct test_target tt;
103         XImage image;
104         uint32_t *cells = calloc(sizeof(uint32_t), t->real.width*t->real.height);
105         int r, s, x, y;
106
107         printf("Testing area sets (%s): ", test_target_name(target));
108         fflush(stdout);
109
110         test_target_create_render(&t->real, target, &tt);
111         clear(&t->real, &tt);
112
113         test_init_image(&image, &t->real.shm, tt.format, tt.width, tt.height);
114
115         for (s = 0; s < sets; s++) {
116                 for (r = 0; r < reps; r++) {
117                         int w = rand() % tt.width;
118                         int h = rand() % tt.height;
119                         int red = rand() % 0xff;
120                         int green = rand() % 0xff;
121                         int blue = rand() % 0xff;
122                         int alpha = rand() % 0xff;
123
124                         x = rand() % (2*tt.width) - tt.width;
125                         y = rand() % (2*tt.height) - tt.height;
126
127                         fill_rect(&t->real, tt.picture, PictOpSrc,
128                                   x, y, w, h, red, green, blue, alpha);
129
130                         if (x < 0)
131                                 w += x, x = 0;
132                         if (y < 0)
133                                 h += y, y = 0;
134                         if (x >= tt.width || y >= tt.height)
135                                 continue;
136
137                         if (x + w > tt.width)
138                                 w = tt.width - x;
139                         if (y + h > tt.height)
140                                 h = tt.height - y;
141                         if (w <= 0 || h <= 0)
142                                 continue;
143
144                         pixman_fill(cells, tt.width, 32, x, y, w, h,
145                                     color(red, green, blue, alpha));
146                 }
147
148                 XShmGetImage(t->real.dpy, tt.draw, &image, 0, 0, AllPlanes);
149
150                 for (y = 0; y < tt.height; y++) {
151                         for (x = 0; x < tt.width; x++) {
152                                 uint32_t result =
153                                         *(uint32_t *)(image.data +
154                                                       y*image.bytes_per_line +
155                                                       image.bits_per_pixel*x/8);
156                                 if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) {
157                                         uint32_t mask;
158                                         if (image.depth == 32)
159                                                 mask = 0xffffffff;
160                                         else
161                                                 mask = (1 << image.depth) - 1;
162                                         die("failed to set pixel (%d,%d) to %08x[%08x], found %08x instead\n",
163                                             x, y,
164                                             cells[y*tt.width+x] & mask,
165                                             cells[y*tt.width+x],
166                                             result & mask);
167                                 }
168                         }
169                 }
170         }
171
172         printf("passed [%d iterations x %d]\n", reps, sets);
173
174         test_target_destroy_render(&t->real, &tt);
175         free(cells);
176 }
177
178 static void rect_tests(struct test *t, int reps, int sets, enum target target)
179 {
180         struct test_target real, ref;
181         int r, s;
182
183         printf("Testing area fills (%s): ", test_target_name(target));
184         fflush(stdout);
185
186         test_target_create_render(&t->real, target, &real);
187         clear(&t->real, &real);
188
189         test_target_create_render(&t->ref, target, &ref);
190         clear(&t->ref, &ref);
191
192         for (s = 0; s < sets; s++) {
193                 for (r = 0; r < reps; r++) {
194                         int x = rand() % (2*real.width) - real.width;
195                         int y = rand() % (2*real.height) - real.height;
196                         int w = rand() % real.width;
197                         int h = rand() % real.height;
198                         int op = ops[rand() % sizeof(ops)];
199                         int red = rand() % 0xff;
200                         int green = rand() % 0xff;
201                         int blue = rand() % 0xff;
202                         int alpha = rand() % 0xff;
203
204                         fill_rect(&t->real, real.picture,
205                                   op, x, y, w, h,
206                                   red, green, blue, alpha);
207                         fill_rect(&t->ref, ref.picture,
208                                   op, x, y, w, h,
209                                   red, green, blue, alpha);
210                 }
211
212                 test_compare(t,
213                              real.draw, real.format,
214                              ref.draw, ref.format,
215                              0, 0, real.width, real.height,
216                              "");
217         }
218
219         printf("passed [%d iterations x %d]\n", reps, sets);
220
221         test_target_destroy_render(&t->real, &real);
222         test_target_destroy_render(&t->ref, &ref);
223 }
224
225 int main(int argc, char **argv)
226 {
227         struct test test;
228         int i;
229
230         test_init(&test, argc, argv);
231
232         for (i = 0; i <= DEFAULT_ITERATIONS; i++) {
233                 int reps = 1 << i;
234                 int sets = 1 << (12 - i);
235                 enum target t;
236
237                 if (sets < 2)
238                         sets = 2;
239
240                 for (t = TARGET_FIRST; t <= TARGET_LAST; t++) {
241                         pixel_tests(&test, reps, sets, t);
242                         area_tests(&test, reps, sets, t);
243                         rect_tests(&test, reps, sets, t);
244                 }
245         }
246
247         return 0;
248 }