When layers are still being added, the total width/height is not known. As such extra care has to be taken to get output rectangle correct. This is required to support a custom dest rectangle, which is currently not used and buggy.
Signed-off-by: Maarten Lankhorst <m.b.lankho...@gmail.com> --- src/gallium/auxiliary/vl/vl_compositor.c | 84 ++++++++++++++++++------------ src/gallium/auxiliary/vl/vl_compositor.h | 2 +- 2 files changed, 52 insertions(+), 34 deletions(-) diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c index fff4340..f8ea24c 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.c +++ b/src/gallium/auxiliary/vl/vl_compositor.c @@ -446,44 +446,52 @@ calc_bottomright(struct vertex2f size, struct pipe_video_rect rect) static INLINE void calc_src_and_dst(struct vl_compositor_layer *layer, unsigned width, unsigned height, - struct pipe_video_rect src, struct pipe_video_rect dst) + struct pipe_video_rect src, struct pipe_video_rect *dst) { - struct vertex2f size = { width, height }; - - layer->src.tl = calc_topleft(size, src); - layer->src.br = calc_bottomright(size, src); - layer->dst.tl = calc_topleft(size, dst); - layer->dst.br = calc_bottomright(size, dst); + struct vertex2f size_in = { width, height }; + struct vertex2f size_out = { 1.f, 1.f }; + + layer->src.tl = calc_topleft(size_in, src); + layer->src.br = calc_bottomright(size_in, src); + if (dst) { + layer->dst.tl = calc_topleft(size_out, *dst); + layer->dst.br = calc_bottomright(size_out, *dst); + layer->custom_dest_rect = 1; + } else { + layer->dst.tl.x = layer->dst.tl.y = 0.f; + layer->dst.br.x = layer->dst.br.y = 1.f; + layer->custom_dest_rect = 0; + } } static void -gen_rect_verts(struct vertex4f *vb, struct vl_compositor_layer *layer) +gen_rect_verts(struct vertex4f *vb, struct vl_compositor_layer *layer, float w, float h) { assert(vb && layer); - vb[0].x = layer->dst.tl.x; - vb[0].y = layer->dst.tl.y; + vb[0].x = layer->dst.tl.x / w; + vb[0].y = layer->dst.tl.y / h; vb[0].z = layer->src.tl.x; vb[0].w = layer->src.tl.y; - vb[1].x = layer->dst.br.x; - vb[1].y = layer->dst.tl.y; + vb[1].x = layer->dst.br.x / w; + vb[1].y = layer->dst.tl.y / h; vb[1].z = layer->src.br.x; vb[1].w = layer->src.tl.y; - vb[2].x = layer->dst.br.x; - vb[2].y = layer->dst.br.y; + vb[2].x = layer->dst.br.x / w; + vb[2].y = layer->dst.br.y / h; vb[2].z = layer->src.br.x; vb[2].w = layer->src.br.y; - vb[3].x = layer->dst.tl.x; - vb[3].y = layer->dst.br.y; + vb[3].x = layer->dst.tl.x / w; + vb[3].y = layer->dst.br.y / h; vb[3].z = layer->src.tl.x; vb[3].w = layer->src.br.y; } static void -gen_vertex_data(struct vl_compositor *c) +gen_vertex_data(struct vl_compositor *c, float w, float h) { struct vertex4f *vb; struct pipe_transfer *buf_transfer; @@ -506,15 +514,18 @@ gen_vertex_data(struct vl_compositor *c) for (i = 0; i < VL_COMPOSITOR_MAX_LAYERS; i++) { if (c->used_layers & (1 << i)) { struct vl_compositor_layer *layer = &c->layers[i]; - gen_rect_verts(vb, layer); + if (layer->custom_dest_rect) + gen_rect_verts(vb, layer, w, h); + else + gen_rect_verts(vb, layer, 1.f, 1.f); vb += 4; if (layer->clearing && - c->dirty_tl.x >= layer->dst.tl.x && - c->dirty_tl.y >= layer->dst.tl.y && - c->dirty_br.x <= layer->dst.br.x && - c->dirty_br.y <= layer->dst.br.y) { - + (!layer->custom_dest_rect || + (c->dirty_tl.x >= layer->dst.tl.x/w && + c->dirty_tl.y >= layer->dst.tl.y/h && + c->dirty_br.x <= layer->dst.br.x/w && + c->dirty_br.y <= layer->dst.br.y/h))) { // We clear the dirty area anyway, no need for clear_render_target c->dirty_tl.x = c->dirty_tl.y = 1.0f; c->dirty_br.x = c->dirty_br.y = 0.0f; @@ -526,7 +537,7 @@ gen_vertex_data(struct vl_compositor *c) } static void -draw_layers(struct vl_compositor *c) +draw_layers(struct vl_compositor *c, float w, float h) { unsigned vb_index, i; @@ -546,10 +557,17 @@ draw_layers(struct vl_compositor *c) vb_index++; // Remember the currently drawn area as dirty for the next draw command - c->dirty_tl.x = MIN2(layer->dst.tl.x, c->dirty_tl.x); - c->dirty_tl.y = MIN2(layer->dst.tl.y, c->dirty_tl.y); - c->dirty_br.x = MAX2(layer->dst.br.x, c->dirty_br.x); - c->dirty_br.y = MAX2(layer->dst.br.y, c->dirty_br.y); + if (layer->custom_dest_rect) { + c->dirty_tl.x = MIN2(layer->dst.tl.x/w, c->dirty_tl.x); + c->dirty_tl.y = MIN2(layer->dst.tl.y/h, c->dirty_tl.y); + c->dirty_br.x = MAX2(layer->dst.br.x/w, c->dirty_br.x); + c->dirty_br.y = MAX2(layer->dst.br.y/h, c->dirty_br.y); + } else { + c->dirty_tl.x = 0.f; + c->dirty_tl.y = 0.f; + c->dirty_br.x = 1.f; + c->dirty_br.y = 1.f; + } } } } @@ -670,7 +688,7 @@ vl_compositor_set_buffer_layer(struct vl_compositor *c, calc_src_and_dst(&c->layers[layer], buffer->width, buffer->height, src_rect ? *src_rect : default_rect(&c->layers[layer]), - dst_rect ? *dst_rect : default_rect(&c->layers[layer])); + dst_rect); } void @@ -699,7 +717,7 @@ vl_compositor_set_palette_layer(struct vl_compositor *c, pipe_sampler_view_reference(&c->layers[layer].sampler_views[2], NULL); calc_src_and_dst(&c->layers[layer], indexes->texture->width0, indexes->texture->height0, src_rect ? *src_rect : default_rect(&c->layers[layer]), - dst_rect ? *dst_rect : default_rect(&c->layers[layer])); + dst_rect); } void @@ -723,7 +741,7 @@ vl_compositor_set_rgba_layer(struct vl_compositor *c, pipe_sampler_view_reference(&c->layers[layer].sampler_views[2], NULL); calc_src_and_dst(&c->layers[layer], rgba->texture->width0, rgba->texture->height0, src_rect ? *src_rect : default_rect(&c->layers[layer]), - dst_rect ? *dst_rect : default_rect(&c->layers[layer])); + dst_rect); } void @@ -766,7 +784,7 @@ vl_compositor_render(struct vl_compositor *c, scissor.maxy = dst_surface->height; } - gen_vertex_data(c); + gen_vertex_data(c, dst_surface->width, dst_surface->height); if (clear_dirty_area && (c->dirty_tl.x < c->dirty_br.x || c->dirty_tl.y < c->dirty_br.y)) { @@ -785,7 +803,7 @@ vl_compositor_render(struct vl_compositor *c, c->pipe->set_constant_buffer(c->pipe, PIPE_SHADER_FRAGMENT, 0, c->csc_matrix); c->pipe->bind_rasterizer_state(c->pipe, c->rast); - draw_layers(c); + draw_layers(c, dst_surface->width, dst_surface->height); } bool diff --git a/src/gallium/auxiliary/vl/vl_compositor.h b/src/gallium/auxiliary/vl/vl_compositor.h index cc91c2b..383f30f 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.h +++ b/src/gallium/auxiliary/vl/vl_compositor.h @@ -44,7 +44,7 @@ struct pipe_context; struct vl_compositor_layer { - bool clearing; + bool clearing, custom_dest_rect; void *fs; void *samplers[3]; -- 1.7.7.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev