[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