1/*
2 * Copyright 2008 Tungsten Graphics
3 *   Jakob Bornecrantz <jakob@tungstengraphics.com>
4 * Copyright 2008 Intel Corporation
5 *   Jesse Barnes <jesse.barnes@intel.com>
6 *
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:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
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
23 * IN THE SOFTWARE.
24 */
25
26#include <stdbool.h>
27#include <stdint.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31
32#include <drm_fourcc.h>
33
34#if HAVE_CAIRO
35#include <cairo.h>
36#include <math.h>
37#endif
38
39#include "common.h"
40#include "format.h"
41#include "pattern.h"
42
43struct color_rgb24 {
44	unsigned int value:24;
45} __attribute__((__packed__));
46
47struct color_yuv {
48	unsigned char y;
49	unsigned char u;
50	unsigned char v;
51};
52
53#define MAKE_YUV_601_Y(r, g, b) \
54	((( 66 * (r) + 129 * (g) +  25 * (b) + 128) >> 8) + 16)
55#define MAKE_YUV_601_U(r, g, b) \
56	(((-38 * (r) -  74 * (g) + 112 * (b) + 128) >> 8) + 128)
57#define MAKE_YUV_601_V(r, g, b) \
58	(((112 * (r) -  94 * (g) -  18 * (b) + 128) >> 8) + 128)
59
60#define MAKE_YUV_601(r, g, b) \
61	{ .y = MAKE_YUV_601_Y(r, g, b), \
62	  .u = MAKE_YUV_601_U(r, g, b), \
63	  .v = MAKE_YUV_601_V(r, g, b) }
64
65static inline uint16_t swap16(uint16_t x)
66{
67	return ((x & 0x00ffU) << 8) | ((x & 0xff00U) >> 8);
68}
69
70static inline uint32_t swap32(uint32_t x)
71{
72	return ((x & 0x000000ffU) << 24) |
73	       ((x & 0x0000ff00U) <<  8) |
74	       ((x & 0x00ff0000U) >>  8) |
75	       ((x & 0xff000000U) >> 24);
76}
77
78#ifdef HAVE_BIG_ENDIAN
79#define cpu_to_be16(x)			(x)
80#define cpu_to_le16(x)			swap16(x)
81#define cpu_to_le32(x)			swap32(x)
82#define fb_foreign_endian(format)	(!((format) & DRM_FORMAT_BIG_ENDIAN))
83#else
84#define cpu_to_be16(x)			swap16(x)
85#define cpu_to_le16(x)			(x)
86#define cpu_to_le32(x)			(x)
87#define fb_foreign_endian(format)	((format) & DRM_FORMAT_BIG_ENDIAN)
88#endif
89
90#define cpu_to_fb16(x)	(fb_be ? cpu_to_be16(x) : cpu_to_le16(x))
91
92/* This function takes 8-bit color values */
93static inline uint32_t shiftcolor8(const struct util_color_component *comp,
94				  uint32_t value)
95{
96	value &= 0xff;
97	/* Fill the low bits with the high bits. */
98	value = (value << 8) | value;
99	/* Shift down to remove unwanted low bits */
100	value = value >> (16 - comp->length);
101	/* Shift back up to where the value should be */
102	return value << comp->offset;
103}
104
105/* This function takes 10-bit color values */
106static inline uint32_t shiftcolor10(const struct util_color_component *comp,
107				    uint32_t value)
108{
109	value &= 0x3ff;
110	/* Fill the low bits with the high bits. */
111	value = (value << 6) | (value >> 4);
112	/* Shift down to remove unwanted low bits */
113	value = value >> (16 - comp->length);
114	/* Shift back up to where the value should be */
115	return value << comp->offset;
116}
117
118/* This function takes 16-bit color values */
119static inline uint64_t shiftcolor16(const struct util_color_component *comp,
120				    uint64_t value)
121{
122	value &= 0xffff;
123	/* Shift down to remove unwanted low bits */
124	value = value >> (16 - comp->length);
125	/* Shift back up to where the value should be */
126	return value << comp->offset;
127}
128
129#define MAKE_RGBA10(rgb, r, g, b, a) \
130	(shiftcolor10(&(rgb)->red, (r)) | \
131	 shiftcolor10(&(rgb)->green, (g)) | \
132	 shiftcolor10(&(rgb)->blue, (b)) | \
133	 shiftcolor10(&(rgb)->alpha, (a)))
134
135#define MAKE_RGBA(rgb, r, g, b, a) \
136	(shiftcolor8(&(rgb)->red, (r)) | \
137	 shiftcolor8(&(rgb)->green, (g)) | \
138	 shiftcolor8(&(rgb)->blue, (b)) | \
139	 shiftcolor8(&(rgb)->alpha, (a)))
140
141#define MAKE_RGB24(rgb, r, g, b) \
142	{ .value = MAKE_RGBA(rgb, r, g, b, 0) }
143
144
145/**
146  * Takes a uint16_t, divides by 65536, converts the infinite-precision
147  * result to fp16 with round-to-zero.
148  *
149  * Copied from mesa:src/util/half_float.c
150  */
151static uint16_t uint16_div_64k_to_half(uint16_t v)
152{
153	/* Zero or subnormal. Set the mantissa to (v << 8) and return. */
154	if (v < 4)
155		return v << 8;
156
157	/* Count the leading 0s in the uint16_t */
158	int n = __builtin_clz(v) - 16;
159
160	/* Shift the mantissa up so bit 16 is the hidden 1 bit,
161	 * mask it off, then shift back down to 10 bits
162	 */
163	int m = ( ((uint32_t)v << (n + 1)) & 0xffff ) >> 6;
164
165	/*  (0{n} 1 X{15-n}) * 2^-16
166	 * = 1.X * 2^(15-n-16)
167	 * = 1.X * 2^(14-n - 15)
168	 * which is the FP16 form with e = 14 - n
169	 */
170	int e = 14 - n;
171
172	return (e << 10) | m;
173}
174
175#define MAKE_RGBA8FP16(rgb, r, g, b, a) \
176	(shiftcolor16(&(rgb)->red, uint16_div_64k_to_half((r) << 8)) | \
177	 shiftcolor16(&(rgb)->green, uint16_div_64k_to_half((g) << 8)) | \
178	 shiftcolor16(&(rgb)->blue, uint16_div_64k_to_half((b) << 8)) | \
179	 shiftcolor16(&(rgb)->alpha, uint16_div_64k_to_half((a) << 8)))
180
181#define MAKE_RGBA10FP16(rgb, r, g, b, a) \
182	(shiftcolor16(&(rgb)->red, uint16_div_64k_to_half((r) << 6)) | \
183	 shiftcolor16(&(rgb)->green, uint16_div_64k_to_half((g) << 6)) | \
184	 shiftcolor16(&(rgb)->blue, uint16_div_64k_to_half((b) << 6)) | \
185	 shiftcolor16(&(rgb)->alpha, uint16_div_64k_to_half((a) << 6)))
186
187static void fill_smpte_yuv_planar(const struct util_yuv_info *yuv,
188				  unsigned char *y_mem, unsigned char *u_mem,
189				  unsigned char *v_mem, unsigned int width,
190				  unsigned int height, unsigned int stride)
191{
192	const struct color_yuv colors_top[] = {
193		MAKE_YUV_601(192, 192, 192),	/* grey */
194		MAKE_YUV_601(192, 192, 0),	/* yellow */
195		MAKE_YUV_601(0, 192, 192),	/* cyan */
196		MAKE_YUV_601(0, 192, 0),	/* green */
197		MAKE_YUV_601(192, 0, 192),	/* magenta */
198		MAKE_YUV_601(192, 0, 0),	/* red */
199		MAKE_YUV_601(0, 0, 192),	/* blue */
200	};
201	const struct color_yuv colors_middle[] = {
202		MAKE_YUV_601(0, 0, 192),	/* blue */
203		MAKE_YUV_601(19, 19, 19),	/* black */
204		MAKE_YUV_601(192, 0, 192),	/* magenta */
205		MAKE_YUV_601(19, 19, 19),	/* black */
206		MAKE_YUV_601(0, 192, 192),	/* cyan */
207		MAKE_YUV_601(19, 19, 19),	/* black */
208		MAKE_YUV_601(192, 192, 192),	/* grey */
209	};
210	const struct color_yuv colors_bottom[] = {
211		MAKE_YUV_601(0, 33, 76),	/* in-phase */
212		MAKE_YUV_601(255, 255, 255),	/* super white */
213		MAKE_YUV_601(50, 0, 106),	/* quadrature */
214		MAKE_YUV_601(19, 19, 19),	/* black */
215		MAKE_YUV_601(9, 9, 9),		/* 3.5% */
216		MAKE_YUV_601(19, 19, 19),	/* 7.5% */
217		MAKE_YUV_601(29, 29, 29),	/* 11.5% */
218		MAKE_YUV_601(19, 19, 19),	/* black */
219	};
220	unsigned int cs = yuv->chroma_stride;
221	unsigned int xsub = yuv->xsub;
222	unsigned int ysub = yuv->ysub;
223	unsigned int x;
224	unsigned int y;
225
226	/* Luma */
227	for (y = 0; y < height * 6 / 9; ++y) {
228		for (x = 0; x < width; ++x)
229			y_mem[x] = colors_top[x * 7 / width].y;
230		y_mem += stride;
231	}
232
233	for (; y < height * 7 / 9; ++y) {
234		for (x = 0; x < width; ++x)
235			y_mem[x] = colors_middle[x * 7 / width].y;
236		y_mem += stride;
237	}
238
239	for (; y < height; ++y) {
240		for (x = 0; x < width * 5 / 7; ++x)
241			y_mem[x] = colors_bottom[x * 4 / (width * 5 / 7)].y;
242		for (; x < width * 6 / 7; ++x)
243			y_mem[x] = colors_bottom[(x - width * 5 / 7) * 3
244						 / (width / 7) + 4].y;
245		for (; x < width; ++x)
246			y_mem[x] = colors_bottom[7].y;
247		y_mem += stride;
248	}
249
250	/* Chroma */
251	for (y = 0; y < height / ysub * 6 / 9; ++y) {
252		for (x = 0; x < width; x += xsub) {
253			u_mem[x*cs/xsub] = colors_top[x * 7 / width].u;
254			v_mem[x*cs/xsub] = colors_top[x * 7 / width].v;
255		}
256		u_mem += stride * cs / xsub;
257		v_mem += stride * cs / xsub;
258	}
259
260	for (; y < height / ysub * 7 / 9; ++y) {
261		for (x = 0; x < width; x += xsub) {
262			u_mem[x*cs/xsub] = colors_middle[x * 7 / width].u;
263			v_mem[x*cs/xsub] = colors_middle[x * 7 / width].v;
264		}
265		u_mem += stride * cs / xsub;
266		v_mem += stride * cs / xsub;
267	}
268
269	for (; y < height / ysub; ++y) {
270		for (x = 0; x < width * 5 / 7; x += xsub) {
271			u_mem[x*cs/xsub] =
272				colors_bottom[x * 4 / (width * 5 / 7)].u;
273			v_mem[x*cs/xsub] =
274				colors_bottom[x * 4 / (width * 5 / 7)].v;
275		}
276		for (; x < width * 6 / 7; x += xsub) {
277			u_mem[x*cs/xsub] = colors_bottom[(x - width * 5 / 7) *
278							 3 / (width / 7) + 4].u;
279			v_mem[x*cs/xsub] = colors_bottom[(x - width * 5 / 7) *
280							 3 / (width / 7) + 4].v;
281		}
282		for (; x < width; x += xsub) {
283			u_mem[x*cs/xsub] = colors_bottom[7].u;
284			v_mem[x*cs/xsub] = colors_bottom[7].v;
285		}
286		u_mem += stride * cs / xsub;
287		v_mem += stride * cs / xsub;
288	}
289}
290
291static void write_pixels_10bpp(unsigned char *mem,
292			       unsigned short a,
293			       unsigned short b,
294			       unsigned short c,
295			       unsigned short d)
296{
297	  mem[0] = (a & 0xff);
298	  mem[1] = ((a >> 8) & 0x3) | ((b & 0x3f) << 2);
299	  mem[2] = ((b >> 6) & 0xf) | ((c & 0xf) << 4);
300	  mem[3] = ((c >> 4) & 0x3f) | ((d & 0x3) << 6);
301	  mem[4] = ((d >> 2) & 0xff);
302}
303
304static void fill_smpte_yuv_planar_10bpp(const struct util_yuv_info *yuv,
305					unsigned char *y_mem,
306					unsigned char *uv_mem,
307					unsigned int width,
308					unsigned int height,
309					unsigned int stride)
310{
311	const struct color_yuv colors_top[] = {
312		MAKE_YUV_601(192, 192, 192),	/* grey */
313		MAKE_YUV_601(192, 192, 0),	/* yellow */
314		MAKE_YUV_601(0, 192, 192),	/* cyan */
315		MAKE_YUV_601(0, 192, 0),	/* green */
316		MAKE_YUV_601(192, 0, 192),	/* magenta */
317		MAKE_YUV_601(192, 0, 0),	/* red */
318		MAKE_YUV_601(0, 0, 192),	/* blue */
319	};
320	const struct color_yuv colors_middle[] = {
321		MAKE_YUV_601(0, 0, 192),	/* blue */
322		MAKE_YUV_601(19, 19, 19),	/* black */
323		MAKE_YUV_601(192, 0, 192),	/* magenta */
324		MAKE_YUV_601(19, 19, 19),	/* black */
325		MAKE_YUV_601(0, 192, 192),	/* cyan */
326		MAKE_YUV_601(19, 19, 19),	/* black */
327		MAKE_YUV_601(192, 192, 192),	/* grey */
328	};
329	const struct color_yuv colors_bottom[] = {
330		MAKE_YUV_601(0, 33, 76),	/* in-phase */
331		MAKE_YUV_601(255, 255, 255),	/* super white */
332		MAKE_YUV_601(50, 0, 106),	/* quadrature */
333		MAKE_YUV_601(19, 19, 19),	/* black */
334		MAKE_YUV_601(9, 9, 9),		/* 3.5% */
335		MAKE_YUV_601(19, 19, 19),	/* 7.5% */
336		MAKE_YUV_601(29, 29, 29),	/* 11.5% */
337		MAKE_YUV_601(19, 19, 19),	/* black */
338	};
339	unsigned int cs = yuv->chroma_stride;
340	unsigned int xsub = yuv->xsub;
341	unsigned int ysub = yuv->ysub;
342	unsigned int xstep = cs * xsub;
343	unsigned int x;
344	unsigned int y;
345
346	/* Luma */
347	for (y = 0; y < height * 6 / 9; ++y) {
348		for (x = 0; x < width; x += 4)
349			write_pixels_10bpp(&y_mem[(x * 5) / 4],
350				colors_top[(x+0) * 7 / width].y << 2,
351				colors_top[(x+1) * 7 / width].y << 2,
352				colors_top[(x+2) * 7 / width].y << 2,
353				colors_top[(x+3) * 7 / width].y << 2);
354		y_mem += stride;
355	}
356
357	for (; y < height * 7 / 9; ++y) {
358		for (x = 0; x < width; x += 4)
359			write_pixels_10bpp(&y_mem[(x * 5) / 4],
360				colors_middle[(x+0) * 7 / width].y << 2,
361				colors_middle[(x+1) * 7 / width].y << 2,
362				colors_middle[(x+2) * 7 / width].y << 2,
363				colors_middle[(x+3) * 7 / width].y << 2);
364		y_mem += stride;
365	}
366
367	for (; y < height; ++y) {
368		for (x = 0; x < width * 5 / 7; x += 4)
369			write_pixels_10bpp(&y_mem[(x * 5) / 4],
370				colors_bottom[(x+0) * 4 / (width * 5 / 7)].y << 2,
371				colors_bottom[(x+1) * 4 / (width * 5 / 7)].y << 2,
372				colors_bottom[(x+2) * 4 / (width * 5 / 7)].y << 2,
373				colors_bottom[(x+3) * 4 / (width * 5 / 7)].y << 2);
374		for (; x < width * 6 / 7; x += 4)
375			write_pixels_10bpp(&y_mem[(x * 5) / 4],
376				colors_bottom[((x+0) - width * 5 / 7) * 3 / (width / 7) + 4].y << 2,
377				colors_bottom[((x+1) - width * 5 / 7) * 3 / (width / 7) + 4].y << 2,
378				colors_bottom[((x+2) - width * 5 / 7) * 3 / (width / 7) + 4].y << 2,
379				colors_bottom[((x+3) - width * 5 / 7) * 3 / (width / 7) + 4].y << 2);
380		for (; x < width; x += 4)
381			write_pixels_10bpp(&y_mem[(x * 5) / 4],
382				colors_bottom[7].y << 2,
383				colors_bottom[7].y << 2,
384				colors_bottom[7].y << 2,
385				colors_bottom[7].y << 2);
386		y_mem += stride;
387	}
388
389	/* Chroma */
390	for (y = 0; y < height * 6 / 9; y += ysub) {
391		for (x = 0; x < width; x += xstep)
392			write_pixels_10bpp(&uv_mem[(x * 5) / xstep],
393				colors_top[(x+0) * 7 / width].u << 2,
394				colors_top[(x+0) * 7 / width].v << 2,
395				colors_top[(x+xsub) * 7 / width].u << 2,
396				colors_top[(x+xsub) * 7 / width].v << 2);
397		uv_mem += stride * cs / xsub;
398	}
399
400	for (; y < height * 7 / 9; y += ysub) {
401		for (x = 0; x < width; x += xstep)
402			write_pixels_10bpp(&uv_mem[(x * 5) / xstep],
403				colors_middle[(x+0) * 7 / width].u << 2,
404				colors_middle[(x+0) * 7 / width].v << 2,
405				colors_middle[(x+xsub) * 7 / width].u << 2,
406				colors_middle[(x+xsub) * 7 / width].v << 2);
407		uv_mem += stride * cs / xsub;
408	}
409
410	for (; y < height; y += ysub) {
411		for (x = 0; x < width * 5 / 7; x += xstep)
412			write_pixels_10bpp(&uv_mem[(x * 5) / xstep],
413				colors_bottom[(x+0) * 4 / (width * 5 / 7)].u << 2,
414				colors_bottom[(x+0) * 4 / (width * 5 / 7)].v << 2,
415				colors_bottom[(x+xsub) * 4 / (width * 5 / 7)].u << 2,
416				colors_bottom[(x+xsub) * 4 / (width * 5 / 7)].v << 2);
417		for (; x < width * 6 / 7; x += xstep)
418			write_pixels_10bpp(&uv_mem[(x * 5) / xstep],
419				colors_bottom[((x+0) - width * 5 / 7) * 3 / (width / 7) + 4].u << 2,
420				colors_bottom[((x+0) - width * 5 / 7) * 3 / (width / 7) + 4].v << 2,
421				colors_bottom[((x+xsub) - width * 5 / 7) * 3 / (width / 7) + 4].u << 2,
422				colors_bottom[((x+xsub) - width * 5 / 7) * 3 / (width / 7) + 4].v << 2);
423		for (; x < width; x += xstep)
424			write_pixels_10bpp(&uv_mem[(x * 5) / xstep],
425				colors_bottom[7].u << 2,
426				colors_bottom[7].v << 2,
427				colors_bottom[7].u << 2,
428				colors_bottom[7].v << 2);
429		uv_mem += stride * cs / xsub;
430	}
431}
432
433static void fill_smpte_yuv_packed(const struct util_yuv_info *yuv, void *mem,
434				  unsigned int width, unsigned int height,
435				  unsigned int stride)
436{
437	const struct color_yuv colors_top[] = {
438		MAKE_YUV_601(192, 192, 192),	/* grey */
439		MAKE_YUV_601(192, 192, 0),	/* yellow */
440		MAKE_YUV_601(0, 192, 192),	/* cyan */
441		MAKE_YUV_601(0, 192, 0),	/* green */
442		MAKE_YUV_601(192, 0, 192),	/* magenta */
443		MAKE_YUV_601(192, 0, 0),	/* red */
444		MAKE_YUV_601(0, 0, 192),	/* blue */
445	};
446	const struct color_yuv colors_middle[] = {
447		MAKE_YUV_601(0, 0, 192),	/* blue */
448		MAKE_YUV_601(19, 19, 19),	/* black */
449		MAKE_YUV_601(192, 0, 192),	/* magenta */
450		MAKE_YUV_601(19, 19, 19),	/* black */
451		MAKE_YUV_601(0, 192, 192),	/* cyan */
452		MAKE_YUV_601(19, 19, 19),	/* black */
453		MAKE_YUV_601(192, 192, 192),	/* grey */
454	};
455	const struct color_yuv colors_bottom[] = {
456		MAKE_YUV_601(0, 33, 76),	/* in-phase */
457		MAKE_YUV_601(255, 255, 255),	/* super white */
458		MAKE_YUV_601(50, 0, 106),	/* quadrature */
459		MAKE_YUV_601(19, 19, 19),	/* black */
460		MAKE_YUV_601(9, 9, 9),		/* 3.5% */
461		MAKE_YUV_601(19, 19, 19),	/* 7.5% */
462		MAKE_YUV_601(29, 29, 29),	/* 11.5% */
463		MAKE_YUV_601(19, 19, 19),	/* black */
464	};
465	unsigned char *y_mem = (yuv->order & YUV_YC) ? mem : mem + 1;
466	unsigned char *c_mem = (yuv->order & YUV_CY) ? mem : mem + 1;
467	unsigned int u = (yuv->order & YUV_YCrCb) ? 2 : 0;
468	unsigned int v = (yuv->order & YUV_YCbCr) ? 2 : 0;
469	unsigned int x;
470	unsigned int y;
471
472	/* Luma */
473	for (y = 0; y < height * 6 / 9; ++y) {
474		for (x = 0; x < width; ++x)
475			y_mem[2*x] = colors_top[x * 7 / width].y;
476		y_mem += stride;
477	}
478
479	for (; y < height * 7 / 9; ++y) {
480		for (x = 0; x < width; ++x)
481			y_mem[2*x] = colors_middle[x * 7 / width].y;
482		y_mem += stride;
483	}
484
485	for (; y < height; ++y) {
486		for (x = 0; x < width * 5 / 7; ++x)
487			y_mem[2*x] = colors_bottom[x * 4 / (width * 5 / 7)].y;
488		for (; x < width * 6 / 7; ++x)
489			y_mem[2*x] = colors_bottom[(x - width * 5 / 7) * 3
490						   / (width / 7) + 4].y;
491		for (; x < width; ++x)
492			y_mem[2*x] = colors_bottom[7].y;
493		y_mem += stride;
494	}
495
496	/* Chroma */
497	for (y = 0; y < height * 6 / 9; ++y) {
498		for (x = 0; x < width; x += 2) {
499			c_mem[2*x+u] = colors_top[x * 7 / width].u;
500			c_mem[2*x+v] = colors_top[x * 7 / width].v;
501		}
502		c_mem += stride;
503	}
504
505	for (; y < height * 7 / 9; ++y) {
506		for (x = 0; x < width; x += 2) {
507			c_mem[2*x+u] = colors_middle[x * 7 / width].u;
508			c_mem[2*x+v] = colors_middle[x * 7 / width].v;
509		}
510		c_mem += stride;
511	}
512
513	for (; y < height; ++y) {
514		for (x = 0; x < width * 5 / 7; x += 2) {
515			c_mem[2*x+u] = colors_bottom[x * 4 / (width * 5 / 7)].u;
516			c_mem[2*x+v] = colors_bottom[x * 4 / (width * 5 / 7)].v;
517		}
518		for (; x < width * 6 / 7; x += 2) {
519			c_mem[2*x+u] = colors_bottom[(x - width * 5 / 7) *
520						     3 / (width / 7) + 4].u;
521			c_mem[2*x+v] = colors_bottom[(x - width * 5 / 7) *
522						     3 / (width / 7) + 4].v;
523		}
524		for (; x < width; x += 2) {
525			c_mem[2*x+u] = colors_bottom[7].u;
526			c_mem[2*x+v] = colors_bottom[7].v;
527		}
528		c_mem += stride;
529	}
530}
531
532static void fill_smpte_rgb16(const struct util_rgb_info *rgb, void *mem,
533			     unsigned int width, unsigned int height,
534			     unsigned int stride, bool fb_be)
535{
536	const uint16_t colors_top[] = {
537		MAKE_RGBA(rgb, 192, 192, 192, 255),	/* grey */
538		MAKE_RGBA(rgb, 192, 192, 0, 255),	/* yellow */
539		MAKE_RGBA(rgb, 0, 192, 192, 255),	/* cyan */
540		MAKE_RGBA(rgb, 0, 192, 0, 255),		/* green */
541		MAKE_RGBA(rgb, 192, 0, 192, 255),	/* magenta */
542		MAKE_RGBA(rgb, 192, 0, 0, 255),		/* red */
543		MAKE_RGBA(rgb, 0, 0, 192, 255),		/* blue */
544	};
545	const uint16_t colors_middle[] = {
546		MAKE_RGBA(rgb, 0, 0, 192, 127),		/* blue */
547		MAKE_RGBA(rgb, 19, 19, 19, 127),	/* black */
548		MAKE_RGBA(rgb, 192, 0, 192, 127),	/* magenta */
549		MAKE_RGBA(rgb, 19, 19, 19, 127),	/* black */
550		MAKE_RGBA(rgb, 0, 192, 192, 127),	/* cyan */
551		MAKE_RGBA(rgb, 19, 19, 19, 127),	/* black */
552		MAKE_RGBA(rgb, 192, 192, 192, 127),	/* grey */
553	};
554	const uint16_t colors_bottom[] = {
555		MAKE_RGBA(rgb, 0, 33, 76, 255),		/* in-phase */
556		MAKE_RGBA(rgb, 255, 255, 255, 255),	/* super white */
557		MAKE_RGBA(rgb, 50, 0, 106, 255),	/* quadrature */
558		MAKE_RGBA(rgb, 19, 19, 19, 255),	/* black */
559		MAKE_RGBA(rgb, 9, 9, 9, 255),		/* 3.5% */
560		MAKE_RGBA(rgb, 19, 19, 19, 255),	/* 7.5% */
561		MAKE_RGBA(rgb, 29, 29, 29, 255),	/* 11.5% */
562		MAKE_RGBA(rgb, 19, 19, 19, 255),	/* black */
563	};
564	unsigned int x;
565	unsigned int y;
566
567	for (y = 0; y < height * 6 / 9; ++y) {
568		for (x = 0; x < width; ++x)
569			((uint16_t *)mem)[x] = cpu_to_fb16(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			((uint16_t *)mem)[x] = cpu_to_fb16(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			((uint16_t *)mem)[x] =
582				cpu_to_fb16(colors_bottom[x * 4 / (width * 5 / 7)]);
583		for (; x < width * 6 / 7; ++x)
584			((uint16_t *)mem)[x] =
585				cpu_to_fb16(colors_bottom[(x - width * 5 / 7) * 3
586							  / (width / 7) + 4]);
587		for (; x < width; ++x)
588			((uint16_t *)mem)[x] = cpu_to_fb16(colors_bottom[7]);
589		mem += stride;
590	}
591}
592
593static void fill_smpte_rgb24(const struct util_rgb_info *rgb, void *mem,
594			     unsigned int width, unsigned int height,
595			     unsigned int stride)
596{
597	const struct color_rgb24 colors_top[] = {
598		MAKE_RGB24(rgb, 192, 192, 192),	/* grey */
599		MAKE_RGB24(rgb, 192, 192, 0),	/* yellow */
600		MAKE_RGB24(rgb, 0, 192, 192),	/* cyan */
601		MAKE_RGB24(rgb, 0, 192, 0),	/* green */
602		MAKE_RGB24(rgb, 192, 0, 192),	/* magenta */
603		MAKE_RGB24(rgb, 192, 0, 0),	/* red */
604		MAKE_RGB24(rgb, 0, 0, 192),	/* blue */
605	};
606	const struct color_rgb24 colors_middle[] = {
607		MAKE_RGB24(rgb, 0, 0, 192),	/* blue */
608		MAKE_RGB24(rgb, 19, 19, 19),	/* black */
609		MAKE_RGB24(rgb, 192, 0, 192),	/* magenta */
610		MAKE_RGB24(rgb, 19, 19, 19),	/* black */
611		MAKE_RGB24(rgb, 0, 192, 192),	/* cyan */
612		MAKE_RGB24(rgb, 19, 19, 19),	/* black */
613		MAKE_RGB24(rgb, 192, 192, 192),	/* grey */
614	};
615	const struct color_rgb24 colors_bottom[] = {
616		MAKE_RGB24(rgb, 0, 33, 76),	/* in-phase */
617		MAKE_RGB24(rgb, 255, 255, 255),	/* super white */
618		MAKE_RGB24(rgb, 50, 0, 106),	/* quadrature */
619		MAKE_RGB24(rgb, 19, 19, 19),	/* black */
620		MAKE_RGB24(rgb, 9, 9, 9),	/* 3.5% */
621		MAKE_RGB24(rgb, 19, 19, 19),	/* 7.5% */
622		MAKE_RGB24(rgb, 29, 29, 29),	/* 11.5% */
623		MAKE_RGB24(rgb, 19, 19, 19),	/* black */
624	};
625	unsigned int x;
626	unsigned int y;
627
628	for (y = 0; y < height * 6 / 9; ++y) {
629		for (x = 0; x < width; ++x)
630			((struct color_rgb24 *)mem)[x] =
631				colors_top[x * 7 / width];
632		mem += stride;
633	}
634
635	for (; y < height * 7 / 9; ++y) {
636		for (x = 0; x < width; ++x)
637			((struct color_rgb24 *)mem)[x] =
638				colors_middle[x * 7 / width];
639		mem += stride;
640	}
641
642	for (; y < height; ++y) {
643		for (x = 0; x < width * 5 / 7; ++x)
644			((struct color_rgb24 *)mem)[x] =
645				colors_bottom[x * 4 / (width * 5 / 7)];
646		for (; x < width * 6 / 7; ++x)
647			((struct color_rgb24 *)mem)[x] =
648				colors_bottom[(x - width * 5 / 7) * 3
649					      / (width / 7) + 4];
650		for (; x < width; ++x)
651			((struct color_rgb24 *)mem)[x] = colors_bottom[7];
652		mem += stride;
653	}
654}
655
656static void fill_smpte_rgb32(const struct util_rgb_info *rgb, void *mem,
657			     unsigned int width, unsigned int height,
658			     unsigned int stride)
659{
660	const uint32_t colors_top[] = {
661		MAKE_RGBA(rgb, 192, 192, 192, 255),	/* grey */
662		MAKE_RGBA(rgb, 192, 192, 0, 255),	/* yellow */
663		MAKE_RGBA(rgb, 0, 192, 192, 255),	/* cyan */
664		MAKE_RGBA(rgb, 0, 192, 0, 255),		/* green */
665		MAKE_RGBA(rgb, 192, 0, 192, 255),	/* magenta */
666		MAKE_RGBA(rgb, 192, 0, 0, 255),		/* red */
667		MAKE_RGBA(rgb, 0, 0, 192, 255),		/* blue */
668	};
669	const uint32_t colors_middle[] = {
670		MAKE_RGBA(rgb, 0, 0, 192, 127),		/* blue */
671		MAKE_RGBA(rgb, 19, 19, 19, 127),	/* black */
672		MAKE_RGBA(rgb, 192, 0, 192, 127),	/* magenta */
673		MAKE_RGBA(rgb, 19, 19, 19, 127),	/* black */
674		MAKE_RGBA(rgb, 0, 192, 192, 127),	/* cyan */
675		MAKE_RGBA(rgb, 19, 19, 19, 127),	/* black */
676		MAKE_RGBA(rgb, 192, 192, 192, 127),	/* grey */
677	};
678	const uint32_t colors_bottom[] = {
679		MAKE_RGBA(rgb, 0, 33, 76, 255),		/* in-phase */
680		MAKE_RGBA(rgb, 255, 255, 255, 255),	/* super white */
681		MAKE_RGBA(rgb, 50, 0, 106, 255),	/* quadrature */
682		MAKE_RGBA(rgb, 19, 19, 19, 255),	/* black */
683		MAKE_RGBA(rgb, 9, 9, 9, 255),		/* 3.5% */
684		MAKE_RGBA(rgb, 19, 19, 19, 255),	/* 7.5% */
685		MAKE_RGBA(rgb, 29, 29, 29, 255),	/* 11.5% */
686		MAKE_RGBA(rgb, 19, 19, 19, 255),	/* black */
687	};
688	unsigned int x;
689	unsigned int y;
690
691	for (y = 0; y < height * 6 / 9; ++y) {
692		for (x = 0; x < width; ++x)
693			((uint32_t *)mem)[x] = cpu_to_le32(colors_top[x * 7 / width]);
694		mem += stride;
695	}
696
697	for (; y < height * 7 / 9; ++y) {
698		for (x = 0; x < width; ++x)
699			((uint32_t *)mem)[x] = cpu_to_le32(colors_middle[x * 7 / width]);
700		mem += stride;
701	}
702
703	for (; y < height; ++y) {
704		for (x = 0; x < width * 5 / 7; ++x)
705			((uint32_t *)mem)[x] =
706				cpu_to_le32(colors_bottom[x * 4 / (width * 5 / 7)]);
707		for (; x < width * 6 / 7; ++x)
708			((uint32_t *)mem)[x] =
709				cpu_to_le32(colors_bottom[(x - width * 5 / 7) * 3
710							  / (width / 7) + 4]);
711		for (; x < width; ++x)
712			((uint32_t *)mem)[x] = cpu_to_le32(colors_bottom[7]);
713		mem += stride;
714	}
715}
716
717static void fill_smpte_rgb16fp(const struct util_rgb_info *rgb, void *mem,
718			       unsigned int width, unsigned int height,
719			       unsigned int stride)
720{
721	const uint64_t colors_top[] = {
722		MAKE_RGBA8FP16(rgb, 192, 192, 192, 255),/* grey */
723		MAKE_RGBA8FP16(rgb, 192, 192, 0, 255),	/* yellow */
724		MAKE_RGBA8FP16(rgb, 0, 192, 192, 255),	/* cyan */
725		MAKE_RGBA8FP16(rgb, 0, 192, 0, 255),	/* green */
726		MAKE_RGBA8FP16(rgb, 192, 0, 192, 255),	/* magenta */
727		MAKE_RGBA8FP16(rgb, 192, 0, 0, 255),	/* red */
728		MAKE_RGBA8FP16(rgb, 0, 0, 192, 255),	/* blue */
729	};
730	const uint64_t colors_middle[] = {
731		MAKE_RGBA8FP16(rgb, 0, 0, 192, 127),	/* blue */
732		MAKE_RGBA8FP16(rgb, 19, 19, 19, 127),	/* black */
733		MAKE_RGBA8FP16(rgb, 192, 0, 192, 127),	/* magenta */
734		MAKE_RGBA8FP16(rgb, 19, 19, 19, 127),	/* black */
735		MAKE_RGBA8FP16(rgb, 0, 192, 192, 127),	/* cyan */
736		MAKE_RGBA8FP16(rgb, 19, 19, 19, 127),	/* black */
737		MAKE_RGBA8FP16(rgb, 192, 192, 192, 127),/* grey */
738	};
739	const uint64_t colors_bottom[] = {
740		MAKE_RGBA8FP16(rgb, 0, 33, 76, 255),	/* in-phase */
741		MAKE_RGBA8FP16(rgb, 255, 255, 255, 255),/* super white */
742		MAKE_RGBA8FP16(rgb, 50, 0, 106, 255),	/* quadrature */
743		MAKE_RGBA8FP16(rgb, 19, 19, 19, 255),	/* black */
744		MAKE_RGBA8FP16(rgb, 9, 9, 9, 255),	/* 3.5% */
745		MAKE_RGBA8FP16(rgb, 19, 19, 19, 255),	/* 7.5% */
746		MAKE_RGBA8FP16(rgb, 29, 29, 29, 255),	/* 11.5% */
747		MAKE_RGBA8FP16(rgb, 19, 19, 19, 255),	/* black */
748	};
749	unsigned int x;
750	unsigned int y;
751
752	for (y = 0; y < height * 6 / 9; ++y) {
753		for (x = 0; x < width; ++x)
754			((uint64_t *)mem)[x] = colors_top[x * 7 / width];
755		mem += stride;
756	}
757
758	for (; y < height * 7 / 9; ++y) {
759		for (x = 0; x < width; ++x)
760			((uint64_t *)mem)[x] = colors_middle[x * 7 / width];
761		mem += stride;
762	}
763
764	for (; y < height; ++y) {
765		for (x = 0; x < width * 5 / 7; ++x)
766			((uint64_t *)mem)[x] =
767				colors_bottom[x * 4 / (width * 5 / 7)];
768		for (; x < width * 6 / 7; ++x)
769			((uint64_t *)mem)[x] =
770				colors_bottom[(x - width * 5 / 7) * 3
771					      / (width / 7) + 4];
772		for (; x < width; ++x)
773			((uint64_t *)mem)[x] = colors_bottom[7];
774		mem += stride;
775	}
776}
777
778enum smpte_colors {
779	SMPTE_COLOR_GREY,
780	SMPTE_COLOR_YELLOW,
781	SMPTE_COLOR_CYAN,
782	SMPTE_COLOR_GREEN,
783	SMPTE_COLOR_MAGENTA,
784	SMPTE_COLOR_RED,
785	SMPTE_COLOR_BLUE,
786	SMPTE_COLOR_BLACK,
787	SMPTE_COLOR_IN_PHASE,
788	SMPTE_COLOR_SUPER_WHITE,
789	SMPTE_COLOR_QUADRATURE,
790	SMPTE_COLOR_3PC5,
791	SMPTE_COLOR_11PC5,
792};
793
794static unsigned int smpte_top[7] = {
795	SMPTE_COLOR_GREY,
796	SMPTE_COLOR_YELLOW,
797	SMPTE_COLOR_CYAN,
798	SMPTE_COLOR_GREEN,
799	SMPTE_COLOR_MAGENTA,
800	SMPTE_COLOR_RED,
801	SMPTE_COLOR_BLUE,
802};
803
804static unsigned int smpte_middle[7] = {
805	SMPTE_COLOR_BLUE,
806	SMPTE_COLOR_BLACK,
807	SMPTE_COLOR_MAGENTA,
808	SMPTE_COLOR_BLACK,
809	SMPTE_COLOR_CYAN,
810	SMPTE_COLOR_BLACK,
811	SMPTE_COLOR_GREY,
812};
813
814static unsigned int smpte_bottom[8] = {
815	SMPTE_COLOR_IN_PHASE,
816	SMPTE_COLOR_SUPER_WHITE,
817	SMPTE_COLOR_QUADRATURE,
818	SMPTE_COLOR_BLACK,
819	SMPTE_COLOR_3PC5,
820	SMPTE_COLOR_BLACK,
821	SMPTE_COLOR_11PC5,
822	SMPTE_COLOR_BLACK,
823};
824
825#define EXPAND_COLOR(r, g, b)	{ (r) * 0x101, (g) * 0x101, (b) * 0x101 }
826
827static const struct drm_color_lut bw_color_lut[] = {
828	EXPAND_COLOR(  0,   0,   0),	/* black */
829	EXPAND_COLOR(255, 255, 255),	/* white */
830};
831
832static const struct drm_color_lut pentile_color_lut[] = {
833	/* PenTile RG-GB */
834	EXPAND_COLOR(  0,   0,   0),	/* black */
835	EXPAND_COLOR(255,   0,   0),	/* red */
836	EXPAND_COLOR(  0, 207,   0),	/* green */
837	EXPAND_COLOR(  0,   0, 255),	/* blue */
838};
839
840static const struct drm_color_lut smpte_color_lut[] = {
841	[SMPTE_COLOR_GREY] =        EXPAND_COLOR(192, 192, 192),
842	[SMPTE_COLOR_YELLOW] =      EXPAND_COLOR(192, 192,   0),
843	[SMPTE_COLOR_CYAN] =        EXPAND_COLOR(  0, 192, 192),
844	[SMPTE_COLOR_GREEN] =       EXPAND_COLOR(  0, 192,   0),
845	[SMPTE_COLOR_MAGENTA] =     EXPAND_COLOR(192,   0, 192),
846	[SMPTE_COLOR_RED] =         EXPAND_COLOR(192,   0,   0),
847	[SMPTE_COLOR_BLUE] =        EXPAND_COLOR(  0,   0, 192),
848	[SMPTE_COLOR_BLACK] =       EXPAND_COLOR( 19,  19,  19),
849	[SMPTE_COLOR_IN_PHASE] =    EXPAND_COLOR(  0,  33,  76),
850	[SMPTE_COLOR_SUPER_WHITE] = EXPAND_COLOR(255, 255, 255),
851	[SMPTE_COLOR_QUADRATURE] =  EXPAND_COLOR( 50,   0, 106),
852	[SMPTE_COLOR_3PC5] =        EXPAND_COLOR(  9,   9,   9),
853	[SMPTE_COLOR_11PC5] =       EXPAND_COLOR( 29,  29,  29),
854};
855
856#undef EXPAND_COLOR
857
858/*
859 * Floyd-Steinberg dithering
860 */
861
862struct fsd {
863	unsigned int width;
864	unsigned int x;
865	unsigned int i;
866	int red;
867	int green;
868	int blue;
869	int error[];
870};
871
872static struct fsd *fsd_alloc(unsigned int width)
873{
874	unsigned int n = 3 * (width + 1);
875	struct fsd *fsd = malloc(sizeof(*fsd) + n * sizeof(fsd->error[0]));
876
877	fsd->width = width;
878	fsd->x = 0;
879	fsd->i = 0;
880	memset(fsd->error, 0, n * sizeof(fsd->error[0]));
881
882	return fsd;
883}
884
885static inline int clamp(int val, int min, int max)
886{
887	if (val < min)
888		return min;
889	if (val > max)
890		return max;
891	return val;
892}
893
894static void fsd_dither(struct fsd *fsd, struct drm_color_lut *color)
895{
896	unsigned int i = fsd->i;
897
898	fsd->red = (int)color->red + (fsd->error[3 * i] + 8) / 16;
899	fsd->green = (int)color->green + (fsd->error[3 * i + 1] + 8) / 16;
900	fsd->blue = (int)color->blue + (fsd->error[3 * i + 2] + 8) / 16;
901
902	color->red = clamp(fsd->red, 0, 65535);
903	color->green = clamp(fsd->green, 0, 65535);
904	color->blue = clamp(fsd->blue, 0, 65535);
905}
906
907static void fsd_update(struct fsd *fsd, const struct drm_color_lut *actual)
908{
909	int error_red = fsd->red - (int)actual->red;
910	int error_green = fsd->green - (int)actual->green;
911	int error_blue = fsd->blue - (int)actual->blue;
912	unsigned int width = fsd->width;
913	unsigned int i = fsd->i, j;
914	unsigned int n = width + 1;
915
916	/* Distribute errors over neighboring pixels */
917	if (fsd->x == width - 1) {
918		/* Last pixel on this scanline */
919		/* South East: initialize to zero */
920		fsd->error[3 * i] = 0;
921		fsd->error[3 * i + 1] = 0;
922		fsd->error[3 * i + 2] = 0;
923	} else {
924		/* East: accumulate error */
925		j = (i + 1) % n;
926		fsd->error[3 * j] += 7 * error_red;
927		fsd->error[3 * j + 1] += 7 * error_green;
928		fsd->error[3 * j + 2] += 7 * error_blue;
929
930		/* South East: initial error */
931		fsd->error[3 * i] = error_red;
932		fsd->error[3 * i + 1] = error_green;
933		fsd->error[3 * i + 2] = error_blue;
934	}
935	/* South West: accumulate error */
936	j = (i + width - 1) % n;
937	fsd->error[3 * j] += 3 * error_red;
938	fsd->error[3 * j + 1] += 3 * error_green;
939	fsd->error[3 * j + 2] += 3 * error_blue;
940
941	/* South: accumulate error */
942	j = (i + width) % n;
943	fsd->error[3 * j] += 5 * error_red;
944	fsd->error[3 * j + 1] += 5 * error_green;
945	fsd->error[3 * j + 2] += 5 * error_blue;
946
947	fsd->x = (fsd->x + 1) % width;
948	fsd->i = (fsd->i + 1) % n;
949}
950
951static void write_pixel_1(uint8_t *mem, unsigned int x, unsigned int pixel)
952{
953	unsigned int shift = 7 - (x & 7);
954	unsigned int mask = 1U << shift;
955
956	mem[x / 8] = (mem[x / 8] & ~mask) | ((pixel << shift) & mask);
957}
958
959static void write_color_1(struct fsd *fsd, uint8_t *mem, unsigned int x,
960			  unsigned int index)
961{
962	struct drm_color_lut color = smpte_color_lut[index];
963	unsigned int pixel;
964
965	fsd_dither(fsd, &color);
966
967	/* ITU BT.601: Y = 0.299 R + 0.587 G + 0.114 B */
968	if (3 * color.red + 6 * color.green + color.blue >= 10 * 32768) {
969		pixel = 1;
970		color.red = color.green = color.blue = 65535;
971	} else {
972		pixel = 0;
973		color.red = color.green = color.blue = 0;
974	}
975
976	fsd_update(fsd, &color);
977
978	write_pixel_1(mem, x, pixel);
979}
980
981static void fill_smpte_c1(void *mem, unsigned int width, unsigned int height,
982			  unsigned int stride)
983{
984	struct fsd *fsd = fsd_alloc(width);
985	unsigned int x;
986	unsigned int y;
987
988	for (y = 0; y < height * 6 / 9; ++y) {
989		for (x = 0; x < width; ++x)
990			write_color_1(fsd, mem, x, smpte_top[x * 7 / width]);
991		mem += stride;
992	}
993
994	for (; y < height * 7 / 9; ++y) {
995		for (x = 0; x < width; ++x)
996			write_color_1(fsd, mem, x, smpte_middle[x * 7 / width]);
997		mem += stride;
998	}
999
1000	for (; y < height; ++y) {
1001		for (x = 0; x < width * 5 / 7; ++x)
1002			write_color_1(fsd, mem, x,
1003				      smpte_bottom[x * 4 / (width * 5 / 7)]);
1004		for (; x < width * 6 / 7; ++x)
1005			write_color_1(fsd, mem, x,
1006				      smpte_bottom[(x - width * 5 / 7) * 3 /
1007						   (width / 7) + 4]);
1008		for (; x < width; ++x)
1009			write_color_1(fsd, mem, x, smpte_bottom[7]);
1010		mem += stride;
1011	}
1012
1013	free(fsd);
1014}
1015
1016static void write_pixel_2(uint8_t *mem, unsigned int x, unsigned int pixel)
1017{
1018	unsigned int shift = 6 - 2 * (x & 3);
1019	unsigned int mask = 3U << shift;
1020
1021	mem[x / 4] = (mem[x / 4] & ~mask) | ((pixel << shift) & mask);
1022}
1023
1024static void write_color_2(struct fsd *fsd, uint8_t *mem, unsigned int stride,
1025			  unsigned int x, unsigned int index)
1026{
1027	struct drm_color_lut color = smpte_color_lut[index];
1028	unsigned int r, g, b;
1029
1030	fsd_dither(fsd, &color);
1031
1032	if (color.red >= 32768) {
1033		r = 1;
1034		color.red = 65535;
1035	} else {
1036		r = 0;
1037		color.red = 0;
1038	}
1039	if (color.green >= 32768) {
1040		g = 2;
1041		color.green = 65535;
1042	} else {
1043		g = 0;
1044		color.green = 0;
1045	}
1046	if (color.blue >= 32768) {
1047		b = 3;
1048		color.blue = 65535;
1049	} else {
1050		b = 0;
1051		color.blue = 0;
1052	}
1053
1054	fsd_update(fsd, &color);
1055
1056	/* Use PenTile RG-GB */
1057	write_pixel_2(mem, 2 * x, r);
1058	write_pixel_2(mem, 2 * x + 1, g);
1059	write_pixel_2(mem + stride, 2 * x, g);
1060	write_pixel_2(mem + stride, 2 * x + 1, b);
1061}
1062
1063static void fill_smpte_c2(void *mem, unsigned int width, unsigned int height,
1064			  unsigned int stride)
1065{
1066	struct fsd *fsd = fsd_alloc(width);
1067	unsigned int x;
1068	unsigned int y;
1069
1070	/* Half resolution for PenTile RG-GB */
1071	width /= 2;
1072	height /= 2;
1073
1074	for (y = 0; y < height * 6 / 9; ++y) {
1075		for (x = 0; x < width; ++x)
1076			write_color_2(fsd, mem, stride, x, smpte_top[x * 7 / width]);
1077		mem += 2 * stride;
1078	}
1079
1080	for (; y < height * 7 / 9; ++y) {
1081		for (x = 0; x < width; ++x)
1082			write_color_2(fsd, mem, stride, x, smpte_middle[x * 7 / width]);
1083		mem += 2 * stride;
1084	}
1085
1086	for (; y < height; ++y) {
1087		for (x = 0; x < width * 5 / 7; ++x)
1088			write_color_2(fsd, mem, stride, x,
1089				      smpte_bottom[x * 4 / (width * 5 / 7)]);
1090		for (; x < width * 6 / 7; ++x)
1091			write_color_2(fsd, mem, stride, x,
1092				      smpte_bottom[(x - width * 5 / 7) * 3 /
1093						   (width / 7) + 4]);
1094		for (; x < width; ++x)
1095			write_color_2(fsd, mem, stride, x, smpte_bottom[7]);
1096		mem += 2 * stride;
1097	}
1098
1099	free(fsd);
1100}
1101
1102static void write_pixel_4(uint8_t *mem, unsigned int x, unsigned int pixel)
1103{
1104	if (x & 1)
1105		mem[x / 2] = (mem[x / 2] & 0xf0) | (pixel & 0x0f);
1106	else
1107		mem[x / 2] = (mem[x / 2] & 0x0f) | (pixel << 4);
1108}
1109
1110static void fill_smpte_c4(void *mem, unsigned int width, unsigned int height,
1111			  unsigned int stride)
1112{
1113	unsigned int x;
1114	unsigned int y;
1115
1116	for (y = 0; y < height * 6 / 9; ++y) {
1117		for (x = 0; x < width; ++x)
1118			write_pixel_4(mem, x, smpte_top[x * 7 / width]);
1119		mem += stride;
1120	}
1121
1122	for (; y < height * 7 / 9; ++y) {
1123		for (x = 0; x < width; ++x)
1124			write_pixel_4(mem, x, smpte_middle[x * 7 / width]);
1125		mem += stride;
1126	}
1127
1128	for (; y < height; ++y) {
1129		for (x = 0; x < width * 5 / 7; ++x)
1130			write_pixel_4(mem, x,
1131				      smpte_bottom[x * 4 / (width * 5 / 7)]);
1132		for (; x < width * 6 / 7; ++x)
1133			write_pixel_4(mem, x,
1134				      smpte_bottom[(x - width * 5 / 7) * 3 /
1135						   (width / 7) + 4]);
1136		for (; x < width; ++x)
1137			write_pixel_4(mem, x, smpte_bottom[7]);
1138		mem += stride;
1139	}
1140}
1141
1142static void fill_smpte_c8(void *mem, unsigned int width, unsigned int height,
1143			  unsigned int stride)
1144{
1145	unsigned int x;
1146	unsigned int y;
1147
1148	for (y = 0; y < height * 6 / 9; ++y) {
1149		for (x = 0; x < width; ++x)
1150			((uint8_t *)mem)[x] = smpte_top[x * 7 / width];
1151		mem += stride;
1152	}
1153
1154	for (; y < height * 7 / 9; ++y) {
1155		for (x = 0; x < width; ++x)
1156			((uint8_t *)mem)[x] = smpte_middle[x * 7 / width];
1157		mem += stride;
1158	}
1159
1160	for (; y < height; ++y) {
1161		for (x = 0; x < width * 5 / 7; ++x)
1162			((uint8_t *)mem)[x] =
1163				smpte_bottom[x * 4 / (width * 5 / 7)];
1164		for (; x < width * 6 / 7; ++x)
1165			((uint8_t *)mem)[x] =
1166				smpte_bottom[(x - width * 5 / 7) * 3
1167					     / (width / 7) + 4];
1168		for (; x < width; ++x)
1169			((uint8_t *)mem)[x] = smpte_bottom[7];
1170		mem += stride;
1171	}
1172}
1173
1174void util_smpte_fill_lut(unsigned int ncolors, struct drm_color_lut *lut)
1175{
1176	if (ncolors < ARRAY_SIZE(bw_color_lut)) {
1177		printf("Error: lut too small: %u < %zu\n", ncolors,
1178		       ARRAY_SIZE(bw_color_lut));
1179		return;
1180	}
1181	memset(lut, 0, ncolors * sizeof(struct drm_color_lut));
1182
1183	if (ncolors < ARRAY_SIZE(pentile_color_lut))
1184		memcpy(lut, bw_color_lut, sizeof(bw_color_lut));
1185	else if (ncolors < ARRAY_SIZE(smpte_color_lut))
1186		memcpy(lut, pentile_color_lut, sizeof(pentile_color_lut));
1187	else
1188		memcpy(lut, smpte_color_lut, sizeof(smpte_color_lut));
1189}
1190
1191static void fill_smpte(const struct util_format_info *info, void *planes[3],
1192		       unsigned int width, unsigned int height,
1193		       unsigned int stride)
1194{
1195	unsigned char *u, *v;
1196
1197	switch (info->format) {
1198	case DRM_FORMAT_C1:
1199		return fill_smpte_c1(planes[0], width, height, stride);
1200	case DRM_FORMAT_C2:
1201		return fill_smpte_c2(planes[0], width, height, stride);
1202	case DRM_FORMAT_C4:
1203		return fill_smpte_c4(planes[0], width, height, stride);
1204	case DRM_FORMAT_C8:
1205		return fill_smpte_c8(planes[0], width, height, stride);
1206	case DRM_FORMAT_UYVY:
1207	case DRM_FORMAT_VYUY:
1208	case DRM_FORMAT_YUYV:
1209	case DRM_FORMAT_YVYU:
1210		return fill_smpte_yuv_packed(&info->yuv, planes[0], width,
1211					     height, stride);
1212
1213	case DRM_FORMAT_NV12:
1214	case DRM_FORMAT_NV21:
1215	case DRM_FORMAT_NV16:
1216	case DRM_FORMAT_NV61:
1217	case DRM_FORMAT_NV24:
1218	case DRM_FORMAT_NV42:
1219		u = info->yuv.order & YUV_YCbCr ? planes[1] : planes[1] + 1;
1220		v = info->yuv.order & YUV_YCrCb ? planes[1] : planes[1] + 1;
1221		return fill_smpte_yuv_planar(&info->yuv, planes[0], u, v,
1222					     width, height, stride);
1223
1224	case DRM_FORMAT_NV15:
1225	case DRM_FORMAT_NV20:
1226	case DRM_FORMAT_NV30:
1227		return fill_smpte_yuv_planar_10bpp(&info->yuv, planes[0],
1228						   planes[1], width, height,
1229						   stride);
1230
1231	case DRM_FORMAT_YUV420:
1232	case DRM_FORMAT_YUV422:
1233	case DRM_FORMAT_YUV444:
1234		return fill_smpte_yuv_planar(&info->yuv, planes[0], planes[1],
1235					     planes[2], width, height, stride);
1236
1237	case DRM_FORMAT_YVU420:
1238	case DRM_FORMAT_YVU422:
1239	case DRM_FORMAT_YVU444:
1240		return fill_smpte_yuv_planar(&info->yuv, planes[0], planes[2],
1241					     planes[1], width, height, stride);
1242
1243	case DRM_FORMAT_ARGB4444:
1244	case DRM_FORMAT_XRGB4444:
1245	case DRM_FORMAT_ABGR4444:
1246	case DRM_FORMAT_XBGR4444:
1247	case DRM_FORMAT_RGBA4444:
1248	case DRM_FORMAT_RGBX4444:
1249	case DRM_FORMAT_BGRA4444:
1250	case DRM_FORMAT_BGRX4444:
1251	case DRM_FORMAT_RGB565:
1252	case DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN:
1253	case DRM_FORMAT_BGR565:
1254	case DRM_FORMAT_ARGB1555:
1255	case DRM_FORMAT_XRGB1555:
1256	case DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN:
1257	case DRM_FORMAT_ABGR1555:
1258	case DRM_FORMAT_XBGR1555:
1259	case DRM_FORMAT_RGBA5551:
1260	case DRM_FORMAT_RGBX5551:
1261	case DRM_FORMAT_BGRA5551:
1262	case DRM_FORMAT_BGRX5551:
1263		return fill_smpte_rgb16(&info->rgb, planes[0],
1264					width, height, stride,
1265					info->format & DRM_FORMAT_BIG_ENDIAN);
1266
1267	case DRM_FORMAT_BGR888:
1268	case DRM_FORMAT_RGB888:
1269		return fill_smpte_rgb24(&info->rgb, planes[0],
1270					width, height, stride);
1271	case DRM_FORMAT_ARGB8888:
1272	case DRM_FORMAT_XRGB8888:
1273	case DRM_FORMAT_ABGR8888:
1274	case DRM_FORMAT_XBGR8888:
1275	case DRM_FORMAT_RGBA8888:
1276	case DRM_FORMAT_RGBX8888:
1277	case DRM_FORMAT_BGRA8888:
1278	case DRM_FORMAT_BGRX8888:
1279	case DRM_FORMAT_ARGB2101010:
1280	case DRM_FORMAT_XRGB2101010:
1281	case DRM_FORMAT_ABGR2101010:
1282	case DRM_FORMAT_XBGR2101010:
1283	case DRM_FORMAT_RGBA1010102:
1284	case DRM_FORMAT_RGBX1010102:
1285	case DRM_FORMAT_BGRA1010102:
1286	case DRM_FORMAT_BGRX1010102:
1287		return fill_smpte_rgb32(&info->rgb, planes[0],
1288					width, height, stride);
1289
1290	case DRM_FORMAT_XRGB16161616F:
1291	case DRM_FORMAT_XBGR16161616F:
1292	case DRM_FORMAT_ARGB16161616F:
1293	case DRM_FORMAT_ABGR16161616F:
1294		return fill_smpte_rgb16fp(&info->rgb, planes[0],
1295					  width, height, stride);
1296	}
1297}
1298
1299#if HAVE_CAIRO
1300static void byteswap_buffer16(void *mem, unsigned int width, unsigned int height,
1301			      unsigned int stride)
1302{
1303	unsigned int x, y;
1304
1305	for (y = 0; y < height; ++y) {
1306		for (x = 0; x < width; ++x)
1307			((uint16_t *)mem)[x] = swap16(((uint16_t *)mem)[x]);
1308		mem += stride;
1309	}
1310}
1311
1312static void byteswap_buffer32(void *mem, unsigned int width, unsigned int height,
1313			      unsigned int stride)
1314{
1315	unsigned int x, y;
1316
1317	for (y = 0; y < height; ++y) {
1318		for (x = 0; x < width; ++x)
1319			((uint32_t *)mem)[x] = swap32(((uint32_t *)mem)[x]);
1320		mem += stride;
1321	}
1322}
1323#endif
1324
1325static void make_pwetty(void *data, unsigned int width, unsigned int height,
1326			unsigned int stride, uint32_t format)
1327{
1328#if HAVE_CAIRO
1329	cairo_surface_t *surface;
1330	cairo_t *cr;
1331	cairo_format_t cairo_format;
1332	bool swap16 = false;
1333	bool swap32 = false;
1334
1335	/* we can ignore the order of R,G,B channels */
1336	switch (format) {
1337	case DRM_FORMAT_XRGB8888:
1338	case DRM_FORMAT_ARGB8888:
1339	case DRM_FORMAT_XBGR8888:
1340	case DRM_FORMAT_ABGR8888:
1341		cairo_format = CAIRO_FORMAT_ARGB32;
1342		break;
1343	case DRM_FORMAT_RGB565:
1344	case DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN:
1345	case DRM_FORMAT_BGR565:
1346		cairo_format = CAIRO_FORMAT_RGB16_565;
1347		swap16 = fb_foreign_endian(format);
1348		break;
1349#if CAIRO_VERSION_MAJOR > 1 || (CAIRO_VERSION_MAJOR == 1 && CAIRO_VERSION_MINOR >= 12)
1350	case DRM_FORMAT_ARGB2101010:
1351	case DRM_FORMAT_XRGB2101010:
1352	case DRM_FORMAT_ABGR2101010:
1353	case DRM_FORMAT_XBGR2101010:
1354		cairo_format = CAIRO_FORMAT_RGB30;
1355		swap32 = fb_foreign_endian(format);
1356		break;
1357#endif
1358	default:
1359		return;
1360	}
1361
1362	/* Cairo uses native byte order, so we may have to byteswap before... */
1363	if (swap16)
1364		byteswap_buffer16(data, width, height, stride);
1365	if (swap32)
1366		byteswap_buffer32(data, width, height, stride);
1367
1368	surface = cairo_image_surface_create_for_data(data,
1369						      cairo_format,
1370						      width, height,
1371						      stride);
1372	cr = cairo_create(surface);
1373	cairo_surface_destroy(surface);
1374
1375	cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
1376	for (unsigned x = 0; x < width; x += 250)
1377		for (unsigned y = 0; y < height; y += 250) {
1378			char buf[64];
1379
1380			cairo_move_to(cr, x, y - 20);
1381			cairo_line_to(cr, x, y + 20);
1382			cairo_move_to(cr, x - 20, y);
1383			cairo_line_to(cr, x + 20, y);
1384			cairo_new_sub_path(cr);
1385			cairo_arc(cr, x, y, 10, 0, M_PI * 2);
1386			cairo_set_line_width(cr, 4);
1387			cairo_set_source_rgb(cr, 0, 0, 0);
1388			cairo_stroke_preserve(cr);
1389			cairo_set_source_rgb(cr, 1, 1, 1);
1390			cairo_set_line_width(cr, 2);
1391			cairo_stroke(cr);
1392
1393			snprintf(buf, sizeof buf, "%d, %d", x, y);
1394			cairo_move_to(cr, x + 20, y + 20);
1395			cairo_text_path(cr, buf);
1396			cairo_set_source_rgb(cr, 0, 0, 0);
1397			cairo_stroke_preserve(cr);
1398			cairo_set_source_rgb(cr, 1, 1, 1);
1399			cairo_fill(cr);
1400		}
1401
1402	cairo_destroy(cr);
1403
1404	/* ... and after */
1405	if (swap16)
1406		byteswap_buffer16(data, width, height, stride);
1407	if (swap32)
1408		byteswap_buffer32(data, width, height, stride);
1409#endif
1410}
1411
1412static struct color_yuv make_tiles_yuv_color(unsigned int x, unsigned int y,
1413					     unsigned int width)
1414{
1415	div_t d = div(x+y, width);
1416	uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
1417		       + 0x000a1120 * (d.rem >> 6);
1418	struct color_yuv color =
1419		MAKE_YUV_601((rgb32 >> 16) & 0xff, (rgb32 >> 8) & 0xff,
1420			     rgb32 & 0xff);
1421	return color;
1422}
1423
1424static void fill_tiles_yuv_planar(const struct util_format_info *info,
1425				  unsigned char *y_mem, unsigned char *u_mem,
1426				  unsigned char *v_mem, unsigned int width,
1427				  unsigned int height, unsigned int stride)
1428{
1429	const struct util_yuv_info *yuv = &info->yuv;
1430	unsigned int cs = yuv->chroma_stride;
1431	unsigned int xsub = yuv->xsub;
1432	unsigned int ysub = yuv->ysub;
1433	unsigned int x;
1434	unsigned int y;
1435
1436	for (y = 0; y < height; ++y) {
1437		for (x = 0; x < width; ++x) {
1438			struct color_yuv color =
1439				make_tiles_yuv_color(x, y, width);
1440
1441			y_mem[x] = color.y;
1442			u_mem[x/xsub*cs] = color.u;
1443			v_mem[x/xsub*cs] = color.v;
1444		}
1445
1446		y_mem += stride;
1447		if ((y + 1) % ysub == 0) {
1448			u_mem += stride * cs / xsub;
1449			v_mem += stride * cs / xsub;
1450		}
1451	}
1452}
1453
1454static void fill_tiles_yuv_planar_10bpp(const struct util_format_info *info,
1455					unsigned char *y_mem,
1456					unsigned char *uv_mem,
1457					unsigned int width,
1458					unsigned int height,
1459					unsigned int stride)
1460{
1461	const struct util_yuv_info *yuv = &info->yuv;
1462	unsigned int cs = yuv->chroma_stride;
1463	unsigned int xsub = yuv->xsub;
1464	unsigned int ysub = yuv->ysub;
1465	unsigned int xstep = cs * xsub;
1466	unsigned int x;
1467	unsigned int y;
1468
1469	for (y = 0; y < height; ++y) {
1470		for (x = 0; x < width; x += 4) {
1471			struct color_yuv a = make_tiles_yuv_color(x+0, y, width);
1472			struct color_yuv b = make_tiles_yuv_color(x+1, y, width);
1473			struct color_yuv c = make_tiles_yuv_color(x+2, y, width);
1474			struct color_yuv d = make_tiles_yuv_color(x+3, y, width);
1475
1476			write_pixels_10bpp(&y_mem[(x * 5) / 4],
1477				a.y << 2, b.y << 2, c.y << 2, d.y << 2);
1478		}
1479		y_mem += stride;
1480	}
1481	for (y = 0; y < height; y += ysub) {
1482		for (x = 0; x < width; x += xstep) {
1483			struct color_yuv a = make_tiles_yuv_color(x+0, y, width);
1484			struct color_yuv b = make_tiles_yuv_color(x+xsub, y, width);
1485
1486			write_pixels_10bpp(&uv_mem[(x * 5) / xstep],
1487				a.u << 2, a.v << 2, b.u << 2, b.v << 2);
1488		}
1489		uv_mem += stride * cs / xsub;
1490	}
1491}
1492
1493static void fill_tiles_yuv_packed(const struct util_format_info *info,
1494				  void *mem, unsigned int width,
1495				  unsigned int height, unsigned int stride)
1496{
1497	const struct util_yuv_info *yuv = &info->yuv;
1498	unsigned char *y_mem = (yuv->order & YUV_YC) ? mem : mem + 1;
1499	unsigned char *c_mem = (yuv->order & YUV_CY) ? mem : mem + 1;
1500	unsigned int u = (yuv->order & YUV_YCrCb) ? 2 : 0;
1501	unsigned int v = (yuv->order & YUV_YCbCr) ? 2 : 0;
1502	unsigned int x;
1503	unsigned int y;
1504
1505	for (y = 0; y < height; ++y) {
1506		for (x = 0; x < width; x += 2) {
1507			struct color_yuv color =
1508				make_tiles_yuv_color(x, y, width);
1509
1510			y_mem[2*x] = color.y;
1511			c_mem[2*x+u] = color.u;
1512			y_mem[2*x+2] = color.y;
1513			c_mem[2*x+v] = color.v;
1514		}
1515
1516		y_mem += stride;
1517		c_mem += stride;
1518	}
1519}
1520
1521static void fill_tiles_rgb16(const struct util_format_info *info, void *mem,
1522			     unsigned int width, unsigned int height,
1523			     unsigned int stride, bool fb_be)
1524{
1525	const struct util_rgb_info *rgb = &info->rgb;
1526	void *mem_base = mem;
1527	unsigned int x, y;
1528
1529	for (y = 0; y < height; ++y) {
1530		for (x = 0; x < width; ++x) {
1531			div_t d = div(x+y, width);
1532			uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
1533				       + 0x000a1120 * (d.rem >> 6);
1534			uint16_t color =
1535				MAKE_RGBA(rgb, (rgb32 >> 16) & 0xff,
1536					  (rgb32 >> 8) & 0xff, rgb32 & 0xff,
1537					  255);
1538
1539			((uint16_t *)mem)[x] = cpu_to_fb16(color);
1540		}
1541		mem += stride;
1542	}
1543
1544	make_pwetty(mem_base, width, height, stride, info->format);
1545}
1546
1547static void fill_tiles_rgb24(const struct util_format_info *info, void *mem,
1548			     unsigned int width, unsigned int height,
1549			     unsigned int stride)
1550{
1551	const struct util_rgb_info *rgb = &info->rgb;
1552	unsigned int x, y;
1553
1554	for (y = 0; y < height; ++y) {
1555		for (x = 0; x < width; ++x) {
1556			div_t d = div(x+y, width);
1557			uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
1558				       + 0x000a1120 * (d.rem >> 6);
1559			struct color_rgb24 color =
1560				MAKE_RGB24(rgb, (rgb32 >> 16) & 0xff,
1561					   (rgb32 >> 8) & 0xff, rgb32 & 0xff);
1562
1563			((struct color_rgb24 *)mem)[x] = color;
1564		}
1565		mem += stride;
1566	}
1567}
1568
1569static void fill_tiles_rgb32(const struct util_format_info *info, void *mem,
1570			     unsigned int width, unsigned int height,
1571			     unsigned int stride)
1572{
1573	const struct util_rgb_info *rgb = &info->rgb;
1574	void *mem_base = mem;
1575	unsigned int x, y;
1576
1577	for (y = 0; y < height; ++y) {
1578		for (x = 0; x < width; ++x) {
1579			div_t d = div(x+y, width);
1580			uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
1581				       + 0x000a1120 * (d.rem >> 6);
1582			uint32_t alpha = ((y < height/2) && (x < width/2)) ? 127 : 255;
1583			uint32_t color =
1584				MAKE_RGBA(rgb, (rgb32 >> 16) & 0xff,
1585					  (rgb32 >> 8) & 0xff, rgb32 & 0xff,
1586					  alpha);
1587
1588			((uint32_t *)mem)[x] = cpu_to_le32(color);
1589		}
1590		mem += stride;
1591	}
1592
1593	make_pwetty(mem_base, width, height, stride, info->format);
1594}
1595
1596static void fill_tiles_rgb16fp(const struct util_format_info *info, void *mem,
1597			       unsigned int width, unsigned int height,
1598			       unsigned int stride)
1599{
1600	const struct util_rgb_info *rgb = &info->rgb;
1601	unsigned int x, y;
1602
1603	/* TODO: Give this actual fp16 precision */
1604	for (y = 0; y < height; ++y) {
1605		for (x = 0; x < width; ++x) {
1606			div_t d = div(x+y, width);
1607			uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
1608				       + 0x000a1120 * (d.rem >> 6);
1609			uint32_t alpha = ((y < height/2) && (x < width/2)) ? 127 : 255;
1610			uint64_t color =
1611				MAKE_RGBA8FP16(rgb, (rgb32 >> 16) & 0xff,
1612					       (rgb32 >> 8) & 0xff, rgb32 & 0xff,
1613					       alpha);
1614
1615			((uint64_t *)mem)[x] = color;
1616		}
1617		mem += stride;
1618	}
1619}
1620
1621static void fill_tiles(const struct util_format_info *info, void *planes[3],
1622		       unsigned int width, unsigned int height,
1623		       unsigned int stride)
1624{
1625	unsigned char *u, *v;
1626
1627	switch (info->format) {
1628	case DRM_FORMAT_UYVY:
1629	case DRM_FORMAT_VYUY:
1630	case DRM_FORMAT_YUYV:
1631	case DRM_FORMAT_YVYU:
1632		return fill_tiles_yuv_packed(info, planes[0],
1633					     width, height, stride);
1634
1635	case DRM_FORMAT_NV12:
1636	case DRM_FORMAT_NV21:
1637	case DRM_FORMAT_NV16:
1638	case DRM_FORMAT_NV61:
1639	case DRM_FORMAT_NV24:
1640	case DRM_FORMAT_NV42:
1641		u = info->yuv.order & YUV_YCbCr ? planes[1] : planes[1] + 1;
1642		v = info->yuv.order & YUV_YCrCb ? planes[1] : planes[1] + 1;
1643		return fill_tiles_yuv_planar(info, planes[0], u, v,
1644					     width, height, stride);
1645
1646	case DRM_FORMAT_NV15:
1647	case DRM_FORMAT_NV20:
1648	case DRM_FORMAT_NV30:
1649		return fill_tiles_yuv_planar_10bpp(info, planes[0], planes[1],
1650						   width, height, stride);
1651
1652	case DRM_FORMAT_YUV420:
1653	case DRM_FORMAT_YUV422:
1654	case DRM_FORMAT_YUV444:
1655		return fill_tiles_yuv_planar(info, planes[0], planes[1],
1656					     planes[2], width, height, stride);
1657
1658	case DRM_FORMAT_YVU420:
1659	case DRM_FORMAT_YVU422:
1660	case DRM_FORMAT_YVU444:
1661		return fill_tiles_yuv_planar(info, planes[0], planes[2],
1662					     planes[1], width, height, stride);
1663
1664	case DRM_FORMAT_ARGB4444:
1665	case DRM_FORMAT_XRGB4444:
1666	case DRM_FORMAT_ABGR4444:
1667	case DRM_FORMAT_XBGR4444:
1668	case DRM_FORMAT_RGBA4444:
1669	case DRM_FORMAT_RGBX4444:
1670	case DRM_FORMAT_BGRA4444:
1671	case DRM_FORMAT_BGRX4444:
1672	case DRM_FORMAT_RGB565:
1673	case DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN:
1674	case DRM_FORMAT_BGR565:
1675	case DRM_FORMAT_ARGB1555:
1676	case DRM_FORMAT_XRGB1555:
1677	case DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN:
1678	case DRM_FORMAT_ABGR1555:
1679	case DRM_FORMAT_XBGR1555:
1680	case DRM_FORMAT_RGBA5551:
1681	case DRM_FORMAT_RGBX5551:
1682	case DRM_FORMAT_BGRA5551:
1683	case DRM_FORMAT_BGRX5551:
1684		return fill_tiles_rgb16(info, planes[0],
1685					width, height, stride,
1686					info->format & DRM_FORMAT_BIG_ENDIAN);
1687
1688	case DRM_FORMAT_BGR888:
1689	case DRM_FORMAT_RGB888:
1690		return fill_tiles_rgb24(info, planes[0],
1691					width, height, stride);
1692	case DRM_FORMAT_ARGB8888:
1693	case DRM_FORMAT_XRGB8888:
1694	case DRM_FORMAT_ABGR8888:
1695	case DRM_FORMAT_XBGR8888:
1696	case DRM_FORMAT_RGBA8888:
1697	case DRM_FORMAT_RGBX8888:
1698	case DRM_FORMAT_BGRA8888:
1699	case DRM_FORMAT_BGRX8888:
1700	case DRM_FORMAT_ARGB2101010:
1701	case DRM_FORMAT_XRGB2101010:
1702	case DRM_FORMAT_ABGR2101010:
1703	case DRM_FORMAT_XBGR2101010:
1704	case DRM_FORMAT_RGBA1010102:
1705	case DRM_FORMAT_RGBX1010102:
1706	case DRM_FORMAT_BGRA1010102:
1707	case DRM_FORMAT_BGRX1010102:
1708		return fill_tiles_rgb32(info, planes[0],
1709					width, height, stride);
1710
1711	case DRM_FORMAT_XRGB16161616F:
1712	case DRM_FORMAT_XBGR16161616F:
1713	case DRM_FORMAT_ARGB16161616F:
1714	case DRM_FORMAT_ABGR16161616F:
1715		return fill_tiles_rgb16fp(info, planes[0],
1716					  width, height, stride);
1717	}
1718}
1719
1720static void fill_plain(const struct util_format_info *info, void *planes[3],
1721		       unsigned int height,
1722		       unsigned int stride)
1723{
1724	switch (info->format) {
1725	case DRM_FORMAT_XRGB16161616F:
1726	case DRM_FORMAT_XBGR16161616F:
1727	case DRM_FORMAT_ARGB16161616F:
1728	case DRM_FORMAT_ABGR16161616F:
1729		/* 0x3838 = 0.5273 */
1730		memset(planes[0], 0x38, stride * height);
1731		break;
1732	default:
1733		memset(planes[0], 0x77, stride * height);
1734		break;
1735	}
1736}
1737
1738static void fill_gradient_rgb32(const struct util_rgb_info *rgb,
1739				void *mem,
1740				unsigned int width, unsigned int height,
1741				unsigned int stride)
1742{
1743	unsigned int i, j;
1744
1745	for (i = 0; i < height / 2; i++) {
1746		uint32_t *row = mem;
1747
1748		for (j = 0; j < width / 2; j++) {
1749			uint32_t value = MAKE_RGBA10(rgb, j & 0x3ff, j & 0x3ff, j & 0x3ff, 0);
1750			row[2*j] = row[2*j+1] = cpu_to_le32(value);
1751		}
1752		mem += stride;
1753	}
1754
1755	for (; i < height; i++) {
1756		uint32_t *row = mem;
1757
1758		for (j = 0; j < width / 2; j++) {
1759			uint32_t value = MAKE_RGBA10(rgb, j & 0x3fc, j & 0x3fc, j & 0x3fc, 0);
1760			row[2*j] = row[2*j+1] = cpu_to_le32(value);
1761		}
1762		mem += stride;
1763	}
1764}
1765
1766static void fill_gradient_rgb16fp(const struct util_rgb_info *rgb,
1767				  void *mem,
1768				  unsigned int width, unsigned int height,
1769				  unsigned int stride)
1770{
1771	unsigned int i, j;
1772
1773	for (i = 0; i < height / 2; i++) {
1774		uint64_t *row = mem;
1775
1776		for (j = 0; j < width / 2; j++) {
1777			uint64_t value = MAKE_RGBA10FP16(rgb, j & 0x3ff, j & 0x3ff, j & 0x3ff, 0);
1778			row[2*j] = row[2*j+1] = value;
1779		}
1780		mem += stride;
1781	}
1782
1783	for (; i < height; i++) {
1784		uint64_t *row = mem;
1785
1786		for (j = 0; j < width / 2; j++) {
1787			uint64_t value = MAKE_RGBA10FP16(rgb, j & 0x3fc, j & 0x3fc, j & 0x3fc, 0);
1788			row[2*j] = row[2*j+1] = value;
1789		}
1790		mem += stride;
1791	}
1792}
1793
1794/* The gradient pattern creates two horizontal gray gradients, split
1795 * into two halves. The top half has 10bpc precision, the bottom half
1796 * has 8bpc precision. When using with a 10bpc fb format, there are 3
1797 * possible outcomes:
1798 *
1799 *  - Pixel data is encoded as 8bpc to the display, no dithering. This
1800 *    would lead to the top and bottom halves looking identical.
1801 *
1802 *  - Pixel data is encoded as 8bpc to the display, with dithering. This
1803 *    would lead to there being a visible difference between the two halves,
1804 *    but the top half would look a little speck-y due to the dithering.
1805 *
1806 *  - Pixel data is encoded at 10bpc+ to the display (which implies
1807 *    the display is able to show this level of depth). This should
1808 *    lead to the top half being a very clean gradient, and visibly different
1809 *    from the bottom half.
1810 *
1811 * Once we support additional fb formats, this approach could be extended
1812 * to distinguish even higher bpc precisions.
1813 *
1814 * Note that due to practical size considerations, for the screens
1815 * where this matters, the pattern actually emits stripes 2-pixels
1816 * wide for each gradient color. Otherwise the difference may be a bit
1817 * hard to notice.
1818 */
1819static void fill_gradient(const struct util_format_info *info, void *planes[3],
1820			  unsigned int width, unsigned int height,
1821			  unsigned int stride)
1822{
1823	switch (info->format) {
1824	case DRM_FORMAT_ARGB8888:
1825	case DRM_FORMAT_XRGB8888:
1826	case DRM_FORMAT_ABGR8888:
1827	case DRM_FORMAT_XBGR8888:
1828	case DRM_FORMAT_RGBA8888:
1829	case DRM_FORMAT_RGBX8888:
1830	case DRM_FORMAT_BGRA8888:
1831	case DRM_FORMAT_BGRX8888:
1832	case DRM_FORMAT_ARGB2101010:
1833	case DRM_FORMAT_XRGB2101010:
1834	case DRM_FORMAT_ABGR2101010:
1835	case DRM_FORMAT_XBGR2101010:
1836	case DRM_FORMAT_RGBA1010102:
1837	case DRM_FORMAT_RGBX1010102:
1838	case DRM_FORMAT_BGRA1010102:
1839	case DRM_FORMAT_BGRX1010102:
1840		return fill_gradient_rgb32(&info->rgb, planes[0],
1841					   width, height, stride);
1842
1843	case DRM_FORMAT_XRGB16161616F:
1844	case DRM_FORMAT_XBGR16161616F:
1845	case DRM_FORMAT_ARGB16161616F:
1846	case DRM_FORMAT_ABGR16161616F:
1847		return fill_gradient_rgb16fp(&info->rgb, planes[0],
1848					     width, height, stride);
1849	}
1850}
1851
1852/*
1853 * util_fill_pattern - Fill a buffer with a test pattern
1854 * @format: Pixel format
1855 * @pattern: Test pattern
1856 * @planes: Array of buffers
1857 * @width: Width in pixels
1858 * @height: Height in pixels
1859 * @stride: Line stride (pitch) in bytes
1860 *
1861 * Fill the buffers with the test pattern specified by the pattern parameter.
1862 * Supported formats vary depending on the selected pattern.
1863 */
1864void util_fill_pattern(uint32_t format, enum util_fill_pattern pattern,
1865		       void *planes[3], unsigned int width,
1866		       unsigned int height, unsigned int stride)
1867{
1868	const struct util_format_info *info;
1869
1870	info = util_format_info_find(format);
1871	if (info == NULL)
1872		return;
1873
1874	switch (pattern) {
1875	case UTIL_PATTERN_TILES:
1876		return fill_tiles(info, planes, width, height, stride);
1877
1878	case UTIL_PATTERN_SMPTE:
1879		return fill_smpte(info, planes, width, height, stride);
1880
1881	case UTIL_PATTERN_PLAIN:
1882		return fill_plain(info, planes, height, stride);
1883
1884	case UTIL_PATTERN_GRADIENT:
1885		return fill_gradient(info, planes, width, height, stride);
1886
1887	default:
1888		printf("Error: unsupported test pattern %u.\n", pattern);
1889		break;
1890	}
1891}
1892
1893static const char *pattern_names[] = {
1894	[UTIL_PATTERN_TILES] = "tiles",
1895	[UTIL_PATTERN_SMPTE] = "smpte",
1896	[UTIL_PATTERN_PLAIN] = "plain",
1897	[UTIL_PATTERN_GRADIENT] = "gradient",
1898};
1899
1900enum util_fill_pattern util_pattern_enum(const char *name)
1901{
1902	unsigned int i;
1903
1904	for (i = 0; i < ARRAY_SIZE(pattern_names); i++)
1905		if (!strcmp(pattern_names[i], name))
1906			return (enum util_fill_pattern)i;
1907
1908	printf("Error: unsupported test pattern %s.\n", name);
1909	return UTIL_PATTERN_SMPTE;
1910}
1911