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