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