2 * Copyright 2008 Tungsten Graphics
3 * Jakob Bornecrantz <jakob@tungstengraphics.com>
4 * Copyright 2008 Intel Corporation
5 * Jesse Barnes <jesse.barnes@intel.com>
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
31 #include <drm_fourcc.h>
43 unsigned int value:24;
44 } __attribute__((__packed__));
52 #define MAKE_YUV_601_Y(r, g, b) \
53 ((( 66 * (r) + 129 * (g) + 25 * (b) + 128) >> 8) + 16)
54 #define MAKE_YUV_601_U(r, g, b) \
55 (((-38 * (r) - 74 * (g) + 112 * (b) + 128) >> 8) + 128)
56 #define MAKE_YUV_601_V(r, g, b) \
57 (((112 * (r) - 94 * (g) - 18 * (b) + 128) >> 8) + 128)
59 #define MAKE_YUV_601(r, g, b) \
60 { .y = MAKE_YUV_601_Y(r, g, b), \
61 .u = MAKE_YUV_601_U(r, g, b), \
62 .v = MAKE_YUV_601_V(r, g, b) }
64 /* This function takes 8-bit color values */
65 static inline uint32_t shiftcolor8(const struct util_color_component *comp,
69 /* Fill the low bits with the high bits. */
70 value = (value << 8) | value;
71 /* Shift down to remove unwanted low bits */
72 value = value >> (16 - comp->length);
73 /* Shift back up to where the value should be */
74 return value << comp->offset;
77 /* This function takes 10-bit color values */
78 static inline uint32_t shiftcolor10(const struct util_color_component *comp,
82 /* Fill the low bits with the high bits. */
83 value = (value << 6) | (value >> 4);
84 /* Shift down to remove unwanted low bits */
85 value = value >> (16 - comp->length);
86 /* Shift back up to where the value should be */
87 return value << comp->offset;
90 /* This function takes 16-bit color values */
91 static inline uint64_t shiftcolor16(const struct util_color_component *comp,
95 /* Shift down to remove unwanted low bits */
96 value = value >> (16 - comp->length);
97 /* Shift back up to where the value should be */
98 return value << comp->offset;
101 #define MAKE_RGBA10(rgb, r, g, b, a) \
102 (shiftcolor10(&(rgb)->red, (r)) | \
103 shiftcolor10(&(rgb)->green, (g)) | \
104 shiftcolor10(&(rgb)->blue, (b)) | \
105 shiftcolor10(&(rgb)->alpha, (a)))
107 #define MAKE_RGBA(rgb, r, g, b, a) \
108 (shiftcolor8(&(rgb)->red, (r)) | \
109 shiftcolor8(&(rgb)->green, (g)) | \
110 shiftcolor8(&(rgb)->blue, (b)) | \
111 shiftcolor8(&(rgb)->alpha, (a)))
113 #define MAKE_RGB24(rgb, r, g, b) \
114 { .value = MAKE_RGBA(rgb, r, g, b, 0) }
118 * Takes a uint16_t, divides by 65536, converts the infinite-precision
119 * result to fp16 with round-to-zero.
121 * Copied from mesa:src/util/half_float.c
123 static uint16_t uint16_div_64k_to_half(uint16_t v)
125 /* Zero or subnormal. Set the mantissa to (v << 8) and return. */
129 /* Count the leading 0s in the uint16_t */
130 int n = __builtin_clz(v) - 16;
132 /* Shift the mantissa up so bit 16 is the hidden 1 bit,
133 * mask it off, then shift back down to 10 bits
135 int m = ( ((uint32_t)v << (n + 1)) & 0xffff ) >> 6;
137 /* (0{n} 1 X{15-n}) * 2^-16
138 * = 1.X * 2^(15-n-16)
139 * = 1.X * 2^(14-n - 15)
140 * which is the FP16 form with e = 14 - n
144 return (e << 10) | m;
147 #define MAKE_RGBA8FP16(rgb, r, g, b, a) \
148 (shiftcolor16(&(rgb)->red, uint16_div_64k_to_half((r) << 8)) | \
149 shiftcolor16(&(rgb)->green, uint16_div_64k_to_half((g) << 8)) | \
150 shiftcolor16(&(rgb)->blue, uint16_div_64k_to_half((b) << 8)) | \
151 shiftcolor16(&(rgb)->alpha, uint16_div_64k_to_half((a) << 8)))
153 #define MAKE_RGBA10FP16(rgb, r, g, b, a) \
154 (shiftcolor16(&(rgb)->red, uint16_div_64k_to_half((r) << 6)) | \
155 shiftcolor16(&(rgb)->green, uint16_div_64k_to_half((g) << 6)) | \
156 shiftcolor16(&(rgb)->blue, uint16_div_64k_to_half((b) << 6)) | \
157 shiftcolor16(&(rgb)->alpha, uint16_div_64k_to_half((a) << 6)))
159 static void fill_smpte_yuv_planar(const struct util_yuv_info *yuv,
160 unsigned char *y_mem, unsigned char *u_mem,
161 unsigned char *v_mem, unsigned int width,
162 unsigned int height, unsigned int stride)
164 const struct color_yuv colors_top[] = {
165 MAKE_YUV_601(192, 192, 192), /* grey */
166 MAKE_YUV_601(192, 192, 0), /* yellow */
167 MAKE_YUV_601(0, 192, 192), /* cyan */
168 MAKE_YUV_601(0, 192, 0), /* green */
169 MAKE_YUV_601(192, 0, 192), /* magenta */
170 MAKE_YUV_601(192, 0, 0), /* red */
171 MAKE_YUV_601(0, 0, 192), /* blue */
173 const struct color_yuv colors_middle[] = {
174 MAKE_YUV_601(0, 0, 192), /* blue */
175 MAKE_YUV_601(19, 19, 19), /* black */
176 MAKE_YUV_601(192, 0, 192), /* magenta */
177 MAKE_YUV_601(19, 19, 19), /* black */
178 MAKE_YUV_601(0, 192, 192), /* cyan */
179 MAKE_YUV_601(19, 19, 19), /* black */
180 MAKE_YUV_601(192, 192, 192), /* grey */
182 const struct color_yuv colors_bottom[] = {
183 MAKE_YUV_601(0, 33, 76), /* in-phase */
184 MAKE_YUV_601(255, 255, 255), /* super white */
185 MAKE_YUV_601(50, 0, 106), /* quadrature */
186 MAKE_YUV_601(19, 19, 19), /* black */
187 MAKE_YUV_601(9, 9, 9), /* 3.5% */
188 MAKE_YUV_601(19, 19, 19), /* 7.5% */
189 MAKE_YUV_601(29, 29, 29), /* 11.5% */
190 MAKE_YUV_601(19, 19, 19), /* black */
192 unsigned int cs = yuv->chroma_stride;
193 unsigned int xsub = yuv->xsub;
194 unsigned int ysub = yuv->ysub;
199 for (y = 0; y < height * 6 / 9; ++y) {
200 for (x = 0; x < width; ++x)
201 y_mem[x] = colors_top[x * 7 / width].y;
205 for (; y < height * 7 / 9; ++y) {
206 for (x = 0; x < width; ++x)
207 y_mem[x] = colors_middle[x * 7 / width].y;
211 for (; y < height; ++y) {
212 for (x = 0; x < width * 5 / 7; ++x)
213 y_mem[x] = colors_bottom[x * 4 / (width * 5 / 7)].y;
214 for (; x < width * 6 / 7; ++x)
215 y_mem[x] = colors_bottom[(x - width * 5 / 7) * 3
216 / (width / 7) + 4].y;
217 for (; x < width; ++x)
218 y_mem[x] = colors_bottom[7].y;
223 for (y = 0; y < height / ysub * 6 / 9; ++y) {
224 for (x = 0; x < width; x += xsub) {
225 u_mem[x*cs/xsub] = colors_top[x * 7 / width].u;
226 v_mem[x*cs/xsub] = colors_top[x * 7 / width].v;
228 u_mem += stride * cs / xsub;
229 v_mem += stride * cs / xsub;
232 for (; y < height / ysub * 7 / 9; ++y) {
233 for (x = 0; x < width; x += xsub) {
234 u_mem[x*cs/xsub] = colors_middle[x * 7 / width].u;
235 v_mem[x*cs/xsub] = colors_middle[x * 7 / width].v;
237 u_mem += stride * cs / xsub;
238 v_mem += stride * cs / xsub;
241 for (; y < height / ysub; ++y) {
242 for (x = 0; x < width * 5 / 7; x += xsub) {
244 colors_bottom[x * 4 / (width * 5 / 7)].u;
246 colors_bottom[x * 4 / (width * 5 / 7)].v;
248 for (; x < width * 6 / 7; x += xsub) {
249 u_mem[x*cs/xsub] = colors_bottom[(x - width * 5 / 7) *
250 3 / (width / 7) + 4].u;
251 v_mem[x*cs/xsub] = colors_bottom[(x - width * 5 / 7) *
252 3 / (width / 7) + 4].v;
254 for (; x < width; x += xsub) {
255 u_mem[x*cs/xsub] = colors_bottom[7].u;
256 v_mem[x*cs/xsub] = colors_bottom[7].v;
258 u_mem += stride * cs / xsub;
259 v_mem += stride * cs / xsub;
263 static void fill_smpte_yuv_packed(const struct util_yuv_info *yuv, void *mem,
264 unsigned int width, unsigned int height,
267 const struct color_yuv colors_top[] = {
268 MAKE_YUV_601(192, 192, 192), /* grey */
269 MAKE_YUV_601(192, 192, 0), /* yellow */
270 MAKE_YUV_601(0, 192, 192), /* cyan */
271 MAKE_YUV_601(0, 192, 0), /* green */
272 MAKE_YUV_601(192, 0, 192), /* magenta */
273 MAKE_YUV_601(192, 0, 0), /* red */
274 MAKE_YUV_601(0, 0, 192), /* blue */
276 const struct color_yuv colors_middle[] = {
277 MAKE_YUV_601(0, 0, 192), /* blue */
278 MAKE_YUV_601(19, 19, 19), /* black */
279 MAKE_YUV_601(192, 0, 192), /* magenta */
280 MAKE_YUV_601(19, 19, 19), /* black */
281 MAKE_YUV_601(0, 192, 192), /* cyan */
282 MAKE_YUV_601(19, 19, 19), /* black */
283 MAKE_YUV_601(192, 192, 192), /* grey */
285 const struct color_yuv colors_bottom[] = {
286 MAKE_YUV_601(0, 33, 76), /* in-phase */
287 MAKE_YUV_601(255, 255, 255), /* super white */
288 MAKE_YUV_601(50, 0, 106), /* quadrature */
289 MAKE_YUV_601(19, 19, 19), /* black */
290 MAKE_YUV_601(9, 9, 9), /* 3.5% */
291 MAKE_YUV_601(19, 19, 19), /* 7.5% */
292 MAKE_YUV_601(29, 29, 29), /* 11.5% */
293 MAKE_YUV_601(19, 19, 19), /* black */
295 unsigned char *y_mem = (yuv->order & YUV_YC) ? mem : mem + 1;
296 unsigned char *c_mem = (yuv->order & YUV_CY) ? mem : mem + 1;
297 unsigned int u = (yuv->order & YUV_YCrCb) ? 2 : 0;
298 unsigned int v = (yuv->order & YUV_YCbCr) ? 2 : 0;
303 for (y = 0; y < height * 6 / 9; ++y) {
304 for (x = 0; x < width; ++x)
305 y_mem[2*x] = colors_top[x * 7 / width].y;
309 for (; y < height * 7 / 9; ++y) {
310 for (x = 0; x < width; ++x)
311 y_mem[2*x] = colors_middle[x * 7 / width].y;
315 for (; y < height; ++y) {
316 for (x = 0; x < width * 5 / 7; ++x)
317 y_mem[2*x] = colors_bottom[x * 4 / (width * 5 / 7)].y;
318 for (; x < width * 6 / 7; ++x)
319 y_mem[2*x] = colors_bottom[(x - width * 5 / 7) * 3
320 / (width / 7) + 4].y;
321 for (; x < width; ++x)
322 y_mem[2*x] = colors_bottom[7].y;
327 for (y = 0; y < height * 6 / 9; ++y) {
328 for (x = 0; x < width; x += 2) {
329 c_mem[2*x+u] = colors_top[x * 7 / width].u;
330 c_mem[2*x+v] = colors_top[x * 7 / width].v;
335 for (; y < height * 7 / 9; ++y) {
336 for (x = 0; x < width; x += 2) {
337 c_mem[2*x+u] = colors_middle[x * 7 / width].u;
338 c_mem[2*x+v] = colors_middle[x * 7 / width].v;
343 for (; y < height; ++y) {
344 for (x = 0; x < width * 5 / 7; x += 2) {
345 c_mem[2*x+u] = colors_bottom[x * 4 / (width * 5 / 7)].u;
346 c_mem[2*x+v] = colors_bottom[x * 4 / (width * 5 / 7)].v;
348 for (; x < width * 6 / 7; x += 2) {
349 c_mem[2*x+u] = colors_bottom[(x - width * 5 / 7) *
350 3 / (width / 7) + 4].u;
351 c_mem[2*x+v] = colors_bottom[(x - width * 5 / 7) *
352 3 / (width / 7) + 4].v;
354 for (; x < width; x += 2) {
355 c_mem[2*x+u] = colors_bottom[7].u;
356 c_mem[2*x+v] = colors_bottom[7].v;
362 static void fill_smpte_rgb16(const struct util_rgb_info *rgb, void *mem,
363 unsigned int width, unsigned int height,
366 const uint16_t colors_top[] = {
367 MAKE_RGBA(rgb, 192, 192, 192, 255), /* grey */
368 MAKE_RGBA(rgb, 192, 192, 0, 255), /* yellow */
369 MAKE_RGBA(rgb, 0, 192, 192, 255), /* cyan */
370 MAKE_RGBA(rgb, 0, 192, 0, 255), /* green */
371 MAKE_RGBA(rgb, 192, 0, 192, 255), /* magenta */
372 MAKE_RGBA(rgb, 192, 0, 0, 255), /* red */
373 MAKE_RGBA(rgb, 0, 0, 192, 255), /* blue */
375 const uint16_t colors_middle[] = {
376 MAKE_RGBA(rgb, 0, 0, 192, 127), /* blue */
377 MAKE_RGBA(rgb, 19, 19, 19, 127), /* black */
378 MAKE_RGBA(rgb, 192, 0, 192, 127), /* magenta */
379 MAKE_RGBA(rgb, 19, 19, 19, 127), /* black */
380 MAKE_RGBA(rgb, 0, 192, 192, 127), /* cyan */
381 MAKE_RGBA(rgb, 19, 19, 19, 127), /* black */
382 MAKE_RGBA(rgb, 192, 192, 192, 127), /* grey */
384 const uint16_t colors_bottom[] = {
385 MAKE_RGBA(rgb, 0, 33, 76, 255), /* in-phase */
386 MAKE_RGBA(rgb, 255, 255, 255, 255), /* super white */
387 MAKE_RGBA(rgb, 50, 0, 106, 255), /* quadrature */
388 MAKE_RGBA(rgb, 19, 19, 19, 255), /* black */
389 MAKE_RGBA(rgb, 9, 9, 9, 255), /* 3.5% */
390 MAKE_RGBA(rgb, 19, 19, 19, 255), /* 7.5% */
391 MAKE_RGBA(rgb, 29, 29, 29, 255), /* 11.5% */
392 MAKE_RGBA(rgb, 19, 19, 19, 255), /* black */
397 for (y = 0; y < height * 6 / 9; ++y) {
398 for (x = 0; x < width; ++x)
399 ((uint16_t *)mem)[x] = colors_top[x * 7 / width];
403 for (; y < height * 7 / 9; ++y) {
404 for (x = 0; x < width; ++x)
405 ((uint16_t *)mem)[x] = colors_middle[x * 7 / width];
409 for (; y < height; ++y) {
410 for (x = 0; x < width * 5 / 7; ++x)
411 ((uint16_t *)mem)[x] =
412 colors_bottom[x * 4 / (width * 5 / 7)];
413 for (; x < width * 6 / 7; ++x)
414 ((uint16_t *)mem)[x] =
415 colors_bottom[(x - width * 5 / 7) * 3
417 for (; x < width; ++x)
418 ((uint16_t *)mem)[x] = colors_bottom[7];
423 static void fill_smpte_rgb24(const struct util_rgb_info *rgb, void *mem,
424 unsigned int width, unsigned int height,
427 const struct color_rgb24 colors_top[] = {
428 MAKE_RGB24(rgb, 192, 192, 192), /* grey */
429 MAKE_RGB24(rgb, 192, 192, 0), /* yellow */
430 MAKE_RGB24(rgb, 0, 192, 192), /* cyan */
431 MAKE_RGB24(rgb, 0, 192, 0), /* green */
432 MAKE_RGB24(rgb, 192, 0, 192), /* magenta */
433 MAKE_RGB24(rgb, 192, 0, 0), /* red */
434 MAKE_RGB24(rgb, 0, 0, 192), /* blue */
436 const struct color_rgb24 colors_middle[] = {
437 MAKE_RGB24(rgb, 0, 0, 192), /* blue */
438 MAKE_RGB24(rgb, 19, 19, 19), /* black */
439 MAKE_RGB24(rgb, 192, 0, 192), /* magenta */
440 MAKE_RGB24(rgb, 19, 19, 19), /* black */
441 MAKE_RGB24(rgb, 0, 192, 192), /* cyan */
442 MAKE_RGB24(rgb, 19, 19, 19), /* black */
443 MAKE_RGB24(rgb, 192, 192, 192), /* grey */
445 const struct color_rgb24 colors_bottom[] = {
446 MAKE_RGB24(rgb, 0, 33, 76), /* in-phase */
447 MAKE_RGB24(rgb, 255, 255, 255), /* super white */
448 MAKE_RGB24(rgb, 50, 0, 106), /* quadrature */
449 MAKE_RGB24(rgb, 19, 19, 19), /* black */
450 MAKE_RGB24(rgb, 9, 9, 9), /* 3.5% */
451 MAKE_RGB24(rgb, 19, 19, 19), /* 7.5% */
452 MAKE_RGB24(rgb, 29, 29, 29), /* 11.5% */
453 MAKE_RGB24(rgb, 19, 19, 19), /* black */
458 for (y = 0; y < height * 6 / 9; ++y) {
459 for (x = 0; x < width; ++x)
460 ((struct color_rgb24 *)mem)[x] =
461 colors_top[x * 7 / width];
465 for (; y < height * 7 / 9; ++y) {
466 for (x = 0; x < width; ++x)
467 ((struct color_rgb24 *)mem)[x] =
468 colors_middle[x * 7 / width];
472 for (; y < height; ++y) {
473 for (x = 0; x < width * 5 / 7; ++x)
474 ((struct color_rgb24 *)mem)[x] =
475 colors_bottom[x * 4 / (width * 5 / 7)];
476 for (; x < width * 6 / 7; ++x)
477 ((struct color_rgb24 *)mem)[x] =
478 colors_bottom[(x - width * 5 / 7) * 3
480 for (; x < width; ++x)
481 ((struct color_rgb24 *)mem)[x] = colors_bottom[7];
486 static void fill_smpte_rgb32(const struct util_rgb_info *rgb, void *mem,
487 unsigned int width, unsigned int height,
490 const uint32_t colors_top[] = {
491 MAKE_RGBA(rgb, 192, 192, 192, 255), /* grey */
492 MAKE_RGBA(rgb, 192, 192, 0, 255), /* yellow */
493 MAKE_RGBA(rgb, 0, 192, 192, 255), /* cyan */
494 MAKE_RGBA(rgb, 0, 192, 0, 255), /* green */
495 MAKE_RGBA(rgb, 192, 0, 192, 255), /* magenta */
496 MAKE_RGBA(rgb, 192, 0, 0, 255), /* red */
497 MAKE_RGBA(rgb, 0, 0, 192, 255), /* blue */
499 const uint32_t colors_middle[] = {
500 MAKE_RGBA(rgb, 0, 0, 192, 127), /* blue */
501 MAKE_RGBA(rgb, 19, 19, 19, 127), /* black */
502 MAKE_RGBA(rgb, 192, 0, 192, 127), /* magenta */
503 MAKE_RGBA(rgb, 19, 19, 19, 127), /* black */
504 MAKE_RGBA(rgb, 0, 192, 192, 127), /* cyan */
505 MAKE_RGBA(rgb, 19, 19, 19, 127), /* black */
506 MAKE_RGBA(rgb, 192, 192, 192, 127), /* grey */
508 const uint32_t colors_bottom[] = {
509 MAKE_RGBA(rgb, 0, 33, 76, 255), /* in-phase */
510 MAKE_RGBA(rgb, 255, 255, 255, 255), /* super white */
511 MAKE_RGBA(rgb, 50, 0, 106, 255), /* quadrature */
512 MAKE_RGBA(rgb, 19, 19, 19, 255), /* black */
513 MAKE_RGBA(rgb, 9, 9, 9, 255), /* 3.5% */
514 MAKE_RGBA(rgb, 19, 19, 19, 255), /* 7.5% */
515 MAKE_RGBA(rgb, 29, 29, 29, 255), /* 11.5% */
516 MAKE_RGBA(rgb, 19, 19, 19, 255), /* black */
521 for (y = 0; y < height * 6 / 9; ++y) {
522 for (x = 0; x < width; ++x)
523 ((uint32_t *)mem)[x] = colors_top[x * 7 / width];
527 for (; y < height * 7 / 9; ++y) {
528 for (x = 0; x < width; ++x)
529 ((uint32_t *)mem)[x] = colors_middle[x * 7 / width];
533 for (; y < height; ++y) {
534 for (x = 0; x < width * 5 / 7; ++x)
535 ((uint32_t *)mem)[x] =
536 colors_bottom[x * 4 / (width * 5 / 7)];
537 for (; x < width * 6 / 7; ++x)
538 ((uint32_t *)mem)[x] =
539 colors_bottom[(x - width * 5 / 7) * 3
541 for (; x < width; ++x)
542 ((uint32_t *)mem)[x] = colors_bottom[7];
547 static void fill_smpte_rgb16fp(const struct util_rgb_info *rgb, void *mem,
548 unsigned int width, unsigned int height,
551 const uint64_t colors_top[] = {
552 MAKE_RGBA8FP16(rgb, 192, 192, 192, 255),/* grey */
553 MAKE_RGBA8FP16(rgb, 192, 192, 0, 255), /* yellow */
554 MAKE_RGBA8FP16(rgb, 0, 192, 192, 255), /* cyan */
555 MAKE_RGBA8FP16(rgb, 0, 192, 0, 255), /* green */
556 MAKE_RGBA8FP16(rgb, 192, 0, 192, 255), /* magenta */
557 MAKE_RGBA8FP16(rgb, 192, 0, 0, 255), /* red */
558 MAKE_RGBA8FP16(rgb, 0, 0, 192, 255), /* blue */
560 const uint64_t colors_middle[] = {
561 MAKE_RGBA8FP16(rgb, 0, 0, 192, 127), /* blue */
562 MAKE_RGBA8FP16(rgb, 19, 19, 19, 127), /* black */
563 MAKE_RGBA8FP16(rgb, 192, 0, 192, 127), /* magenta */
564 MAKE_RGBA8FP16(rgb, 19, 19, 19, 127), /* black */
565 MAKE_RGBA8FP16(rgb, 0, 192, 192, 127), /* cyan */
566 MAKE_RGBA8FP16(rgb, 19, 19, 19, 127), /* black */
567 MAKE_RGBA8FP16(rgb, 192, 192, 192, 127),/* grey */
569 const uint64_t colors_bottom[] = {
570 MAKE_RGBA8FP16(rgb, 0, 33, 76, 255), /* in-phase */
571 MAKE_RGBA8FP16(rgb, 255, 255, 255, 255),/* super white */
572 MAKE_RGBA8FP16(rgb, 50, 0, 106, 255), /* quadrature */
573 MAKE_RGBA8FP16(rgb, 19, 19, 19, 255), /* black */
574 MAKE_RGBA8FP16(rgb, 9, 9, 9, 255), /* 3.5% */
575 MAKE_RGBA8FP16(rgb, 19, 19, 19, 255), /* 7.5% */
576 MAKE_RGBA8FP16(rgb, 29, 29, 29, 255), /* 11.5% */
577 MAKE_RGBA8FP16(rgb, 19, 19, 19, 255), /* black */
582 for (y = 0; y < height * 6 / 9; ++y) {
583 for (x = 0; x < width; ++x)
584 ((uint64_t *)mem)[x] = colors_top[x * 7 / width];
588 for (; y < height * 7 / 9; ++y) {
589 for (x = 0; x < width; ++x)
590 ((uint64_t *)mem)[x] = colors_middle[x * 7 / width];
594 for (; y < height; ++y) {
595 for (x = 0; x < width * 5 / 7; ++x)
596 ((uint64_t *)mem)[x] =
597 colors_bottom[x * 4 / (width * 5 / 7)];
598 for (; x < width * 6 / 7; ++x)
599 ((uint64_t *)mem)[x] =
600 colors_bottom[(x - width * 5 / 7) * 3
602 for (; x < width; ++x)
603 ((uint64_t *)mem)[x] = colors_bottom[7];
608 static void fill_smpte_c8(void *mem, unsigned int width, unsigned int height,
614 for (y = 0; y < height * 6 / 9; ++y) {
615 for (x = 0; x < width; ++x)
616 ((uint8_t *)mem)[x] = x * 7 / width;
620 for (; y < height * 7 / 9; ++y) {
621 for (x = 0; x < width; ++x)
622 ((uint8_t *)mem)[x] = 7 + (x * 7 / width);
626 for (; y < height; ++y) {
627 for (x = 0; x < width * 5 / 7; ++x)
628 ((uint8_t *)mem)[x] =
629 14 + (x * 4 / (width * 5 / 7));
630 for (; x < width * 6 / 7; ++x)
631 ((uint8_t *)mem)[x] =
632 14 + ((x - width * 5 / 7) * 3
634 for (; x < width; ++x)
635 ((uint8_t *)mem)[x] = 14 + 7;
640 void util_smpte_c8_gamma(unsigned size, struct drm_color_lut *lut)
642 if (size < 7 + 7 + 8) {
643 printf("Error: gamma too small: %d < %d\n", size, 7 + 7 + 8);
646 memset(lut, 0, size * sizeof(struct drm_color_lut));
648 #define FILL_COLOR(idx, r, g, b) \
649 lut[idx].red = (r) << 8; \
650 lut[idx].green = (g) << 8; \
651 lut[idx].blue = (b) << 8
653 FILL_COLOR( 0, 192, 192, 192); /* grey */
654 FILL_COLOR( 1, 192, 192, 0 ); /* yellow */
655 FILL_COLOR( 2, 0, 192, 192); /* cyan */
656 FILL_COLOR( 3, 0, 192, 0 ); /* green */
657 FILL_COLOR( 4, 192, 0, 192); /* magenta */
658 FILL_COLOR( 5, 192, 0, 0 ); /* red */
659 FILL_COLOR( 6, 0, 0, 192); /* blue */
661 FILL_COLOR( 7, 0, 0, 192); /* blue */
662 FILL_COLOR( 8, 19, 19, 19 ); /* black */
663 FILL_COLOR( 9, 192, 0, 192); /* magenta */
664 FILL_COLOR(10, 19, 19, 19 ); /* black */
665 FILL_COLOR(11, 0, 192, 192); /* cyan */
666 FILL_COLOR(12, 19, 19, 19 ); /* black */
667 FILL_COLOR(13, 192, 192, 192); /* grey */
669 FILL_COLOR(14, 0, 33, 76); /* in-phase */
670 FILL_COLOR(15, 255, 255, 255); /* super white */
671 FILL_COLOR(16, 50, 0, 106); /* quadrature */
672 FILL_COLOR(17, 19, 19, 19); /* black */
673 FILL_COLOR(18, 9, 9, 9); /* 3.5% */
674 FILL_COLOR(19, 19, 19, 19); /* 7.5% */
675 FILL_COLOR(20, 29, 29, 29); /* 11.5% */
676 FILL_COLOR(21, 19, 19, 19); /* black */
681 static void fill_smpte(const struct util_format_info *info, void *planes[3],
682 unsigned int width, unsigned int height,
685 unsigned char *u, *v;
687 switch (info->format) {
689 return fill_smpte_c8(planes[0], width, height, stride);
690 case DRM_FORMAT_UYVY:
691 case DRM_FORMAT_VYUY:
692 case DRM_FORMAT_YUYV:
693 case DRM_FORMAT_YVYU:
694 return fill_smpte_yuv_packed(&info->yuv, planes[0], width,
697 case DRM_FORMAT_NV12:
698 case DRM_FORMAT_NV21:
699 case DRM_FORMAT_NV16:
700 case DRM_FORMAT_NV61:
701 case DRM_FORMAT_NV24:
702 case DRM_FORMAT_NV42:
703 u = info->yuv.order & YUV_YCbCr ? planes[1] : planes[1] + 1;
704 v = info->yuv.order & YUV_YCrCb ? planes[1] : planes[1] + 1;
705 return fill_smpte_yuv_planar(&info->yuv, planes[0], u, v,
706 width, height, stride);
708 case DRM_FORMAT_YUV420:
709 return fill_smpte_yuv_planar(&info->yuv, planes[0], planes[1],
710 planes[2], width, height, stride);
712 case DRM_FORMAT_YVU420:
713 return fill_smpte_yuv_planar(&info->yuv, planes[0], planes[2],
714 planes[1], width, height, stride);
716 case DRM_FORMAT_ARGB4444:
717 case DRM_FORMAT_XRGB4444:
718 case DRM_FORMAT_ABGR4444:
719 case DRM_FORMAT_XBGR4444:
720 case DRM_FORMAT_RGBA4444:
721 case DRM_FORMAT_RGBX4444:
722 case DRM_FORMAT_BGRA4444:
723 case DRM_FORMAT_BGRX4444:
724 case DRM_FORMAT_RGB565:
725 case DRM_FORMAT_BGR565:
726 case DRM_FORMAT_ARGB1555:
727 case DRM_FORMAT_XRGB1555:
728 case DRM_FORMAT_ABGR1555:
729 case DRM_FORMAT_XBGR1555:
730 case DRM_FORMAT_RGBA5551:
731 case DRM_FORMAT_RGBX5551:
732 case DRM_FORMAT_BGRA5551:
733 case DRM_FORMAT_BGRX5551:
734 return fill_smpte_rgb16(&info->rgb, planes[0],
735 width, height, stride);
737 case DRM_FORMAT_BGR888:
738 case DRM_FORMAT_RGB888:
739 return fill_smpte_rgb24(&info->rgb, planes[0],
740 width, height, stride);
741 case DRM_FORMAT_ARGB8888:
742 case DRM_FORMAT_XRGB8888:
743 case DRM_FORMAT_ABGR8888:
744 case DRM_FORMAT_XBGR8888:
745 case DRM_FORMAT_RGBA8888:
746 case DRM_FORMAT_RGBX8888:
747 case DRM_FORMAT_BGRA8888:
748 case DRM_FORMAT_BGRX8888:
749 case DRM_FORMAT_ARGB2101010:
750 case DRM_FORMAT_XRGB2101010:
751 case DRM_FORMAT_ABGR2101010:
752 case DRM_FORMAT_XBGR2101010:
753 case DRM_FORMAT_RGBA1010102:
754 case DRM_FORMAT_RGBX1010102:
755 case DRM_FORMAT_BGRA1010102:
756 case DRM_FORMAT_BGRX1010102:
757 return fill_smpte_rgb32(&info->rgb, planes[0],
758 width, height, stride);
760 case DRM_FORMAT_XRGB16161616F:
761 case DRM_FORMAT_XBGR16161616F:
762 case DRM_FORMAT_ARGB16161616F:
763 case DRM_FORMAT_ABGR16161616F:
764 return fill_smpte_rgb16fp(&info->rgb, planes[0],
765 width, height, stride);
769 /* swap these for big endian.. */
774 static void make_pwetty(void *data, unsigned int width, unsigned int height,
775 unsigned int stride, uint32_t format)
778 cairo_surface_t *surface;
780 cairo_format_t cairo_format;
782 /* we can ignore the order of R,G,B channels */
784 case DRM_FORMAT_XRGB8888:
785 case DRM_FORMAT_ARGB8888:
786 case DRM_FORMAT_XBGR8888:
787 case DRM_FORMAT_ABGR8888:
788 cairo_format = CAIRO_FORMAT_ARGB32;
790 case DRM_FORMAT_RGB565:
791 case DRM_FORMAT_BGR565:
792 cairo_format = CAIRO_FORMAT_RGB16_565;
794 #if CAIRO_VERSION_MAJOR > 1 || (CAIRO_VERSION_MAJOR == 1 && CAIRO_VERSION_MINOR >= 12)
795 case DRM_FORMAT_ARGB2101010:
796 case DRM_FORMAT_XRGB2101010:
797 case DRM_FORMAT_ABGR2101010:
798 case DRM_FORMAT_XBGR2101010:
799 cairo_format = CAIRO_FORMAT_RGB30;
806 surface = cairo_image_surface_create_for_data(data,
810 cr = cairo_create(surface);
811 cairo_surface_destroy(surface);
813 cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
814 for (unsigned x = 0; x < width; x += 250)
815 for (unsigned y = 0; y < height; y += 250) {
818 cairo_move_to(cr, x, y - 20);
819 cairo_line_to(cr, x, y + 20);
820 cairo_move_to(cr, x - 20, y);
821 cairo_line_to(cr, x + 20, y);
822 cairo_new_sub_path(cr);
823 cairo_arc(cr, x, y, 10, 0, M_PI * 2);
824 cairo_set_line_width(cr, 4);
825 cairo_set_source_rgb(cr, 0, 0, 0);
826 cairo_stroke_preserve(cr);
827 cairo_set_source_rgb(cr, 1, 1, 1);
828 cairo_set_line_width(cr, 2);
831 snprintf(buf, sizeof buf, "%d, %d", x, y);
832 cairo_move_to(cr, x + 20, y + 20);
833 cairo_text_path(cr, buf);
834 cairo_set_source_rgb(cr, 0, 0, 0);
835 cairo_stroke_preserve(cr);
836 cairo_set_source_rgb(cr, 1, 1, 1);
844 static void fill_tiles_yuv_planar(const struct util_format_info *info,
845 unsigned char *y_mem, unsigned char *u_mem,
846 unsigned char *v_mem, unsigned int width,
847 unsigned int height, unsigned int stride)
849 const struct util_yuv_info *yuv = &info->yuv;
850 unsigned int cs = yuv->chroma_stride;
851 unsigned int xsub = yuv->xsub;
852 unsigned int ysub = yuv->ysub;
856 for (y = 0; y < height; ++y) {
857 for (x = 0; x < width; ++x) {
858 div_t d = div(x+y, width);
859 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
860 + 0x000a1120 * (d.rem >> 6);
861 struct color_yuv color =
862 MAKE_YUV_601((rgb32 >> 16) & 0xff,
863 (rgb32 >> 8) & 0xff, rgb32 & 0xff);
866 u_mem[x/xsub*cs] = color.u;
867 v_mem[x/xsub*cs] = color.v;
871 if ((y + 1) % ysub == 0) {
872 u_mem += stride * cs / xsub;
873 v_mem += stride * cs / xsub;
878 static void fill_tiles_yuv_packed(const struct util_format_info *info,
879 void *mem, unsigned int width,
880 unsigned int height, unsigned int stride)
882 const struct util_yuv_info *yuv = &info->yuv;
883 unsigned char *y_mem = (yuv->order & YUV_YC) ? mem : mem + 1;
884 unsigned char *c_mem = (yuv->order & YUV_CY) ? mem : mem + 1;
885 unsigned int u = (yuv->order & YUV_YCrCb) ? 2 : 0;
886 unsigned int v = (yuv->order & YUV_YCbCr) ? 2 : 0;
890 for (y = 0; y < height; ++y) {
891 for (x = 0; x < width; x += 2) {
892 div_t d = div(x+y, width);
893 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
894 + 0x000a1120 * (d.rem >> 6);
895 struct color_yuv color =
896 MAKE_YUV_601((rgb32 >> 16) & 0xff,
897 (rgb32 >> 8) & 0xff, rgb32 & 0xff);
899 y_mem[2*x] = color.y;
900 c_mem[2*x+u] = color.u;
901 y_mem[2*x+2] = color.y;
902 c_mem[2*x+v] = color.v;
910 static void fill_tiles_rgb16(const struct util_format_info *info, void *mem,
911 unsigned int width, unsigned int height,
914 const struct util_rgb_info *rgb = &info->rgb;
915 void *mem_base = mem;
918 for (y = 0; y < height; ++y) {
919 for (x = 0; x < width; ++x) {
920 div_t d = div(x+y, width);
921 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
922 + 0x000a1120 * (d.rem >> 6);
924 MAKE_RGBA(rgb, (rgb32 >> 16) & 0xff,
925 (rgb32 >> 8) & 0xff, rgb32 & 0xff,
928 ((uint16_t *)mem)[x] = color;
933 make_pwetty(mem_base, width, height, stride, info->format);
936 static void fill_tiles_rgb24(const struct util_format_info *info, void *mem,
937 unsigned int width, unsigned int height,
940 const struct util_rgb_info *rgb = &info->rgb;
943 for (y = 0; y < height; ++y) {
944 for (x = 0; x < width; ++x) {
945 div_t d = div(x+y, width);
946 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
947 + 0x000a1120 * (d.rem >> 6);
948 struct color_rgb24 color =
949 MAKE_RGB24(rgb, (rgb32 >> 16) & 0xff,
950 (rgb32 >> 8) & 0xff, rgb32 & 0xff);
952 ((struct color_rgb24 *)mem)[x] = color;
958 static void fill_tiles_rgb32(const struct util_format_info *info, void *mem,
959 unsigned int width, unsigned int height,
962 const struct util_rgb_info *rgb = &info->rgb;
963 void *mem_base = mem;
966 for (y = 0; y < height; ++y) {
967 for (x = 0; x < width; ++x) {
968 div_t d = div(x+y, width);
969 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
970 + 0x000a1120 * (d.rem >> 6);
971 uint32_t alpha = ((y < height/2) && (x < width/2)) ? 127 : 255;
973 MAKE_RGBA(rgb, (rgb32 >> 16) & 0xff,
974 (rgb32 >> 8) & 0xff, rgb32 & 0xff,
977 ((uint32_t *)mem)[x] = color;
982 make_pwetty(mem_base, width, height, stride, info->format);
985 static void fill_tiles_rgb16fp(const struct util_format_info *info, void *mem,
986 unsigned int width, unsigned int height,
989 const struct util_rgb_info *rgb = &info->rgb;
992 /* TODO: Give this actual fp16 precision */
993 for (y = 0; y < height; ++y) {
994 for (x = 0; x < width; ++x) {
995 div_t d = div(x+y, width);
996 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
997 + 0x000a1120 * (d.rem >> 6);
998 uint32_t alpha = ((y < height/2) && (x < width/2)) ? 127 : 255;
1000 MAKE_RGBA8FP16(rgb, (rgb32 >> 16) & 0xff,
1001 (rgb32 >> 8) & 0xff, rgb32 & 0xff,
1004 ((uint64_t *)mem)[x] = color;
1010 static void fill_tiles(const struct util_format_info *info, void *planes[3],
1011 unsigned int width, unsigned int height,
1012 unsigned int stride)
1014 unsigned char *u, *v;
1016 switch (info->format) {
1017 case DRM_FORMAT_UYVY:
1018 case DRM_FORMAT_VYUY:
1019 case DRM_FORMAT_YUYV:
1020 case DRM_FORMAT_YVYU:
1021 return fill_tiles_yuv_packed(info, planes[0],
1022 width, height, stride);
1024 case DRM_FORMAT_NV12:
1025 case DRM_FORMAT_NV21:
1026 case DRM_FORMAT_NV16:
1027 case DRM_FORMAT_NV61:
1028 case DRM_FORMAT_NV24:
1029 case DRM_FORMAT_NV42:
1030 u = info->yuv.order & YUV_YCbCr ? planes[1] : planes[1] + 1;
1031 v = info->yuv.order & YUV_YCrCb ? planes[1] : planes[1] + 1;
1032 return fill_tiles_yuv_planar(info, planes[0], u, v,
1033 width, height, stride);
1035 case DRM_FORMAT_YUV420:
1036 return fill_tiles_yuv_planar(info, planes[0], planes[1],
1037 planes[2], width, height, stride);
1039 case DRM_FORMAT_YVU420:
1040 return fill_tiles_yuv_planar(info, planes[0], planes[2],
1041 planes[1], width, height, stride);
1043 case DRM_FORMAT_ARGB4444:
1044 case DRM_FORMAT_XRGB4444:
1045 case DRM_FORMAT_ABGR4444:
1046 case DRM_FORMAT_XBGR4444:
1047 case DRM_FORMAT_RGBA4444:
1048 case DRM_FORMAT_RGBX4444:
1049 case DRM_FORMAT_BGRA4444:
1050 case DRM_FORMAT_BGRX4444:
1051 case DRM_FORMAT_RGB565:
1052 case DRM_FORMAT_BGR565:
1053 case DRM_FORMAT_ARGB1555:
1054 case DRM_FORMAT_XRGB1555:
1055 case DRM_FORMAT_ABGR1555:
1056 case DRM_FORMAT_XBGR1555:
1057 case DRM_FORMAT_RGBA5551:
1058 case DRM_FORMAT_RGBX5551:
1059 case DRM_FORMAT_BGRA5551:
1060 case DRM_FORMAT_BGRX5551:
1061 return fill_tiles_rgb16(info, planes[0],
1062 width, height, stride);
1064 case DRM_FORMAT_BGR888:
1065 case DRM_FORMAT_RGB888:
1066 return fill_tiles_rgb24(info, planes[0],
1067 width, height, stride);
1068 case DRM_FORMAT_ARGB8888:
1069 case DRM_FORMAT_XRGB8888:
1070 case DRM_FORMAT_ABGR8888:
1071 case DRM_FORMAT_XBGR8888:
1072 case DRM_FORMAT_RGBA8888:
1073 case DRM_FORMAT_RGBX8888:
1074 case DRM_FORMAT_BGRA8888:
1075 case DRM_FORMAT_BGRX8888:
1076 case DRM_FORMAT_ARGB2101010:
1077 case DRM_FORMAT_XRGB2101010:
1078 case DRM_FORMAT_ABGR2101010:
1079 case DRM_FORMAT_XBGR2101010:
1080 case DRM_FORMAT_RGBA1010102:
1081 case DRM_FORMAT_RGBX1010102:
1082 case DRM_FORMAT_BGRA1010102:
1083 case DRM_FORMAT_BGRX1010102:
1084 return fill_tiles_rgb32(info, planes[0],
1085 width, height, stride);
1087 case DRM_FORMAT_XRGB16161616F:
1088 case DRM_FORMAT_XBGR16161616F:
1089 case DRM_FORMAT_ARGB16161616F:
1090 case DRM_FORMAT_ABGR16161616F:
1091 return fill_tiles_rgb16fp(info, planes[0],
1092 width, height, stride);
1096 static void fill_plain(const struct util_format_info *info, void *planes[3],
1097 unsigned int height,
1098 unsigned int stride)
1100 switch (info->format) {
1101 case DRM_FORMAT_XRGB16161616F:
1102 case DRM_FORMAT_XBGR16161616F:
1103 case DRM_FORMAT_ARGB16161616F:
1104 case DRM_FORMAT_ABGR16161616F:
1105 /* 0x3838 = 0.5273 */
1106 memset(planes[0], 0x38, stride * height);
1109 memset(planes[0], 0x77, stride * height);
1114 static void fill_gradient_rgb32(const struct util_rgb_info *rgb,
1116 unsigned int width, unsigned int height,
1117 unsigned int stride)
1121 for (i = 0; i < height / 2; i++) {
1122 uint32_t *row = mem;
1124 for (j = 0; j < width / 2; j++) {
1125 uint32_t value = MAKE_RGBA10(rgb, j & 0x3ff, j & 0x3ff, j & 0x3ff, 0);
1126 row[2*j] = row[2*j+1] = value;
1131 for (; i < height; i++) {
1132 uint32_t *row = mem;
1134 for (j = 0; j < width / 2; j++) {
1135 uint32_t value = MAKE_RGBA10(rgb, j & 0x3fc, j & 0x3fc, j & 0x3fc, 0);
1136 row[2*j] = row[2*j+1] = value;
1142 static void fill_gradient_rgb16fp(const struct util_rgb_info *rgb,
1144 unsigned int width, unsigned int height,
1145 unsigned int stride)
1149 for (i = 0; i < height / 2; i++) {
1150 uint64_t *row = mem;
1152 for (j = 0; j < width / 2; j++) {
1153 uint64_t value = MAKE_RGBA10FP16(rgb, j & 0x3ff, j & 0x3ff, j & 0x3ff, 0);
1154 row[2*j] = row[2*j+1] = value;
1159 for (; i < height; i++) {
1160 uint64_t *row = mem;
1162 for (j = 0; j < width / 2; j++) {
1163 uint64_t value = MAKE_RGBA10FP16(rgb, j & 0x3fc, j & 0x3fc, j & 0x3fc, 0);
1164 row[2*j] = row[2*j+1] = value;
1170 /* The gradient pattern creates two horizontal gray gradients, split
1171 * into two halves. The top half has 10bpc precision, the bottom half
1172 * has 8bpc precision. When using with a 10bpc fb format, there are 3
1173 * possible outcomes:
1175 * - Pixel data is encoded as 8bpc to the display, no dithering. This
1176 * would lead to the top and bottom halves looking identical.
1178 * - Pixel data is encoded as 8bpc to the display, with dithering. This
1179 * would lead to there being a visible difference between the two halves,
1180 * but the top half would look a little speck-y due to the dithering.
1182 * - Pixel data is encoded at 10bpc+ to the display (which implies
1183 * the display is able to show this level of depth). This should
1184 * lead to the top half being a very clean gradient, and visibly different
1185 * from the bottom half.
1187 * Once we support additional fb formats, this approach could be extended
1188 * to distinguish even higher bpc precisions.
1190 * Note that due to practical size considerations, for the screens
1191 * where this matters, the pattern actually emits stripes 2-pixels
1192 * wide for each gradient color. Otherwise the difference may be a bit
1195 static void fill_gradient(const struct util_format_info *info, void *planes[3],
1196 unsigned int width, unsigned int height,
1197 unsigned int stride)
1199 switch (info->format) {
1200 case DRM_FORMAT_ARGB8888:
1201 case DRM_FORMAT_XRGB8888:
1202 case DRM_FORMAT_ABGR8888:
1203 case DRM_FORMAT_XBGR8888:
1204 case DRM_FORMAT_RGBA8888:
1205 case DRM_FORMAT_RGBX8888:
1206 case DRM_FORMAT_BGRA8888:
1207 case DRM_FORMAT_BGRX8888:
1208 case DRM_FORMAT_ARGB2101010:
1209 case DRM_FORMAT_XRGB2101010:
1210 case DRM_FORMAT_ABGR2101010:
1211 case DRM_FORMAT_XBGR2101010:
1212 case DRM_FORMAT_RGBA1010102:
1213 case DRM_FORMAT_RGBX1010102:
1214 case DRM_FORMAT_BGRA1010102:
1215 case DRM_FORMAT_BGRX1010102:
1216 return fill_gradient_rgb32(&info->rgb, planes[0],
1217 width, height, stride);
1219 case DRM_FORMAT_XRGB16161616F:
1220 case DRM_FORMAT_XBGR16161616F:
1221 case DRM_FORMAT_ARGB16161616F:
1222 case DRM_FORMAT_ABGR16161616F:
1223 return fill_gradient_rgb16fp(&info->rgb, planes[0],
1224 width, height, stride);
1229 * util_fill_pattern - Fill a buffer with a test pattern
1230 * @format: Pixel format
1231 * @pattern: Test pattern
1232 * @planes: Array of buffers
1233 * @width: Width in pixels
1234 * @height: Height in pixels
1235 * @stride: Line stride (pitch) in bytes
1237 * Fill the buffers with the test pattern specified by the pattern parameter.
1238 * Supported formats vary depending on the selected pattern.
1240 void util_fill_pattern(uint32_t format, enum util_fill_pattern pattern,
1241 void *planes[3], unsigned int width,
1242 unsigned int height, unsigned int stride)
1244 const struct util_format_info *info;
1246 info = util_format_info_find(format);
1251 case UTIL_PATTERN_TILES:
1252 return fill_tiles(info, planes, width, height, stride);
1254 case UTIL_PATTERN_SMPTE:
1255 return fill_smpte(info, planes, width, height, stride);
1257 case UTIL_PATTERN_PLAIN:
1258 return fill_plain(info, planes, height, stride);
1260 case UTIL_PATTERN_GRADIENT:
1261 return fill_gradient(info, planes, width, height, stride);
1264 printf("Error: unsupported test pattern %u.\n", pattern);
1269 static const char *pattern_names[] = {
1270 [UTIL_PATTERN_TILES] = "tiles",
1271 [UTIL_PATTERN_SMPTE] = "smpte",
1272 [UTIL_PATTERN_PLAIN] = "plain",
1273 [UTIL_PATTERN_GRADIENT] = "gradient",
1276 enum util_fill_pattern util_pattern_enum(const char *name)
1280 for (i = 0; i < ARRAY_SIZE(pattern_names); i++)
1281 if (!strcmp(pattern_names[i], name))
1282 return (enum util_fill_pattern)i;
1284 printf("Error: unsupported test pattern %s.\n", name);
1285 return UTIL_PATTERN_SMPTE;