Mesa (pipe-video): [g3dvl] make mapping and flushing of buffers a public interface

Christian König deathsimple at kemper.freedesktop.org
Thu Mar 24 20:25:42 UTC 2011


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

Author: Christian König <deathsimple at vodafone.de>
Date:   Thu Mar 24 20:33:32 2011 +0100

[g3dvl] make mapping and flushing of buffers a public interface

---

 src/gallium/auxiliary/vl/vl_mpeg12_context.c       |  151 +++++++++-----------
 src/gallium/auxiliary/vl/vl_mpeg12_context.h       |    1 -
 src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c   |   62 ++------
 src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h   |   16 +--
 src/gallium/include/pipe/p_video_context.h         |   12 +-
 src/gallium/state_trackers/xorg/xvmc/surface.c     |   66 +++++++--
 .../state_trackers/xorg/xvmc/xvmc_private.h        |    5 +
 7 files changed, 156 insertions(+), 157 deletions(-)

diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_context.c b/src/gallium/auxiliary/vl/vl_mpeg12_context.c
index 73e2a95..4c0188c 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_context.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_context.c
@@ -45,63 +45,6 @@ static const unsigned const_empty_block_mask_420[3][2][2] = {
 };
 
 static void
-map_buffer(struct vl_mpeg12_buffer *buf)
-{
-   struct vl_mpeg12_context *ctx;
-   assert(buf);
-
-   ctx = (struct vl_mpeg12_context *)buf->base.context;
-   assert(ctx);
-
-   if (!buf->mapped) {
-      vl_vb_map(&buf->vertex_stream, ctx->pipe);
-      vl_idct_map_buffers(&ctx->idct_y, &buf->idct_y);
-      vl_idct_map_buffers(&ctx->idct_cr, &buf->idct_cr);
-      vl_idct_map_buffers(&ctx->idct_cb, &buf->idct_cb);
-      buf->mapped = 1;
-   }
-}
-
-static void
-unmap_buffer(struct vl_mpeg12_buffer *buf)
-{
-   struct vl_mpeg12_context *ctx;
-   assert(buf);
-
-   ctx = (struct vl_mpeg12_context *)buf->base.context;
-   assert(ctx);
-
-   if (buf->mapped) {
-      vl_vb_unmap(&buf->vertex_stream, ctx->pipe);
-      vl_idct_unmap_buffers(&ctx->idct_y, &buf->idct_y);
-      vl_idct_unmap_buffers(&ctx->idct_cr, &buf->idct_cr);
-      vl_idct_unmap_buffers(&ctx->idct_cb, &buf->idct_cb);
-      buf->mapped = 0;
-   }
-}
-
-static void
-flush_buffer(struct vl_mpeg12_buffer *buf)
-{
-   unsigned ne_start, ne_num, e_start, e_num;
-   struct vl_mpeg12_context *ctx;
-   assert(buf);
-
-   ctx = (struct vl_mpeg12_context *)buf->base.context;
-   assert(ctx);
-
-   vl_vb_restart(&buf->vertex_stream, &ne_start, &ne_num, &e_start, &e_num);
-
-   ctx->pipe->set_vertex_buffers(ctx->pipe, 2, buf->vertex_bufs.all);
-   ctx->pipe->bind_vertex_elements_state(ctx->pipe, ctx->vertex_elems_state);
-   vl_idct_flush(&ctx->idct_y, &buf->idct_y, ne_num);
-   vl_idct_flush(&ctx->idct_cr, &buf->idct_cr, ne_num);
-   vl_idct_flush(&ctx->idct_cb, &buf->idct_cb, ne_num);
-   vl_mpeg12_mc_renderer_flush(&ctx->mc_renderer, &buf->mc,
-                               ne_start, ne_num, e_start, e_num);
-}
-
-static void
 upload_buffer(struct vl_mpeg12_context *ctx,
               struct vl_mpeg12_buffer *buffer,
               struct pipe_mpeg12_macroblock *mb)
@@ -149,24 +92,35 @@ vl_mpeg12_buffer_destroy(struct pipe_video_buffer *buffer)
    vl_idct_cleanup_buffer(&ctx->idct_y, &buf->idct_y);
    vl_idct_cleanup_buffer(&ctx->idct_cb, &buf->idct_cb);
    vl_idct_cleanup_buffer(&ctx->idct_cr, &buf->idct_cr);
-   vl_mpeg12_mc_cleanup_buffer(&ctx->mc_renderer, &buf->mc);
+   vl_mpeg12_mc_cleanup_buffer(&buf->mc);
    pipe_surface_reference(&buf->surface, NULL);
 
    FREE(buf);
 }
 
 static void
+vl_mpeg12_buffer_map(struct pipe_video_buffer *buffer)
+{
+   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
+   struct vl_mpeg12_context *ctx;
+   assert(buf);
+
+   ctx = (struct vl_mpeg12_context *)buf->base.context;
+   assert(ctx);
+
+   vl_vb_map(&buf->vertex_stream, ctx->pipe);
+   vl_idct_map_buffers(&ctx->idct_y, &buf->idct_y);
+   vl_idct_map_buffers(&ctx->idct_cr, &buf->idct_cr);
+   vl_idct_map_buffers(&ctx->idct_cb, &buf->idct_cb);
+}
+
+static void
 vl_mpeg12_buffer_add_macroblocks(struct pipe_video_buffer *buffer,
-                                 struct pipe_video_buffer *past,
-                                 struct pipe_video_buffer *future,
                                  unsigned num_macroblocks,
-                                 struct pipe_macroblock *macroblocks,
-                                 struct pipe_fence_handle **fence)
+                                 struct pipe_macroblock *macroblocks)
 {
    struct pipe_mpeg12_macroblock *mpeg12_macroblocks = (struct pipe_mpeg12_macroblock*)macroblocks;
    struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
-   struct vl_mpeg12_buffer *buf_past = (struct vl_mpeg12_buffer*)past;
-   struct vl_mpeg12_buffer *buf_future = (struct vl_mpeg12_buffer*)future;
    struct vl_mpeg12_context *ctx;
    unsigned i;
 
@@ -179,28 +133,61 @@ vl_mpeg12_buffer_add_macroblocks(struct pipe_video_buffer *buffer,
    assert(macroblocks);
    assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12);
 
-   map_buffer(buf);
-
    for ( i = 0; i < num_macroblocks; ++i ) {
       vl_vb_add_block(&buf->vertex_stream, &mpeg12_macroblocks[i], ctx->empty_block_mask);
       upload_buffer(ctx, buf, &mpeg12_macroblocks[i]);
    }
+}
 
-   // TODO this doesn't belong here
-   if (buf_past) {
-      unmap_buffer(buf_past);
-      flush_buffer(buf_past);
-   }
+static void
+vl_mpeg12_buffer_unmap(struct pipe_video_buffer *buffer)
+{
+   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
+   struct vl_mpeg12_context *ctx;
+   assert(buf);
 
-   if (buf_future) {
-      unmap_buffer(buf_future);
-      flush_buffer(buf_future);
-   }
+   ctx = (struct vl_mpeg12_context *)buf->base.context;
+   assert(ctx);
 
-   vl_mpeg12_mc_set_surfaces(&ctx->mc_renderer, &buf->mc, buf->surface,
-                             buf_past ? buf_past->surface : NULL,
-                             buf_future ? buf_future->surface : NULL,
-                             fence);
+   vl_vb_unmap(&buf->vertex_stream, ctx->pipe);
+   vl_idct_unmap_buffers(&ctx->idct_y, &buf->idct_y);
+   vl_idct_unmap_buffers(&ctx->idct_cr, &buf->idct_cr);
+   vl_idct_unmap_buffers(&ctx->idct_cb, &buf->idct_cb);
+}
+
+static void
+vl_mpeg12_buffer_flush(struct pipe_video_buffer *buffer,
+                       struct pipe_video_buffer *refs[2],
+                       struct pipe_fence_handle **fence)
+{
+   struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer *)buffer;
+   struct vl_mpeg12_buffer *past = (struct vl_mpeg12_buffer *)refs[0];
+   struct vl_mpeg12_buffer *future = (struct vl_mpeg12_buffer *)refs[1];
+
+   struct pipe_surface *surf_refs[2];
+   unsigned ne_start, ne_num, e_start, e_num;
+   struct vl_mpeg12_context *ctx;
+
+   assert(buf);
+
+   ctx = (struct vl_mpeg12_context *)buf->base.context;
+   assert(ctx);
+
+   vl_vb_restart(&buf->vertex_stream, &ne_start, &ne_num, &e_start, &e_num);
+
+   ctx->pipe->set_vertex_buffers(ctx->pipe, 2, buf->vertex_bufs.all);
+   ctx->pipe->bind_vertex_elements_state(ctx->pipe, ctx->vertex_elems_state);
+   vl_idct_flush(&ctx->idct_y, &buf->idct_y, ne_num);
+   vl_idct_flush(&ctx->idct_cr, &buf->idct_cr, ne_num);
+   vl_idct_flush(&ctx->idct_cb, &buf->idct_cb, ne_num);
+
+   surf_refs[0] = past ? past->surface : NULL;
+   surf_refs[1] = future ? future->surface : NULL;
+
+   vl_mpeg12_mc_renderer_flush(&ctx->mc_renderer, &buf->mc,
+                               buf->surface, surf_refs,
+                               ne_start, ne_num, e_start, e_num,
+                               fence);
 }
 
 static void
@@ -280,7 +267,10 @@ vl_mpeg12_create_buffer(struct pipe_video_context *vpipe)
 
    buffer->base.context = vpipe;
    buffer->base.destroy = vl_mpeg12_buffer_destroy;
+   buffer->base.map = vl_mpeg12_buffer_map;
    buffer->base.add_macroblocks = vl_mpeg12_buffer_add_macroblocks;
+   buffer->base.unmap = vl_mpeg12_buffer_unmap;
+   buffer->base.flush = vl_mpeg12_buffer_flush;
 
    memset(&res_template, 0, sizeof(res_template));
    res_template.target = PIPE_TEXTURE_2D;
@@ -508,9 +498,6 @@ vl_mpeg12_render_picture(struct pipe_video_context     *vpipe,
    assert(dst_surface);
    assert(dst_area);
 
-   unmap_buffer(buf);
-   flush_buffer(buf);
-
    vl_compositor_render(&ctx->compositor, buf->surface,
                         picture_type, src_area,
                         dst_surface, dst_area, fence);
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_context.h b/src/gallium/auxiliary/vl/vl_mpeg12_context.h
index b2097c2..7269fa9 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_context.h
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_context.h
@@ -63,7 +63,6 @@ struct vl_mpeg12_buffer
 {
    struct pipe_video_buffer base;
    struct pipe_surface *surface;
-   bool mapped;
 
    struct vl_vertex_buffer vertex_stream;
 
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
index 6cd811b..2f2c787 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
@@ -282,7 +282,7 @@ fetch_ref(struct ureg_program *shader, struct ureg_dst field)
    struct ureg_src info;
    struct ureg_src tc[4], sampler[2];
    struct ureg_dst ref[2], result;
-   unsigned i, intra_label, bi_label, label;
+   unsigned i, intra_label;
 
    info = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_INFO, TGSI_INTERPOLATE_CONSTANT);
 
@@ -549,10 +549,6 @@ vl_mpeg12_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg1
 
    assert(renderer && buffer);
 
-   buffer->surface = NULL;
-   buffer->past = NULL;
-   buffer->future = NULL;
-
    pipe_resource_reference(&buffer->textures.individual.y, y);
    pipe_resource_reference(&buffer->textures.individual.cr, cr);
    pipe_resource_reference(&buffer->textures.individual.cb, cb);
@@ -573,70 +569,45 @@ vl_mpeg12_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg1
 }
 
 void
-vl_mpeg12_mc_cleanup_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer)
+vl_mpeg12_mc_cleanup_buffer(struct vl_mpeg12_mc_buffer *buffer)
 {
    unsigned i;
 
-   assert(renderer && buffer);
+   assert(buffer);
 
    for (i = 0; i < 3; ++i) {
       pipe_sampler_view_reference(&buffer->sampler_views.all[i], NULL);
       pipe_resource_reference(&buffer->textures.all[i], NULL);
    }
-
-   pipe_surface_reference(&buffer->surface, NULL);
-   pipe_surface_reference(&buffer->past, NULL);
-   pipe_surface_reference(&buffer->future, NULL);
-}
-
-void
-vl_mpeg12_mc_set_surfaces(struct vl_mpeg12_mc_renderer *renderer,
-                          struct vl_mpeg12_mc_buffer *buffer,
-                          struct pipe_surface *surface,
-                          struct pipe_surface *past,
-                          struct pipe_surface *future,
-                          struct pipe_fence_handle **fence)
-{
-   assert(renderer && buffer);
-   assert(surface);
-
-   if (surface != buffer->surface) {
-      pipe_surface_reference(&buffer->surface, surface);
-      pipe_surface_reference(&buffer->past, past);
-      pipe_surface_reference(&buffer->future, future);
-      buffer->fence = fence;
-   } else {
-      /* If the surface we're rendering hasn't changed the ref frames shouldn't change. */
-      assert(buffer->past == past);
-      assert(buffer->future == future);
-   }
 }
 
 void
 vl_mpeg12_mc_renderer_flush(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer,
+                            struct pipe_surface *surface, struct pipe_surface *ref[2],
                             unsigned not_empty_start_instance, unsigned not_empty_num_instances,
-                            unsigned empty_start_instance, unsigned empty_num_instances)
+                            unsigned empty_start_instance, unsigned empty_num_instances,
+                            struct pipe_fence_handle **fence)
 {
    assert(renderer && buffer);
 
    if (not_empty_num_instances == 0 && empty_num_instances == 0)
       return;
 
-   renderer->fb_state.cbufs[0] = buffer->surface;
+   renderer->fb_state.cbufs[0] = surface;
    renderer->pipe->bind_rasterizer_state(renderer->pipe, renderer->rs_state);
    renderer->pipe->set_framebuffer_state(renderer->pipe, &renderer->fb_state);
    renderer->pipe->set_viewport_state(renderer->pipe, &renderer->viewport);
 
-   if (buffer->past) {
-      buffer->sampler_views.individual.ref[0] = find_or_create_sampler_view(renderer, buffer->past);
+   if (ref[0]) {
+      buffer->sampler_views.individual.ref[0] = find_or_create_sampler_view(renderer, ref[0]);
    } else {
-      buffer->sampler_views.individual.ref[0] = find_or_create_sampler_view(renderer, buffer->surface);
+      buffer->sampler_views.individual.ref[0] = find_or_create_sampler_view(renderer, surface);
    }
 
-   if (buffer->future) {
-      buffer->sampler_views.individual.ref[1] = find_or_create_sampler_view(renderer, buffer->future);
+   if (ref[1]) {
+      buffer->sampler_views.individual.ref[1] = find_or_create_sampler_view(renderer, ref[1]);
    } else {
-      buffer->sampler_views.individual.ref[1] = find_or_create_sampler_view(renderer, buffer->surface);
+      buffer->sampler_views.individual.ref[1] = find_or_create_sampler_view(renderer, surface);
    }
 
    renderer->pipe->set_fragment_sampler_views(renderer->pipe, 5, buffer->sampler_views.all);
@@ -653,10 +624,5 @@ vl_mpeg12_mc_renderer_flush(struct vl_mpeg12_mc_renderer *renderer, struct vl_mp
       util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4,
                                  empty_start_instance, empty_num_instances);
 
-   renderer->pipe->flush(renderer->pipe, buffer->fence);
-
-   /* Next time we get this surface it may have new ref frames */
-   pipe_surface_reference(&buffer->surface, NULL);
-   pipe_surface_reference(&buffer->past, NULL);
-   pipe_surface_reference(&buffer->future, NULL);
+   renderer->pipe->flush(renderer->pipe, fence);
 }
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h
index b761961..fa81c77 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h
@@ -73,9 +73,6 @@ struct vl_mpeg12_mc_buffer
       struct pipe_resource *all[3];
       struct { struct pipe_resource *y, *cb, *cr; } individual;
    } textures;
-
-   struct pipe_surface *surface, *past, *future;
-   struct pipe_fence_handle **fence;
 };
 
 bool vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
@@ -89,17 +86,12 @@ void vl_mpeg12_mc_renderer_cleanup(struct vl_mpeg12_mc_renderer *renderer);
 bool vl_mpeg12_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer,
                               struct pipe_resource *y, struct pipe_resource *cr, struct pipe_resource *cb);
 
-void vl_mpeg12_mc_cleanup_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer);
-
-void vl_mpeg12_mc_set_surfaces(struct vl_mpeg12_mc_renderer *renderer,
-                               struct vl_mpeg12_mc_buffer *buffer,
-                               struct pipe_surface *surface,
-                               struct pipe_surface *past,
-                               struct pipe_surface *future,
-                               struct pipe_fence_handle **fence);
+void vl_mpeg12_mc_cleanup_buffer(struct vl_mpeg12_mc_buffer *buffer);
 
 void vl_mpeg12_mc_renderer_flush(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer,
+                                 struct pipe_surface *surface, struct pipe_surface *ref[2],
                                  unsigned not_empty_start_instance, unsigned not_empty_num_instances,
-                                 unsigned empty_start_instance, unsigned empty_num_instances);
+                                 unsigned empty_start_instance, unsigned empty_num_instances,
+                                 struct pipe_fence_handle **fence);
 
 #endif /* vl_mpeg12_mc_renderer_h */
diff --git a/src/gallium/include/pipe/p_video_context.h b/src/gallium/include/pipe/p_video_context.h
index 08e3c7e..aa903dd 100644
--- a/src/gallium/include/pipe/p_video_context.h
+++ b/src/gallium/include/pipe/p_video_context.h
@@ -176,13 +176,17 @@ struct pipe_video_buffer
 
    void (*destroy)(struct pipe_video_buffer *buffer);
 
+   void (*map)(struct pipe_video_buffer *buffer);
+
    void (*add_macroblocks)(struct pipe_video_buffer *buffer,
-                           struct pipe_video_buffer *past,
-                           struct pipe_video_buffer *future,
                            unsigned num_macroblocks,
-                           struct pipe_macroblock *macroblocks,
-                           struct pipe_fence_handle **fence);
+                           struct pipe_macroblock *macroblocks);
+
+   void (*unmap)(struct pipe_video_buffer *buffer);
 
+   void (*flush)(struct pipe_video_buffer *buffer,
+                 struct pipe_video_buffer *ref_frames[2],
+                 struct pipe_fence_handle **fence);
 
 };
 
diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c
index 4dedf00..bb60192 100644
--- a/src/gallium/state_trackers/xorg/xvmc/surface.c
+++ b/src/gallium/state_trackers/xorg/xvmc/surface.c
@@ -198,6 +198,37 @@ MacroBlocksToPipe(struct pipe_screen *screen,
    }
 }
 
+static void
+unmap_and_flush_surface(XvMCSurfacePrivate *surface)
+{
+   struct pipe_video_buffer *ref_frames[2];
+   unsigned i;
+
+   assert(surface);
+
+   for ( i = 0; i < 3; ++i ) {
+      if (surface->ref_surfaces[i]) {
+         XvMCSurfacePrivate *ref = surface->ref_surfaces[i]->privData;
+
+         assert(ref);
+
+         unmap_and_flush_surface(ref);
+         surface->ref_surfaces[i] = NULL;
+         ref_frames[i] = ref->pipe_buffer;
+      } else {
+         ref_frames[i] = NULL;
+      }
+   }
+
+   if (surface->mapped) {
+      surface->pipe_buffer->unmap(surface->pipe_buffer);
+      surface->pipe_buffer->flush(surface->pipe_buffer,
+                                  ref_frames,
+                                  &surface->flush_fence);
+      surface->mapped = 0;
+   }
+}
+
 PUBLIC
 Status XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surface)
 {
@@ -221,8 +252,6 @@ Status XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surfac
    if (!surface_priv)
       return BadAlloc;
 
-
-
    surface_priv->pipe_buffer = vpipe->create_buffer(vpipe);
    surface_priv->context = context;
 
@@ -248,9 +277,7 @@ Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int pictur
 )
 {
    struct pipe_video_context *vpipe;
-   struct pipe_video_buffer *t_vsfc;
-   struct pipe_video_buffer *p_vsfc;
-   struct pipe_video_buffer *f_vsfc;
+   struct pipe_video_buffer *t_buffer;
    XvMCContextPrivate *context_priv;
    XvMCSurfacePrivate *target_surface_priv;
    XvMCSurfacePrivate *past_surface_priv;
@@ -297,15 +324,30 @@ Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int pictur
    context_priv = context->privData;
    vpipe = context_priv->vctx->vpipe;
 
-   t_vsfc = target_surface_priv->pipe_buffer;
-   p_vsfc = past_surface ? past_surface_priv->pipe_buffer : NULL;
-   f_vsfc = future_surface ? future_surface_priv->pipe_buffer : NULL;
+   t_buffer = target_surface_priv->pipe_buffer;
+
+   // enshure that all reference frames are flushed
+   // not really nessasary, but speeds ups rendering
+   if (past_surface)
+      unmap_and_flush_surface(past_surface->privData);
+
+   if (future_surface)
+      unmap_and_flush_surface(future_surface->privData);
 
    MacroBlocksToPipe(vpipe->screen, picture_structure, macroblocks, blocks, first_macroblock,
                      num_macroblocks, pipe_macroblocks);
 
-   t_vsfc->add_macroblocks(t_vsfc, p_vsfc, f_vsfc, num_macroblocks,
-                           &pipe_macroblocks->base, &target_surface_priv->render_fence);
+   if (!target_surface_priv->mapped) {
+      t_buffer->map(t_buffer);
+      target_surface_priv->ref_surfaces[0] = past_surface;
+      target_surface_priv->ref_surfaces[1] = future_surface;
+      target_surface_priv->mapped = 1;
+   } else {
+      /* If the surface we're rendering hasn't changed the ref frames shouldn't change. */
+      assert(target_surface_priv->ref_surfaces[0] == past_surface);
+      assert(target_surface_priv->ref_surfaces[1] == future_surface);
+   }
+   t_buffer->add_macroblocks(t_buffer, num_macroblocks, &pipe_macroblocks->base);
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for rendering.\n", target_surface);
 
@@ -320,6 +362,9 @@ Status XvMCFlushSurface(Display *dpy, XvMCSurface *surface)
    if (!surface)
       return XvMCBadSurface;
 
+   // don't call flush here, because this is usually
+   // called once for every slice instead of every frame
+
    return Success;
 }
 
@@ -406,6 +451,7 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
    else
       vpipe->set_picture_layers(vpipe, 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);
 
diff --git a/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h b/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h
index 01b82df..26be1f7 100644
--- a/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h
+++ b/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h
@@ -50,6 +50,11 @@ typedef struct
 typedef struct
 {
    struct pipe_video_buffer *pipe_buffer;
+   bool mapped; // are we still mapped to memory?
+
+   XvMCSurface *ref_surfaces[2];
+
+   struct pipe_fence_handle *flush_fence;
    struct pipe_fence_handle *render_fence;
    struct pipe_fence_handle *disp_fence;
 




More information about the mesa-commit mailing list