cleanup_pipe_state(compositor);
}
- struct vertex2f bg_inv_size = {1.0f / c->bg->width[0], 1.0f / c->bg->height[0]};
+void vl_compositor_set_background(struct vl_compositor *compositor,
+ struct pipe_texture *bg, struct pipe_video_rect *bg_src_rect)
+{
+ assert(compositor);
+ assert((bg && bg_src_rect) || (!bg && !bg_src_rect));
+
+ if (compositor->bg != bg ||
+ !u_video_rects_equal(&compositor->bg_src_rect, bg_src_rect)) {
+ pipe_texture_reference(&compositor->bg, bg);
+ /*if (!u_video_rects_equal(&compositor->bg_src_rect, bg_src_rect))*/
+ compositor->bg_src_rect = *bg_src_rect;
+ compositor->dirty_bg = true;
+ }
+}
+
+void vl_compositor_set_layers(struct vl_compositor *compositor,
+ struct pipe_texture *layers[],
+ struct pipe_video_rect *src_rects[],
+ struct pipe_video_rect *dst_rects[],
+ unsigned num_layers)
+{
+ unsigned i;
+
+ assert(compositor);
+ assert(num_layers <= VL_COMPOSITOR_MAX_LAYERS);
+
+ for (i = 0; i < num_layers; ++i)
+ {
+ assert((layers[i] && src_rects[i] && dst_rects[i]) ||
+ (!layers[i] && !src_rects[i] && !dst_rects[i]));
+
+ if (compositor->layers[i] != layers[i] ||
+ !u_video_rects_equal(&compositor->layer_src_rects[i], src_rects[i]) ||
+ !u_video_rects_equal(&compositor->layer_dst_rects[i], dst_rects[i]))
+ {
+ pipe_texture_reference(&compositor->layers[i], layers[i]);
+ /*if (!u_video_rects_equal(&compositor->layer_src_rects[i], src_rects[i]))*/
+ compositor->layer_src_rects[i] = *src_rects[i];
+ /*if (!u_video_rects_equal(&compositor->layer_dst_rects[i], dst_rects[i]))*/
+ compositor->layer_dst_rects[i] = *dst_rects[i];
+ compositor->dirty_layers |= 1 << i;
+ }
+ }
+
+ for (; i < VL_COMPOSITOR_MAX_LAYERS; ++i)
+ pipe_texture_reference(&compositor->layers[i], NULL);
+}
+
+static void gen_rect_verts(unsigned pos,
+ struct pipe_video_rect *src_rect,
+ struct vertex2f *src_inv_size,
+ struct pipe_video_rect *dst_rect,
+ struct vertex2f *dst_inv_size,
+ struct vertex4f *vb)
+{
+ assert(pos < VL_COMPOSITOR_MAX_LAYERS + 2);
+ assert(src_rect);
+ assert(src_inv_size);
+ assert((dst_rect && dst_inv_size) || (!dst_rect && !dst_inv_size));
+ assert(vb);
+
+ vb[pos * 6 + 0].x = dst_rect->x * dst_inv_size->x;
+ vb[pos * 6 + 0].y = dst_rect->y * dst_inv_size->y;
+ vb[pos * 6 + 0].z = src_rect->x * src_inv_size->x;
+ vb[pos * 6 + 0].w = src_rect->y * src_inv_size->y;
+
+ vb[pos * 6 + 1].x = dst_rect->x * dst_inv_size->x;
+ vb[pos * 6 + 1].y = (dst_rect->y + dst_rect->h) * dst_inv_size->y;
+ vb[pos * 6 + 1].z = src_rect->x * src_inv_size->x;
+ vb[pos * 6 + 1].w = (src_rect->y + src_rect->h) * src_inv_size->y;
+
+ vb[pos * 6 + 2].x = (dst_rect->x + dst_rect->w) * dst_inv_size->x;
+ vb[pos * 6 + 2].y = dst_rect->y * dst_inv_size->y;
+ vb[pos * 6 + 2].z = (src_rect->x + src_rect->w) * src_inv_size->x;
+ vb[pos * 6 + 2].w = src_rect->y * src_inv_size->y;
+
+ vb[pos * 6 + 3].x = (dst_rect->x + dst_rect->w) * dst_inv_size->x;
+ vb[pos * 6 + 3].y = dst_rect->y * dst_inv_size->y;
+ vb[pos * 6 + 3].z = (src_rect->x + src_rect->w) * src_inv_size->x;
+ vb[pos * 6 + 3].w = src_rect->y * src_inv_size->y;
+
+ vb[pos * 6 + 4].x = dst_rect->x * dst_inv_size->x;
+ vb[pos * 6 + 4].y = (dst_rect->y + dst_rect->h) * dst_inv_size->y;
+ vb[pos * 6 + 4].z = src_rect->x * src_inv_size->x;
+ vb[pos * 6 + 4].w = (src_rect->y + src_rect->h) * src_inv_size->y;
+
+ vb[pos * 6 + 5].x = (dst_rect->x + dst_rect->w) * dst_inv_size->x;
+ vb[pos * 6 + 5].y = (dst_rect->y + dst_rect->h) * dst_inv_size->y;
+ vb[pos * 6 + 5].z = (src_rect->x + src_rect->w) * src_inv_size->x;
+ vb[pos * 6 + 5].w = (src_rect->y + src_rect->h) * src_inv_size->y;
+}
+
+static unsigned gen_verts(struct vl_compositor *c,
+ struct pipe_video_rect *src_rect,
+ struct vertex2f *src_inv_size,
+ struct pipe_video_rect *dst_rect)
+{
+ void *vb;
+ unsigned num_rects = 0;
+ unsigned i;
+
+ assert(c);
+ assert(src_rect);
+ assert(src_inv_size);
+ assert(dst_rect);
+
+ vb = pipe_buffer_map(c->pipe->screen, c->vertex_buf.buffer,
+ PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD);
+
+ if (c->dirty_bg) {
- struct vertex2f layer_inv_size = {1.0f / c->layers[i]->width[0], 1.0f / c->layers[i]->height[0]};
++ struct vertex2f bg_inv_size = {1.0f / c->bg->width0, 1.0f / c->bg->height0};
+ gen_rect_verts(num_rects++, &c->bg_src_rect, &bg_inv_size, NULL, NULL, vb);
+ c->dirty_bg = false;
+ }
+
+ gen_rect_verts(num_rects++, src_rect, src_inv_size, dst_rect, &c->fb_inv_size, vb);
+
+ for (i = 0; c->dirty_layers > 0; i++)
+ {
+ assert(i < VL_COMPOSITOR_MAX_LAYERS);
+
+ if (c->dirty_layers & (1 << i)) {
++ struct vertex2f layer_inv_size = {1.0f / c->layers[i]->width0, 1.0f / c->layers[i]->height0};
+ gen_rect_verts(num_rects++, &c->layer_src_rects[i], &layer_inv_size,
+ &c->layer_dst_rects[i], &c->fb_inv_size, vb);
+ c->dirty_layers &= ~(1 << i);
+ }
+ }
+
+ pipe_buffer_unmap(c->pipe->screen, c->vertex_buf.buffer);
+
+ return num_rects;
+}
+
void vl_compositor_render(struct vl_compositor *compositor,
- /*struct pipe_texture *backround,
- struct pipe_video_rect *backround_area,*/
struct pipe_texture *src_surface,
enum pipe_mpeg12_picture_type picture_type,
/*unsigned num_past_surfaces,
assert(dst_area);
assert(picture_type == PIPE_MPEG12_PICTURE_TYPE_FRAME);
- if (compositor->fb_state.width != dst_surface->width[0]) {
- compositor->fb_inv_size.x = 1.0f / dst_surface->width[0];
- compositor->fb_state.width = dst_surface->width[0];
- compositor->fb_state.width = dst_surface->width0;
- compositor->fb_state.height = dst_surface->height0;
++ if (compositor->fb_state.width != dst_surface->width0) {
++ compositor->fb_inv_size.x = 1.0f / dst_surface->width0;
++ compositor->fb_state.width = dst_surface->width0;
+ }
- if (compositor->fb_state.height != dst_surface->height[0]) {
- compositor->fb_inv_size.y = 1.0f / dst_surface->height[0];
- compositor->fb_state.height = dst_surface->height[0];
++ if (compositor->fb_state.height != dst_surface->height0) {
++ compositor->fb_inv_size.y = 1.0f / dst_surface->height0;
++ compositor->fb_state.height = dst_surface->height0;
+ }
+
compositor->fb_state.cbufs[0] = compositor->pipe->screen->get_tex_surface
(
compositor->pipe->screen,
compositor->viewport.translate[2] = 0;
compositor->viewport.translate[3] = 0;
- compositor->scissor.maxx = compositor->fb_state.width;
- compositor->scissor.maxy = compositor->fb_state.height;
-
compositor->pipe->set_framebuffer_state(compositor->pipe, &compositor->fb_state);
compositor->pipe->set_viewport_state(compositor->pipe, &compositor->viewport);
- compositor->pipe->bind_sampler_states(compositor->pipe, 1, &compositor->sampler);
- compositor->pipe->set_sampler_textures(compositor->pipe, 1, &src_surface);
- compositor->pipe->set_scissor_state(compositor->pipe, &compositor->scissor);
+ compositor->pipe->bind_fragment_sampler_states(compositor->pipe, 1, &compositor->sampler);
+ compositor->pipe->set_fragment_sampler_textures(compositor->pipe, 1, &src_surface);
compositor->pipe->bind_vs_state(compositor->pipe, compositor->vertex_shader);
compositor->pipe->bind_fs_state(compositor->pipe, compositor->fragment_shader);
- compositor->pipe->set_vertex_buffers(compositor->pipe, 2, compositor->vertex_bufs);
+ compositor->pipe->set_vertex_buffers(compositor->pipe, 1, &compositor->vertex_buf);
compositor->pipe->set_vertex_elements(compositor->pipe, 2, compositor->vertex_elems);
- compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_VERTEX, 0, &compositor->vs_const_buf);
compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_FRAGMENT, 0, &compositor->fs_const_buf);
- vs_consts = pipe_buffer_map
- (
- compositor->pipe->screen,
- compositor->vs_const_buf.buffer,
- PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
- );
+ {
- struct vertex2f src_inv_size = {1.0f / src_surface->width[0], 1.0f / src_surface->height[0]};
++ struct vertex2f src_inv_size = {1.0f / src_surface->width0, 1.0f / src_surface->height0};
+ num_rects = gen_verts(compositor, src_area, &src_inv_size, dst_area);
+ }
+
+ assert(!compositor->dirty_bg && !compositor->dirty_layers);
+ assert(num_rects > 0);
- vs_consts->dst_scale.x = dst_area->w / (float)compositor->fb_state.cbufs[0]->width;
- vs_consts->dst_scale.y = dst_area->h / (float)compositor->fb_state.cbufs[0]->height;
- vs_consts->dst_scale.z = 1;
- vs_consts->dst_scale.w = 1;
- vs_consts->dst_trans.x = dst_area->x / (float)compositor->fb_state.cbufs[0]->width;
- vs_consts->dst_trans.y = dst_area->y / (float)compositor->fb_state.cbufs[0]->height;
- vs_consts->dst_trans.z = 0;
- vs_consts->dst_trans.w = 0;
-
- vs_consts->src_scale.x = src_area->w / (float)src_surface->width0;
- vs_consts->src_scale.y = src_area->h / (float)src_surface->height0;
- vs_consts->src_scale.z = 1;
- vs_consts->src_scale.w = 1;
- vs_consts->src_trans.x = src_area->x / (float)src_surface->width0;
- vs_consts->src_trans.y = src_area->y / (float)src_surface->height0;
- vs_consts->src_trans.z = 0;
- vs_consts->src_trans.w = 0;
-
- pipe_buffer_unmap(compositor->pipe->screen, compositor->vs_const_buf.buffer);
-
- compositor->pipe->draw_arrays(compositor->pipe, PIPE_PRIM_TRIANGLE_STRIP, 0, 4);
+ compositor->pipe->draw_arrays(compositor->pipe, PIPE_PRIM_TRIANGLES, 0, num_rects * 6);
compositor->pipe->flush(compositor->pipe, PIPE_FLUSH_RENDER_CACHE, fence);
pipe_surface_reference(&compositor->fb_state.cbufs[0], NULL);