correct usage of rand_r()
[platform/core/uifw/libtdm.git] / tools / buffers.c
1 /*
2  * DRM based mode setting test program
3  * Copyright 2008 Tungsten Graphics
4  *   Jakob Bornecrantz <jakob@tungstengraphics.com>
5  * Copyright 2008 Intel Corporation
6  *   Jesse Barnes <jesse.barnes@intel.com>
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24  * IN THE SOFTWARE.
25  */
26
27 #include <assert.h>
28 #include <errno.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <stdint.h>
32 #include <string.h>
33 #include <string.h>
34 #include <time.h>
35 #include <math.h>
36
37 #include <tbm_bufmgr.h>
38 #include <tbm_surface.h>
39
40 #include <tdm_log.h>
41 #include "tdm_macro.h"
42 #include "buffers.h"
43
44 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
45
46 /* -----------------------------------------------------------------------------
47  * Formats
48  */
49
50 struct color_component {
51         unsigned int length;
52         unsigned int offset;
53 };
54
55 struct rgb_info {
56         struct color_component red;
57         struct color_component green;
58         struct color_component blue;
59         struct color_component alpha;
60 };
61
62 enum yuv_order {
63         YUV_YCbCr = 1,
64         YUV_YCrCb = 2,
65         YUV_YC = 4,
66         YUV_CY = 8,
67 };
68
69 struct yuv_info {
70         enum yuv_order order;
71         unsigned int xsub;
72         unsigned int ysub;
73         unsigned int chroma_stride;
74 };
75
76 struct format_info {
77         unsigned int format;
78         const char *name;
79         const struct rgb_info rgb;
80         const struct yuv_info yuv;
81 };
82
83 #define MAKE_RGB_INFO(rl, ro, bl, bo, gl, go, al, ao) \
84         .rgb = { { (rl), (ro) }, { (bl), (bo) }, { (gl), (go) }, { (al), (ao) } }
85
86 #define MAKE_YUV_INFO(order, xsub, ysub, chroma_stride) \
87         .yuv = { (order), (xsub), (ysub), (chroma_stride) }
88
89 static const struct format_info format_info[] = {
90         /* YUV packed */
91         { TBM_FORMAT_UYVY, "UYVY", MAKE_YUV_INFO(YUV_YCbCr | YUV_CY, 2, 2, 2) },
92         { TBM_FORMAT_VYUY, "VYUY", MAKE_YUV_INFO(YUV_YCrCb | YUV_CY, 2, 2, 2) },
93         { TBM_FORMAT_YUYV, "YUYV", MAKE_YUV_INFO(YUV_YCbCr | YUV_YC, 2, 2, 2) },
94         { TBM_FORMAT_YVYU, "YVYU", MAKE_YUV_INFO(YUV_YCrCb | YUV_YC, 2, 2, 2) },
95         /* YUV semi-planar */
96         { TBM_FORMAT_NV12, "NV12", MAKE_YUV_INFO(YUV_YCbCr, 2, 2, 2) },
97         { TBM_FORMAT_NV21, "NV21", MAKE_YUV_INFO(YUV_YCrCb, 2, 2, 2) },
98         { TBM_FORMAT_NV16, "NV16", MAKE_YUV_INFO(YUV_YCbCr, 2, 1, 2) },
99         { TBM_FORMAT_NV61, "NV61", MAKE_YUV_INFO(YUV_YCrCb, 2, 1, 2) },
100         /* YUV planar */
101         { TBM_FORMAT_YUV420, "YU12", MAKE_YUV_INFO(YUV_YCbCr, 2, 2, 1) },
102         { TBM_FORMAT_YVU420, "YV12", MAKE_YUV_INFO(YUV_YCrCb, 2, 2, 1) },
103         /* RGB16 */
104         { TBM_FORMAT_ARGB4444, "AR12", MAKE_RGB_INFO(4, 8, 4, 4, 4, 0, 4, 12) },
105         { TBM_FORMAT_XRGB4444, "XR12", MAKE_RGB_INFO(4, 8, 4, 4, 4, 0, 0, 0) },
106         { TBM_FORMAT_ABGR4444, "AB12", MAKE_RGB_INFO(4, 0, 4, 4, 4, 8, 4, 12) },
107         { TBM_FORMAT_XBGR4444, "XB12", MAKE_RGB_INFO(4, 0, 4, 4, 4, 8, 0, 0) },
108         { TBM_FORMAT_RGBA4444, "RA12", MAKE_RGB_INFO(4, 12, 4, 8, 4, 4, 4, 0) },
109         { TBM_FORMAT_RGBX4444, "RX12", MAKE_RGB_INFO(4, 12, 4, 8, 4, 4, 0, 0) },
110         { TBM_FORMAT_BGRA4444, "BA12", MAKE_RGB_INFO(4, 4, 4, 8, 4, 12, 4, 0) },
111         { TBM_FORMAT_BGRX4444, "BX12", MAKE_RGB_INFO(4, 4, 4, 8, 4, 12, 0, 0) },
112         { TBM_FORMAT_ARGB1555, "AR15", MAKE_RGB_INFO(5, 10, 5, 5, 5, 0, 1, 15) },
113         { TBM_FORMAT_XRGB1555, "XR15", MAKE_RGB_INFO(5, 10, 5, 5, 5, 0, 0, 0) },
114         { TBM_FORMAT_ABGR1555, "AB15", MAKE_RGB_INFO(5, 0, 5, 5, 5, 10, 1, 15) },
115         { TBM_FORMAT_XBGR1555, "XB15", MAKE_RGB_INFO(5, 0, 5, 5, 5, 10, 0, 0) },
116         { TBM_FORMAT_RGBA5551, "RA15", MAKE_RGB_INFO(5, 11, 5, 6, 5, 1, 1, 0) },
117         { TBM_FORMAT_RGBX5551, "RX15", MAKE_RGB_INFO(5, 11, 5, 6, 5, 1, 0, 0) },
118         { TBM_FORMAT_BGRA5551, "BA15", MAKE_RGB_INFO(5, 1, 5, 6, 5, 11, 1, 0) },
119         { TBM_FORMAT_BGRX5551, "BX15", MAKE_RGB_INFO(5, 1, 5, 6, 5, 11, 0, 0) },
120         { TBM_FORMAT_RGB565, "RG16", MAKE_RGB_INFO(5, 11, 6, 5, 5, 0, 0, 0) },
121         { TBM_FORMAT_BGR565, "BG16", MAKE_RGB_INFO(5, 0, 6, 5, 5, 11, 0, 0) },
122         /* RGB24 */
123         { TBM_FORMAT_BGR888, "BG24", MAKE_RGB_INFO(8, 0, 8, 8, 8, 16, 0, 0) },
124         { TBM_FORMAT_RGB888, "RG24", MAKE_RGB_INFO(8, 16, 8, 8, 8, 0, 0, 0) },
125         /* RGB32 */
126         { TBM_FORMAT_ARGB8888, "AR24", MAKE_RGB_INFO(8, 16, 8, 8, 8, 0, 8, 24) },
127         { TBM_FORMAT_XRGB8888, "XR24", MAKE_RGB_INFO(8, 16, 8, 8, 8, 0, 0, 0) },
128         { TBM_FORMAT_ABGR8888, "AB24", MAKE_RGB_INFO(8, 0, 8, 8, 8, 16, 8, 24) },
129         { TBM_FORMAT_XBGR8888, "XB24", MAKE_RGB_INFO(8, 0, 8, 8, 8, 16, 0, 0) },
130         { TBM_FORMAT_RGBA8888, "RA24", MAKE_RGB_INFO(8, 24, 8, 16, 8, 8, 8, 0) },
131         { TBM_FORMAT_RGBX8888, "RX24", MAKE_RGB_INFO(8, 24, 8, 16, 8, 8, 0, 0) },
132         { TBM_FORMAT_BGRA8888, "BA24", MAKE_RGB_INFO(8, 8, 8, 16, 8, 24, 8, 0) },
133         { TBM_FORMAT_BGRX8888, "BX24", MAKE_RGB_INFO(8, 8, 8, 16, 8, 24, 0, 0) },
134         { TBM_FORMAT_ARGB2101010, "AR30", MAKE_RGB_INFO(10, 20, 10, 10, 10, 0, 2, 30) },
135         { TBM_FORMAT_XRGB2101010, "XR30", MAKE_RGB_INFO(10, 20, 10, 10, 10, 0, 0, 0) },
136         { TBM_FORMAT_ABGR2101010, "AB30", MAKE_RGB_INFO(10, 0, 10, 10, 10, 20, 2, 30) },
137         { TBM_FORMAT_XBGR2101010, "XB30", MAKE_RGB_INFO(10, 0, 10, 10, 10, 20, 0, 0) },
138         { TBM_FORMAT_RGBA1010102, "RA30", MAKE_RGB_INFO(10, 22, 10, 12, 10, 2, 2, 0) },
139         { TBM_FORMAT_RGBX1010102, "RX30", MAKE_RGB_INFO(10, 22, 10, 12, 10, 2, 0, 0) },
140         { TBM_FORMAT_BGRA1010102, "BA30", MAKE_RGB_INFO(10, 2, 10, 12, 10, 22, 2, 0) },
141         { TBM_FORMAT_BGRX1010102, "BX30", MAKE_RGB_INFO(10, 2, 10, 12, 10, 22, 0, 0) },
142 };
143
144 static unsigned int rand_seed;
145
146 unsigned int format_fourcc(const char *name)
147 {
148         unsigned int i;
149         for (i = 0; i < ARRAY_SIZE(format_info); i++) {
150                 if (!strcmp(format_info[i].name, name))
151                         return format_info[i].format;
152         }
153         return 0;
154 }
155
156 /* -----------------------------------------------------------------------------
157  * Test patterns
158  */
159
160 struct color_rgb24 {
161         unsigned int value: 24;
162 } __attribute__((__packed__));
163
164 struct color_yuv {
165         unsigned char y;
166         unsigned char u;
167         unsigned char v;
168 };
169
170 #define MAKE_YUV_601_Y(r, g, b) \
171         ((( 66 * (r) + 129 * (g) +  25 * (b) + 128) >> 8) + 16)
172 #define MAKE_YUV_601_U(r, g, b) \
173         (((-38 * (r) -  74 * (g) + 112 * (b) + 128) >> 8) + 128)
174 #define MAKE_YUV_601_V(r, g, b) \
175         (((112 * (r) -  94 * (g) -  18 * (b) + 128) >> 8) + 128)
176
177 #define MAKE_YUV_601(r, g, b) \
178         { .y = MAKE_YUV_601_Y(r, g, b), \
179           .u = MAKE_YUV_601_U(r, g, b), \
180           .v = MAKE_YUV_601_V(r, g, b) }
181
182 #define MAKE_RGBA(rgb, r, g, b, a) \
183         ((((r) >> (8 - (rgb)->red.length)) << (rgb)->red.offset) | \
184          (((g) >> (8 - (rgb)->green.length)) << (rgb)->green.offset) | \
185          (((b) >> (8 - (rgb)->blue.length)) << (rgb)->blue.offset) | \
186          (((a) >> (8 - (rgb)->alpha.length)) << (rgb)->alpha.offset))
187
188 #define MAKE_RGB24(rgb, r, g, b) \
189         { .value = MAKE_RGBA(rgb, r, g, b, 0) }
190
191 static void
192 fill_smpte_yuv_planar(const struct yuv_info *yuv,
193                                           unsigned char *y_mem, unsigned char *u_mem,
194                                           unsigned char *v_mem, unsigned int width,
195                                           unsigned int height, unsigned int stride)
196 {
197         const struct color_yuv colors_top[] = {
198                 MAKE_YUV_601(191, 192, 192),    /* grey */
199                 MAKE_YUV_601(192, 192, 0),      /* yellow */
200                 MAKE_YUV_601(0, 192, 192),      /* cyan */
201                 MAKE_YUV_601(0, 192, 0),        /* green */
202                 MAKE_YUV_601(192, 0, 192),      /* magenta */
203                 MAKE_YUV_601(192, 0, 0),        /* red */
204                 MAKE_YUV_601(0, 0, 192),        /* blue */
205         };
206         const struct color_yuv colors_middle[] = {
207                 MAKE_YUV_601(0, 0, 192),        /* blue */
208                 MAKE_YUV_601(19, 19, 19),       /* black */
209                 MAKE_YUV_601(192, 0, 192),      /* magenta */
210                 MAKE_YUV_601(19, 19, 19),       /* black */
211                 MAKE_YUV_601(0, 192, 192),      /* cyan */
212                 MAKE_YUV_601(19, 19, 19),       /* black */
213                 MAKE_YUV_601(192, 192, 192),    /* grey */
214         };
215         const struct color_yuv colors_bottom[] = {
216                 MAKE_YUV_601(0, 33, 76),        /* in-phase */
217                 MAKE_YUV_601(255, 255, 255),    /* super white */
218                 MAKE_YUV_601(50, 0, 106),       /* quadrature */
219                 MAKE_YUV_601(19, 19, 19),       /* black */
220                 MAKE_YUV_601(9, 9, 9),          /* 3.5% */
221                 MAKE_YUV_601(19, 19, 19),       /* 7.5% */
222                 MAKE_YUV_601(29, 29, 29),       /* 11.5% */
223                 MAKE_YUV_601(19, 19, 19),       /* black */
224         };
225         unsigned int cs = yuv->chroma_stride;
226         unsigned int xsub = yuv->xsub;
227         unsigned int ysub = yuv->ysub;
228         unsigned int x;
229         unsigned int y;
230
231         /* Luma */
232         for (y = 0; y < height * 6 / 9; ++y) {
233                 for (x = 0; x < width; ++x)
234                         y_mem[x] = colors_top[x * 7 / width].y;
235                 y_mem += stride;
236         }
237
238         for (; y < height * 7 / 9; ++y) {
239                 for (x = 0; x < width; ++x)
240                         y_mem[x] = colors_middle[x * 7 / width].y;
241                 y_mem += stride;
242         }
243
244         for (; y < height; ++y) {
245                 for (x = 0; x < width * 5 / 7; ++x)
246                         y_mem[x] = colors_bottom[x * 4 / (width * 5 / 7)].y;
247                 for (; x < width * 6 / 7; ++x)
248                         y_mem[x] = colors_bottom[(x - width * 5 / 7) * 3
249                                                                          / (width / 7) + 4].y;
250                 for (; x < width; ++x)
251                         y_mem[x] = colors_bottom[7].y;
252                 y_mem += stride;
253         }
254
255         /* Chroma */
256         for (y = 0; y < height / ysub * 6 / 9; ++y) {
257                 for (x = 0; x < width; x += xsub) {
258                         u_mem[x * cs / xsub] = colors_top[x * 7 / width].u;
259                         v_mem[x * cs / xsub] = colors_top[x * 7 / width].v;
260                 }
261                 u_mem += stride * cs / xsub;
262                 v_mem += stride * cs / xsub;
263         }
264
265         for (; y < height / ysub * 7 / 9; ++y) {
266                 for (x = 0; x < width; x += xsub) {
267                         u_mem[x * cs / xsub] = colors_middle[x * 7 / width].u;
268                         v_mem[x * cs / xsub] = colors_middle[x * 7 / width].v;
269                 }
270                 u_mem += stride * cs / xsub;
271                 v_mem += stride * cs / xsub;
272         }
273
274         for (; y < height / ysub; ++y) {
275                 for (x = 0; x < width * 5 / 7; x += xsub) {
276                         u_mem[x * cs / xsub] =
277                                 colors_bottom[x * 4 / (width * 5 / 7)].u;
278                         v_mem[x * cs / xsub] =
279                                 colors_bottom[x * 4 / (width * 5 / 7)].v;
280                 }
281                 for (; x < width * 6 / 7; x += xsub) {
282                         u_mem[x * cs / xsub] = colors_bottom[(x - width * 5 / 7) *
283                                                                                                  3 / (width / 7) + 4].u;
284                         v_mem[x * cs / xsub] = colors_bottom[(x - width * 5 / 7) *
285                                                                                                  3 / (width / 7) + 4].v;
286                 }
287                 for (; x < width; x += xsub) {
288                         u_mem[x * cs / xsub] = colors_bottom[7].u;
289                         v_mem[x * cs / xsub] = colors_bottom[7].v;
290                 }
291                 u_mem += stride * cs / xsub;
292                 v_mem += stride * cs / xsub;
293         }
294 }
295
296 static void
297 fill_smpte_yuv_packed(const struct yuv_info *yuv, unsigned char *mem,
298                                           unsigned int width, unsigned int height,
299                                           unsigned int stride)
300 {
301         const struct color_yuv colors_top[] = {
302                 MAKE_YUV_601(191, 192, 192),    /* grey */
303                 MAKE_YUV_601(192, 192, 0),      /* yellow */
304                 MAKE_YUV_601(0, 192, 192),      /* cyan */
305                 MAKE_YUV_601(0, 192, 0),        /* green */
306                 MAKE_YUV_601(192, 0, 192),      /* magenta */
307                 MAKE_YUV_601(192, 0, 0),        /* red */
308                 MAKE_YUV_601(0, 0, 192),        /* blue */
309         };
310         const struct color_yuv colors_middle[] = {
311                 MAKE_YUV_601(0, 0, 192),        /* blue */
312                 MAKE_YUV_601(19, 19, 19),       /* black */
313                 MAKE_YUV_601(192, 0, 192),      /* magenta */
314                 MAKE_YUV_601(19, 19, 19),       /* black */
315                 MAKE_YUV_601(0, 192, 192),      /* cyan */
316                 MAKE_YUV_601(19, 19, 19),       /* black */
317                 MAKE_YUV_601(192, 192, 192),    /* grey */
318         };
319         const struct color_yuv colors_bottom[] = {
320                 MAKE_YUV_601(0, 33, 76),        /* in-phase */
321                 MAKE_YUV_601(255, 255, 255),    /* super white */
322                 MAKE_YUV_601(50, 0, 106),       /* quadrature */
323                 MAKE_YUV_601(19, 19, 19),       /* black */
324                 MAKE_YUV_601(9, 9, 9),          /* 3.5% */
325                 MAKE_YUV_601(19, 19, 19),       /* 7.5% */
326                 MAKE_YUV_601(29, 29, 29),       /* 11.5% */
327                 MAKE_YUV_601(19, 19, 19),       /* black */
328         };
329         unsigned char *y_mem = (yuv->order & YUV_YC) ? mem : mem + 1;
330         unsigned char *c_mem = (yuv->order & YUV_CY) ? mem : mem + 1;
331         unsigned int u = (yuv->order & YUV_YCrCb) ? 2 : 0;
332         unsigned int v = (yuv->order & YUV_YCbCr) ? 2 : 0;
333         unsigned int x;
334         unsigned int y;
335
336         if (width < 8)
337                 return;
338
339         /* Luma */
340         for (y = 0; y < height * 6 / 9; ++y) {
341                 for (x = 0; x < width; ++x)
342                         y_mem[2 * x] = colors_top[x * 7 / width].y;
343                 y_mem += stride;
344         }
345
346         for (; y < height * 7 / 9; ++y) {
347                 for (x = 0; x < width; ++x)
348                         y_mem[2 * x] = colors_middle[x * 7 / width].y;
349                 y_mem += stride;
350         }
351
352         for (; y < height; ++y) {
353                 for (x = 0; x < width * 5 / 7; ++x)
354                         y_mem[2 * x] = colors_bottom[x * 4 / (width * 5 / 7)].y;
355                 for (; x < width * 6 / 7; ++x)
356                         y_mem[2 * x] = colors_bottom[(x - width * 5 / 7) * 3
357                                                                                  / (width / 7) + 4].y;
358                 for (; x < width; ++x)
359                         y_mem[2 * x] = colors_bottom[7].y;
360                 y_mem += stride;
361         }
362
363         /* Chroma */
364         for (y = 0; y < height * 6 / 9; ++y) {
365                 for (x = 0; x < width; x += 2) {
366                         c_mem[2 * x + u] = colors_top[x * 7 / width].u;
367                         c_mem[2 * x + v] = colors_top[x * 7 / width].v;
368                 }
369                 c_mem += stride;
370         }
371
372         for (; y < height * 7 / 9; ++y) {
373                 for (x = 0; x < width; x += 2) {
374                         c_mem[2 * x + u] = colors_middle[x * 7 / width].u;
375                         c_mem[2 * x + v] = colors_middle[x * 7 / width].v;
376                 }
377                 c_mem += stride;
378         }
379
380         for (; y < height; ++y) {
381                 for (x = 0; x < width * 5 / 7; x += 2) {
382                         c_mem[2 * x + u] = colors_bottom[x * 4 / (width * 5 / 7)].u;
383                         c_mem[2 * x + v] = colors_bottom[x * 4 / (width * 5 / 7)].v;
384                 }
385                 for (; x < width * 6 / 7; x += 2) {
386                         c_mem[2 * x + u] = colors_bottom[(x - width * 5 / 7) *
387                                                                                          3 / (width / 7) + 4].u;
388                         c_mem[2 * x + v] = colors_bottom[(x - width * 5 / 7) *
389                                                                                          3 / (width / 7) + 4].v;
390                 }
391                 for (; x < width; x += 2) {
392                         c_mem[2 * x + u] = colors_bottom[7].u;
393                         c_mem[2 * x + v] = colors_bottom[7].v;
394                 }
395                 c_mem += stride;
396         }
397 }
398
399 static void
400 fill_smpte_rgb16(const struct rgb_info *rgb, unsigned char *mem,
401                                  unsigned int width, unsigned int height, unsigned int stride)
402 {
403         const uint16_t colors_top[] = {
404                 MAKE_RGBA(rgb, 192, 192, 192, 255),     /* grey */
405                 MAKE_RGBA(rgb, 192, 192, 0, 255),       /* yellow */
406                 MAKE_RGBA(rgb, 0, 192, 192, 255),       /* cyan */
407                 MAKE_RGBA(rgb, 0, 192, 0, 255),         /* green */
408                 MAKE_RGBA(rgb, 192, 0, 192, 255),       /* magenta */
409                 MAKE_RGBA(rgb, 192, 0, 0, 255),         /* red */
410                 MAKE_RGBA(rgb, 0, 0, 192, 255),         /* blue */
411         };
412         const uint16_t colors_middle[] = {
413                 MAKE_RGBA(rgb, 0, 0, 192, 255),         /* blue */
414                 MAKE_RGBA(rgb, 19, 19, 19, 255),        /* black */
415                 MAKE_RGBA(rgb, 192, 0, 192, 255),       /* magenta */
416                 MAKE_RGBA(rgb, 19, 19, 19, 255),        /* black */
417                 MAKE_RGBA(rgb, 0, 192, 192, 255),       /* cyan */
418                 MAKE_RGBA(rgb, 19, 19, 19, 255),        /* black */
419                 MAKE_RGBA(rgb, 192, 192, 192, 255),     /* grey */
420         };
421         const uint16_t colors_bottom[] = {
422                 MAKE_RGBA(rgb, 0, 33, 76, 255),         /* in-phase */
423                 MAKE_RGBA(rgb, 255, 255, 255, 255),     /* super white */
424                 MAKE_RGBA(rgb, 50, 0, 106, 255),        /* quadrature */
425                 MAKE_RGBA(rgb, 19, 19, 19, 255),        /* black */
426                 MAKE_RGBA(rgb, 9, 9, 9, 255),           /* 3.5% */
427                 MAKE_RGBA(rgb, 19, 19, 19, 255),        /* 7.5% */
428                 MAKE_RGBA(rgb, 29, 29, 29, 255),        /* 11.5% */
429                 MAKE_RGBA(rgb, 19, 19, 19, 255),        /* black */
430         };
431         unsigned int x;
432         unsigned int y;
433
434         if (width < 8)
435                 return;
436
437         for (y = 0; y < height * 6 / 9; ++y) {
438                 for (x = 0; x < width; ++x)
439                         ((uint16_t *)mem)[x] = colors_top[x * 7 / width];
440                 mem += stride;
441         }
442
443         for (; y < height * 7 / 9; ++y) {
444                 for (x = 0; x < width; ++x)
445                         ((uint16_t *)mem)[x] = colors_middle[x * 7 / width];
446                 mem += stride;
447         }
448
449         for (; y < height; ++y) {
450                 for (x = 0; x < width * 5 / 7; ++x)
451                         ((uint16_t *)mem)[x] =
452                                 colors_bottom[x * 4 / (width * 5 / 7)];
453                 for (; x < width * 6 / 7; ++x)
454                         ((uint16_t *)mem)[x] =
455                                 colors_bottom[(x - width * 5 / 7) * 3
456                                                           / (width / 7) + 4];
457                 for (; x < width; ++x)
458                         ((uint16_t *)mem)[x] = colors_bottom[7];
459                 mem += stride;
460         }
461 }
462
463 static void
464 fill_smpte_rgb24(const struct rgb_info *rgb, void *mem,
465                                  unsigned int width, unsigned int height, unsigned int stride)
466 {
467         const struct color_rgb24 colors_top[] = {
468                 MAKE_RGB24(rgb, 192, 192, 192), /* grey */
469                 MAKE_RGB24(rgb, 192, 192, 0),   /* yellow */
470                 MAKE_RGB24(rgb, 0, 192, 192),   /* cyan */
471                 MAKE_RGB24(rgb, 0, 192, 0),     /* green */
472                 MAKE_RGB24(rgb, 192, 0, 192),   /* magenta */
473                 MAKE_RGB24(rgb, 192, 0, 0),     /* red */
474                 MAKE_RGB24(rgb, 0, 0, 192),     /* blue */
475         };
476         const struct color_rgb24 colors_middle[] = {
477                 MAKE_RGB24(rgb, 0, 0, 192),     /* blue */
478                 MAKE_RGB24(rgb, 19, 19, 19),    /* black */
479                 MAKE_RGB24(rgb, 192, 0, 192),   /* magenta */
480                 MAKE_RGB24(rgb, 19, 19, 19),    /* black */
481                 MAKE_RGB24(rgb, 0, 192, 192),   /* cyan */
482                 MAKE_RGB24(rgb, 19, 19, 19),    /* black */
483                 MAKE_RGB24(rgb, 192, 192, 192), /* grey */
484         };
485         const struct color_rgb24 colors_bottom[] = {
486                 MAKE_RGB24(rgb, 0, 33, 76),     /* in-phase */
487                 MAKE_RGB24(rgb, 255, 255, 255), /* super white */
488                 MAKE_RGB24(rgb, 50, 0, 106),    /* quadrature */
489                 MAKE_RGB24(rgb, 19, 19, 19),    /* black */
490                 MAKE_RGB24(rgb, 9, 9, 9),       /* 3.5% */
491                 MAKE_RGB24(rgb, 19, 19, 19),    /* 7.5% */
492                 MAKE_RGB24(rgb, 29, 29, 29),    /* 11.5% */
493                 MAKE_RGB24(rgb, 19, 19, 19),    /* black */
494         };
495         unsigned int x;
496         unsigned int y;
497
498         if (width < 8)
499                 return;
500
501         for (y = 0; y < height * 6 / 9; ++y) {
502                 for (x = 0; x < width; ++x)
503                         ((struct color_rgb24 *)mem)[x] =
504                                 colors_top[x * 7 / width];
505                 mem += stride;
506         }
507
508         for (; y < height * 7 / 9; ++y) {
509                 for (x = 0; x < width; ++x)
510                         ((struct color_rgb24 *)mem)[x] =
511                                 colors_middle[x * 7 / width];
512                 mem += stride;
513         }
514
515         for (; y < height; ++y) {
516                 for (x = 0; x < width * 5 / 7; ++x)
517                         ((struct color_rgb24 *)mem)[x] =
518                                 colors_bottom[x * 4 / (width * 5 / 7)];
519                 for (; x < width * 6 / 7; ++x)
520                         ((struct color_rgb24 *)mem)[x] =
521                                 colors_bottom[(x - width * 5 / 7) * 3
522                                                           / (width / 7) + 4];
523                 for (; x < width; ++x)
524                         ((struct color_rgb24 *)mem)[x] = colors_bottom[7];
525                 mem += stride;
526         }
527 }
528
529 static void
530 fill_smpte_rgb32(const struct rgb_info *rgb, unsigned char *mem,
531                                  unsigned int width, unsigned int height, unsigned int stride)
532 {
533         const uint32_t colors_top[] = {
534                 MAKE_RGBA(rgb, 192, 192, 192, 255),     /* grey */
535                 MAKE_RGBA(rgb, 192, 192, 0, 255),       /* yellow */
536                 MAKE_RGBA(rgb, 0, 192, 192, 255),       /* cyan */
537                 MAKE_RGBA(rgb, 0, 192, 0, 255),         /* green */
538                 MAKE_RGBA(rgb, 192, 0, 192, 255),       /* magenta */
539                 MAKE_RGBA(rgb, 192, 0, 0, 255),         /* red */
540                 MAKE_RGBA(rgb, 0, 0, 192, 255),         /* blue */
541         };
542         const uint32_t colors_middle[] = {
543                 MAKE_RGBA(rgb, 0, 0, 192, 255),         /* blue */
544                 MAKE_RGBA(rgb, 19, 19, 19, 255),        /* black */
545                 MAKE_RGBA(rgb, 192, 0, 192, 255),       /* magenta */
546                 MAKE_RGBA(rgb, 19, 19, 19, 255),        /* black */
547                 MAKE_RGBA(rgb, 0, 192, 192, 255),       /* cyan */
548                 MAKE_RGBA(rgb, 19, 19, 19, 255),        /* black */
549                 MAKE_RGBA(rgb, 192, 192, 192, 255),     /* grey */
550         };
551         const uint32_t colors_bottom[] = {
552                 MAKE_RGBA(rgb, 0, 33, 76, 255),         /* in-phase */
553                 MAKE_RGBA(rgb, 255, 255, 255, 255),     /* super white */
554                 MAKE_RGBA(rgb, 50, 0, 106, 255),        /* quadrature */
555                 MAKE_RGBA(rgb, 19, 19, 19, 255),        /* black */
556                 MAKE_RGBA(rgb, 9, 9, 9, 255),           /* 3.5% */
557                 MAKE_RGBA(rgb, 19, 19, 19, 255),        /* 7.5% */
558                 MAKE_RGBA(rgb, 29, 29, 29, 255),        /* 11.5% */
559                 MAKE_RGBA(rgb, 19, 19, 19, 255),        /* black */
560         };
561         unsigned int x;
562         unsigned int y;
563
564         if (width < 8)
565                 return;
566
567         for (y = 0; y < height * 6 / 9; ++y) {
568                 for (x = 0; x < width; ++x)
569                         ((uint32_t *)mem)[x] = colors_top[x * 7 / width];
570                 mem += stride;
571         }
572
573         for (; y < height * 7 / 9; ++y) {
574                 for (x = 0; x < width; ++x)
575                         ((uint32_t *)mem)[x] = colors_middle[x * 7 / width];
576                 mem += stride;
577         }
578
579         for (; y < height; ++y) {
580                 for (x = 0; x < width * 5 / 7; ++x)
581                         ((uint32_t *)mem)[x] =
582                                 colors_bottom[x * 4 / (width * 5 / 7)];
583                 for (; x < width * 6 / 7; ++x)
584                         ((uint32_t *)mem)[x] =
585                                 colors_bottom[(x - width * 5 / 7) * 3
586                                                           / (width / 7) + 4];
587                 for (; x < width; ++x) {
588                         ((uint32_t *)mem)[x] = (rand_r(&rand_seed) % 2) ? MAKE_RGBA(rgb, 255, 255, 255, 255) : MAKE_RGBA(rgb, 0, 0, 0, 255);
589                 }
590                 mem += stride;
591         }
592 }
593
594 static void
595 fill_smpte(const struct format_info *info, void *planes[3], unsigned int width,
596                    unsigned int height, unsigned int stride)
597 {
598         unsigned char *u, *v;
599
600         switch (info->format) {
601         case TBM_FORMAT_UYVY:
602         case TBM_FORMAT_VYUY:
603         case TBM_FORMAT_YUYV:
604         case TBM_FORMAT_YVYU:
605                 return fill_smpte_yuv_packed(&info->yuv, planes[0], width,
606                                                                          height, stride);
607
608         case TBM_FORMAT_NV12:
609         case TBM_FORMAT_NV21:
610         case TBM_FORMAT_NV16:
611         case TBM_FORMAT_NV61:
612                 u = info->yuv.order & YUV_YCbCr ? planes[1] : planes[1] + 1;
613                 v = info->yuv.order & YUV_YCrCb ? planes[1] : planes[1] + 1;
614                 return fill_smpte_yuv_planar(&info->yuv, planes[0], u, v,
615                                                                          width, height, stride);
616
617         case TBM_FORMAT_YUV420:
618                 return fill_smpte_yuv_planar(&info->yuv, planes[0], planes[1],
619                                                                          planes[2], width, height, stride);
620
621         case TBM_FORMAT_YVU420:
622                 return fill_smpte_yuv_planar(&info->yuv, planes[0], planes[2],
623                                                                          planes[1], width, height, stride);
624
625         case TBM_FORMAT_ARGB4444:
626         case TBM_FORMAT_XRGB4444:
627         case TBM_FORMAT_ABGR4444:
628         case TBM_FORMAT_XBGR4444:
629         case TBM_FORMAT_RGBA4444:
630         case TBM_FORMAT_RGBX4444:
631         case TBM_FORMAT_BGRA4444:
632         case TBM_FORMAT_BGRX4444:
633         case TBM_FORMAT_RGB565:
634         case TBM_FORMAT_BGR565:
635         case TBM_FORMAT_ARGB1555:
636         case TBM_FORMAT_XRGB1555:
637         case TBM_FORMAT_ABGR1555:
638         case TBM_FORMAT_XBGR1555:
639         case TBM_FORMAT_RGBA5551:
640         case TBM_FORMAT_RGBX5551:
641         case TBM_FORMAT_BGRA5551:
642         case TBM_FORMAT_BGRX5551:
643                 return fill_smpte_rgb16(&info->rgb, planes[0],
644                                                                 width, height, stride);
645
646         case TBM_FORMAT_BGR888:
647         case TBM_FORMAT_RGB888:
648                 return fill_smpte_rgb24(&info->rgb, planes[0],
649                                                                 width, height, stride);
650         case TBM_FORMAT_ARGB8888:
651         case TBM_FORMAT_XRGB8888:
652         case TBM_FORMAT_ABGR8888:
653         case TBM_FORMAT_XBGR8888:
654         case TBM_FORMAT_RGBA8888:
655         case TBM_FORMAT_RGBX8888:
656         case TBM_FORMAT_BGRA8888:
657         case TBM_FORMAT_BGRX8888:
658         case TBM_FORMAT_ARGB2101010:
659         case TBM_FORMAT_XRGB2101010:
660         case TBM_FORMAT_ABGR2101010:
661         case TBM_FORMAT_XBGR2101010:
662         case TBM_FORMAT_RGBA1010102:
663         case TBM_FORMAT_RGBX1010102:
664         case TBM_FORMAT_BGRA1010102:
665         case TBM_FORMAT_BGRX1010102:
666                 return fill_smpte_rgb32(&info->rgb, planes[0],
667                                                                 width, height, stride);
668         }
669 }
670
671 static void
672 fill_tiles_yuv_planar(const struct format_info *info,
673                                           unsigned char *y_mem, unsigned char *u_mem,
674                                           unsigned char *v_mem, unsigned int width,
675                                           unsigned int height, unsigned int stride)
676 {
677         const struct yuv_info *yuv = &info->yuv;
678         unsigned int cs = yuv->chroma_stride;
679         unsigned int xsub = yuv->xsub;
680         unsigned int ysub = yuv->ysub;
681         unsigned int x;
682         unsigned int y;
683
684         for (y = 0; y < height; ++y) {
685                 for (x = 0; x < width; ++x) {
686                         div_t d = div(x + y, width);
687                         uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
688                                                          + 0x000a1120 * (d.rem >> 6);
689                         struct color_yuv color =
690                                 MAKE_YUV_601((rgb32 >> 16) & 0xff,
691                                                          (rgb32 >> 8) & 0xff, rgb32 & 0xff);
692
693                         y_mem[x] = color.y;
694                         u_mem[x / xsub * cs] = color.u;
695                         v_mem[x / xsub * cs] = color.v;
696                 }
697
698                 y_mem += stride;
699                 if ((y + 1) % ysub == 0) {
700                         u_mem += stride * cs / xsub;
701                         v_mem += stride * cs / xsub;
702                 }
703         }
704 }
705
706 static void
707 fill_tiles_yuv_packed(const struct format_info *info, unsigned char *mem,
708                                           unsigned int width, unsigned int height,
709                                           unsigned int stride)
710 {
711         const struct yuv_info *yuv = &info->yuv;
712         unsigned char *y_mem = (yuv->order & YUV_YC) ? mem : mem + 1;
713         unsigned char *c_mem = (yuv->order & YUV_CY) ? mem : mem + 1;
714         unsigned int u = (yuv->order & YUV_YCrCb) ? 2 : 0;
715         unsigned int v = (yuv->order & YUV_YCbCr) ? 2 : 0;
716         unsigned int x;
717         unsigned int y;
718
719         for (y = 0; y < height; ++y) {
720                 for (x = 0; x < width; x += 2) {
721                         div_t d = div(x + y, width);
722                         uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
723                                                          + 0x000a1120 * (d.rem >> 6);
724                         struct color_yuv color =
725                                 MAKE_YUV_601((rgb32 >> 16) & 0xff,
726                                                          (rgb32 >> 8) & 0xff, rgb32 & 0xff);
727
728                         y_mem[2 * x] = color.y;
729                         c_mem[2 * x + u] = color.u;
730                         y_mem[2 * x + 2] = color.y;
731                         c_mem[2 * x + v] = color.v;
732                 }
733
734                 y_mem += stride;
735                 c_mem += stride;
736         }
737 }
738
739 static void
740 fill_tiles_rgb16(const struct format_info *info, unsigned char *mem,
741                                  unsigned int width, unsigned int height, unsigned int stride)
742 {
743         const struct rgb_info *rgb = &info->rgb;
744         unsigned int x, y;
745
746         for (y = 0; y < height; ++y) {
747                 for (x = 0; x < width; ++x) {
748                         div_t d = div(x + y, width);
749                         uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
750                                                          + 0x000a1120 * (d.rem >> 6);
751                         uint16_t color =
752                                 MAKE_RGBA(rgb, (rgb32 >> 16) & 0xff,
753                                                   (rgb32 >> 8) & 0xff, rgb32 & 0xff,
754                                                   255);
755
756                         ((uint16_t *)mem)[x] = color;
757                 }
758                 mem += stride;
759         }
760 }
761
762 static void
763 fill_tiles_rgb24(const struct format_info *info, unsigned char *mem,
764                                  unsigned int width, unsigned int height, unsigned int stride)
765 {
766         const struct rgb_info *rgb = &info->rgb;
767         unsigned int x, y;
768
769         for (y = 0; y < height; ++y) {
770                 for (x = 0; x < width; ++x) {
771                         div_t d = div(x + y, width);
772                         uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
773                                                          + 0x000a1120 * (d.rem >> 6);
774                         struct color_rgb24 color =
775                                 MAKE_RGB24(rgb, (rgb32 >> 16) & 0xff,
776                                                    (rgb32 >> 8) & 0xff, rgb32 & 0xff);
777
778                         ((struct color_rgb24 *)mem)[x] = color;
779                 }
780                 mem += stride;
781         }
782 }
783
784 static void
785 fill_tiles_rgb32(const struct format_info *info, unsigned char *mem,
786                                  unsigned int width, unsigned int height, unsigned int stride)
787 {
788         const struct rgb_info *rgb = &info->rgb;
789         unsigned int x, y;
790
791         for (y = 0; y < height; ++y) {
792                 for (x = 0; x < width; ++x) {
793                         div_t d = div(x + y, width);
794                         uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
795                                                          + 0x000a1120 * (d.rem >> 6);
796                         uint32_t color =
797                                 MAKE_RGBA(rgb, (rgb32 >> 16) & 0xff,
798                                                   (rgb32 >> 8) & 0xff, rgb32 & 0xff,
799                                                   255);
800
801                         ((uint32_t *)mem)[x] = color;
802                 }
803                 mem += stride;
804         }
805 }
806
807 static void
808 fill_tiles(const struct format_info *info, void *planes[3], unsigned int width,
809                    unsigned int height, unsigned int stride)
810 {
811         unsigned char *u, *v;
812
813         switch (info->format) {
814         case TBM_FORMAT_UYVY:
815         case TBM_FORMAT_VYUY:
816         case TBM_FORMAT_YUYV:
817         case TBM_FORMAT_YVYU:
818                 return fill_tiles_yuv_packed(info, planes[0],
819                                                                          width, height, stride);
820
821         case TBM_FORMAT_NV12:
822         case TBM_FORMAT_NV21:
823         case TBM_FORMAT_NV16:
824         case TBM_FORMAT_NV61:
825                 u = info->yuv.order & YUV_YCbCr ? planes[1] : planes[1] + 1;
826                 v = info->yuv.order & YUV_YCrCb ? planes[1] : planes[1] + 1;
827                 return fill_tiles_yuv_planar(info, planes[0], u, v,
828                                                                          width, height, stride);
829
830         case TBM_FORMAT_YUV420:
831                 return fill_tiles_yuv_planar(info, planes[0], planes[1],
832                                                                          planes[2], width, height, stride);
833
834         case TBM_FORMAT_YVU420:
835                 return fill_tiles_yuv_planar(info, planes[0], planes[2],
836                                                                          planes[1], width, height, stride);
837
838         case TBM_FORMAT_ARGB4444:
839         case TBM_FORMAT_XRGB4444:
840         case TBM_FORMAT_ABGR4444:
841         case TBM_FORMAT_XBGR4444:
842         case TBM_FORMAT_RGBA4444:
843         case TBM_FORMAT_RGBX4444:
844         case TBM_FORMAT_BGRA4444:
845         case TBM_FORMAT_BGRX4444:
846         case TBM_FORMAT_RGB565:
847         case TBM_FORMAT_BGR565:
848         case TBM_FORMAT_ARGB1555:
849         case TBM_FORMAT_XRGB1555:
850         case TBM_FORMAT_ABGR1555:
851         case TBM_FORMAT_XBGR1555:
852         case TBM_FORMAT_RGBA5551:
853         case TBM_FORMAT_RGBX5551:
854         case TBM_FORMAT_BGRA5551:
855         case TBM_FORMAT_BGRX5551:
856                 return fill_tiles_rgb16(info, planes[0],
857                                                                 width, height, stride);
858
859         case TBM_FORMAT_BGR888:
860         case TBM_FORMAT_RGB888:
861                 return fill_tiles_rgb24(info, planes[0],
862                                                                 width, height, stride);
863         case TBM_FORMAT_ARGB8888:
864         case TBM_FORMAT_XRGB8888:
865         case TBM_FORMAT_ABGR8888:
866         case TBM_FORMAT_XBGR8888:
867         case TBM_FORMAT_RGBA8888:
868         case TBM_FORMAT_RGBX8888:
869         case TBM_FORMAT_BGRA8888:
870         case TBM_FORMAT_BGRX8888:
871         case TBM_FORMAT_ARGB2101010:
872         case TBM_FORMAT_XRGB2101010:
873         case TBM_FORMAT_ABGR2101010:
874         case TBM_FORMAT_XBGR2101010:
875         case TBM_FORMAT_RGBA1010102:
876         case TBM_FORMAT_RGBX1010102:
877         case TBM_FORMAT_BGRA1010102:
878         case TBM_FORMAT_BGRX1010102:
879                 return fill_tiles_rgb32(info, planes[0],
880                                                                 width, height, stride);
881         }
882 }
883
884 static void
885 fill_plain(const struct format_info *info, void *planes[3], unsigned int width,
886                    unsigned int height, unsigned int stride)
887 {
888         memset(planes[0], 0x77, stride * height);
889 }
890
891 /*
892  * fill_pattern - Fill a buffer with a test pattern
893  * @format: Pixel format
894  * @pattern: Test pattern
895  * @buffer: Buffer memory
896  * @width: Width in pixels
897  * @height: Height in pixels
898  * @stride: Line stride (pitch) in bytes
899  *
900  * Fill the buffer with the test pattern specified by the pattern parameter.
901  * Supported formats vary depending on the selected pattern.
902  */
903 static void
904 fill_pattern(unsigned int format, enum fill_pattern pattern, void *planes[3],
905                          unsigned int width, unsigned int height, unsigned int stride)
906 {
907         const struct format_info *info = NULL;
908         unsigned int i;
909
910         for (i = 0; i < ARRAY_SIZE(format_info); ++i) {
911                 if (format_info[i].format == format) {
912                         info = &format_info[i];
913                         break;
914                 }
915         }
916
917         if (info == NULL)
918                 return;
919
920         switch (pattern) {
921         case PATTERN_TILES:
922                 return fill_tiles(info, planes, width, height, stride);
923
924         case PATTERN_SMPTE:
925                 return fill_smpte(info, planes, width, height, stride);
926
927         case PATTERN_PLAIN:
928                 return fill_plain(info, planes, width, height, stride);
929
930         default:
931                 printf("Error: unsupported test pattern %u.\n", pattern);
932                 break;
933         }
934 }
935
936 void
937 tdm_test_buffer_fill(tbm_surface_h buffer, int pattern)
938 {
939         tbm_surface_info_s info;
940         void *plane[3];
941         int ret;
942
943         if (rand_seed == 0)
944                 rand_seed = time(NULL);
945
946         ret = tbm_surface_map(buffer, TBM_OPTION_WRITE, &info);
947         TDM_EXIT_IF_FAIL(ret == 0);
948
949         plane[0] = info.planes[0].ptr;
950         plane[1] = info.planes[1].ptr;
951         plane[2] = info.planes[2].ptr;
952         fill_pattern(info.format, pattern, plane, info.width, info.height, info.planes[0].stride);
953         tbm_surface_unmap(buffer);
954 }