Mesa (pipe-video): [g3dvl] split compositor out of video context

Christian König deathsimple at kemper.freedesktop.org
Sun Apr 3 12:01:21 PDT 2011


Module: Mesa
Branch: pipe-video
Commit: e5f78a74f8294ee02015552db664dae1e7da9f47
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=e5f78a74f8294ee02015552db664dae1e7da9f47

Author: Christian König <deathsimple at vodafone.de>
Date:   Sun Apr  3 16:09:23 2011 +0200

[g3dvl] split compositor out of video context

Also redesign the compositor a bit and make the result a public available interface

---

 src/gallium/auxiliary/vl/vl_compositor.c           |  556 ++++++++++----------
 src/gallium/auxiliary/vl/vl_compositor.h           |   63 +--
 src/gallium/auxiliary/vl/vl_mpeg12_context.c       |   90 +---
 src/gallium/auxiliary/vl/vl_mpeg12_context.h       |    1 -
 src/gallium/include/pipe/p_video_context.h         |  106 +++--
 src/gallium/state_trackers/xorg/xvmc/context.c     |   12 +-
 src/gallium/state_trackers/xorg/xvmc/surface.c     |   21 +-
 .../state_trackers/xorg/xvmc/xvmc_private.h        |    2 +
 8 files changed, 423 insertions(+), 428 deletions(-)

diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c
index f62706e..45e9cea 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.c
+++ b/src/gallium/auxiliary/vl/vl_compositor.c
@@ -36,38 +36,11 @@
 #include <util/u_sampler.h>
 #include <tgsi/tgsi_ureg.h>
 #include "vl_csc.h"
+#include "vl_types.h"
 
-struct vertex_shader_consts
-{
-   struct vertex4f dst_scale;
-   struct vertex4f dst_trans;
-   struct vertex4f src_scale;
-   struct vertex4f src_trans;
-};
-
-struct fragment_shader_consts
-{
-   float matrix[16];
-};
-
-static bool
-u_video_rects_equal(struct pipe_video_rect *a, struct pipe_video_rect *b)
-{
-   assert(a && b);
-
-   if (a->x != b->x)
-      return false;
-   if (a->y != b->y)
-      return false;
-   if (a->w != b->w)
-      return false;
-   if (a->h != b->h)
-      return false;
-
-   return true;
-}
+typedef float csc_matrix[16];
 
-static bool
+static void *
 create_vert_shader(struct vl_compositor *c)
 {
    struct ureg_program *shader;
@@ -92,15 +65,11 @@ create_vert_shader(struct vl_compositor *c)
 
    ureg_END(shader);
 
-   c->vertex_shader = ureg_create_shader_and_destroy(shader, c->pipe);
-   if (!c->vertex_shader)
-      return false;
-
-   return true;
+   return ureg_create_shader_and_destroy(shader, c->pipe);
 }
 
-static bool
-create_frag_shader_ycbcr_2_rgb(struct vl_compositor *c)
+static void *
+create_frag_shader_video_buffer(struct vl_compositor *c)
 {
    struct ureg_program *shader;
    struct ureg_src tc;
@@ -139,15 +108,11 @@ create_frag_shader_ycbcr_2_rgb(struct vl_compositor *c)
    ureg_release_temporary(shader, texel);
    ureg_END(shader);
 
-   c->fragment_shader.ycbcr_2_rgb = ureg_create_shader_and_destroy(shader, c->pipe);
-   if (!c->fragment_shader.ycbcr_2_rgb)
-      return false;
-
-   return true;
+   return ureg_create_shader_and_destroy(shader, c->pipe);
 }
 
-static bool
-create_frag_shader_palette_2_rgb(struct vl_compositor *c)
+static void *
+create_frag_shader_palette(struct vl_compositor *c)
 {
    struct ureg_program *shader;
    struct ureg_src tc;
@@ -167,7 +132,9 @@ create_frag_shader_palette_2_rgb(struct vl_compositor *c)
    texel = ureg_DECL_temporary(shader);
 
    /*
-    * fragment = tex(tc, sampler)
+    * texel = tex(tc, sampler)
+    * fragment.xyz = tex(texel, palette)
+    * fragment.a = texel.a
     */
    ureg_TEX(shader, texel, TGSI_TEXTURE_2D, tc, sampler);
    ureg_TEX(shader, fragment, TGSI_TEXTURE_1D, ureg_src(texel), palette);
@@ -176,15 +143,11 @@ create_frag_shader_palette_2_rgb(struct vl_compositor *c)
    ureg_release_temporary(shader, texel);
    ureg_END(shader);
 
-   c->fragment_shader.palette_2_rgb = ureg_create_shader_and_destroy(shader, c->pipe);
-   if (!c->fragment_shader.palette_2_rgb)
-      return false;
-
-   return true;
+   return ureg_create_shader_and_destroy(shader, c->pipe);
 }
 
-static bool
-create_frag_shader_rgb_2_rgb(struct vl_compositor *c)
+static void *
+create_frag_shader_rgba(struct vl_compositor *c)
 {
    struct ureg_program *shader;
    struct ureg_src tc;
@@ -205,13 +168,51 @@ create_frag_shader_rgb_2_rgb(struct vl_compositor *c)
    ureg_TEX(shader, fragment, TGSI_TEXTURE_2D, tc, sampler);
    ureg_END(shader);
 
-   c->fragment_shader.rgb_2_rgb = ureg_create_shader_and_destroy(shader, c->pipe);
-   if (!c->fragment_shader.rgb_2_rgb)
+   return ureg_create_shader_and_destroy(shader, c->pipe);
+}
+
+static bool
+init_shaders(struct vl_compositor *c)
+{
+   assert(c);
+
+   c->vs = create_vert_shader(c);
+   if (!c->vs) {
+      debug_printf("Unable to create vertex shader.\n");
       return false;
+   }
+
+   c->fs_video_buffer = create_frag_shader_video_buffer(c);
+   if (!c->fs_video_buffer) {
+      debug_printf("Unable to create YCbCr-to-RGB fragment shader.\n");
+      return false;
+   }
+
+   c->fs_palette = create_frag_shader_palette(c);
+   if (!c->fs_palette) {
+      debug_printf("Unable to create Palette-to-RGB fragment shader.\n");
+      return false;
+   }
+
+   c->fs_rgba = create_frag_shader_rgba(c);
+   if (!c->fs_rgba) {
+      debug_printf("Unable to create RGB-to-RGB fragment shader.\n");
+      return false;
+   }
 
    return true;
 }
 
+static void cleanup_shaders(struct vl_compositor *c)
+{
+   assert(c);
+
+   c->pipe->delete_vs_state(c->pipe, c->vs);
+   c->pipe->delete_fs_state(c->pipe, c->fs_video_buffer);
+   c->pipe->delete_fs_state(c->pipe, c->fs_palette);
+   c->pipe->delete_fs_state(c->pipe, c->fs_rgba);
+}
+
 static bool
 init_pipe_state(struct vl_compositor *c)
 {
@@ -223,6 +224,13 @@ init_pipe_state(struct vl_compositor *c)
    c->fb_state.nr_cbufs = 1;
    c->fb_state.zsbuf = NULL;
 
+   c->viewport.scale[2] = 1;
+   c->viewport.scale[3] = 1;
+   c->viewport.translate[0] = 0;
+   c->viewport.translate[1] = 0;
+   c->viewport.translate[2] = 0;
+   c->viewport.translate[3] = 0;
+
    memset(&sampler, 0, sizeof(sampler));
    sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
    sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
@@ -267,44 +275,8 @@ static void cleanup_pipe_state(struct vl_compositor *c)
 }
 
 static bool
-init_shaders(struct vl_compositor *c)
-{
-   assert(c);
-
-   if (!create_vert_shader(c)) {
-      debug_printf("Unable to create vertex shader.\n");
-      return false;
-   }
-   if (!create_frag_shader_ycbcr_2_rgb(c)) {
-      debug_printf("Unable to create YCbCr-to-RGB fragment shader.\n");
-      return false;
-   }
-   if (!create_frag_shader_palette_2_rgb(c)) {
-      debug_printf("Unable to create Palette-to-RGB fragment shader.\n");
-      return false;
-   }
-   if (!create_frag_shader_rgb_2_rgb(c)) {
-      debug_printf("Unable to create RGB-to-RGB fragment shader.\n");
-      return false;
-   }
-
-   return true;
-}
-
-static void cleanup_shaders(struct vl_compositor *c)
-{
-   assert(c);
-
-   c->pipe->delete_vs_state(c->pipe, c->vertex_shader);
-   c->pipe->delete_fs_state(c->pipe, c->fragment_shader.ycbcr_2_rgb);
-   c->pipe->delete_fs_state(c->pipe, c->fragment_shader.palette_2_rgb);
-   c->pipe->delete_fs_state(c->pipe, c->fragment_shader.rgb_2_rgb);
-}
-
-static bool
 init_buffers(struct vl_compositor *c)
 {
-   struct fragment_shader_consts fsc;
    struct pipe_vertex_element vertex_elems[2];
 
    assert(c);
@@ -338,18 +310,14 @@ init_buffers(struct vl_compositor *c)
     * Const buffer contains the color conversion matrix and bias vectors
     */
    /* XXX: Create with IMMUTABLE/STATIC... although it does change every once in a long while... */
-   c->fs_const_buf = pipe_buffer_create
+   c->csc_matrix = pipe_buffer_create
    (
       c->pipe->screen,
       PIPE_BIND_CONSTANT_BUFFER,
       PIPE_USAGE_STATIC,
-      sizeof(struct fragment_shader_consts)
+      sizeof(csc_matrix)
    );
 
-   vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_IDENTITY, NULL, true, fsc.matrix);
-
-   vl_compositor_set_csc_matrix(c, fsc.matrix);
-
    return true;
 }
 
@@ -360,99 +328,27 @@ cleanup_buffers(struct vl_compositor *c)
 
    c->pipe->delete_vertex_elements_state(c->pipe, c->vertex_elems_state);
    pipe_resource_reference(&c->vertex_buf.buffer, NULL);
-   pipe_resource_reference(&c->fs_const_buf, NULL);
+   pipe_resource_reference(&c->csc_matrix, NULL);
 }
 
-bool vl_compositor_init(struct vl_compositor *compositor, struct pipe_context *pipe)
+static inline struct pipe_video_rect
+default_rect(struct vl_compositor_layer *layer)
 {
-   unsigned i;
-
-   assert(compositor);
-
-   memset(compositor, 0, sizeof(struct vl_compositor));
-
-   compositor->pipe = pipe;
-
-   if (!init_pipe_state(compositor))
-      return false;
-
-   if (!init_shaders(compositor)) {
-      cleanup_pipe_state(compositor);
-      return false;
-   }
-   if (!init_buffers(compositor)) {
-      cleanup_shaders(compositor);
-      cleanup_pipe_state(compositor);
-      return false;
-   }
-
-   compositor->fb_state.width = 0;
-   compositor->fb_state.height = 0;
-   for (i = 0; i < VL_COMPOSITOR_MAX_LAYERS; ++i)
-      compositor->layers[i] = NULL;
-   compositor->dirty_layers = 0;
-
-   return true;
+   struct pipe_resource *res = layer->sampler_views[0]->texture;
+   struct pipe_video_rect rect = { 0, 0, res->width0, res->height0 };
+   return rect;
 }
 
-void vl_compositor_cleanup(struct vl_compositor *compositor)
-{
-   assert(compositor);
-
-   cleanup_buffers(compositor);
-   cleanup_shaders(compositor);
-   cleanup_pipe_state(compositor);
-}
-
-void vl_compositor_set_layers(struct vl_compositor *compositor,
-                              struct pipe_sampler_view *layers[],
-                              struct pipe_sampler_view *palettes[],
-                              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] ||
-          compositor->palettes[i] != palettes[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_sampler_view_reference(&compositor->layers[i], layers[i]);
-         pipe_sampler_view_reference(&compositor->palettes[i], palettes[i]);
-         compositor->layer_src_rects[i] = *src_rects[i];
-         compositor->layer_dst_rects[i] = *dst_rects[i];
-         compositor->dirty_layers |= 1 << i;
-      }
-
-      if (layers[i])
-         compositor->dirty_layers |= 1 << i;
-   }
-
-   for (; i < VL_COMPOSITOR_MAX_LAYERS; ++i) {
-      pipe_sampler_view_reference(&compositor->layers[i], NULL);
-      pipe_sampler_view_reference(&compositor->palettes[i], NULL);
-   }
-}
-
-static void gen_rect_verts(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)
+static void
+gen_rect_verts(struct vertex4f *vb,
+               struct pipe_video_rect *src_rect,
+               struct vertex2f *src_inv_size,
+               struct pipe_video_rect *dst_rect,
+               struct vertex2f *dst_inv_size)
 {
-   assert(src_rect);
-   assert(src_inv_size);
-   assert((dst_rect && dst_inv_size) /*|| (!dst_rect && !dst_inv_size)*/);
    assert(vb);
+   assert(src_rect && src_inv_size);
+   assert(dst_rect && dst_inv_size);
 
    vb[0].x = dst_rect->x * dst_inv_size->x;
    vb[0].y = dst_rect->y * dst_inv_size->y;
@@ -475,162 +371,252 @@ static void gen_rect_verts(struct pipe_video_rect *src_rect,
    vb[3].w = (src_rect->y + src_rect->h) * src_inv_size->y;
 }
 
-static unsigned gen_data(struct vl_compositor *c,
-                         struct pipe_sampler_view *src_surface,
-                         struct pipe_video_rect *src_rect,
-                         struct pipe_video_rect *dst_rect,
-                         struct pipe_sampler_view *textures[VL_COMPOSITOR_MAX_LAYERS + 1][2],
-                         void **frag_shaders)
+static void
+gen_vertex_data(struct vl_compositor *c, struct pipe_video_rect *dst_rect, struct vertex2f *dst_inv_size)
 {
    struct vertex4f *vb;
    struct pipe_transfer *buf_transfer;
-   unsigned num_rects = 0;
    unsigned i;
 
    assert(c);
-   assert(src_surface);
-   assert(src_rect);
    assert(dst_rect);
-   assert(textures);
 
    vb = pipe_buffer_map(c->pipe, c->vertex_buf.buffer,
                         PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
                         &buf_transfer);
 
    if (!vb)
-      return 0;
-
-   {
-      struct vertex2f src_inv_size = { 1.0f / src_surface->texture->width0, 1.0f / src_surface->texture->height0};
-      gen_rect_verts(src_rect, &src_inv_size, dst_rect, &c->fb_inv_size, vb);
-      textures[num_rects][0] = src_surface;
-      textures[num_rects][1] = NULL;
-      /* XXX: Hack, sort of */
-      frag_shaders[num_rects] = c->fragment_shader.ycbcr_2_rgb;
-      ++num_rects;
-      vb += 4;
-   }
+      return;
 
-   for (i = 0; c->dirty_layers > 0; i++) {
-      assert(i < VL_COMPOSITOR_MAX_LAYERS);
+   for (i = 0; i < VL_COMPOSITOR_MAX_LAYERS; i++) {
+      if (c->used_layers & (1 << i)) {
+         struct pipe_sampler_view *sv = c->layers[i].sampler_views[0];
+         struct vertex2f src_inv_size = {1.0f / sv->texture->width0, 1.0f / sv->texture->height0};
 
-      if (c->dirty_layers & (1 << i)) {
-         struct vertex2f layer_inv_size = {1.0f / c->layers[i]->texture->width0, 1.0f / c->layers[i]->texture->height0};
-         gen_rect_verts(&c->layer_src_rects[i], &layer_inv_size, &c->layer_dst_rects[i], &layer_inv_size, vb);
-         textures[num_rects][0] = c->layers[i];
-         textures[num_rects][1] = c->palettes[i];
-
-         if (c->palettes[i])
-            frag_shaders[num_rects] = c->fragment_shader.palette_2_rgb;
+         if (&c->layers[i].fs == c->fs_video_buffer)
+            gen_rect_verts(vb, &c->layers[i].src_rect, &src_inv_size, dst_rect, dst_inv_size);
          else
-            frag_shaders[num_rects] = c->fragment_shader.rgb_2_rgb;
+            gen_rect_verts(vb, &c->layers[i].src_rect, &src_inv_size, &c->layers[i].dst_rect, &src_inv_size);
 
-         ++num_rects;
          vb += 4;
-         c->dirty_layers &= ~(1 << i);
       }
    }
 
    pipe_buffer_unmap(c->pipe, buf_transfer);
-
-   return num_rects;
 }
 
-static void draw_layers(struct vl_compositor *c,
-                        struct vl_ycbcr_sampler_views *src_sampler,
-                        struct pipe_video_rect *src_rect,
-                        struct pipe_video_rect *dst_rect)
+static void
+draw_layers(struct vl_compositor *c)
 {
-   unsigned num_rects;
-   struct pipe_sampler_view *surfaces[VL_COMPOSITOR_MAX_LAYERS + 1][2];
-   void *frag_shaders[VL_COMPOSITOR_MAX_LAYERS + 1];
-   unsigned i;
+   unsigned vb_index, i;
 
    assert(c);
-   assert(src_sampler);
-   assert(src_rect);
-   assert(dst_rect);
 
-   num_rects = gen_data(c, src_sampler->y, src_rect, dst_rect, surfaces, frag_shaders);
+   for (i = 0, vb_index = 0; i < VL_COMPOSITOR_MAX_LAYERS; ++i) {
+      if (c->used_layers & (1 << i)) {
+         struct pipe_sampler_view **samplers = &c->layers[i].sampler_views[0];
+         unsigned num_sampler_views = !samplers[1] ? 1 : !samplers[2] ? 2 : 3;
 
-   c->pipe->bind_blend_state(c->pipe, c->blend);
-   for (i = 0; i < num_rects; ++i) {
-      c->pipe->bind_fs_state(c->pipe, frag_shaders[i]);
-      if (i == 0) {
-         c->pipe->set_fragment_sampler_views(c->pipe, 3, &src_sampler->y);
-      } else {
-         c->pipe->set_fragment_sampler_views(c->pipe, surfaces[i][1] ? 2 : 1, &surfaces[i][0]);
+         c->pipe->bind_fs_state(c->pipe, c->layers[i].fs);
+         c->pipe->set_fragment_sampler_views(c->pipe, num_sampler_views, samplers);
+         util_draw_arrays(c->pipe, PIPE_PRIM_QUADS, vb_index * 4, 4);
+         vb_index++;
       }
-
-      util_draw_arrays(c->pipe, PIPE_PRIM_QUADS, i * 4, 4);
    }
 }
 
-void vl_compositor_render(struct vl_compositor          *compositor,
-                          struct vl_ycbcr_sampler_views *src_sampler,
-                          struct pipe_video_rect        *src_area,
-                          struct pipe_surface           *dst_surface,
-                          struct pipe_video_rect        *dst_area,
-                          struct pipe_fence_handle      **fence)
+static void
+vl_compositor_clear_layers(struct pipe_video_compositor *compositor)
 {
-   void *samplers[3];
+   struct vl_compositor *c = (struct vl_compositor *)compositor;
+   unsigned i, j;
 
    assert(compositor);
-   assert(src_sampler);
-   assert(src_area);
-   assert(dst_surface);
-   assert(dst_area);
 
-   if (compositor->fb_state.width != dst_surface->width) {
-      compositor->fb_inv_size.x = 1.0f / dst_surface->width;
-      compositor->fb_state.width = dst_surface->width;
-   }
-   if (compositor->fb_state.height != dst_surface->height) {
-      compositor->fb_inv_size.y = 1.0f / dst_surface->height;
-      compositor->fb_state.height = dst_surface->height;
+   c->used_layers = 0;
+   for ( i = 0; i < VL_COMPOSITOR_MAX_LAYERS; ++i) {
+      c->layers[i].fs = NULL;
+      for ( j = 0; j < 3; j++)
+         pipe_sampler_view_reference(&c->layers[i].sampler_views[j], NULL);
    }
+}
 
-   compositor->fb_state.cbufs[0] = dst_surface;
-
-   compositor->viewport.scale[0] = compositor->fb_state.width;
-   compositor->viewport.scale[1] = compositor->fb_state.height;
-   compositor->viewport.scale[2] = 1;
-   compositor->viewport.scale[3] = 1;
-   compositor->viewport.translate[0] = 0;
-   compositor->viewport.translate[1] = 0;
-   compositor->viewport.translate[2] = 0;
-   compositor->viewport.translate[3] = 0;
-
-   samplers[0] = samplers[1] = samplers[2] = compositor->sampler;
+static void
+vl_compositor_destroy(struct pipe_video_compositor *compositor)
+{
+   struct vl_compositor *c = (struct vl_compositor *)compositor;
+   assert(compositor);
 
-   compositor->pipe->set_framebuffer_state(compositor->pipe, &compositor->fb_state);
-   compositor->pipe->set_viewport_state(compositor->pipe, &compositor->viewport);
-   compositor->pipe->bind_fragment_sampler_states(compositor->pipe, 3, &samplers[0]);
-   compositor->pipe->bind_vs_state(compositor->pipe, compositor->vertex_shader);
-   compositor->pipe->set_vertex_buffers(compositor->pipe, 1, &compositor->vertex_buf);
-   compositor->pipe->bind_vertex_elements_state(compositor->pipe, compositor->vertex_elems_state);
-   compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_FRAGMENT, 0, compositor->fs_const_buf);
+   vl_compositor_clear_layers(compositor);
 
-   draw_layers(compositor, src_sampler, src_area, dst_area);
+   cleanup_buffers(c);
+   cleanup_shaders(c);
+   cleanup_pipe_state(c);
 
-   assert(!compositor->dirty_layers);
-   compositor->pipe->flush(compositor->pipe, fence);
+   FREE(compositor);
 }
 
-void vl_compositor_set_csc_matrix(struct vl_compositor *compositor, const float *mat)
+static void
+vl_compositor_set_csc_matrix(struct pipe_video_compositor *compositor, const float matrix[16])
 {
+   struct vl_compositor *c = (struct vl_compositor *)compositor;
    struct pipe_transfer *buf_transfer;
 
    assert(compositor);
 
    memcpy
    (
-      pipe_buffer_map(compositor->pipe, compositor->fs_const_buf,
+      pipe_buffer_map(c->pipe, c->csc_matrix,
                       PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
                       &buf_transfer),
-		mat,
-		sizeof(struct fragment_shader_consts)
+		matrix,
+		sizeof(csc_matrix)
    );
 
-   pipe_buffer_unmap(compositor->pipe, buf_transfer);
+   pipe_buffer_unmap(c->pipe, buf_transfer);
+}
+
+static void
+vl_compositor_set_buffer_layer(struct pipe_video_compositor *compositor,
+                               unsigned layer,
+                               struct pipe_video_buffer *buffer,
+                               struct pipe_video_rect *src_rect,
+                               struct pipe_video_rect *dst_rect)
+{
+   struct vl_compositor *c = (struct vl_compositor *)compositor;
+   assert(compositor && buffer);
+
+   assert(layer < VL_COMPOSITOR_MAX_LAYERS);
+
+   c->used_layers |= 1 << layer;
+   c->layers[layer].fs = c->fs_video_buffer;
+   buffer->get_sampler_views(buffer, c->layers[layer].sampler_views);
+   c->layers[layer].src_rect = src_rect ? *src_rect : default_rect(&c->layers[layer]);
+   c->layers[layer].dst_rect = dst_rect ? *dst_rect : default_rect(&c->layers[layer]);
+}
+
+static void
+vl_compositor_set_palette_layer(struct pipe_video_compositor *compositor,
+                                unsigned layer,
+                                struct pipe_sampler_view *indexes,
+                                struct pipe_sampler_view *palette,
+                                struct pipe_video_rect *src_rect,
+                                struct pipe_video_rect *dst_rect)
+{
+   struct vl_compositor *c = (struct vl_compositor *)compositor;
+   assert(compositor && indexes && palette);
+
+   assert(layer < VL_COMPOSITOR_MAX_LAYERS);
+
+   c->used_layers |= 1 << layer;
+   c->layers[layer].fs = c->fs_palette;
+   pipe_sampler_view_reference(&c->layers[layer].sampler_views[0], indexes);
+   pipe_sampler_view_reference(&c->layers[layer].sampler_views[1], palette);
+   pipe_sampler_view_reference(&c->layers[layer].sampler_views[2], NULL);
+   c->layers[layer].src_rect = src_rect ? *src_rect : default_rect(&c->layers[layer]);
+   c->layers[layer].dst_rect = dst_rect ? *dst_rect : default_rect(&c->layers[layer]);
+}
+
+static void
+vl_compositor_set_rgba_layer(struct pipe_video_compositor *compositor,
+                             unsigned layer,
+                             struct pipe_sampler_view *rgba,
+                             struct pipe_video_rect *src_rect,
+                             struct pipe_video_rect *dst_rect)
+{
+   struct vl_compositor *c = (struct vl_compositor *)compositor;
+   assert(compositor && rgba);
+
+   assert(layer < VL_COMPOSITOR_MAX_LAYERS);
+
+   c->used_layers |= 1 << layer;
+   c->layers[layer].fs = c->fs_rgba;
+   pipe_sampler_view_reference(&c->layers[layer].sampler_views[0], rgba);
+   pipe_sampler_view_reference(&c->layers[layer].sampler_views[1], NULL);
+   pipe_sampler_view_reference(&c->layers[layer].sampler_views[2], NULL);
+   c->layers[layer].src_rect = src_rect ? *src_rect : default_rect(&c->layers[layer]);
+   c->layers[layer].dst_rect = dst_rect ? *dst_rect : default_rect(&c->layers[layer]);
+}
+
+static void
+vl_compositor_render(struct pipe_video_compositor *compositor,
+                     enum pipe_mpeg12_picture_type picture_type,
+                     struct pipe_surface           *dst_surface,
+                     struct pipe_video_rect        *dst_area,
+                     struct pipe_fence_handle      **fence)
+{
+   struct vl_compositor *c = (struct vl_compositor *)compositor;
+   struct vertex2f dst_inv_size;
+   void *samplers[3];
+
+   assert(compositor);
+   assert(dst_surface);
+   assert(dst_area);
+
+   c->fb_state.width = dst_surface->width;
+   c->fb_state.height = dst_surface->height;
+   c->fb_state.cbufs[0] = dst_surface;
+
+   c->viewport.scale[0] = dst_surface->width;
+   c->viewport.scale[1] = dst_surface->height;
+
+   dst_inv_size.x = 1.0f / dst_surface->width;
+   dst_inv_size.y = 1.0f / dst_surface->height;
+
+   samplers[0] = samplers[1] = samplers[2] = c->sampler;
+
+   gen_vertex_data(c, dst_area, &dst_inv_size);
+
+   c->pipe->set_framebuffer_state(c->pipe, &c->fb_state);
+   c->pipe->set_viewport_state(c->pipe, &c->viewport);
+   c->pipe->bind_fragment_sampler_states(c->pipe, 3, &samplers[0]);
+   c->pipe->bind_vs_state(c->pipe, c->vs);
+   c->pipe->set_vertex_buffers(c->pipe, 1, &c->vertex_buf);
+   c->pipe->bind_vertex_elements_state(c->pipe, c->vertex_elems_state);
+   c->pipe->set_constant_buffer(c->pipe, PIPE_SHADER_FRAGMENT, 0, c->csc_matrix);
+   c->pipe->bind_blend_state(c->pipe, c->blend);
+
+   draw_layers(c);
+
+   c->pipe->flush(c->pipe, fence);
+}
+
+struct pipe_video_compositor *
+vl_compositor_init(struct pipe_video_context *vpipe, struct pipe_context *pipe)
+{
+   csc_matrix csc_matrix;
+   struct vl_compositor *compositor;
+
+   compositor = CALLOC_STRUCT(vl_compositor);
+
+   compositor->base.context = vpipe;
+   compositor->base.destroy = vl_compositor_destroy;
+   compositor->base.set_csc_matrix = vl_compositor_set_csc_matrix;
+   compositor->base.clear_layers = vl_compositor_clear_layers;
+   compositor->base.set_buffer_layer = vl_compositor_set_buffer_layer;
+   compositor->base.set_palette_layer = vl_compositor_set_palette_layer;
+   compositor->base.set_rgba_layer = vl_compositor_set_rgba_layer;
+   compositor->base.render_picture = vl_compositor_render;
+
+   compositor->pipe = pipe;
+
+   if (!init_pipe_state(compositor))
+      return false;
+
+   if (!init_shaders(compositor)) {
+      cleanup_pipe_state(compositor);
+      return false;
+   }
+   if (!init_buffers(compositor)) {
+      cleanup_shaders(compositor);
+      cleanup_pipe_state(compositor);
+      return false;
+   }
+
+   vl_compositor_clear_layers(&compositor->base);
+
+   vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_IDENTITY, NULL, true, csc_matrix);
+   vl_compositor_set_csc_matrix(&compositor->base, csc_matrix);
+
+   return &compositor->base;
 }
diff --git a/src/gallium/auxiliary/vl/vl_compositor.h b/src/gallium/auxiliary/vl/vl_compositor.h
index e10a663..0e4badb 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.h
+++ b/src/gallium/auxiliary/vl/vl_compositor.h
@@ -28,63 +28,46 @@
 #ifndef vl_compositor_h
 #define vl_compositor_h
 
-#include <pipe/p_compiler.h>
 #include <pipe/p_state.h>
+#include <pipe/p_video_context.h>
 #include <pipe/p_video_state.h>
-#include "vl_types.h"
-#include "vl_ycbcr_buffer.h"
 
 struct pipe_context;
-struct keymap;
 
 #define VL_COMPOSITOR_MAX_LAYERS 16
 
+struct vl_compositor_layer
+{
+   void *fs;
+   struct pipe_sampler_view *sampler_views[3];
+   struct pipe_video_rect src_rect;
+   struct pipe_video_rect dst_rect;
+};
+
 struct vl_compositor
 {
+   struct pipe_video_compositor base;
    struct pipe_context *pipe;
 
    struct pipe_framebuffer_state fb_state;
-   struct vertex2f fb_inv_size;
-   void *sampler;
-   void *blend;
-   struct pipe_sampler_view *sampler_view;
-   void *vertex_shader;
-   struct
-   {
-      void *ycbcr_2_rgb;
-      void *rgb_2_rgb;
-      void *palette_2_rgb;
-   } fragment_shader;
    struct pipe_viewport_state viewport;
    struct pipe_vertex_buffer vertex_buf;
-   void *vertex_elems_state;
-   struct pipe_resource *fs_const_buf;
+   struct pipe_resource *csc_matrix;
 
-   struct pipe_sampler_view *layers[VL_COMPOSITOR_MAX_LAYERS];
-   struct pipe_sampler_view *palettes[VL_COMPOSITOR_MAX_LAYERS];
-   struct pipe_video_rect layer_src_rects[VL_COMPOSITOR_MAX_LAYERS];
-   struct pipe_video_rect layer_dst_rects[VL_COMPOSITOR_MAX_LAYERS];
-   unsigned dirty_layers;
-};
-
-bool vl_compositor_init(struct vl_compositor *compositor, struct pipe_context *pipe);
-
-void vl_compositor_cleanup(struct vl_compositor *compositor);
+   void *sampler;
+   void *blend;
+   void *vertex_elems_state;
 
-void vl_compositor_set_layers(struct vl_compositor *compositor,
-                              struct pipe_sampler_view *layers[],
-                              struct pipe_sampler_view *palettes[],
-                              struct pipe_video_rect *src_rects[],
-                              struct pipe_video_rect *dst_rects[],
-                              unsigned num_layers);
+   void *vs;
+   void *fs_video_buffer;
+   void *fs_palette;
+   void *fs_rgba;
 
-void vl_compositor_render(struct vl_compositor          *compositor,
-                          struct vl_ycbcr_sampler_views *src_sampler,
-                          struct pipe_video_rect        *src_area,
-                          struct pipe_surface           *dst_surface,
-                          struct pipe_video_rect        *dst_area,
-                          struct pipe_fence_handle      **fence);
+   unsigned used_layers:VL_COMPOSITOR_MAX_LAYERS;
+   struct vl_compositor_layer layers[VL_COMPOSITOR_MAX_LAYERS];
+};
 
-void vl_compositor_set_csc_matrix(struct vl_compositor *compositor, const float *mat);
+struct pipe_video_compositor *vl_compositor_init(struct pipe_video_context *vpipe,
+                                                 struct pipe_context *pipe);
 
 #endif /* vl_compositor_h */
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_context.c b/src/gallium/auxiliary/vl/vl_mpeg12_context.c
index be598a8..d860539 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_context.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_context.c
@@ -222,6 +222,24 @@ vl_mpeg12_buffer_flush(struct pipe_video_buffer *buffer,
 }
 
 static void
+vl_mpeg12_buffer_get_sampler_views(struct pipe_video_buffer *buffer,
+                                   struct pipe_sampler_view *sampler_views[3])
+{
+   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
+   struct vl_ycbcr_sampler_views *samplers;
+
+   assert(buf);
+
+   samplers = vl_ycbcr_get_sampler_views(&buf->render_result);
+
+   assert(samplers);
+
+   pipe_sampler_view_reference(&sampler_views[0], samplers->y);
+   pipe_sampler_view_reference(&sampler_views[1], samplers->cb);
+   pipe_sampler_view_reference(&sampler_views[2], samplers->cr);
+}
+
+static void
 vl_mpeg12_destroy(struct pipe_video_context *vpipe)
 {
    struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
@@ -236,7 +254,6 @@ vl_mpeg12_destroy(struct pipe_video_context *vpipe)
    ctx->pipe->delete_rasterizer_state(ctx->pipe, ctx->rast);
    ctx->pipe->delete_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
 
-   vl_compositor_cleanup(&ctx->compositor);
    vl_mpeg12_mc_renderer_cleanup(&ctx->mc);
    vl_idct_cleanup(&ctx->idct_y);
    vl_idct_cleanup(&ctx->idct_c);
@@ -308,6 +325,7 @@ vl_mpeg12_create_buffer(struct pipe_video_context *vpipe)
    buffer->base.add_macroblocks = vl_mpeg12_buffer_add_macroblocks;
    buffer->base.unmap = vl_mpeg12_buffer_unmap;
    buffer->base.flush = vl_mpeg12_buffer_flush;
+   buffer->base.get_sampler_views = vl_mpeg12_buffer_get_sampler_views;
 
    buffer->vertex_bufs.individual.quad.stride = ctx->quads.stride;
    buffer->vertex_bufs.individual.quad.buffer_offset = ctx->quads.buffer_offset;
@@ -494,56 +512,14 @@ error_map:
    ctx->pipe->transfer_destroy(ctx->pipe, transfer);
 }
 
-static void
-vl_mpeg12_render_picture(struct pipe_video_context     *vpipe,
-                         struct pipe_video_buffer      *src_surface,
-                         struct pipe_video_rect        *src_area,
-                         enum pipe_mpeg12_picture_type picture_type,
-                         struct pipe_surface           *dst_surface,
-                         struct pipe_video_rect        *dst_area,
-                         struct pipe_fence_handle      **fence)
+static struct pipe_video_compositor *
+vl_mpeg12_create_compositor(struct pipe_video_context *vpipe)
 {
    struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
-   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)src_surface;
-   struct vl_ycbcr_sampler_views *sampler_views;
 
    assert(vpipe);
-   assert(src_surface);
-   assert(src_area);
-   assert(dst_surface);
-   assert(dst_area);
-
-   sampler_views = vl_ycbcr_get_sampler_views(&buf->render_result);
 
-   vl_compositor_render(&ctx->compositor, sampler_views, src_area,
-                        dst_surface, dst_area, fence);
-}
-
-static void
-vl_mpeg12_set_picture_layers(struct pipe_video_context *vpipe,
-                             struct pipe_sampler_view *layers[],
-                             struct pipe_sampler_view *palettes[],
-                             struct pipe_video_rect *src_rects[],
-                             struct pipe_video_rect *dst_rects[],
-                             unsigned num_layers)
-{
-   struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
-
-   assert(vpipe);
-   assert((layers && src_rects && dst_rects) ||
-          (!layers && !src_rects && !dst_rects));
-
-   vl_compositor_set_layers(&ctx->compositor, layers, palettes, src_rects, dst_rects, num_layers);
-}
-
-static void
-vl_mpeg12_set_csc_matrix(struct pipe_video_context *vpipe, const float *mat)
-{
-   struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
-
-   assert(vpipe);
-
-   vl_compositor_set_csc_matrix(&ctx->compositor, mat);
+   return vl_compositor_init(vpipe, ctx->pipe);
 }
 
 static bool
@@ -707,11 +683,9 @@ vl_create_mpeg12_context(struct pipe_context *pipe,
    ctx->base.create_surface = vl_mpeg12_create_surface;
    ctx->base.create_sampler_view = vl_mpeg12_create_sampler_view;
    ctx->base.create_buffer = vl_mpeg12_create_buffer;
-   ctx->base.render_picture = vl_mpeg12_render_picture;
    ctx->base.clear_sampler = vl_mpeg12_clear_sampler;
    ctx->base.upload_sampler = vl_mpeg12_upload_sampler;
-   ctx->base.set_picture_layers = vl_mpeg12_set_picture_layers;
-   ctx->base.set_csc_matrix = vl_mpeg12_set_csc_matrix;
+   ctx->base.create_compositor = vl_mpeg12_create_compositor;
 
    ctx->pipe = pipe;
    ctx->pot_buffers = pot_buffers;
@@ -731,26 +705,20 @@ vl_create_mpeg12_context(struct pipe_context *pipe,
    if (!vl_mpeg12_mc_renderer_init(&ctx->mc, ctx->pipe, ctx->buffer_width, ctx->buffer_height))
       goto error_mc;
 
-   if (!vl_compositor_init(&ctx->compositor, ctx->pipe))
-      goto error_compositor;
-
    if (!init_pipe_state(ctx))
       goto error_pipe_state;
 
    return &ctx->base;
 
 error_pipe_state:
-      vl_compositor_cleanup(&ctx->compositor);
-
-error_compositor:
-      vl_mpeg12_mc_renderer_cleanup(&ctx->mc);
+   vl_mpeg12_mc_renderer_cleanup(&ctx->mc);
 
 error_mc:
-      vl_idct_cleanup(&ctx->idct_y);
-      vl_idct_cleanup(&ctx->idct_c);
+   vl_idct_cleanup(&ctx->idct_y);
+   vl_idct_cleanup(&ctx->idct_c);
 
 error_idct:
-      ctx->pipe->destroy(ctx->pipe);
-      FREE(ctx);
-      return NULL;
+   ctx->pipe->destroy(ctx->pipe);
+   FREE(ctx);
+   return NULL;
 }
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_context.h b/src/gallium/auxiliary/vl/vl_mpeg12_context.h
index 3cc0529..a90110b 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_context.h
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_context.h
@@ -52,7 +52,6 @@ struct vl_mpeg12_context
 
    struct vl_idct idct_y, idct_c;
    struct vl_mpeg12_mc_renderer mc;
-   struct vl_compositor compositor;
 
    void *rast;
    void *dsa;
diff --git a/src/gallium/include/pipe/p_video_context.h b/src/gallium/include/pipe/p_video_context.h
index 7786f0a..dec524d 100644
--- a/src/gallium/include/pipe/p_video_context.h
+++ b/src/gallium/include/pipe/p_video_context.h
@@ -109,12 +109,18 @@ struct pipe_video_context
                          struct pipe_sampler_view *dst,
                          const struct pipe_box *dst_box,
                          const float *rgba);
+
    /**
     * Creates a buffer as decoding target
     */
    struct pipe_video_buffer *(*create_buffer)(struct pipe_video_context *vpipe);
 
    /**
+    * Creates a video compositor
+    */
+   struct pipe_video_compositor *(*create_compositor)(struct pipe_video_context *vpipe);
+
+   /**
     * Picture decoding and displaying
     */
 
@@ -124,38 +130,6 @@ struct pipe_video_context
                             struct pipe_buffer **bitstream_buf);
 #endif
 
-   /**
-    * render a video buffer to the frontbuffer
-    */
-   void (*render_picture)(struct pipe_video_context     *vpipe,
-                          struct pipe_video_buffer      *src_surface,
-                          struct pipe_video_rect        *src_area,
-                          enum pipe_mpeg12_picture_type picture_type,
-                          struct pipe_surface           *dst_surface,
-                          struct pipe_video_rect        *dst_area,
-                          struct pipe_fence_handle      **fence);
-
-   /*@}*/
-
-   /**
-    * Parameter-like states (or properties)
-    */
-   /*@{*/
-
-   /**
-    * set overlay samplers
-    */
-   void (*set_picture_layers)(struct pipe_video_context *vpipe,
-                              struct pipe_sampler_view *layers[],
-                              struct pipe_sampler_view *palettes[],
-                              struct pipe_video_rect *src_rects[],
-                              struct pipe_video_rect *dst_rects[],
-                              unsigned num_layers);
-
-   void (*set_csc_matrix)(struct pipe_video_context *vpipe, const float *mat);
-
-   /* TODO: Interface for scaling modes, post-processing, etc. */
-   /*@}*/
 };
 
 struct pipe_video_buffer
@@ -191,6 +165,74 @@ struct pipe_video_buffer
                  struct pipe_video_buffer *ref_frames[2],
                  struct pipe_fence_handle **fence);
 
+
+   void (*get_sampler_views)(struct pipe_video_buffer *buffer,
+                             struct pipe_sampler_view *sampler_views[3]);
+};
+
+struct pipe_video_compositor
+{
+   struct pipe_video_context* context;
+
+   /**
+    * destroy this compositor
+    */
+   void (*destroy)(struct pipe_video_compositor *compositor);
+
+   /**
+    * set yuv -> rgba conversion matrix
+    */
+   void (*set_csc_matrix)(struct pipe_video_compositor *compositor, const float mat[16]);
+
+   /**
+    * set overlay samplers
+    */
+   /*@{*/
+
+   /**
+    * reset all currently set layers
+    */
+   void (*clear_layers)(struct pipe_video_compositor *compositor);
+
+   /**
+    * set a video buffer as a layer to render
+    */
+   void (*set_buffer_layer)(struct pipe_video_compositor *compositor,
+                            unsigned layer,
+                            struct pipe_video_buffer *buffer,
+                            struct pipe_video_rect *src_rect,
+                            struct pipe_video_rect *dst_rect);
+
+   /**
+    * set a paletted sampler as a layer to render
+    */
+   void (*set_palette_layer)(struct pipe_video_compositor *compositor,
+                             unsigned layer,
+                             struct pipe_sampler_view *indexes,
+                             struct pipe_sampler_view *palette,
+                             struct pipe_video_rect *src_rect,
+                             struct pipe_video_rect *dst_rect);
+
+   /**
+    * set a rgba sampler as a layer to render
+    */
+   void (*set_rgba_layer)(struct pipe_video_compositor *compositor,
+                          unsigned layer,
+                          struct pipe_sampler_view *rgba,
+                          struct pipe_video_rect *src_rect,
+                          struct pipe_video_rect *dst_rect);
+
+   /*@}*/
+
+   /**
+    * render the layers to the frontbuffer
+    */
+   void (*render_picture)(struct pipe_video_compositor  *compositor,
+                          enum pipe_mpeg12_picture_type picture_type,
+                          struct pipe_surface           *dst_surface,
+                          struct pipe_video_rect        *dst_area,
+                          struct pipe_fence_handle      **fence);
+
 };
 
 #ifdef __cplusplus
diff --git a/src/gallium/state_trackers/xorg/xvmc/context.c b/src/gallium/state_trackers/xorg/xvmc/context.c
index bcfd085..bdcba72 100644
--- a/src/gallium/state_trackers/xorg/xvmc/context.c
+++ b/src/gallium/state_trackers/xorg/xvmc/context.c
@@ -241,6 +241,15 @@ Status XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id,
       return BadAlloc;
    }
 
+   context_priv->compositor = vctx->vpipe->create_compositor(vctx->vpipe);
+   if (!context_priv->compositor) {
+      XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL compositor.\n");
+      vl_video_destroy(vctx);
+      vl_screen_destroy(vscreen);
+      FREE(context_priv);
+      return BadAlloc;
+   }
+
    /* TODO: Define some Xv attribs to allow users to specify color standard, procamp */
    vl_csc_get_matrix
    (
@@ -248,7 +257,7 @@ Status XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id,
       VL_CSC_COLOR_STANDARD_IDENTITY : VL_CSC_COLOR_STANDARD_BT_601,
       NULL, true, csc
    );
-   vctx->vpipe->set_csc_matrix(vctx->vpipe, csc);
+   context_priv->compositor->set_csc_matrix(context_priv->compositor, csc);
 
    context_priv->vctx = vctx;
    context_priv->subpicture_max_width = subpic_max_w;
@@ -286,6 +295,7 @@ Status XvMCDestroyContext(Display *dpy, XvMCContext *context)
    context_priv = context->privData;
    vctx = context_priv->vctx;
    vscreen = vctx->vscreen;
+   context_priv->compositor->destroy(context_priv->compositor);
    vl_video_destroy(vctx);
    vl_screen_destroy(vscreen);
    FREE(context_priv);
diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c
index 23f97b3..679b5cf 100644
--- a/src/gallium/state_trackers/xorg/xvmc/surface.c
+++ b/src/gallium/state_trackers/xorg/xvmc/surface.c
@@ -343,6 +343,8 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
    static int dump_window = -1;
 
    struct pipe_video_context *vpipe;
+   struct pipe_video_compositor *compositor;
+
    XvMCSurfacePrivate *surface_priv;
    XvMCContextPrivate *context_priv;
    XvMCSubpicturePrivate *subpicture_priv;
@@ -383,27 +385,30 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
 
    subpicture_priv = surface_priv->subpicture ? surface_priv->subpicture->privData : NULL;
    vpipe = context_priv->vctx->vpipe;
+   compositor = context_priv->compositor;
+
+   unmap_and_flush_surface(surface_priv);
+
+   compositor->clear_layers(compositor);
+   compositor->set_buffer_layer(compositor, 0, surface_priv->pipe_buffer, &src_rect, NULL);
 
    if (subpicture_priv) {
       struct pipe_video_rect src_rect = {surface_priv->subx, surface_priv->suby, surface_priv->subw, surface_priv->subh};
       struct pipe_video_rect dst_rect = {surface_priv->surfx, surface_priv->surfy, surface_priv->surfw, surface_priv->surfh};
-      struct pipe_video_rect *src_rects[1] = {&src_rect};
-      struct pipe_video_rect *dst_rects[1] = {&dst_rect};
 
       XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p has subpicture %p.\n", surface, surface_priv->subpicture);
 
       assert(subpicture_priv->surface == surface);
-      vpipe->set_picture_layers(vpipe, &subpicture_priv->sampler, &subpicture_priv->palette, src_rects, dst_rects, 1);
+      if (subpicture_priv->palette)
+         compositor->set_palette_layer(compositor, 1, subpicture_priv->sampler, subpicture_priv->palette, &src_rect, &dst_rect);
+      else
+         compositor->set_rgba_layer(compositor, 1, subpicture_priv->sampler, &src_rect, &dst_rect);
 
       surface_priv->subpicture = NULL;
       subpicture_priv->surface = NULL;
    }
-   else
-      vpipe->set_picture_layers(vpipe, NULL, NULL, NULL, NULL, 0);
 
-   unmap_and_flush_surface(surface_priv);
-   vpipe->render_picture(vpipe, surface_priv->pipe_buffer, &src_rect, PictureToPipe(flags),
-                         drawable_surface, &dst_rect, &surface_priv->disp_fence);
+   compositor->render_picture(compositor, PictureToPipe(flags), drawable_surface, &dst_rect, &surface_priv->disp_fence);
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for display. Pushing to front buffer.\n", surface);
 
diff --git a/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h b/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h
index 330c8c2..29518b3 100644
--- a/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h
+++ b/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h
@@ -42,6 +42,8 @@ struct pipe_fence_handle;
 typedef struct
 {
    struct vl_context *vctx;
+   struct pipe_video_compositor *compositor;
+
    unsigned short subpicture_max_width;
    unsigned short subpicture_max_height;
 } XvMCContextPrivate;



More information about the mesa-commit mailing list