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];
617 SMPTE_COLOR_IN_PHASE,
618 SMPTE_COLOR_SUPER_WHITE,
619 SMPTE_COLOR_QUADRATURE,
624 static unsigned int smpte_top[7] = {
634 static unsigned int smpte_middle[7] = {
644 static unsigned int smpte_bottom[8] = {
645 SMPTE_COLOR_IN_PHASE,
646 SMPTE_COLOR_SUPER_WHITE,
647 SMPTE_COLOR_QUADRATURE,
655 #define EXPAND_COLOR(r, g, b) { (r) * 0x101, (g) * 0x101, (b) * 0x101 }
657 static const struct drm_color_lut smpte_color_lut[] = {
658 [SMPTE_COLOR_GREY] = EXPAND_COLOR(192, 192, 192),
659 [SMPTE_COLOR_YELLOW] = EXPAND_COLOR(192, 192, 0),
660 [SMPTE_COLOR_CYAN] = EXPAND_COLOR( 0, 192, 192),
661 [SMPTE_COLOR_GREEN] = EXPAND_COLOR( 0, 192, 0),
662 [SMPTE_COLOR_MAGENTA] = EXPAND_COLOR(192, 0, 192),
663 [SMPTE_COLOR_RED] = EXPAND_COLOR(192, 0, 0),
664 [SMPTE_COLOR_BLUE] = EXPAND_COLOR( 0, 0, 192),
665 [SMPTE_COLOR_BLACK] = EXPAND_COLOR( 19, 19, 19),
666 [SMPTE_COLOR_IN_PHASE] = EXPAND_COLOR( 0, 33, 76),
667 [SMPTE_COLOR_SUPER_WHITE] = EXPAND_COLOR(255, 255, 255),
668 [SMPTE_COLOR_QUADRATURE] = EXPAND_COLOR( 50, 0, 106),
669 [SMPTE_COLOR_3PC5] = EXPAND_COLOR( 9, 9, 9),
670 [SMPTE_COLOR_11PC5] = EXPAND_COLOR( 29, 29, 29),
675 static void fill_smpte_c8(void *mem, unsigned int width, unsigned int height,
681 for (y = 0; y < height * 6 / 9; ++y) {
682 for (x = 0; x < width; ++x)
683 ((uint8_t *)mem)[x] = smpte_top[x * 7 / width];
687 for (; y < height * 7 / 9; ++y) {
688 for (x = 0; x < width; ++x)
689 ((uint8_t *)mem)[x] = smpte_middle[x * 7 / width];
693 for (; y < height; ++y) {
694 for (x = 0; x < width * 5 / 7; ++x)
695 ((uint8_t *)mem)[x] =
696 smpte_bottom[x * 4 / (width * 5 / 7)];
697 for (; x < width * 6 / 7; ++x)
698 ((uint8_t *)mem)[x] =
699 smpte_bottom[(x - width * 5 / 7) * 3
701 for (; x < width; ++x)
702 ((uint8_t *)mem)[x] = smpte_bottom[7];
707 void util_smpte_fill_lut(unsigned int ncolors, struct drm_color_lut *lut)
709 if (ncolors < ARRAY_SIZE(smpte_color_lut)) {
710 printf("Error: lut too small: %u < %zu\n", ncolors,
711 ARRAY_SIZE(smpte_color_lut));
714 memset(lut, 0, ncolors * sizeof(struct drm_color_lut));
716 memcpy(lut, smpte_color_lut, sizeof(smpte_color_lut));
719 static void fill_smpte(const struct util_format_info *info, void *planes[3],
720 unsigned int width, unsigned int height,
723 unsigned char *u, *v;
725 switch (info->format) {
727 return fill_smpte_c8(planes[0], width, height, stride);
728 case DRM_FORMAT_UYVY:
729 case DRM_FORMAT_VYUY:
730 case DRM_FORMAT_YUYV:
731 case DRM_FORMAT_YVYU:
732 return fill_smpte_yuv_packed(&info->yuv, planes[0], width,
735 case DRM_FORMAT_NV12:
736 case DRM_FORMAT_NV21:
737 case DRM_FORMAT_NV16:
738 case DRM_FORMAT_NV61:
739 case DRM_FORMAT_NV24:
740 case DRM_FORMAT_NV42:
741 u = info->yuv.order & YUV_YCbCr ? planes[1] : planes[1] + 1;
742 v = info->yuv.order & YUV_YCrCb ? planes[1] : planes[1] + 1;
743 return fill_smpte_yuv_planar(&info->yuv, planes[0], u, v,
744 width, height, stride);
746 case DRM_FORMAT_YUV420:
747 return fill_smpte_yuv_planar(&info->yuv, planes[0], planes[1],
748 planes[2], width, height, stride);
750 case DRM_FORMAT_YVU420:
751 return fill_smpte_yuv_planar(&info->yuv, planes[0], planes[2],
752 planes[1], width, height, stride);
754 case DRM_FORMAT_ARGB4444:
755 case DRM_FORMAT_XRGB4444:
756 case DRM_FORMAT_ABGR4444:
757 case DRM_FORMAT_XBGR4444:
758 case DRM_FORMAT_RGBA4444:
759 case DRM_FORMAT_RGBX4444:
760 case DRM_FORMAT_BGRA4444:
761 case DRM_FORMAT_BGRX4444:
762 case DRM_FORMAT_RGB565:
763 case DRM_FORMAT_BGR565:
764 case DRM_FORMAT_ARGB1555:
765 case DRM_FORMAT_XRGB1555:
766 case DRM_FORMAT_ABGR1555:
767 case DRM_FORMAT_XBGR1555:
768 case DRM_FORMAT_RGBA5551:
769 case DRM_FORMAT_RGBX5551:
770 case DRM_FORMAT_BGRA5551:
771 case DRM_FORMAT_BGRX5551:
772 return fill_smpte_rgb16(&info->rgb, planes[0],
773 width, height, stride);
775 case DRM_FORMAT_BGR888:
776 case DRM_FORMAT_RGB888:
777 return fill_smpte_rgb24(&info->rgb, planes[0],
778 width, height, stride);
779 case DRM_FORMAT_ARGB8888:
780 case DRM_FORMAT_XRGB8888:
781 case DRM_FORMAT_ABGR8888:
782 case DRM_FORMAT_XBGR8888:
783 case DRM_FORMAT_RGBA8888:
784 case DRM_FORMAT_RGBX8888:
785 case DRM_FORMAT_BGRA8888:
786 case DRM_FORMAT_BGRX8888:
787 case DRM_FORMAT_ARGB2101010:
788 case DRM_FORMAT_XRGB2101010:
789 case DRM_FORMAT_ABGR2101010:
790 case DRM_FORMAT_XBGR2101010:
791 case DRM_FORMAT_RGBA1010102:
792 case DRM_FORMAT_RGBX1010102:
793 case DRM_FORMAT_BGRA1010102:
794 case DRM_FORMAT_BGRX1010102:
795 return fill_smpte_rgb32(&info->rgb, planes[0],
796 width, height, stride);
798 case DRM_FORMAT_XRGB16161616F:
799 case DRM_FORMAT_XBGR16161616F:
800 case DRM_FORMAT_ARGB16161616F:
801 case DRM_FORMAT_ABGR16161616F:
802 return fill_smpte_rgb16fp(&info->rgb, planes[0],
803 width, height, stride);
807 static void make_pwetty(void *data, unsigned int width, unsigned int height,
808 unsigned int stride, uint32_t format)
811 cairo_surface_t *surface;
813 cairo_format_t cairo_format;
815 /* we can ignore the order of R,G,B channels */
817 case DRM_FORMAT_XRGB8888:
818 case DRM_FORMAT_ARGB8888:
819 case DRM_FORMAT_XBGR8888:
820 case DRM_FORMAT_ABGR8888:
821 cairo_format = CAIRO_FORMAT_ARGB32;
823 case DRM_FORMAT_RGB565:
824 case DRM_FORMAT_BGR565:
825 cairo_format = CAIRO_FORMAT_RGB16_565;
827 #if CAIRO_VERSION_MAJOR > 1 || (CAIRO_VERSION_MAJOR == 1 && CAIRO_VERSION_MINOR >= 12)
828 case DRM_FORMAT_ARGB2101010:
829 case DRM_FORMAT_XRGB2101010:
830 case DRM_FORMAT_ABGR2101010:
831 case DRM_FORMAT_XBGR2101010:
832 cairo_format = CAIRO_FORMAT_RGB30;
839 surface = cairo_image_surface_create_for_data(data,
843 cr = cairo_create(surface);
844 cairo_surface_destroy(surface);
846 cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
847 for (unsigned x = 0; x < width; x += 250)
848 for (unsigned y = 0; y < height; y += 250) {
851 cairo_move_to(cr, x, y - 20);
852 cairo_line_to(cr, x, y + 20);
853 cairo_move_to(cr, x - 20, y);
854 cairo_line_to(cr, x + 20, y);
855 cairo_new_sub_path(cr);
856 cairo_arc(cr, x, y, 10, 0, M_PI * 2);
857 cairo_set_line_width(cr, 4);
858 cairo_set_source_rgb(cr, 0, 0, 0);
859 cairo_stroke_preserve(cr);
860 cairo_set_source_rgb(cr, 1, 1, 1);
861 cairo_set_line_width(cr, 2);
864 snprintf(buf, sizeof buf, "%d, %d", x, y);
865 cairo_move_to(cr, x + 20, y + 20);
866 cairo_text_path(cr, buf);
867 cairo_set_source_rgb(cr, 0, 0, 0);
868 cairo_stroke_preserve(cr);
869 cairo_set_source_rgb(cr, 1, 1, 1);
877 static void fill_tiles_yuv_planar(const struct util_format_info *info,
878 unsigned char *y_mem, unsigned char *u_mem,
879 unsigned char *v_mem, unsigned int width,
880 unsigned int height, unsigned int stride)
882 const struct util_yuv_info *yuv = &info->yuv;
883 unsigned int cs = yuv->chroma_stride;
884 unsigned int xsub = yuv->xsub;
885 unsigned int ysub = yuv->ysub;
889 for (y = 0; y < height; ++y) {
890 for (x = 0; x < width; ++x) {
891 div_t d = div(x+y, width);
892 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
893 + 0x000a1120 * (d.rem >> 6);
894 struct color_yuv color =
895 MAKE_YUV_601((rgb32 >> 16) & 0xff,
896 (rgb32 >> 8) & 0xff, rgb32 & 0xff);
899 u_mem[x/xsub*cs] = color.u;
900 v_mem[x/xsub*cs] = color.v;
904 if ((y + 1) % ysub == 0) {
905 u_mem += stride * cs / xsub;
906 v_mem += stride * cs / xsub;
911 static void fill_tiles_yuv_packed(const struct util_format_info *info,
912 void *mem, unsigned int width,
913 unsigned int height, unsigned int stride)
915 const struct util_yuv_info *yuv = &info->yuv;
916 unsigned char *y_mem = (yuv->order & YUV_YC) ? mem : mem + 1;
917 unsigned char *c_mem = (yuv->order & YUV_CY) ? mem : mem + 1;
918 unsigned int u = (yuv->order & YUV_YCrCb) ? 2 : 0;
919 unsigned int v = (yuv->order & YUV_YCbCr) ? 2 : 0;
923 for (y = 0; y < height; ++y) {
924 for (x = 0; x < width; x += 2) {
925 div_t d = div(x+y, width);
926 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
927 + 0x000a1120 * (d.rem >> 6);
928 struct color_yuv color =
929 MAKE_YUV_601((rgb32 >> 16) & 0xff,
930 (rgb32 >> 8) & 0xff, rgb32 & 0xff);
932 y_mem[2*x] = color.y;
933 c_mem[2*x+u] = color.u;
934 y_mem[2*x+2] = color.y;
935 c_mem[2*x+v] = color.v;
943 static void fill_tiles_rgb16(const struct util_format_info *info, void *mem,
944 unsigned int width, unsigned int height,
947 const struct util_rgb_info *rgb = &info->rgb;
948 void *mem_base = mem;
951 for (y = 0; y < height; ++y) {
952 for (x = 0; x < width; ++x) {
953 div_t d = div(x+y, width);
954 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
955 + 0x000a1120 * (d.rem >> 6);
957 MAKE_RGBA(rgb, (rgb32 >> 16) & 0xff,
958 (rgb32 >> 8) & 0xff, rgb32 & 0xff,
961 ((uint16_t *)mem)[x] = color;
966 make_pwetty(mem_base, width, height, stride, info->format);
969 static void fill_tiles_rgb24(const struct util_format_info *info, void *mem,
970 unsigned int width, unsigned int height,
973 const struct util_rgb_info *rgb = &info->rgb;
976 for (y = 0; y < height; ++y) {
977 for (x = 0; x < width; ++x) {
978 div_t d = div(x+y, width);
979 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
980 + 0x000a1120 * (d.rem >> 6);
981 struct color_rgb24 color =
982 MAKE_RGB24(rgb, (rgb32 >> 16) & 0xff,
983 (rgb32 >> 8) & 0xff, rgb32 & 0xff);
985 ((struct color_rgb24 *)mem)[x] = color;
991 static void fill_tiles_rgb32(const struct util_format_info *info, void *mem,
992 unsigned int width, unsigned int height,
995 const struct util_rgb_info *rgb = &info->rgb;
996 void *mem_base = mem;
999 for (y = 0; y < height; ++y) {
1000 for (x = 0; x < width; ++x) {
1001 div_t d = div(x+y, width);
1002 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
1003 + 0x000a1120 * (d.rem >> 6);
1004 uint32_t alpha = ((y < height/2) && (x < width/2)) ? 127 : 255;
1006 MAKE_RGBA(rgb, (rgb32 >> 16) & 0xff,
1007 (rgb32 >> 8) & 0xff, rgb32 & 0xff,
1010 ((uint32_t *)mem)[x] = color;
1015 make_pwetty(mem_base, width, height, stride, info->format);
1018 static void fill_tiles_rgb16fp(const struct util_format_info *info, void *mem,
1019 unsigned int width, unsigned int height,
1020 unsigned int stride)
1022 const struct util_rgb_info *rgb = &info->rgb;
1025 /* TODO: Give this actual fp16 precision */
1026 for (y = 0; y < height; ++y) {
1027 for (x = 0; x < width; ++x) {
1028 div_t d = div(x+y, width);
1029 uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
1030 + 0x000a1120 * (d.rem >> 6);
1031 uint32_t alpha = ((y < height/2) && (x < width/2)) ? 127 : 255;
1033 MAKE_RGBA8FP16(rgb, (rgb32 >> 16) & 0xff,
1034 (rgb32 >> 8) & 0xff, rgb32 & 0xff,
1037 ((uint64_t *)mem)[x] = color;
1043 static void fill_tiles(const struct util_format_info *info, void *planes[3],
1044 unsigned int width, unsigned int height,
1045 unsigned int stride)
1047 unsigned char *u, *v;
1049 switch (info->format) {
1050 case DRM_FORMAT_UYVY:
1051 case DRM_FORMAT_VYUY:
1052 case DRM_FORMAT_YUYV:
1053 case DRM_FORMAT_YVYU:
1054 return fill_tiles_yuv_packed(info, planes[0],
1055 width, height, stride);
1057 case DRM_FORMAT_NV12:
1058 case DRM_FORMAT_NV21:
1059 case DRM_FORMAT_NV16:
1060 case DRM_FORMAT_NV61:
1061 case DRM_FORMAT_NV24:
1062 case DRM_FORMAT_NV42:
1063 u = info->yuv.order & YUV_YCbCr ? planes[1] : planes[1] + 1;
1064 v = info->yuv.order & YUV_YCrCb ? planes[1] : planes[1] + 1;
1065 return fill_tiles_yuv_planar(info, planes[0], u, v,
1066 width, height, stride);
1068 case DRM_FORMAT_YUV420:
1069 return fill_tiles_yuv_planar(info, planes[0], planes[1],
1070 planes[2], width, height, stride);
1072 case DRM_FORMAT_YVU420:
1073 return fill_tiles_yuv_planar(info, planes[0], planes[2],
1074 planes[1], width, height, stride);
1076 case DRM_FORMAT_ARGB4444:
1077 case DRM_FORMAT_XRGB4444:
1078 case DRM_FORMAT_ABGR4444:
1079 case DRM_FORMAT_XBGR4444:
1080 case DRM_FORMAT_RGBA4444:
1081 case DRM_FORMAT_RGBX4444:
1082 case DRM_FORMAT_BGRA4444:
1083 case DRM_FORMAT_BGRX4444:
1084 case DRM_FORMAT_RGB565:
1085 case DRM_FORMAT_BGR565:
1086 case DRM_FORMAT_ARGB1555:
1087 case DRM_FORMAT_XRGB1555:
1088 case DRM_FORMAT_ABGR1555:
1089 case DRM_FORMAT_XBGR1555:
1090 case DRM_FORMAT_RGBA5551:
1091 case DRM_FORMAT_RGBX5551:
1092 case DRM_FORMAT_BGRA5551:
1093 case DRM_FORMAT_BGRX5551:
1094 return fill_tiles_rgb16(info, planes[0],
1095 width, height, stride);
1097 case DRM_FORMAT_BGR888:
1098 case DRM_FORMAT_RGB888:
1099 return fill_tiles_rgb24(info, planes[0],
1100 width, height, stride);
1101 case DRM_FORMAT_ARGB8888:
1102 case DRM_FORMAT_XRGB8888:
1103 case DRM_FORMAT_ABGR8888:
1104 case DRM_FORMAT_XBGR8888:
1105 case DRM_FORMAT_RGBA8888:
1106 case DRM_FORMAT_RGBX8888:
1107 case DRM_FORMAT_BGRA8888:
1108 case DRM_FORMAT_BGRX8888:
1109 case DRM_FORMAT_ARGB2101010:
1110 case DRM_FORMAT_XRGB2101010:
1111 case DRM_FORMAT_ABGR2101010:
1112 case DRM_FORMAT_XBGR2101010:
1113 case DRM_FORMAT_RGBA1010102:
1114 case DRM_FORMAT_RGBX1010102:
1115 case DRM_FORMAT_BGRA1010102:
1116 case DRM_FORMAT_BGRX1010102:
1117 return fill_tiles_rgb32(info, planes[0],
1118 width, height, stride);
1120 case DRM_FORMAT_XRGB16161616F:
1121 case DRM_FORMAT_XBGR16161616F:
1122 case DRM_FORMAT_ARGB16161616F:
1123 case DRM_FORMAT_ABGR16161616F:
1124 return fill_tiles_rgb16fp(info, planes[0],
1125 width, height, stride);
1129 static void fill_plain(const struct util_format_info *info, void *planes[3],
1130 unsigned int height,
1131 unsigned int stride)
1133 switch (info->format) {
1134 case DRM_FORMAT_XRGB16161616F:
1135 case DRM_FORMAT_XBGR16161616F:
1136 case DRM_FORMAT_ARGB16161616F:
1137 case DRM_FORMAT_ABGR16161616F:
1138 /* 0x3838 = 0.5273 */
1139 memset(planes[0], 0x38, stride * height);
1142 memset(planes[0], 0x77, stride * height);
1147 static void fill_gradient_rgb32(const struct util_rgb_info *rgb,
1149 unsigned int width, unsigned int height,
1150 unsigned int stride)
1154 for (i = 0; i < height / 2; i++) {
1155 uint32_t *row = mem;
1157 for (j = 0; j < width / 2; j++) {
1158 uint32_t value = MAKE_RGBA10(rgb, j & 0x3ff, j & 0x3ff, j & 0x3ff, 0);
1159 row[2*j] = row[2*j+1] = value;
1164 for (; i < height; i++) {
1165 uint32_t *row = mem;
1167 for (j = 0; j < width / 2; j++) {
1168 uint32_t value = MAKE_RGBA10(rgb, j & 0x3fc, j & 0x3fc, j & 0x3fc, 0);
1169 row[2*j] = row[2*j+1] = value;
1175 static void fill_gradient_rgb16fp(const struct util_rgb_info *rgb,
1177 unsigned int width, unsigned int height,
1178 unsigned int stride)
1182 for (i = 0; i < height / 2; i++) {
1183 uint64_t *row = mem;
1185 for (j = 0; j < width / 2; j++) {
1186 uint64_t value = MAKE_RGBA10FP16(rgb, j & 0x3ff, j & 0x3ff, j & 0x3ff, 0);
1187 row[2*j] = row[2*j+1] = value;
1192 for (; i < height; i++) {
1193 uint64_t *row = mem;
1195 for (j = 0; j < width / 2; j++) {
1196 uint64_t value = MAKE_RGBA10FP16(rgb, j & 0x3fc, j & 0x3fc, j & 0x3fc, 0);
1197 row[2*j] = row[2*j+1] = value;
1203 /* The gradient pattern creates two horizontal gray gradients, split
1204 * into two halves. The top half has 10bpc precision, the bottom half
1205 * has 8bpc precision. When using with a 10bpc fb format, there are 3
1206 * possible outcomes:
1208 * - Pixel data is encoded as 8bpc to the display, no dithering. This
1209 * would lead to the top and bottom halves looking identical.
1211 * - Pixel data is encoded as 8bpc to the display, with dithering. This
1212 * would lead to there being a visible difference between the two halves,
1213 * but the top half would look a little speck-y due to the dithering.
1215 * - Pixel data is encoded at 10bpc+ to the display (which implies
1216 * the display is able to show this level of depth). This should
1217 * lead to the top half being a very clean gradient, and visibly different
1218 * from the bottom half.
1220 * Once we support additional fb formats, this approach could be extended
1221 * to distinguish even higher bpc precisions.
1223 * Note that due to practical size considerations, for the screens
1224 * where this matters, the pattern actually emits stripes 2-pixels
1225 * wide for each gradient color. Otherwise the difference may be a bit
1228 static void fill_gradient(const struct util_format_info *info, void *planes[3],
1229 unsigned int width, unsigned int height,
1230 unsigned int stride)
1232 switch (info->format) {
1233 case DRM_FORMAT_ARGB8888:
1234 case DRM_FORMAT_XRGB8888:
1235 case DRM_FORMAT_ABGR8888:
1236 case DRM_FORMAT_XBGR8888:
1237 case DRM_FORMAT_RGBA8888:
1238 case DRM_FORMAT_RGBX8888:
1239 case DRM_FORMAT_BGRA8888:
1240 case DRM_FORMAT_BGRX8888:
1241 case DRM_FORMAT_ARGB2101010:
1242 case DRM_FORMAT_XRGB2101010:
1243 case DRM_FORMAT_ABGR2101010:
1244 case DRM_FORMAT_XBGR2101010:
1245 case DRM_FORMAT_RGBA1010102:
1246 case DRM_FORMAT_RGBX1010102:
1247 case DRM_FORMAT_BGRA1010102:
1248 case DRM_FORMAT_BGRX1010102:
1249 return fill_gradient_rgb32(&info->rgb, planes[0],
1250 width, height, stride);
1252 case DRM_FORMAT_XRGB16161616F:
1253 case DRM_FORMAT_XBGR16161616F:
1254 case DRM_FORMAT_ARGB16161616F:
1255 case DRM_FORMAT_ABGR16161616F:
1256 return fill_gradient_rgb16fp(&info->rgb, planes[0],
1257 width, height, stride);
1262 * util_fill_pattern - Fill a buffer with a test pattern
1263 * @format: Pixel format
1264 * @pattern: Test pattern
1265 * @planes: Array of buffers
1266 * @width: Width in pixels
1267 * @height: Height in pixels
1268 * @stride: Line stride (pitch) in bytes
1270 * Fill the buffers with the test pattern specified by the pattern parameter.
1271 * Supported formats vary depending on the selected pattern.
1273 void util_fill_pattern(uint32_t format, enum util_fill_pattern pattern,
1274 void *planes[3], unsigned int width,
1275 unsigned int height, unsigned int stride)
1277 const struct util_format_info *info;
1279 info = util_format_info_find(format);
1284 case UTIL_PATTERN_TILES:
1285 return fill_tiles(info, planes, width, height, stride);
1287 case UTIL_PATTERN_SMPTE:
1288 return fill_smpte(info, planes, width, height, stride);
1290 case UTIL_PATTERN_PLAIN:
1291 return fill_plain(info, planes, height, stride);
1293 case UTIL_PATTERN_GRADIENT:
1294 return fill_gradient(info, planes, width, height, stride);
1297 printf("Error: unsupported test pattern %u.\n", pattern);
1302 static const char *pattern_names[] = {
1303 [UTIL_PATTERN_TILES] = "tiles",
1304 [UTIL_PATTERN_SMPTE] = "smpte",
1305 [UTIL_PATTERN_PLAIN] = "plain",
1306 [UTIL_PATTERN_GRADIENT] = "gradient",
1309 enum util_fill_pattern util_pattern_enum(const char *name)
1313 for (i = 0; i < ARRAY_SIZE(pattern_names); i++)
1314 if (!strcmp(pattern_names[i], name))
1315 return (enum util_fill_pattern)i;
1317 printf("Error: unsupported test pattern %s.\n", name);
1318 return UTIL_PATTERN_SMPTE;