[Mesa-dev] [PATCH 1/2] vl: Handle custom destination rectangles correctly
Maarten Lankhorst
m.b.lankhorst at gmail.com
Fri Dec 2 09:28:37 PST 2011
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.lankhorst at 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
More information about the mesa-dev
mailing list