xref: /OK3568_Linux_fs/buildroot/package/pixman/0004-Support-PIXMAN_nv16-format.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1From b780905b23300534554421264bb43df15881ac32 Mon Sep 17 00:00:00 2001
2From: Jeffy Chen <jeffy.chen@rock-chips.com>
3Date: Thu, 13 Jan 2022 09:15:54 +0800
4Subject: [PATCH 4/6] Support PIXMAN_nv16 format
5
6Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
7---
8 pixman/pixman-access.c | 75 ++++++++++++++++++++++++++++++++++++++++++
9 pixman/pixman.c        |  3 +-
10 pixman/pixman.h        |  2 ++
11 3 files changed, 79 insertions(+), 1 deletion(-)
12
13diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
14index e7f97ea..05c1a18 100644
15--- a/pixman/pixman-access.c
16+++ b/pixman/pixman-access.c
17@@ -220,6 +220,14 @@
18     ((uint8_t *) ((bits) + offset0 +                                    \
19                   (stride) * ((line) >> 1)))
20
21+/*
22+ * NV16 setup and access macros
23+ */
24+
25+#define NV16_SETUP(image) NV12_SETUP(image)
26+#define NV16_Y(line) NV12_Y(line)
27+#define NV16_UV(line) ((uint8_t *) ((bits) + offset0 + (stride) * (line)))
28+
29 /* Misc. helpers */
30
31 static force_inline void
32@@ -946,6 +954,42 @@ fetch_scanline_nv12 (bits_image_t   *image,
33     }
34 }
35
36+static void
37+fetch_scanline_nv16 (bits_image_t   *image,
38+                     int             x,
39+                     int             line,
40+                     int             width,
41+                     uint32_t *      buffer,
42+                     const uint32_t *mask)
43+{
44+    NV16_SETUP (image);
45+    uint8_t *y_line = NV16_Y (line);
46+    uint8_t *uv_line = NV16_UV (line);
47+    int i;
48+
49+    for (i = 0; i < width; i++)
50+    {
51+	int16_t y, u, v;
52+	int32_t r, g, b;
53+
54+	y = y_line[x + i] - 16;
55+	u = uv_line[(x + i) & -2] - 128;
56+	v = uv_line[((x + i) & -2) + 1] - 128;
57+
58+	/* R = 1.164(Y - 16) + 1.596(V - 128) */
59+	r = 0x012b27 * y + 0x019a2e * v;
60+	/* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
61+	g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
62+	/* B = 1.164(Y - 16) + 2.018(U - 128) */
63+	b = 0x012b27 * y + 0x0206a2 * u;
64+
65+	*buffer++ = 0xff000000 |
66+	    (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
67+	    (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
68+	    (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
69+    }
70+}
71+
72 /**************************** Pixel wise fetching *****************************/
73
74 #ifndef PIXMAN_FB_ACCESSORS
75@@ -1189,6 +1233,32 @@ fetch_pixel_nv12 (bits_image_t *image,
76 	(b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
77 }
78
79+static uint32_t
80+fetch_pixel_nv16 (bits_image_t *image,
81+		  int           offset,
82+		  int           line)
83+{
84+    NV16_SETUP (image);
85+    int16_t y = NV16_Y (line)[offset] - 16;
86+    int16_t u = NV16_UV (line)[offset & -2] - 128;
87+    int16_t v = NV16_UV (line)[(offset & -2) + 1] - 128;
88+    int32_t r, g, b;
89+
90+    /* R = 1.164(Y - 16) + 1.596(V - 128) */
91+    r = 0x012b27 * y + 0x019a2e * v;
92+
93+    /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
94+    g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
95+
96+    /* B = 1.164(Y - 16) + 2.018(U - 128) */
97+    b = 0x012b27 * y + 0x0206a2 * u;
98+
99+    return 0xff000000 |
100+	(r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
101+	(g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
102+	(b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
103+}
104+
105 /*********************************** Store ************************************/
106
107 #ifndef PIXMAN_FB_ACCESSORS
108@@ -1672,6 +1742,11 @@ static const format_info_t accessors[] =
109       fetch_pixel_nv12, fetch_pixel_generic_float,
110       NULL, NULL },
111
112+    { PIXMAN_nv16,
113+      fetch_scanline_nv16, fetch_scanline_generic_float,
114+      fetch_pixel_nv16, fetch_pixel_generic_float,
115+      NULL, NULL },
116+
117     { PIXMAN_null },
118 };
119
120diff --git a/pixman/pixman.c b/pixman/pixman.c
121index ac06002..cd7479a 100644
122--- a/pixman/pixman.c
123+++ b/pixman/pixman.c
124@@ -1072,6 +1072,7 @@ pixman_format_supported_source (pixman_format_code_t format)
125     case PIXMAN_yv12:
126     case PIXMAN_i420:
127     case PIXMAN_nv12:
128+    case PIXMAN_nv16:
129 	return TRUE;
130
131     default:
132@@ -1095,7 +1096,7 @@ pixman_format_supported_destination (pixman_format_code_t format)
133 {
134     /* YUV formats cannot be written to at the moment */
135     if (format == PIXMAN_yuy2 || format == PIXMAN_yv12 ||
136-	format == PIXMAN_nv12 || format == PIXMAN_i420)
137+	format == PIXMAN_nv12 || format == PIXMAN_i420 || format == PIXMAN_nv16)
138 	return FALSE;
139
140     return pixman_format_supported_source (format);
141diff --git a/pixman/pixman.h b/pixman/pixman.h
142index e8b0a78..2ff0d7f 100644
143--- a/pixman/pixman.h
144+++ b/pixman/pixman.h
145@@ -864,6 +864,7 @@ struct pixman_indexed
146 /* HACK: Use maximum value to avoid conflict */
147 #define PIXMAN_TYPE_NV12	0x3f
148 #define PIXMAN_TYPE_I420	0x3e
149+#define PIXMAN_TYPE_NV16	0x3d
150
151 #define PIXMAN_FORMAT_COLOR(f)				\
152 	(PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ARGB ||	\
153@@ -945,6 +946,7 @@ typedef enum {
154
155 /* YUV formats */
156     PIXMAN_yuy2 =	 PIXMAN_FORMAT(16,PIXMAN_TYPE_YUY2,0,0,0,0),
157+    PIXMAN_nv16 =	 PIXMAN_FORMAT(16,PIXMAN_TYPE_NV16,0,0,0,0),
158     PIXMAN_yv12 =	 PIXMAN_FORMAT(12,PIXMAN_TYPE_YV12,0,0,0,0),
159     PIXMAN_i420 =	 PIXMAN_FORMAT(12,PIXMAN_TYPE_I420,0,0,0,0),
160     PIXMAN_nv12 =	 PIXMAN_FORMAT(12,PIXMAN_TYPE_NV12,0,0,0,0),
161--
1622.20.1
163
164