1 /**************************************************************************
3 * Copyright 2009 Younes Manton.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
28 #include "util/u_sampler.h"
30 #include "vl_compositor_gfx.h"
31 #include "vl_compositor_cs.h"
34 init_shaders(struct vl_compositor
*c
)
38 if (c
->pipe_cs_composit_supported
) {
39 if (!vl_compositor_cs_init_shaders(c
))
42 } else if (c
->pipe_gfx_supported
) {
43 c
->fs_video_buffer
= create_frag_shader_video_buffer(c
);
44 if (!c
->fs_video_buffer
) {
45 debug_printf("Unable to create YCbCr-to-RGB fragment shader.\n");
49 c
->fs_weave_rgb
= create_frag_shader_weave_rgb(c
);
50 if (!c
->fs_weave_rgb
) {
51 debug_printf("Unable to create YCbCr-to-RGB weave fragment shader.\n");
55 c
->fs_yuv
.weave
.y
= create_frag_shader_deint_yuv(c
, true, true);
56 c
->fs_yuv
.weave
.uv
= create_frag_shader_deint_yuv(c
, false, true);
57 c
->fs_yuv
.bob
.y
= create_frag_shader_deint_yuv(c
, true, false);
58 c
->fs_yuv
.bob
.uv
= create_frag_shader_deint_yuv(c
, false, false);
59 if (!c
->fs_yuv
.weave
.y
|| !c
->fs_yuv
.weave
.uv
||
60 !c
->fs_yuv
.bob
.y
|| !c
->fs_yuv
.bob
.uv
) {
61 debug_printf("Unable to create YCbCr i-to-YCbCr p deint fragment shader.\n");
66 if (c
->pipe_gfx_supported
) {
67 c
->vs
= create_vert_shader(c
);
69 debug_printf("Unable to create vertex shader.\n");
73 c
->fs_palette
.yuv
= create_frag_shader_palette(c
, true);
74 if (!c
->fs_palette
.yuv
) {
75 debug_printf("Unable to create YUV-Palette-to-RGB fragment shader.\n");
79 c
->fs_palette
.rgb
= create_frag_shader_palette(c
, false);
80 if (!c
->fs_palette
.rgb
) {
81 debug_printf("Unable to create RGB-Palette-to-RGB fragment shader.\n");
85 c
->fs_rgb_yuv
.y
= create_frag_shader_rgb_yuv(c
, true);
86 c
->fs_rgb_yuv
.uv
= create_frag_shader_rgb_yuv(c
, false);
87 if (!c
->fs_rgb_yuv
.y
|| !c
->fs_rgb_yuv
.uv
) {
88 debug_printf("Unable to create RGB-to-YUV fragment shader.\n");
92 c
->fs_rgba
= create_frag_shader_rgba(c
);
94 debug_printf("Unable to create RGB-to-RGB fragment shader.\n");
102 static void cleanup_shaders(struct vl_compositor
*c
)
106 if (c
->pipe_cs_composit_supported
) {
107 vl_compositor_cs_cleanup_shaders(c
);
108 } else if (c
->pipe_gfx_supported
) {
109 c
->pipe
->delete_fs_state(c
->pipe
, c
->fs_video_buffer
);
110 c
->pipe
->delete_fs_state(c
->pipe
, c
->fs_weave_rgb
);
111 c
->pipe
->delete_fs_state(c
->pipe
, c
->fs_yuv
.weave
.y
);
112 c
->pipe
->delete_fs_state(c
->pipe
, c
->fs_yuv
.weave
.uv
);
113 c
->pipe
->delete_fs_state(c
->pipe
, c
->fs_yuv
.bob
.y
);
114 c
->pipe
->delete_fs_state(c
->pipe
, c
->fs_yuv
.bob
.uv
);
117 if (c
->pipe_gfx_supported
) {
118 c
->pipe
->delete_vs_state(c
->pipe
, c
->vs
);
119 c
->pipe
->delete_fs_state(c
->pipe
, c
->fs_palette
.yuv
);
120 c
->pipe
->delete_fs_state(c
->pipe
, c
->fs_palette
.rgb
);
121 c
->pipe
->delete_fs_state(c
->pipe
, c
->fs_rgb_yuv
.y
);
122 c
->pipe
->delete_fs_state(c
->pipe
, c
->fs_rgb_yuv
.uv
);
123 c
->pipe
->delete_fs_state(c
->pipe
, c
->fs_rgba
);
128 init_pipe_state(struct vl_compositor
*c
)
130 struct pipe_rasterizer_state rast
;
131 struct pipe_sampler_state sampler
;
132 struct pipe_blend_state blend
;
133 struct pipe_depth_stencil_alpha_state dsa
;
138 c
->fb_state
.nr_cbufs
= 1;
139 c
->fb_state
.zsbuf
= NULL
;
141 memset(&sampler
, 0, sizeof(sampler
));
142 sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
143 sampler
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
144 sampler
.wrap_r
= PIPE_TEX_WRAP_REPEAT
;
145 sampler
.min_img_filter
= PIPE_TEX_FILTER_LINEAR
;
146 sampler
.min_mip_filter
= PIPE_TEX_MIPFILTER_NONE
;
147 sampler
.mag_img_filter
= PIPE_TEX_FILTER_LINEAR
;
148 sampler
.compare_mode
= PIPE_TEX_COMPARE_NONE
;
149 sampler
.compare_func
= PIPE_FUNC_ALWAYS
;
150 sampler
.normalized_coords
= 1;
152 c
->sampler_linear
= c
->pipe
->create_sampler_state(c
->pipe
, &sampler
);
154 sampler
.min_img_filter
= PIPE_TEX_FILTER_NEAREST
;
155 sampler
.mag_img_filter
= PIPE_TEX_FILTER_NEAREST
;
156 c
->sampler_nearest
= c
->pipe
->create_sampler_state(c
->pipe
, &sampler
);
158 if (c
->pipe_gfx_supported
) {
159 memset(&blend
, 0, sizeof blend
);
160 blend
.independent_blend_enable
= 0;
161 blend
.rt
[0].blend_enable
= 0;
162 blend
.logicop_enable
= 0;
163 blend
.logicop_func
= PIPE_LOGICOP_CLEAR
;
164 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
166 c
->blend_clear
= c
->pipe
->create_blend_state(c
->pipe
, &blend
);
168 blend
.rt
[0].blend_enable
= 1;
169 blend
.rt
[0].rgb_func
= PIPE_BLEND_ADD
;
170 blend
.rt
[0].rgb_src_factor
= PIPE_BLENDFACTOR_SRC_ALPHA
;
171 blend
.rt
[0].rgb_dst_factor
= PIPE_BLENDFACTOR_INV_SRC_ALPHA
;
172 blend
.rt
[0].alpha_func
= PIPE_BLEND_ADD
;
173 blend
.rt
[0].alpha_src_factor
= PIPE_BLENDFACTOR_ONE
;
174 blend
.rt
[0].alpha_dst_factor
= PIPE_BLENDFACTOR_ONE
;
175 c
->blend_add
= c
->pipe
->create_blend_state(c
->pipe
, &blend
);
177 memset(&rast
, 0, sizeof rast
);
180 rast
.cull_face
= PIPE_FACE_NONE
;
181 rast
.fill_back
= PIPE_POLYGON_MODE_FILL
;
182 rast
.fill_front
= PIPE_POLYGON_MODE_FILL
;
185 rast
.point_size_per_vertex
= 1;
186 rast
.offset_units
= 1;
187 rast
.offset_scale
= 1;
188 rast
.half_pixel_center
= 1;
189 rast
.bottom_edge_rule
= 1;
190 rast
.depth_clip_near
= 1;
191 rast
.depth_clip_far
= 1;
193 c
->rast
= c
->pipe
->create_rasterizer_state(c
->pipe
, &rast
);
195 memset(&dsa
, 0, sizeof dsa
);
196 dsa
.depth
.enabled
= 0;
197 dsa
.depth
.writemask
= 0;
198 dsa
.depth
.func
= PIPE_FUNC_ALWAYS
;
199 for (i
= 0; i
< 2; ++i
) {
200 dsa
.stencil
[i
].enabled
= 0;
201 dsa
.stencil
[i
].func
= PIPE_FUNC_ALWAYS
;
202 dsa
.stencil
[i
].fail_op
= PIPE_STENCIL_OP_KEEP
;
203 dsa
.stencil
[i
].zpass_op
= PIPE_STENCIL_OP_KEEP
;
204 dsa
.stencil
[i
].zfail_op
= PIPE_STENCIL_OP_KEEP
;
205 dsa
.stencil
[i
].valuemask
= 0;
206 dsa
.stencil
[i
].writemask
= 0;
208 dsa
.alpha
.enabled
= 0;
209 dsa
.alpha
.func
= PIPE_FUNC_ALWAYS
;
210 dsa
.alpha
.ref_value
= 0;
211 c
->dsa
= c
->pipe
->create_depth_stencil_alpha_state(c
->pipe
, &dsa
);
212 c
->pipe
->bind_depth_stencil_alpha_state(c
->pipe
, c
->dsa
);
218 static void cleanup_pipe_state(struct vl_compositor
*c
)
222 if (c
->pipe_gfx_supported
) {
223 /* Asserted in softpipe_delete_fs_state() for some reason */
224 c
->pipe
->bind_vs_state(c
->pipe
, NULL
);
225 c
->pipe
->bind_fs_state(c
->pipe
, NULL
);
227 c
->pipe
->delete_depth_stencil_alpha_state(c
->pipe
, c
->dsa
);
228 c
->pipe
->delete_blend_state(c
->pipe
, c
->blend_clear
);
229 c
->pipe
->delete_blend_state(c
->pipe
, c
->blend_add
);
230 c
->pipe
->delete_rasterizer_state(c
->pipe
, c
->rast
);
232 c
->pipe
->delete_sampler_state(c
->pipe
, c
->sampler_linear
);
233 c
->pipe
->delete_sampler_state(c
->pipe
, c
->sampler_nearest
);
237 init_buffers(struct vl_compositor
*c
)
239 struct pipe_vertex_element vertex_elems
[3];
244 * Create our vertex buffer and vertex buffer elements
246 c
->vertex_buf
.stride
= sizeof(struct vertex2f
) + sizeof(struct vertex4f
) * 2;
247 c
->vertex_buf
.buffer_offset
= 0;
248 c
->vertex_buf
.buffer
.resource
= NULL
;
249 c
->vertex_buf
.is_user_buffer
= false;
251 if (c
->pipe_gfx_supported
) {
252 vertex_elems
[0].src_offset
= 0;
253 vertex_elems
[0].instance_divisor
= 0;
254 vertex_elems
[0].vertex_buffer_index
= 0;
255 vertex_elems
[0].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
256 vertex_elems
[1].src_offset
= sizeof(struct vertex2f
);
257 vertex_elems
[1].instance_divisor
= 0;
258 vertex_elems
[1].vertex_buffer_index
= 0;
259 vertex_elems
[1].src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
260 vertex_elems
[2].src_offset
= sizeof(struct vertex2f
) + sizeof(struct vertex4f
);
261 vertex_elems
[2].instance_divisor
= 0;
262 vertex_elems
[2].vertex_buffer_index
= 0;
263 vertex_elems
[2].src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
264 c
->vertex_elems_state
= c
->pipe
->create_vertex_elements_state(c
->pipe
, 3, vertex_elems
);
271 cleanup_buffers(struct vl_compositor
*c
)
275 if (c
->pipe_gfx_supported
) {
276 c
->pipe
->delete_vertex_elements_state(c
->pipe
, c
->vertex_elems_state
);
278 pipe_resource_reference(&c
->vertex_buf
.buffer
.resource
, NULL
);
281 static inline struct u_rect
282 default_rect(struct vl_compositor_layer
*layer
)
284 struct pipe_resource
*res
= layer
->sampler_views
[0]->texture
;
285 struct u_rect rect
= { 0, res
->width0
, 0, res
->height0
* res
->array_size
};
289 static inline struct vertex2f
290 calc_topleft(struct vertex2f size
, struct u_rect rect
)
292 struct vertex2f res
= { rect
.x0
/ size
.x
, rect
.y0
/ size
.y
};
296 static inline struct vertex2f
297 calc_bottomright(struct vertex2f size
, struct u_rect rect
)
299 struct vertex2f res
= { rect
.x1
/ size
.x
, rect
.y1
/ size
.y
};
304 calc_src_and_dst(struct vl_compositor_layer
*layer
, unsigned width
, unsigned height
,
305 struct u_rect src
, struct u_rect dst
)
307 struct vertex2f size
= { width
, height
};
309 layer
->src
.tl
= calc_topleft(size
, src
);
310 layer
->src
.br
= calc_bottomright(size
, src
);
311 layer
->dst
.tl
= calc_topleft(size
, dst
);
312 layer
->dst
.br
= calc_bottomright(size
, dst
);
314 layer
->zw
.y
= size
.y
;
318 set_yuv_layer(struct vl_compositor_state
*s
, struct vl_compositor
*c
,
319 unsigned layer
, struct pipe_video_buffer
*buffer
,
320 struct u_rect
*src_rect
, struct u_rect
*dst_rect
,
321 bool y
, enum vl_compositor_deinterlace deinterlace
)
323 struct pipe_sampler_view
**sampler_views
;
327 assert(s
&& c
&& buffer
);
329 assert(layer
< VL_COMPOSITOR_MAX_LAYERS
);
331 s
->interlaced
= buffer
->interlaced
;
332 s
->used_layers
|= 1 << layer
;
333 sampler_views
= buffer
->get_sampler_view_components(buffer
);
334 for (i
= 0; i
< 3; ++i
) {
335 s
->layers
[layer
].samplers
[i
] = c
->sampler_linear
;
336 pipe_sampler_view_reference(&s
->layers
[layer
].sampler_views
[i
], sampler_views
[i
]);
339 calc_src_and_dst(&s
->layers
[layer
], buffer
->width
, buffer
->height
,
340 src_rect
? *src_rect
: default_rect(&s
->layers
[layer
]),
341 dst_rect
? *dst_rect
: default_rect(&s
->layers
[layer
]));
343 half_a_line
= 0.5f
/ s
->layers
[layer
].zw
.y
;
345 switch(deinterlace
) {
346 case VL_COMPOSITOR_BOB_TOP
:
347 s
->layers
[layer
].zw
.x
= 0.0f
;
348 s
->layers
[layer
].src
.tl
.y
+= half_a_line
;
349 s
->layers
[layer
].src
.br
.y
+= half_a_line
;
350 if (c
->pipe_gfx_supported
)
351 s
->layers
[layer
].fs
= (y
) ? c
->fs_yuv
.bob
.y
: c
->fs_yuv
.bob
.uv
;
352 if (c
->pipe_cs_composit_supported
)
353 s
->layers
[layer
].cs
= (y
) ? c
->cs_yuv
.bob
.y
: c
->cs_yuv
.bob
.uv
;
356 case VL_COMPOSITOR_BOB_BOTTOM
:
357 s
->layers
[layer
].zw
.x
= 1.0f
;
358 s
->layers
[layer
].src
.tl
.y
-= half_a_line
;
359 s
->layers
[layer
].src
.br
.y
-= half_a_line
;
360 if (c
->pipe_gfx_supported
)
361 s
->layers
[layer
].fs
= (y
) ? c
->fs_yuv
.bob
.y
: c
->fs_yuv
.bob
.uv
;
362 if (c
->pipe_cs_composit_supported
)
363 s
->layers
[layer
].cs
= (y
) ? c
->cs_yuv
.bob
.y
: c
->cs_yuv
.bob
.uv
;
367 if (c
->pipe_gfx_supported
)
368 s
->layers
[layer
].fs
= (y
) ? c
->fs_yuv
.weave
.y
: c
->fs_yuv
.weave
.uv
;
369 if (c
->pipe_cs_composit_supported
)
370 s
->layers
[layer
].cs
= (y
) ? c
->cs_yuv
.weave
.y
: c
->cs_yuv
.weave
.uv
;
376 set_rgb_to_yuv_layer(struct vl_compositor_state
*s
, struct vl_compositor
*c
,
377 unsigned layer
, struct pipe_sampler_view
*v
,
378 struct u_rect
*src_rect
, struct u_rect
*dst_rect
, bool y
)
380 vl_csc_matrix csc_matrix
;
384 assert(layer
< VL_COMPOSITOR_MAX_LAYERS
);
386 s
->used_layers
|= 1 << layer
;
388 s
->layers
[layer
].fs
= y
? c
->fs_rgb_yuv
.y
: c
->fs_rgb_yuv
.uv
;
390 vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_709_REV
, NULL
, false, &csc_matrix
);
391 vl_compositor_set_csc_matrix(s
, (const vl_csc_matrix
*)&csc_matrix
, 1.0f
, 0.0f
);
393 s
->layers
[layer
].samplers
[0] = c
->sampler_linear
;
394 s
->layers
[layer
].samplers
[1] = NULL
;
395 s
->layers
[layer
].samplers
[2] = NULL
;
397 pipe_sampler_view_reference(&s
->layers
[layer
].sampler_views
[0], v
);
398 pipe_sampler_view_reference(&s
->layers
[layer
].sampler_views
[1], NULL
);
399 pipe_sampler_view_reference(&s
->layers
[layer
].sampler_views
[2], NULL
);
401 calc_src_and_dst(&s
->layers
[layer
], v
->texture
->width0
, v
->texture
->height0
,
402 src_rect
? *src_rect
: default_rect(&s
->layers
[layer
]),
403 dst_rect
? *dst_rect
: default_rect(&s
->layers
[layer
]));
407 vl_compositor_reset_dirty_area(struct u_rect
*dirty
)
411 dirty
->x0
= dirty
->y0
= VL_COMPOSITOR_MIN_DIRTY
;
412 dirty
->x1
= dirty
->y1
= VL_COMPOSITOR_MAX_DIRTY
;
416 vl_compositor_set_clear_color(struct vl_compositor_state
*s
, union pipe_color_union
*color
)
421 s
->clear_color
= *color
;
425 vl_compositor_get_clear_color(struct vl_compositor_state
*s
, union pipe_color_union
*color
)
430 *color
= s
->clear_color
;
434 vl_compositor_clear_layers(struct vl_compositor_state
*s
)
439 s
->interlaced
= false;
441 for ( i
= 0; i
< VL_COMPOSITOR_MAX_LAYERS
; ++i
) {
442 struct vertex4f v_one
= { 1.0f
, 1.0f
, 1.0f
, 1.0f
};
443 s
->layers
[i
].clearing
= i
? false : true;
444 s
->layers
[i
].blend
= NULL
;
445 s
->layers
[i
].fs
= NULL
;
446 s
->layers
[i
].cs
= NULL
;
447 s
->layers
[i
].viewport
.scale
[2] = 1;
448 s
->layers
[i
].viewport
.translate
[2] = 0;
449 s
->layers
[i
].rotate
= VL_COMPOSITOR_ROTATE_0
;
451 for ( j
= 0; j
< 3; j
++)
452 pipe_sampler_view_reference(&s
->layers
[i
].sampler_views
[j
], NULL
);
453 for ( j
= 0; j
< 4; ++j
)
454 s
->layers
[i
].colors
[j
] = v_one
;
459 vl_compositor_cleanup(struct vl_compositor
*c
)
465 cleanup_pipe_state(c
);
469 vl_compositor_set_csc_matrix(struct vl_compositor_state
*s
,
470 vl_csc_matrix
const *matrix
,
471 float luma_min
, float luma_max
)
473 struct pipe_transfer
*buf_transfer
;
477 float *ptr
= pipe_buffer_map(s
->pipe
, s
->shader_params
,
478 PIPE_TRANSFER_WRITE
| PIPE_TRANSFER_DISCARD_RANGE
,
484 memcpy(ptr
, matrix
, sizeof(vl_csc_matrix
));
486 ptr
+= sizeof(vl_csc_matrix
)/sizeof(float);
490 pipe_buffer_unmap(s
->pipe
, buf_transfer
);
496 vl_compositor_set_dst_clip(struct vl_compositor_state
*s
, struct u_rect
*dst_clip
)
500 s
->scissor_valid
= dst_clip
!= NULL
;
502 s
->scissor
.minx
= dst_clip
->x0
;
503 s
->scissor
.miny
= dst_clip
->y0
;
504 s
->scissor
.maxx
= dst_clip
->x1
;
505 s
->scissor
.maxy
= dst_clip
->y1
;
510 vl_compositor_set_layer_blend(struct vl_compositor_state
*s
,
511 unsigned layer
, void *blend
,
516 assert(layer
< VL_COMPOSITOR_MAX_LAYERS
);
518 s
->layers
[layer
].clearing
= is_clearing
;
519 s
->layers
[layer
].blend
= blend
;
523 vl_compositor_set_layer_dst_area(struct vl_compositor_state
*s
,
524 unsigned layer
, struct u_rect
*dst_area
)
528 assert(layer
< VL_COMPOSITOR_MAX_LAYERS
);
530 s
->layers
[layer
].viewport_valid
= dst_area
!= NULL
;
532 s
->layers
[layer
].viewport
.scale
[0] = dst_area
->x1
- dst_area
->x0
;
533 s
->layers
[layer
].viewport
.scale
[1] = dst_area
->y1
- dst_area
->y0
;
534 s
->layers
[layer
].viewport
.translate
[0] = dst_area
->x0
;
535 s
->layers
[layer
].viewport
.translate
[1] = dst_area
->y0
;
540 vl_compositor_set_buffer_layer(struct vl_compositor_state
*s
,
541 struct vl_compositor
*c
,
543 struct pipe_video_buffer
*buffer
,
544 struct u_rect
*src_rect
,
545 struct u_rect
*dst_rect
,
546 enum vl_compositor_deinterlace deinterlace
)
548 struct pipe_sampler_view
**sampler_views
;
551 assert(s
&& c
&& buffer
);
553 assert(layer
< VL_COMPOSITOR_MAX_LAYERS
);
555 s
->interlaced
= buffer
->interlaced
;
556 s
->used_layers
|= 1 << layer
;
557 sampler_views
= buffer
->get_sampler_view_components(buffer
);
558 for (i
= 0; i
< 3; ++i
) {
559 s
->layers
[layer
].samplers
[i
] = c
->sampler_linear
;
560 pipe_sampler_view_reference(&s
->layers
[layer
].sampler_views
[i
], sampler_views
[i
]);
563 calc_src_and_dst(&s
->layers
[layer
], buffer
->width
, buffer
->height
,
564 src_rect
? *src_rect
: default_rect(&s
->layers
[layer
]),
565 dst_rect
? *dst_rect
: default_rect(&s
->layers
[layer
]));
567 if (buffer
->interlaced
) {
568 float half_a_line
= 0.5f
/ s
->layers
[layer
].zw
.y
;
569 switch(deinterlace
) {
570 case VL_COMPOSITOR_WEAVE
:
571 if (c
->pipe_cs_composit_supported
)
572 s
->layers
[layer
].cs
= c
->cs_weave_rgb
;
573 else if (c
->pipe_gfx_supported
)
574 s
->layers
[layer
].fs
= c
->fs_weave_rgb
;
577 case VL_COMPOSITOR_BOB_TOP
:
578 s
->layers
[layer
].zw
.x
= 0.0f
;
579 s
->layers
[layer
].src
.tl
.y
+= half_a_line
;
580 s
->layers
[layer
].src
.br
.y
+= half_a_line
;
581 if (c
->pipe_cs_composit_supported
)
582 s
->layers
[layer
].cs
= c
->cs_video_buffer
;
583 else if (c
->pipe_gfx_supported
)
584 s
->layers
[layer
].fs
= c
->fs_video_buffer
;
587 case VL_COMPOSITOR_BOB_BOTTOM
:
588 s
->layers
[layer
].zw
.x
= 1.0f
;
589 s
->layers
[layer
].src
.tl
.y
-= half_a_line
;
590 s
->layers
[layer
].src
.br
.y
-= half_a_line
;
591 if (c
->pipe_cs_composit_supported
)
592 s
->layers
[layer
].cs
= c
->cs_video_buffer
;
593 else if (c
->pipe_gfx_supported
)
594 s
->layers
[layer
].fs
= c
->fs_video_buffer
;
599 if (c
->pipe_cs_composit_supported
)
600 s
->layers
[layer
].cs
= c
->cs_video_buffer
;
601 else if (c
->pipe_gfx_supported
)
602 s
->layers
[layer
].fs
= c
->fs_video_buffer
;
607 vl_compositor_set_palette_layer(struct vl_compositor_state
*s
,
608 struct vl_compositor
*c
,
610 struct pipe_sampler_view
*indexes
,
611 struct pipe_sampler_view
*palette
,
612 struct u_rect
*src_rect
,
613 struct u_rect
*dst_rect
,
614 bool include_color_conversion
)
616 assert(s
&& c
&& indexes
&& palette
);
618 assert(layer
< VL_COMPOSITOR_MAX_LAYERS
);
620 s
->used_layers
|= 1 << layer
;
622 s
->layers
[layer
].fs
= include_color_conversion
?
623 c
->fs_palette
.yuv
: c
->fs_palette
.rgb
;
625 s
->layers
[layer
].samplers
[0] = c
->sampler_linear
;
626 s
->layers
[layer
].samplers
[1] = c
->sampler_nearest
;
627 s
->layers
[layer
].samplers
[2] = NULL
;
628 pipe_sampler_view_reference(&s
->layers
[layer
].sampler_views
[0], indexes
);
629 pipe_sampler_view_reference(&s
->layers
[layer
].sampler_views
[1], palette
);
630 pipe_sampler_view_reference(&s
->layers
[layer
].sampler_views
[2], NULL
);
631 calc_src_and_dst(&s
->layers
[layer
], indexes
->texture
->width0
, indexes
->texture
->height0
,
632 src_rect
? *src_rect
: default_rect(&s
->layers
[layer
]),
633 dst_rect
? *dst_rect
: default_rect(&s
->layers
[layer
]));
637 vl_compositor_set_rgba_layer(struct vl_compositor_state
*s
,
638 struct vl_compositor
*c
,
640 struct pipe_sampler_view
*rgba
,
641 struct u_rect
*src_rect
,
642 struct u_rect
*dst_rect
,
643 struct vertex4f
*colors
)
647 assert(s
&& c
&& rgba
);
649 assert(layer
< VL_COMPOSITOR_MAX_LAYERS
);
651 s
->used_layers
|= 1 << layer
;
652 s
->layers
[layer
].fs
= c
->fs_rgba
;
653 s
->layers
[layer
].samplers
[0] = c
->sampler_linear
;
654 s
->layers
[layer
].samplers
[1] = NULL
;
655 s
->layers
[layer
].samplers
[2] = NULL
;
656 pipe_sampler_view_reference(&s
->layers
[layer
].sampler_views
[0], rgba
);
657 pipe_sampler_view_reference(&s
->layers
[layer
].sampler_views
[1], NULL
);
658 pipe_sampler_view_reference(&s
->layers
[layer
].sampler_views
[2], NULL
);
659 calc_src_and_dst(&s
->layers
[layer
], rgba
->texture
->width0
, rgba
->texture
->height0
,
660 src_rect
? *src_rect
: default_rect(&s
->layers
[layer
]),
661 dst_rect
? *dst_rect
: default_rect(&s
->layers
[layer
]));
664 for (i
= 0; i
< 4; ++i
)
665 s
->layers
[layer
].colors
[i
] = colors
[i
];
669 vl_compositor_set_layer_rotation(struct vl_compositor_state
*s
,
671 enum vl_compositor_rotation rotate
)
674 assert(layer
< VL_COMPOSITOR_MAX_LAYERS
);
675 s
->layers
[layer
].rotate
= rotate
;
679 vl_compositor_yuv_deint_full(struct vl_compositor_state
*s
,
680 struct vl_compositor
*c
,
681 struct pipe_video_buffer
*src
,
682 struct pipe_video_buffer
*dst
,
683 struct u_rect
*src_rect
,
684 struct u_rect
*dst_rect
,
685 enum vl_compositor_deinterlace deinterlace
)
687 struct pipe_surface
**dst_surfaces
;
689 dst_surfaces
= dst
->get_surfaces(dst
);
690 vl_compositor_clear_layers(s
);
692 set_yuv_layer(s
, c
, 0, src
, src_rect
, NULL
, true, deinterlace
);
693 vl_compositor_set_layer_dst_area(s
, 0, dst_rect
);
694 vl_compositor_render(s
, c
, dst_surfaces
[0], NULL
, false);
701 set_yuv_layer(s
, c
, 0, src
, src_rect
, NULL
, false, deinterlace
);
702 vl_compositor_set_layer_dst_area(s
, 0, dst_rect
);
703 vl_compositor_render(s
, c
, dst_surfaces
[1], NULL
, false);
705 s
->pipe
->flush(s
->pipe
, NULL
, 0);
709 vl_compositor_convert_rgb_to_yuv(struct vl_compositor_state
*s
,
710 struct vl_compositor
*c
,
712 struct pipe_resource
*src_res
,
713 struct pipe_video_buffer
*dst
,
714 struct u_rect
*src_rect
,
715 struct u_rect
*dst_rect
)
717 struct pipe_sampler_view
*sv
, sv_templ
;
718 struct pipe_surface
**dst_surfaces
;
720 dst_surfaces
= dst
->get_surfaces(dst
);
722 memset(&sv_templ
, 0, sizeof(sv_templ
));
723 u_sampler_view_default_template(&sv_templ
, src_res
, src_res
->format
);
724 sv
= s
->pipe
->create_sampler_view(s
->pipe
, src_res
, &sv_templ
);
726 vl_compositor_clear_layers(s
);
728 set_rgb_to_yuv_layer(s
, c
, 0, sv
, src_rect
, NULL
, true);
729 vl_compositor_set_layer_dst_area(s
, 0, dst_rect
);
730 vl_compositor_render(s
, c
, dst_surfaces
[0], NULL
, false);
737 set_rgb_to_yuv_layer(s
, c
, 0, sv
, src_rect
, NULL
, false);
738 vl_compositor_set_layer_dst_area(s
, 0, dst_rect
);
739 vl_compositor_render(s
, c
, dst_surfaces
[1], NULL
, false);
740 pipe_sampler_view_reference(&sv
, NULL
);
742 s
->pipe
->flush(s
->pipe
, NULL
, 0);
746 vl_compositor_render(struct vl_compositor_state
*s
,
747 struct vl_compositor
*c
,
748 struct pipe_surface
*dst_surface
,
749 struct u_rect
*dirty_area
,
755 vl_compositor_cs_render(s
, c
, dst_surface
, dirty_area
, clear_dirty
);
756 else if (s
->layers
->fs
)
757 vl_compositor_gfx_render(s
, c
, dst_surface
, dirty_area
, clear_dirty
);
759 debug_warning("Hardware don't support.\n");;
763 vl_compositor_init(struct vl_compositor
*c
, struct pipe_context
*pipe
)
767 memset(c
, 0, sizeof(*c
));
769 c
->pipe_cs_composit_supported
= pipe
->screen
->get_param(pipe
->screen
, PIPE_CAP_PREFER_COMPUTE_FOR_MULTIMEDIA
) &&
770 pipe
->screen
->get_param(pipe
->screen
, PIPE_CAP_TGSI_TEX_TXF_LZ
) &&
771 pipe
->screen
->get_param(pipe
->screen
, PIPE_CAP_TGSI_DIV
);
773 c
->pipe_gfx_supported
= pipe
->screen
->get_param(pipe
->screen
, PIPE_CAP_GRAPHICS
);
776 if (!init_pipe_state(c
)) {
780 if (!init_shaders(c
)) {
781 cleanup_pipe_state(c
);
785 if (!init_buffers(c
)) {
787 cleanup_pipe_state(c
);
795 vl_compositor_init_state(struct vl_compositor_state
*s
, struct pipe_context
*pipe
)
797 vl_csc_matrix csc_matrix
;
801 memset(s
, 0, sizeof(*s
));
805 s
->clear_color
.f
[0] = s
->clear_color
.f
[1] = 0.0f
;
806 s
->clear_color
.f
[2] = s
->clear_color
.f
[3] = 0.0f
;
809 * Create our fragment shader's constant buffer
810 * Const buffer contains the color conversion matrix and bias vectors
812 /* XXX: Create with IMMUTABLE/STATIC... although it does change every once in a long while... */
813 s
->shader_params
= pipe_buffer_create_const0
816 PIPE_BIND_CONSTANT_BUFFER
,
818 sizeof(csc_matrix
) + 6*sizeof(float) + 10*sizeof(int)
821 if (!s
->shader_params
)
824 vl_compositor_clear_layers(s
);
826 vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_IDENTITY
, NULL
, true, &csc_matrix
);
827 if (!vl_compositor_set_csc_matrix(s
, (const vl_csc_matrix
*)&csc_matrix
, 1.0f
, 0.0f
))
834 vl_compositor_cleanup_state(struct vl_compositor_state
*s
)
838 vl_compositor_clear_layers(s
);
839 pipe_resource_reference(&s
->shader_params
, NULL
);