xref: /OK3568_Linux_fs/buildroot/package/pixman/0002-Support-PIXMAN_nv12-format.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1From b276d982a27c421495582b120b0215ad578b7367 Mon Sep 17 00:00:00 2001
2From: Jeffy Chen <jeffy.chen@rock-chips.com>
3Date: Mon, 4 Nov 2019 11:11:59 +0800
4Subject: [PATCH 2/6] Support PIXMAN_nv12 format
5
6Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
7---
8 pixman/pixman-access.c | 86 ++++++++++++++++++++++++++++++++++++++++++
9 pixman/pixman.c        |  3 +-
10 pixman/pixman.h        |  6 ++-
11 3 files changed, 93 insertions(+), 2 deletions(-)
12
13diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
14index 7c5ce78..1e5c0ba 100644
15--- a/pixman/pixman-access.c
16+++ b/pixman/pixman-access.c
17@@ -192,6 +192,25 @@
18     ((uint8_t *) ((bits) + offset0 +                                    \
19                   ((stride) >> 1) * ((line) >> 1)))
20
21+/*
22+ * NV12 setup and access macros
23+ */
24+
25+#define NV12_SETUP(image)                                               \
26+    bits_image_t *__bits_image = (bits_image_t *)image;                 \
27+    uint32_t *bits = __bits_image->bits;                                \
28+    int stride = __bits_image->rowstride;                               \
29+    int offset0 = stride < 0 ?                                          \
30+    (-stride) * ((__bits_image->height - 1) >> 1) - stride :	\
31+    stride * __bits_image->height
32+
33+#define NV12_Y(line)                                                    \
34+    ((uint8_t *) ((bits) + (stride) * (line)))
35+
36+#define NV12_UV(line)                                                    \
37+    ((uint8_t *) ((bits) + offset0 +                                    \
38+                  (stride) * ((line) >> 1)))
39+
40 /* Misc. helpers */
41
42 static force_inline void
43@@ -845,6 +864,42 @@ fetch_scanline_yv12 (bits_image_t   *image,
44     }
45 }
46
47+static void
48+fetch_scanline_nv12 (bits_image_t   *image,
49+                     int             x,
50+                     int             line,
51+                     int             width,
52+                     uint32_t *      buffer,
53+                     const uint32_t *mask)
54+{
55+    NV12_SETUP (image);
56+    uint8_t *y_line = NV12_Y (line);
57+    uint8_t *uv_line = NV12_UV (line);
58+    int i;
59+
60+    for (i = 0; i < width; i++)
61+    {
62+	int16_t y, u, v;
63+	int32_t r, g, b;
64+
65+	y = y_line[x + i] - 16;
66+	u = uv_line[(x + i) & -2] - 128;
67+	v = uv_line[((x + i) & -2) + 1] - 128;
68+
69+	/* R = 1.164(Y - 16) + 1.596(V - 128) */
70+	r = 0x012b27 * y + 0x019a2e * v;
71+	/* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
72+	g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
73+	/* B = 1.164(Y - 16) + 2.018(U - 128) */
74+	b = 0x012b27 * y + 0x0206a2 * u;
75+
76+	*buffer++ = 0xff000000 |
77+	    (r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
78+	    (g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
79+	    (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
80+    }
81+}
82+
83 /**************************** Pixel wise fetching *****************************/
84
85 #ifndef PIXMAN_FB_ACCESSORS
86@@ -1036,6 +1091,32 @@ fetch_pixel_yv12 (bits_image_t *image,
87 	(b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
88 }
89
90+static uint32_t
91+fetch_pixel_nv12 (bits_image_t *image,
92+		  int           offset,
93+		  int           line)
94+{
95+    NV12_SETUP (image);
96+    int16_t y = NV12_Y (line)[offset] - 16;
97+    int16_t u = NV12_UV (line)[offset & -2] - 128;
98+    int16_t v = NV12_UV (line)[(offset & -2) + 1] - 128;
99+    int32_t r, g, b;
100+
101+    /* R = 1.164(Y - 16) + 1.596(V - 128) */
102+    r = 0x012b27 * y + 0x019a2e * v;
103+
104+    /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
105+    g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
106+
107+    /* B = 1.164(Y - 16) + 2.018(U - 128) */
108+    b = 0x012b27 * y + 0x0206a2 * u;
109+
110+    return 0xff000000 |
111+	(r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
112+	(g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
113+	(b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
114+}
115+
116 /*********************************** Store ************************************/
117
118 #ifndef PIXMAN_FB_ACCESSORS
119@@ -1509,6 +1590,11 @@ static const format_info_t accessors[] =
120       fetch_pixel_yv12, fetch_pixel_generic_float,
121       NULL, NULL },
122
123+    { PIXMAN_nv12,
124+      fetch_scanline_nv12, fetch_scanline_generic_float,
125+      fetch_pixel_nv12, fetch_pixel_generic_float,
126+      NULL, NULL },
127+
128     { PIXMAN_null },
129 };
130
131diff --git a/pixman/pixman.c b/pixman/pixman.c
132index c09b528..d8a2d24 100644
133--- a/pixman/pixman.c
134+++ b/pixman/pixman.c
135@@ -1070,6 +1070,7 @@ pixman_format_supported_source (pixman_format_code_t format)
136     /* YUV formats */
137     case PIXMAN_yuy2:
138     case PIXMAN_yv12:
139+    case PIXMAN_nv12:
140 	return TRUE;
141
142     default:
143@@ -1092,7 +1093,7 @@ PIXMAN_EXPORT pixman_bool_t
144 pixman_format_supported_destination (pixman_format_code_t format)
145 {
146     /* YUV formats cannot be written to at the moment */
147-    if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
148+    if (format == PIXMAN_yuy2 || format == PIXMAN_yv12 || format == PIXMAN_nv12)
149 	return FALSE;
150
151     return pixman_format_supported_source (format);
152diff --git a/pixman/pixman.h b/pixman/pixman.h
153index 08303b5..3bb2fa5 100644
154--- a/pixman/pixman.h
155+++ b/pixman/pixman.h
156@@ -861,6 +861,9 @@ struct pixman_indexed
157 #define PIXMAN_TYPE_ARGB_SRGB	10
158 #define PIXMAN_TYPE_RGBA_FLOAT	11
159
160+/* HACK: Use maximum value to avoid conflict */
161+#define PIXMAN_TYPE_NV12	0x3f
162+
163 #define PIXMAN_FORMAT_COLOR(f)				\
164 	(PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ARGB ||	\
165 	 PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ABGR ||	\
166@@ -941,7 +944,8 @@ typedef enum {
167
168 /* YUV formats */
169     PIXMAN_yuy2 =	 PIXMAN_FORMAT(16,PIXMAN_TYPE_YUY2,0,0,0,0),
170-    PIXMAN_yv12 =	 PIXMAN_FORMAT(12,PIXMAN_TYPE_YV12,0,0,0,0)
171+    PIXMAN_yv12 =	 PIXMAN_FORMAT(12,PIXMAN_TYPE_YV12,0,0,0,0),
172+    PIXMAN_nv12 =	 PIXMAN_FORMAT(12,PIXMAN_TYPE_NV12,0,0,0,0),
173 } pixman_format_code_t;
174
175 /* Querying supported format values. */
176--
1772.20.1
178
179