diff options
Diffstat (limited to 'recipes-graphics/xorg-xserver/xserver-xorg/0003-glamor-add-support-for-NV12-in-Xv.patch')
-rw-r--r-- | recipes-graphics/xorg-xserver/xserver-xorg/0003-glamor-add-support-for-NV12-in-Xv.patch | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/recipes-graphics/xorg-xserver/xserver-xorg/0003-glamor-add-support-for-NV12-in-Xv.patch b/recipes-graphics/xorg-xserver/xserver-xorg/0003-glamor-add-support-for-NV12-in-Xv.patch new file mode 100644 index 00000000..855d1938 --- /dev/null +++ b/recipes-graphics/xorg-xserver/xserver-xorg/0003-glamor-add-support-for-NV12-in-Xv.patch | |||
@@ -0,0 +1,322 @@ | |||
1 | From 17a3528162304f1586329aabd606d3498bfe48a5 Mon Sep 17 00:00:00 2001 | ||
2 | From: Julien Isorce <julien.isorce@gmail.com> | ||
3 | Date: Tue, 11 Sep 2018 10:28:33 -0700 | ||
4 | Subject: [PATCH 3/8] glamor: add support for NV12 in Xv | ||
5 | |||
6 | Useful when video decoders only output NV12. Currently | ||
7 | glamor Xv only supports I420 and YV12. | ||
8 | |||
9 | Note that Intel's sna supports I420, YV12, YUY2, UYVY, NV12. | ||
10 | |||
11 | Test: xvinfo | grep NV12 | ||
12 | Test: gst-launch-1.0 videotestsrc ! video/x-raw, format=NV12 ! xvimagesink | ||
13 | |||
14 | v2: Combine the two texture2Ds on u_sampler. | ||
15 | |||
16 | Upstream-Status: Backport | ||
17 | Signed-off-by: Julien Isorce <jisorce@oblong.com> | ||
18 | Tested-by: Olivier Fourdan <ofourdan@redhat.com> | ||
19 | Reviewed-by: Alex Deucher <alexander.deucher@amd.com> | ||
20 | --- | ||
21 | glamor/glamor_xv.c | 180 ++++++++++++++++++++++++++++++++++++++------- | ||
22 | 1 file changed, 155 insertions(+), 25 deletions(-) | ||
23 | |||
24 | diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c | ||
25 | index 62fc4fff5..6fef6ed0d 100644 | ||
26 | --- a/glamor/glamor_xv.c | ||
27 | +++ b/glamor/glamor_xv.c | ||
28 | @@ -59,8 +59,40 @@ typedef struct tagREF_TRANSFORM { | ||
29 | #define RTFContrast(a) (1.0 + ((a)*1.0)/1000.0) | ||
30 | #define RTFHue(a) (((a)*3.1416)/1000.0) | ||
31 | |||
32 | -static const glamor_facet glamor_facet_xv_planar = { | ||
33 | - .name = "xv_planar", | ||
34 | +static const glamor_facet glamor_facet_xv_planar_2 = { | ||
35 | + .name = "xv_planar_2", | ||
36 | + | ||
37 | + .version = 120, | ||
38 | + | ||
39 | + .source_name = "v_texcoord0", | ||
40 | + .vs_vars = ("attribute vec2 position;\n" | ||
41 | + "attribute vec2 v_texcoord0;\n" | ||
42 | + "varying vec2 tcs;\n"), | ||
43 | + .vs_exec = (GLAMOR_POS(gl_Position, position) | ||
44 | + " tcs = v_texcoord0;\n"), | ||
45 | + | ||
46 | + .fs_vars = ("uniform sampler2D y_sampler;\n" | ||
47 | + "uniform sampler2D u_sampler;\n" | ||
48 | + "uniform vec4 offsetyco;\n" | ||
49 | + "uniform vec4 ucogamma;\n" | ||
50 | + "uniform vec4 vco;\n" | ||
51 | + "varying vec2 tcs;\n"), | ||
52 | + .fs_exec = ( | ||
53 | + " float sample;\n" | ||
54 | + " vec2 sample_uv;\n" | ||
55 | + " vec4 temp1;\n" | ||
56 | + " sample = texture2D(y_sampler, tcs).w;\n" | ||
57 | + " temp1.xyz = offsetyco.www * vec3(sample) + offsetyco.xyz;\n" | ||
58 | + " sample_uv = texture2D(u_sampler, tcs).xy;\n" | ||
59 | + " temp1.xyz = ucogamma.xyz * vec3(sample_uv.x) + temp1.xyz;\n" | ||
60 | + " temp1.xyz = clamp(vco.xyz * vec3(sample_uv.y) + temp1.xyz, 0.0, 1.0);\n" | ||
61 | + " temp1.w = 1.0;\n" | ||
62 | + " gl_FragColor = temp1;\n" | ||
63 | + ), | ||
64 | +}; | ||
65 | + | ||
66 | +static const glamor_facet glamor_facet_xv_planar_3 = { | ||
67 | + .name = "xv_planar_3", | ||
68 | |||
69 | .version = 120, | ||
70 | |||
71 | @@ -110,26 +142,50 @@ Atom glamorBrightness, glamorContrast, glamorSaturation, glamorHue, | ||
72 | XvImageRec glamor_xv_images[] = { | ||
73 | XVIMAGE_YV12, | ||
74 | XVIMAGE_I420, | ||
75 | + XVIMAGE_NV12 | ||
76 | }; | ||
77 | int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images); | ||
78 | |||
79 | static void | ||
80 | -glamor_init_xv_shader(ScreenPtr screen) | ||
81 | +glamor_init_xv_shader(ScreenPtr screen, int id) | ||
82 | { | ||
83 | glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); | ||
84 | GLint sampler_loc; | ||
85 | + const glamor_facet *glamor_facet_xv_planar = NULL; | ||
86 | + | ||
87 | + switch (id) { | ||
88 | + case FOURCC_YV12: | ||
89 | + case FOURCC_I420: | ||
90 | + glamor_facet_xv_planar = &glamor_facet_xv_planar_3; | ||
91 | + break; | ||
92 | + case FOURCC_NV12: | ||
93 | + glamor_facet_xv_planar = &glamor_facet_xv_planar_2; | ||
94 | + break; | ||
95 | + default: | ||
96 | + break; | ||
97 | + } | ||
98 | |||
99 | glamor_build_program(screen, | ||
100 | &glamor_priv->xv_prog, | ||
101 | - &glamor_facet_xv_planar, NULL, NULL, NULL); | ||
102 | + glamor_facet_xv_planar, NULL, NULL, NULL); | ||
103 | |||
104 | glUseProgram(glamor_priv->xv_prog.prog); | ||
105 | sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "y_sampler"); | ||
106 | glUniform1i(sampler_loc, 0); | ||
107 | sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "u_sampler"); | ||
108 | glUniform1i(sampler_loc, 1); | ||
109 | - sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "v_sampler"); | ||
110 | - glUniform1i(sampler_loc, 2); | ||
111 | + | ||
112 | + switch (id) { | ||
113 | + case FOURCC_YV12: | ||
114 | + case FOURCC_I420: | ||
115 | + sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "v_sampler"); | ||
116 | + glUniform1i(sampler_loc, 2); | ||
117 | + break; | ||
118 | + case FOURCC_NV12: | ||
119 | + break; | ||
120 | + default: | ||
121 | + break; | ||
122 | + } | ||
123 | |||
124 | } | ||
125 | |||
126 | @@ -227,6 +283,21 @@ glamor_xv_query_image_attributes(int id, | ||
127 | offsets[2] = size; | ||
128 | size += tmp; | ||
129 | break; | ||
130 | + case FOURCC_NV12: | ||
131 | + *w = ALIGN(*w, 2); | ||
132 | + *h = ALIGN(*h, 2); | ||
133 | + size = ALIGN(*w, 4); | ||
134 | + if (pitches) | ||
135 | + pitches[0] = size; | ||
136 | + size *= *h; | ||
137 | + if (offsets) | ||
138 | + offsets[1] = offsets[2] = size; | ||
139 | + tmp = ALIGN(*w, 4); | ||
140 | + if (pitches) | ||
141 | + pitches[1] = pitches[2] = tmp; | ||
142 | + tmp *= (*h >> 1); | ||
143 | + size += tmp; | ||
144 | + break; | ||
145 | } | ||
146 | return size; | ||
147 | } | ||
148 | @@ -240,7 +311,7 @@ static REF_TRANSFORM trans[2] = { | ||
149 | }; | ||
150 | |||
151 | void | ||
152 | -glamor_xv_render(glamor_port_private *port_priv) | ||
153 | +glamor_xv_render(glamor_port_private *port_priv, int id) | ||
154 | { | ||
155 | ScreenPtr screen = port_priv->pPixmap->drawable.pScreen; | ||
156 | glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); | ||
157 | @@ -264,7 +335,7 @@ glamor_xv_render(glamor_port_private *port_priv) | ||
158 | int dst_box_index; | ||
159 | |||
160 | if (!glamor_priv->xv_prog.prog) | ||
161 | - glamor_init_xv_shader(screen); | ||
162 | + glamor_init_xv_shader(screen, id); | ||
163 | |||
164 | cont = RTFContrast(port_priv->contrast); | ||
165 | bright = RTFBrightness(port_priv->brightness); | ||
166 | @@ -293,6 +364,8 @@ glamor_xv_render(glamor_port_private *port_priv) | ||
167 | glamor_get_pixmap_private(port_priv->src_pix[i]); | ||
168 | pixmap_priv_get_scale(src_pixmap_priv[i], &src_xscale[i], | ||
169 | &src_yscale[i]); | ||
170 | + } else { | ||
171 | + src_pixmap_priv[i] = NULL; | ||
172 | } | ||
173 | } | ||
174 | glamor_make_current(glamor_priv); | ||
175 | @@ -319,12 +392,21 @@ glamor_xv_render(glamor_port_private *port_priv) | ||
176 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
177 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
178 | |||
179 | - glActiveTexture(GL_TEXTURE2); | ||
180 | - glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->fbo->tex); | ||
181 | - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
182 | - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
183 | - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
184 | - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
185 | + switch (id) { | ||
186 | + case FOURCC_YV12: | ||
187 | + case FOURCC_I420: | ||
188 | + glActiveTexture(GL_TEXTURE2); | ||
189 | + glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->fbo->tex); | ||
190 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
191 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
192 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
193 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
194 | + break; | ||
195 | + case FOURCC_NV12: | ||
196 | + break; | ||
197 | + default: | ||
198 | + break; | ||
199 | + } | ||
200 | |||
201 | glEnableVertexAttribArray(GLAMOR_VERTEX_POS); | ||
202 | glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); | ||
203 | @@ -336,7 +418,7 @@ glamor_xv_render(glamor_port_private *port_priv) | ||
204 | /* Set up a single primitive covering the area being drawn. We'll | ||
205 | * clip it to port_priv->clip using GL scissors instead of just | ||
206 | * emitting a GL_QUAD per box, because this way we hopefully avoid | ||
207 | - * diagonal tearing between the two trangles used to rasterize a | ||
208 | + * diagonal tearing between the two triangles used to rasterize a | ||
209 | * GL_QUAD. | ||
210 | */ | ||
211 | i = 0; | ||
212 | @@ -417,6 +499,7 @@ glamor_xv_put_image(glamor_port_private *port_priv, | ||
213 | RegionPtr clipBoxes) | ||
214 | { | ||
215 | ScreenPtr pScreen = pDrawable->pScreen; | ||
216 | + glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen); | ||
217 | int srcPitch, srcPitch2; | ||
218 | int top, nlines; | ||
219 | int s2offset, s3offset, tmp; | ||
220 | @@ -425,9 +508,16 @@ glamor_xv_put_image(glamor_port_private *port_priv, | ||
221 | s2offset = s3offset = srcPitch2 = 0; | ||
222 | |||
223 | if (!port_priv->src_pix[0] || | ||
224 | - (width != port_priv->src_pix_w || height != port_priv->src_pix_h)) { | ||
225 | + (width != port_priv->src_pix_w || height != port_priv->src_pix_h) || | ||
226 | + (port_priv->src_pix[2] && id == FOURCC_NV12) || | ||
227 | + (!port_priv->src_pix[2] && id != FOURCC_NV12)) { | ||
228 | int i; | ||
229 | |||
230 | + if (glamor_priv->xv_prog.prog) { | ||
231 | + glDeleteProgram(glamor_priv->xv_prog.prog); | ||
232 | + glamor_priv->xv_prog.prog = 0; | ||
233 | + } | ||
234 | + | ||
235 | for (i = 0; i < 3; i++) | ||
236 | if (port_priv->src_pix[i]) | ||
237 | glamor_destroy_pixmap(port_priv->src_pix[i]); | ||
238 | @@ -435,17 +525,34 @@ glamor_xv_put_image(glamor_port_private *port_priv, | ||
239 | port_priv->src_pix[0] = | ||
240 | glamor_create_pixmap(pScreen, width, height, 8, | ||
241 | GLAMOR_CREATE_FBO_NO_FBO); | ||
242 | - port_priv->src_pix[1] = | ||
243 | - glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, | ||
244 | - GLAMOR_CREATE_FBO_NO_FBO); | ||
245 | - port_priv->src_pix[2] = | ||
246 | - glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, | ||
247 | - GLAMOR_CREATE_FBO_NO_FBO); | ||
248 | + | ||
249 | + switch (id) { | ||
250 | + case FOURCC_YV12: | ||
251 | + case FOURCC_I420: | ||
252 | + port_priv->src_pix[1] = | ||
253 | + glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, | ||
254 | + GLAMOR_CREATE_FBO_NO_FBO); | ||
255 | + port_priv->src_pix[2] = | ||
256 | + glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, | ||
257 | + GLAMOR_CREATE_FBO_NO_FBO); | ||
258 | + if (!port_priv->src_pix[2]) | ||
259 | + return BadAlloc; | ||
260 | + break; | ||
261 | + case FOURCC_NV12: | ||
262 | + port_priv->src_pix[1] = | ||
263 | + glamor_create_pixmap(pScreen, width >> 1, height >> 1, 16, | ||
264 | + GLAMOR_CREATE_FBO_NO_FBO | | ||
265 | + GLAMOR_CREATE_FORMAT_CBCR); | ||
266 | + port_priv->src_pix[2] = NULL; | ||
267 | + break; | ||
268 | + default: | ||
269 | + return BadMatch; | ||
270 | + } | ||
271 | + | ||
272 | port_priv->src_pix_w = width; | ||
273 | port_priv->src_pix_h = height; | ||
274 | |||
275 | - if (!port_priv->src_pix[0] || !port_priv->src_pix[1] || | ||
276 | - !port_priv->src_pix[2]) | ||
277 | + if (!port_priv->src_pix[0] || !port_priv->src_pix[1]) | ||
278 | return BadAlloc; | ||
279 | } | ||
280 | |||
281 | @@ -489,6 +596,29 @@ glamor_xv_put_image(glamor_port_private *port_priv, | ||
282 | 0, 0, 0, 0, | ||
283 | buf + s3offset, srcPitch2); | ||
284 | break; | ||
285 | + case FOURCC_NV12: | ||
286 | + srcPitch = ALIGN(width, 4); | ||
287 | + s2offset = srcPitch * height; | ||
288 | + s2offset += ((top >> 1) * srcPitch); | ||
289 | + | ||
290 | + full_box.x1 = 0; | ||
291 | + full_box.y1 = 0; | ||
292 | + full_box.x2 = width; | ||
293 | + full_box.y2 = nlines; | ||
294 | + | ||
295 | + half_box.x1 = 0; | ||
296 | + half_box.y1 = 0; | ||
297 | + half_box.x2 = width; | ||
298 | + half_box.y2 = (nlines + 1) >> 1; | ||
299 | + | ||
300 | + glamor_upload_boxes(port_priv->src_pix[0], &full_box, 1, | ||
301 | + 0, 0, 0, 0, | ||
302 | + buf + (top * srcPitch), srcPitch); | ||
303 | + | ||
304 | + glamor_upload_boxes(port_priv->src_pix[1], &half_box, 1, | ||
305 | + 0, 0, 0, 0, | ||
306 | + buf + s2offset, srcPitch); | ||
307 | + break; | ||
308 | default: | ||
309 | return BadMatch; | ||
310 | } | ||
311 | @@ -511,7 +641,7 @@ glamor_xv_put_image(glamor_port_private *port_priv, | ||
312 | port_priv->w = width; | ||
313 | port_priv->h = height; | ||
314 | port_priv->pDraw = pDrawable; | ||
315 | - glamor_xv_render(port_priv); | ||
316 | + glamor_xv_render(port_priv, id); | ||
317 | return Success; | ||
318 | } | ||
319 | |||
320 | -- | ||
321 | 2.17.1 | ||
322 | |||