Mesa (pipe-video): vl: Drop DRI1, clean up DRI2 bits.

Younes Manton ymanton at kemper.freedesktop.org
Sun Jun 6 10:32:55 PDT 2010


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

Author: Younes Manton <younes.m at gmail.com>
Date:   Sun Jun  6 11:48:47 2010 -0400

vl: Drop DRI1, clean up DRI2 bits.

---

 src/gallium/drivers/nvfx/nvfx_video_context.c   |    3 +-
 src/gallium/drivers/softpipe/sp_video_context.c |   18 +-
 src/gallium/drivers/softpipe/sp_video_context.h |    7 +-
 src/gallium/state_trackers/xorg/xvmc/surface.c  |   26 +-
 src/gallium/targets/xvmc-nouveau/Makefile       |    2 +-
 src/gallium/winsys/g3dvl/dri/dri_winsys.c       |  443 ++++++-----------------
 src/gallium/winsys/g3dvl/dri/driclient.c        |   19 +
 src/gallium/winsys/g3dvl/dri/driclient.h        |    1 +
 src/gallium/winsys/g3dvl/vl_winsys.h            |    9 +-
 src/gallium/winsys/g3dvl/xlib/xsp_winsys.c      |  115 +++++--
 10 files changed, 252 insertions(+), 391 deletions(-)

diff --git a/src/gallium/drivers/nvfx/nvfx_video_context.c b/src/gallium/drivers/nvfx/nvfx_video_context.c
index 5b85b29..4e21f35 100644
--- a/src/gallium/drivers/nvfx/nvfx_video_context.c
+++ b/src/gallium/drivers/nvfx/nvfx_video_context.c
@@ -44,5 +44,6 @@ nvfx_video_create(struct pipe_screen *screen, enum pipe_video_profile profile,
    return sp_video_create_ex(pipe, profile, chroma_format, width, height,
                              VL_MPEG12_MC_RENDERER_BUFFER_PICTURE,
                              VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE,
-                             true);
+                             true,
+                             PIPE_FORMAT_VUYA);
 }
diff --git a/src/gallium/drivers/softpipe/sp_video_context.c b/src/gallium/drivers/softpipe/sp_video_context.c
index fcee9b6..9aec8a8 100644
--- a/src/gallium/drivers/softpipe/sp_video_context.c
+++ b/src/gallium/drivers/softpipe/sp_video_context.c
@@ -74,8 +74,7 @@ sp_mpeg12_get_param(struct pipe_video_context *vpipe, int param)
 #endif
          return FALSE;
       case PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT:
-         //return PIPE_FORMAT_AYUV;
-         return PIPE_FORMAT_VUYA;
+         return ctx->decode_format;
       default:
       {
          debug_printf("Softpipe: Unknown PIPE_CAP %d\n", param);
@@ -322,7 +321,8 @@ sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile,
                  unsigned width, unsigned height,
                  enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
                  enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling,
-                 bool pot_buffers)
+                 bool pot_buffers,
+                 enum pipe_format decode_format)
 {
    struct sp_mpeg12_context *ctx;
 
@@ -352,6 +352,7 @@ sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile,
    ctx->base.set_csc_matrix = sp_mpeg12_set_csc_matrix;
 
    ctx->pipe = pipe;
+   ctx->decode_format = decode_format;
 
    if (!vl_mpeg12_mc_renderer_init(&ctx->mc_renderer, ctx->pipe,
                                    width, height, chroma_format,
@@ -382,7 +383,7 @@ sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile,
 struct pipe_video_context *
 sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile,
                 enum pipe_video_chroma_format chroma_format,
-                unsigned width, unsigned height)
+                unsigned width, unsigned height, void *priv)
 {
    struct pipe_context *pipe;
 
@@ -400,7 +401,8 @@ sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile,
                              width, height,
                              VL_MPEG12_MC_RENDERER_BUFFER_PICTURE,
                              VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE,
-                             true);
+                             true,
+                             PIPE_FORMAT_AYUV);
 }
 
 struct pipe_video_context *
@@ -409,7 +411,8 @@ sp_video_create_ex(struct pipe_context *pipe, enum pipe_video_profile profile,
                    unsigned width, unsigned height,
                    enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
                    enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling,
-                   bool pot_buffers)
+                   bool pot_buffers,
+                   enum pipe_format decode_format)
 {
    assert(pipe);
    assert(width && height);
@@ -420,7 +423,8 @@ sp_video_create_ex(struct pipe_context *pipe, enum pipe_video_profile profile,
                                  chroma_format,
                                  width, height,
                                  bufmode, eb_handling,
-                                 pot_buffers);
+                                 pot_buffers,
+                                 decode_format);
       default:
          return NULL;
    }
diff --git a/src/gallium/drivers/softpipe/sp_video_context.h b/src/gallium/drivers/softpipe/sp_video_context.h
index bc5daa0..0fe48d7 100644
--- a/src/gallium/drivers/softpipe/sp_video_context.h
+++ b/src/gallium/drivers/softpipe/sp_video_context.h
@@ -46,12 +46,14 @@ struct sp_mpeg12_context
    void *rast;
    void *dsa;
    void *blend;
+
+   enum pipe_format decode_format;
 };
 
 struct pipe_video_context *
 sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile,
                 enum pipe_video_chroma_format chroma_format,
-                unsigned width, unsigned height);
+                unsigned width, unsigned height, void *priv);
 
 /* Other drivers can call this function in their pipe_video_context constructors and pass it
    an accelerated pipe_context along with suitable buffering modes, etc */
@@ -61,6 +63,7 @@ sp_video_create_ex(struct pipe_context *pipe, enum pipe_video_profile profile,
                    unsigned width, unsigned height,
                    enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
                    enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling,
-                   bool pot_buffers);
+                   bool pot_buffers,
+                   enum pipe_format decode_format);
 
 #endif /* SP_VIDEO_CONTEXT_H */
diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c
index 985cc1a..ea1f648 100644
--- a/src/gallium/state_trackers/xorg/xvmc/surface.c
+++ b/src/gallium/state_trackers/xorg/xvmc/surface.c
@@ -94,6 +94,7 @@ static enum pipe_mpeg12_motion_type MotionToPipe(int xvmc_motion_type, int xvmc_
    return -1;
 }
 
+#if 0
 static bool
 CreateOrResizeBackBuffer(struct vl_context *vctx, unsigned int width, unsigned int height,
                          struct pipe_surface **backbuffer)
@@ -141,6 +142,7 @@ CreateOrResizeBackBuffer(struct vl_context *vctx, unsigned int width, unsigned i
 
    return true;
 }
+#endif
 
 static void
 MacroBlocksToPipe(struct pipe_screen *screen,
@@ -280,7 +282,6 @@ Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int pictur
    XvMCSurfacePrivate *past_surface_priv;
    XvMCSurfacePrivate *future_surface_priv;
    struct pipe_mpeg12_macroblock pipe_macroblocks[num_macroblocks];
-   unsigned int i;
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Rendering to surface %p.\n", target_surface);
 
@@ -331,7 +332,7 @@ Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int pictur
 
    vpipe->set_decode_target(vpipe, t_vsfc);
    vpipe->decode_macroblocks(vpipe, p_vsfc, f_vsfc, num_macroblocks,
-                             &pipe_macroblocks->base, target_surface_priv->render_fence);
+                             &pipe_macroblocks->base, &target_surface_priv->render_fence);
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for rendering.\n", target_surface);
 
@@ -373,8 +374,7 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
    XvMCContext *context;
    struct pipe_video_rect src_rect = {srcx, srcy, srcw, srch};
    struct pipe_video_rect dst_rect = {destx, desty, destw, desth};
-   void *displaytarget;
-   unsigned width, height;
+   struct pipe_surface *drawable_surface;
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Displaying surface %p.\n", surface);
 
@@ -387,8 +387,8 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
    context = surface_priv->context;
    context_priv = context->privData;
 
-   displaytarget = vl_displaytarget_get(context_priv->vctx->vscreen, drawable, &width, &height);
-   if (!displaytarget)
+   drawable_surface = vl_drawable_surface_get(context_priv->vctx->vscreen, drawable);
+   if (!drawable_surface)
       return BadDrawable;
 
    assert(flags == XVMC_TOP_FIELD || flags == XVMC_BOTTOM_FIELD || flags == XVMC_FRAME_PICTURE);
@@ -402,15 +402,17 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
     * until the app updates destw and desth.
     */
    /*
-   assert(destx + destw - 1 < width);
-   assert(desty + desth - 1 < height);
+   assert(destx + destw - 1 < drawable_surface->width);
+   assert(desty + desth - 1 < drawable_surface->height);
     */
 
    subpicture_priv = surface_priv->subpicture ? surface_priv->subpicture->privData : NULL;
    vpipe = context_priv->vctx->vpipe;
 
+#if 0
    if (!CreateOrResizeBackBuffer(context_priv->vctx, width, height, &context_priv->backbuffer))
       return BadAlloc;
+#endif
 
    if (subpicture_priv) {
       struct pipe_video_rect src_rect = {surface_priv->subx, surface_priv->suby, surface_priv->subw, surface_priv->subh};
@@ -430,17 +432,19 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
       vpipe->set_picture_layers(vpipe, NULL, NULL, NULL, 0);
 
    vpipe->render_picture(vpipe, surface_priv->pipe_vsfc, PictureToPipe(flags), &src_rect,
-                         context_priv->backbuffer, &dst_rect, surface_priv->disp_fence);
+                         drawable_surface, &dst_rect, surface_priv->disp_fence);
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for display. Pushing to front buffer.\n", surface);
 
    vpipe->screen->flush_frontbuffer
    (
       vpipe->screen,
-      context_priv->backbuffer,
-      displaytarget
+      drawable_surface,
+      vl_contextprivate_get(context_priv->vctx, drawable_surface)
    );
 
+   pipe_surface_reference(&drawable_surface, NULL);
+
    XVMC_MSG(XVMC_TRACE, "[XvMC] Pushed surface %p to front buffer.\n", surface);
 
    return Success;
diff --git a/src/gallium/targets/xvmc-nouveau/Makefile b/src/gallium/targets/xvmc-nouveau/Makefile
index 045dbcb..fe418b0 100644
--- a/src/gallium/targets/xvmc-nouveau/Makefile
+++ b/src/gallium/targets/xvmc-nouveau/Makefile
@@ -16,7 +16,7 @@ C_SOURCES = \
 	$(COMMON_GALLIUM_SOURCES) \
 	$(DRIVER_SOURCES)
 
-DRIVER_LIBS = $(shell pkg-config libdrm_nouveau --libs)
+DRIVER_LIBS = $(shell pkg-config libdrm_nouveau --libs) -lXfixes
 
 include ../Makefile.xvmc
 
diff --git a/src/gallium/winsys/g3dvl/dri/dri_winsys.c b/src/gallium/winsys/g3dvl/dri/dri_winsys.c
index 892f93d..0663184 100644
--- a/src/gallium/winsys/g3dvl/dri/dri_winsys.c
+++ b/src/gallium/winsys/g3dvl/dri/dri_winsys.c
@@ -27,251 +27,29 @@
 
 #include <vl_winsys.h>
 #include <driclient.h>
-#include <state_tracker/dri1_api.h>
 #include <pipe/p_video_context.h>
 #include <pipe/p_state.h>
 #include <util/u_memory.h>
+#include <util/u_hash.h>
+#include <util/u_hash_table.h>
+#include <state_tracker/drm_api.h>
+#include <X11/Xlibint.h>
 
 struct vl_dri_screen
 {
    struct vl_screen base;
-   Visual *visual;
    struct drm_api *api;
    dri_screen_t *dri_screen;
-   dri_framebuffer_t dri_framebuf;
-   struct dri1_api *api_hooks;
-   boolean dri2;
+   struct util_hash_table *drawable_table;
+   Drawable last_seen_drawable;
 };
 
 struct vl_dri_context
 {
    struct vl_context base;
-   boolean is_locked;
-   boolean lost_lock;
-   drmLock *lock;
-   dri_context_t *dri_context;
    int fd;
-   struct pipe_video_context *vpipe;
-   dri_drawable_t *drawable;
-   struct pipe_surface *dri2_front;
 };
 
-static void
-vl_dri_lock(void *priv)
-{
-   struct vl_dri_context *vl_dri_ctx = priv;
-   drm_context_t hw_context;
-   char ret = 0;
-
-   assert(priv);
-
-   hw_context = vl_dri_ctx->dri_context->drm_context;
-
-   DRM_CAS(vl_dri_ctx->lock, hw_context, DRM_LOCK_HELD | hw_context, ret);
-   if (ret) {
-      drmGetLock(vl_dri_ctx->fd, hw_context, 0);
-      vl_dri_ctx->lost_lock = TRUE;
-   }
-   vl_dri_ctx->is_locked = TRUE;
-}
-
-static void
-vl_dri_unlock(void *priv)
-{
-   struct vl_dri_context *vl_dri_ctx = priv;
-   drm_context_t hw_context;
-
-   assert(priv);
-
-   hw_context = vl_dri_ctx->dri_context->drm_context;
-
-   vl_dri_ctx->is_locked = FALSE;
-   DRM_UNLOCK(vl_dri_ctx->fd, vl_dri_ctx->lock, hw_context);
-}
-
-static boolean
-vl_dri_is_locked(void *priv)
-{
-   struct vl_dri_context *vl_dri_ctx = priv;
-
-   assert(priv);
-
-   return vl_dri_ctx->is_locked;
-}
-
-static boolean
-vl_dri_lost_lock(void *priv)
-{
-   struct vl_dri_context *vl_dri_ctx = priv;
-
-   assert(priv);
-
-   return vl_dri_ctx->lost_lock;
-}
-
-static void
-vl_dri_clear_lost_lock(void *priv)
-{
-   struct vl_dri_context *vl_dri_ctx = priv;
-
-   assert(priv);
-
-   vl_dri_ctx->lost_lock = FALSE;
-}
-
-struct dri1_api_lock_funcs dri1_lf =
-{
-   .lock = vl_dri_lock,
-   .unlock = vl_dri_unlock,
-   .is_locked = vl_dri_is_locked,
-   .is_lock_lost = vl_dri_lost_lock,
-   .clear_lost_lock = vl_dri_clear_lost_lock
-};
-
-static void
-vl_dri_copy_version(struct dri1_api_version *dst, dri_version_t *src)
-{
-   assert(src);
-   assert(dst);
-   dst->major = src->major;
-   dst->minor = src->minor;
-   dst->patch_level = src->patch;
-}
-
-static boolean
-vl_dri_intersect_src_bbox(struct drm_clip_rect *dst, int dst_x, int dst_y,
-                          const struct drm_clip_rect *src, const struct drm_clip_rect *bbox)
-{
-   int xy1;
-   int xy2;
-
-   assert(dst);
-   assert(src);
-   assert(bbox);
-
-   xy1 = ((int)src->x1 > (int)bbox->x1 + dst_x) ? src->x1 :
-      (int)bbox->x1 + dst_x;
-   xy2 = ((int)src->x2 < (int)bbox->x2 + dst_x) ? src->x2 :
-      (int)bbox->x2 + dst_x;
-   if (xy1 >= xy2 || xy1 < 0)
-      return FALSE;
-
-   dst->x1 = xy1;
-   dst->x2 = xy2;
-
-   xy1 = ((int)src->y1 > (int)bbox->y1 + dst_y) ? src->y1 :
-      (int)bbox->y1 + dst_y;
-   xy2 = ((int)src->y2 < (int)bbox->y2 + dst_y) ? src->y2 :
-      (int)bbox->y2 + dst_y;
-   if (xy1 >= xy2 || xy1 < 0)
-      return FALSE;
-
-   dst->y1 = xy1;
-   dst->y2 = xy2;
-   return TRUE;
-}
-
-static void
-vl_clip_copy(struct vl_dri_context *vl_dri_ctx,
-             struct pipe_surface *dst,
-             struct pipe_surface *src,
-             const struct drm_clip_rect *src_bbox)
-{
-   struct pipe_video_context *vpipe;
-   struct drm_clip_rect clip;
-   struct drm_clip_rect *cur;
-   int i;
-
-   assert(vl_dri_ctx);
-   assert(dst);
-   assert(src);
-   assert(src_bbox);
-
-   vpipe = vl_dri_ctx->base.vpipe;
-
-   assert(vl_dri_ctx->drawable->cliprects);
-   assert(vl_dri_ctx->drawable->num_cliprects > 0);
-
-   cur = vl_dri_ctx->drawable->cliprects;
-
-   for (i = 0; i < vl_dri_ctx->drawable->num_cliprects; ++i) {
-      if (vl_dri_intersect_src_bbox(&clip, vl_dri_ctx->drawable->x, vl_dri_ctx->drawable->y, cur++, src_bbox))
-         vpipe->surface_copy
-         (
-            vpipe, dst, clip.x1, clip.y1, src,
-            (int)clip.x1 - vl_dri_ctx->drawable->x,
-            (int)clip.y1 - vl_dri_ctx->drawable->y,
-            clip.x2 - clip.x1, clip.y2 - clip.y1
-         );
-   }
-}
-
-static void
-vl_dri_update_drawables_locked(struct vl_dri_context *vl_dri_ctx)
-{
-   struct vl_dri_screen *vl_dri_scrn;
-
-   assert(vl_dri_ctx);
-
-   vl_dri_scrn = (struct vl_dri_screen*)vl_dri_ctx->base.vscreen;
-
-   if (vl_dri_ctx->lost_lock) {
-      vl_dri_ctx->lost_lock = FALSE;
-      DRI_VALIDATE_DRAWABLE_INFO(vl_dri_scrn->dri_screen, vl_dri_ctx->drawable);
-   }
-}
-
-static void
-vl_dri_flush_frontbuffer(struct pipe_screen *screen,
-                         struct pipe_surface *surf, void *context_private)
-{
-   struct vl_dri_context *vl_dri_ctx = (struct vl_dri_context*)context_private;
-   struct vl_dri_screen *vl_dri_scrn;
-   struct drm_clip_rect src_bbox;
-   boolean save_lost_lock = FALSE;
-
-   assert(screen);
-   assert(surf);
-   assert(context_private);
-
-   vl_dri_scrn = (struct vl_dri_screen*)vl_dri_ctx->base.vscreen;
-
-   vl_dri_lock(vl_dri_ctx);
-
-   save_lost_lock = vl_dri_ctx->lost_lock;
-
-   vl_dri_update_drawables_locked(vl_dri_ctx);
-
-   if (vl_dri_ctx->drawable->cliprects) {
-      src_bbox.x1 = 0;
-      src_bbox.x2 = vl_dri_ctx->drawable->w;
-      src_bbox.y1 = 0;
-      src_bbox.y2 = vl_dri_ctx->drawable->h;
-
-#if 0
-      if (vl_dri_scrn->_api_hooks->present_locked)
-         vl_dri_scrn->api_hooks->present_locked(pipe, surf,
-                                                vl_dri_ctx->drawable->cliprects,
-                                                vl_dri_ctx->drawable->num_cliprects,
-                                                vl_dri_ctx->drawable->x, vl_dri_drawable->y,
-                                                &bbox, NULL /*fence*/);
-      else
-#endif
-      if (vl_dri_scrn->api_hooks->front_srf_locked) {
-         struct pipe_surface *front = vl_dri_scrn->api_hooks->front_srf_locked(screen);
-
-         if (front)
-            vl_clip_copy(vl_dri_ctx, front, surf, &src_bbox);
-
-         //st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, fence);
-      }
-   }
-
-   vl_dri_ctx->lost_lock = save_lost_lock;
-
-   vl_dri_unlock(vl_dri_ctx);
-}
-
 static struct pipe_surface*
 vl_dri2_get_front(struct vl_dri_screen *vl_dri_scrn, Drawable drawable)
 {
@@ -286,6 +64,9 @@ vl_dri2_get_front(struct vl_dri_screen *vl_dri_scrn, Drawable drawable)
 
    dri2_front = DRI2GetBuffers(vl_dri_scrn->dri_screen->display,
                                drawable, &w, &h, attachments, 1, &count);
+
+   assert(count == 1);
+
    if (dri2_front) {
       struct winsys_handle dri2_front_handle =
       {
@@ -297,7 +78,7 @@ vl_dri2_get_front(struct vl_dri_screen *vl_dri_scrn, Drawable drawable)
 
       memset(&template, 0, sizeof(struct pipe_resource));
       template.target = PIPE_TEXTURE_2D;
-      template.format = vl_dri_scrn->base.format;
+      template.format = PIPE_FORMAT_B8G8R8X8_UNORM;
       template.last_level = 0;
       template.width0 = w;
       template.height0 = h;
@@ -310,8 +91,9 @@ vl_dri2_get_front(struct vl_dri_screen *vl_dri_scrn, Drawable drawable)
       if (front_tex)
          front_surf = vl_dri_scrn->base.pscreen->get_tex_surface(vl_dri_scrn->base.pscreen,
                                                                  front_tex, 0, 0, 0,
-                                                                 /*PIPE_BIND_RENDER_TARGET*/ PIPE_BIND_BLIT_DESTINATION);
+                                                                 PIPE_BIND_RENDER_TARGET);
       pipe_resource_reference(&front_tex, NULL);
+      Xfree(dri2_front);
    }
 
    return front_surf;
@@ -322,119 +104,121 @@ vl_dri2_flush_frontbuffer(struct pipe_screen *screen,
                           struct pipe_surface *surf, void *context_private)
 {
    struct vl_dri_context *vl_dri_ctx = (struct vl_dri_context*)context_private;
-   struct vl_dri_screen *vl_dri_scrn;
-   struct pipe_video_context *vpipe;
+   struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vl_dri_ctx->base.vscreen;
 
    assert(screen);
    assert(surf);
    assert(context_private);
-   assert(vl_dri_ctx->dri2_front);
-
-   vl_dri_scrn = (struct vl_dri_screen*)vl_dri_ctx->base.vscreen;
-   vpipe = vl_dri_ctx->base.vpipe;
 
-   /* XXX: Why not just render to fake front? */
-   vpipe->surface_copy(vpipe, vl_dri_ctx->dri2_front, 0, 0, surf, 0, 0, surf->width, surf->height);
-
-   //st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, fence);
+   dri2CopyDrawable(vl_dri_scrn->dri_screen, vl_dri_scrn->last_seen_drawable,
+                    DRI_BUFFER_FRONT_LEFT, DRI_BUFFER_FAKE_FRONT_LEFT);
 }
 
-/* XXX: Kill with fire */
-struct vl_dri_context *_vl_dri_ctx = NULL;
-
-void*
-vl_displaytarget_get(struct vl_screen *vscreen, Drawable drawable,
-                     unsigned *width, unsigned *height)
+struct pipe_surface*
+vl_drawable_surface_get(struct vl_screen *vscreen, Drawable drawable)
 {
    struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vscreen;
 
    assert(vscreen);
-   assert(width);
-   assert(height);
-
-   if (vl_dri_scrn->dri2 && _vl_dri_ctx) {
-      if (!_vl_dri_ctx->dri2_front) {
-         _vl_dri_ctx->dri2_front = vl_dri2_get_front((struct vl_dri_screen*)vscreen, drawable);
-         if (!_vl_dri_ctx->dri2_front)
-            return NULL;
-         *width = _vl_dri_ctx->dri2_front->width;
-         *height = _vl_dri_ctx->dri2_front->height;
+
+   if (vl_dri_scrn->last_seen_drawable != drawable) {
+      /* Hash table business depends on this equality */
+      assert(None == NULL);
+      Drawable lookup_drawable = (Drawable)util_hash_table_get(vl_dri_scrn->drawable_table, (void*)drawable);
+      if (lookup_drawable == None) {
+         dri2CreateDrawable(vl_dri_scrn->dri_screen, drawable);
+         util_hash_table_set(vl_dri_scrn->drawable_table, (void*)drawable, (void*)drawable);
       }
-      return _vl_dri_ctx;
+      vl_dri_scrn->last_seen_drawable = drawable;
    }
-   else
-      return NULL;
+
+   return vl_dri2_get_front(vl_dri_scrn, drawable);
+}
+
+void*
+vl_contextprivate_get(struct vl_context *vctx, struct pipe_surface *displaytarget)
+{
+   return vctx;
+}
+
+static unsigned drawable_hash(void *key)
+{
+   Drawable drawable = (Drawable)key;
+   assert(drawable != None);
+   return util_hash_crc32(&drawable, sizeof(Drawable));
+}
+
+static int drawable_cmp(void *key1, void *key2)
+{
+   Drawable d1 = (Drawable)key1;
+   Drawable d2 = (Drawable)key2;
+   assert(d1 != None);
+   assert(d2 != None);
+   return d1 != d2;
+}
+
+static enum pipe_error
+drawable_destroy(void *key, void *value, void *data)
+{
+   Drawable drawable = (Drawable)key;
+   struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)data;
+
+   assert(drawable != None);
+   assert(value);
+   assert(data);
+
+   dri2DestroyDrawable(vl_dri_scrn->dri_screen, drawable);
+
+   return PIPE_OK;
 }
 
 struct vl_screen*
 vl_screen_create(Display *display, int screen)
 {
    struct vl_dri_screen *vl_dri_scrn;
-   struct dri1_create_screen_arg arg;
+   struct drm_create_screen_arg arg;
 
    assert(display);
 
    vl_dri_scrn = CALLOC_STRUCT(vl_dri_screen);
    if (!vl_dri_scrn)
-      return NULL;
-
-   /* Try DRI2 first */
-   if (dri2CreateScreen(display, screen, &vl_dri_scrn->dri_screen)) {
-      /* If not, try DRI */
-      if (driCreateScreen(display, screen, &vl_dri_scrn->dri_screen, &vl_dri_scrn->dri_framebuf)) {
-         /* Now what? */
-         FREE(vl_dri_scrn);
-         return NULL;
-      }
-      else {
-         /* Got DRI */
-         arg.base.mode = DRM_CREATE_DRI1;
-         arg.lf = &dri1_lf;
-         arg.ddx_info = vl_dri_scrn->dri_framebuf.private;
-         arg.ddx_info_size = vl_dri_scrn->dri_framebuf.private_size;
-         arg.sarea = vl_dri_scrn->dri_screen->sarea;
-         vl_dri_copy_version(&arg.ddx_version, &vl_dri_scrn->dri_screen->ddx);
-         vl_dri_copy_version(&arg.dri_version, &vl_dri_scrn->dri_screen->dri);
-         vl_dri_copy_version(&arg.drm_version, &vl_dri_scrn->dri_screen->drm);
-         arg.api = NULL;
-         vl_dri_scrn->dri2 = FALSE;
-      }
-   }
-   else {
-      /* Got DRI2 */
-      arg.base.mode = DRM_CREATE_NORMAL;
-      vl_dri_scrn->dri2 = TRUE;
-   }
+      goto no_struct;
+
+   if (dri2CreateScreen(display, screen, &vl_dri_scrn->dri_screen))
+      goto no_dri2screen;
 
    vl_dri_scrn->api = drm_api_create();
-   if (!vl_dri_scrn->api) {
-      FREE(vl_dri_scrn);
-      return NULL;
-   }
+   if (!vl_dri_scrn->api)
+      goto no_drmapi;
+
+   arg.mode = DRM_CREATE_NORMAL;
 
    vl_dri_scrn->base.pscreen = vl_dri_scrn->api->create_screen(vl_dri_scrn->api,
                                                                vl_dri_scrn->dri_screen->fd,
-                                                               &arg.base);
+                                                               &arg);
 
-   if (!vl_dri_scrn->base.pscreen) {
-      FREE(vl_dri_scrn);
-      return NULL;
-   }
+   if (!vl_dri_scrn->base.pscreen)
+      goto no_pscreen;
 
-   if (!vl_dri_scrn->dri2) {
-      vl_dri_scrn->visual = XDefaultVisual(display, screen);
-      vl_dri_scrn->api_hooks = arg.api;
-      vl_dri_scrn->base.format = vl_dri_scrn->api_hooks->front_srf_locked(vl_dri_scrn->base.pscreen)->format;
-      vl_dri_scrn->base.pscreen->flush_frontbuffer = vl_dri_flush_frontbuffer;
-   }
-   else {
-      /* XXX: Fuuuuu... Can't possibly get this right with current code.
-       * Need to rethink this in st/xvmc and winsys dri/xlib winsyses */
-      vl_dri_scrn->base.format = PIPE_FORMAT_B8G8R8X8_UNORM;
-      vl_dri_scrn->base.pscreen->flush_frontbuffer = vl_dri2_flush_frontbuffer;
-   }
+   vl_dri_scrn->drawable_table = util_hash_table_create(&drawable_hash, &drawable_cmp);
+   if (!vl_dri_scrn->drawable_table)
+      goto no_hash;
+
+   vl_dri_scrn->last_seen_drawable = None;
+   vl_dri_scrn->base.pscreen->flush_frontbuffer = vl_dri2_flush_frontbuffer;
 
    return &vl_dri_scrn->base;
+
+no_hash:
+   vl_dri_scrn->base.pscreen->destroy(vl_dri_scrn->base.pscreen);
+no_pscreen:
+   vl_dri_scrn->api->destroy(vl_dri_scrn->api);
+no_drmapi:
+   dri2DestroyScreen(vl_dri_scrn->dri_screen);
+no_dri2screen:
+   FREE(vl_dri_scrn);
+no_struct:
+   return NULL;
 }
 
 void vl_screen_destroy(struct vl_screen *vscreen)
@@ -443,11 +227,12 @@ void vl_screen_destroy(struct vl_screen *vscreen)
 
    assert(vscreen);
 
+   util_hash_table_foreach(vl_dri_scrn->drawable_table, drawable_destroy, vl_dri_scrn);
+   util_hash_table_destroy(vl_dri_scrn->drawable_table);
    vl_dri_scrn->base.pscreen->destroy(vl_dri_scrn->base.pscreen);
-   if (vl_dri_scrn->dri2)
-      dri2DestroyScreen(vl_dri_scrn->dri_screen);
-   else
-      driDestroyScreen(vl_dri_scrn->dri_screen);
+   if (vl_dri_scrn->api->destroy)
+      vl_dri_scrn->api->destroy(vl_dri_scrn->api);
+   dri2DestroyScreen(vl_dri_scrn->dri_screen);
    FREE(vl_dri_scrn);
 }
 
@@ -462,39 +247,33 @@ vl_video_create(struct vl_screen *vscreen,
 
    vl_dri_ctx = CALLOC_STRUCT(vl_dri_context);
    if (!vl_dri_ctx)
-      return NULL;
-
-   /* XXX: Is default visual correct/sufficient here? */
-   if (!vl_dri_scrn->dri2)
-      driCreateContext(vl_dri_scrn->dri_screen, vl_dri_scrn->visual, &vl_dri_ctx->dri_context);
+      goto no_struct;
 
    if (!vscreen->pscreen->video_context_create) {
       debug_printf("[G3DVL] No video support found on %s/%s.\n",
                    vscreen->pscreen->get_vendor(vscreen->pscreen),
                    vscreen->pscreen->get_name(vscreen->pscreen));
-      FREE(vl_dri_ctx);
-      return NULL;
+      goto no_vpipe;
    }
 
    vl_dri_ctx->base.vpipe = vscreen->pscreen->video_context_create(vscreen->pscreen,
                                                                    profile, chroma_format,
                                                                    width, height,
-                                                                   vl_dri_ctx->dri_context);
+                                                                   vl_dri_ctx);
 
-   if (!vl_dri_ctx->base.vpipe) {
-      FREE(vl_dri_ctx);
-      return NULL;
-   }
+   if (!vl_dri_ctx->base.vpipe)
+      goto no_vpipe;
 
    vl_dri_ctx->base.vpipe->priv = vl_dri_ctx;
    vl_dri_ctx->base.vscreen = vscreen;
    vl_dri_ctx->fd = vl_dri_scrn->dri_screen->fd;
-   if (!vl_dri_scrn->dri2)
-      vl_dri_ctx->lock = (drmLock*)&vl_dri_scrn->dri_screen->sarea->lock;
-   else
-      _vl_dri_ctx = vl_dri_ctx;
 
    return &vl_dri_ctx->base;
+
+no_vpipe:
+   FREE(vl_dri_ctx);
+no_struct:
+   return NULL;
 }
 
 void vl_video_destroy(struct vl_context *vctx)
@@ -504,9 +283,5 @@ void vl_video_destroy(struct vl_context *vctx)
    assert(vctx);
 
    vl_dri_ctx->base.vpipe->destroy(vl_dri_ctx->base.vpipe);
-   if (vl_dri_ctx->dri2_front)
-      pipe_surface_reference(&vl_dri_ctx->dri2_front, NULL);
-   if (!((struct vl_dri_screen *)vctx->vscreen)->dri2)
-      driDestroyContext(vl_dri_ctx->dri_context);
    FREE(vl_dri_ctx);
 }
diff --git a/src/gallium/winsys/g3dvl/dri/driclient.c b/src/gallium/winsys/g3dvl/dri/driclient.c
index 7a2469c..90e48a7 100644
--- a/src/gallium/winsys/g3dvl/dri/driclient.c
+++ b/src/gallium/winsys/g3dvl/dri/driclient.c
@@ -353,17 +353,36 @@ free_screen:
 int dri2DestroyScreen(dri_screen_t *dri_screen)
 {
 	/* Not much to do here apparently... */
+	assert(dri_screen);
+	free(dri_screen);
 	return 0;
 }
 
 int dri2CreateDrawable(dri_screen_t *dri_screen, XID drawable)
 {
+	assert(dri_screen);
 	DRI2CreateDrawable(dri_screen->display, drawable);
 	return 0;
 }
 
 int dri2DestroyDrawable(dri_screen_t *dri_screen, XID drawable)
 {
+	assert(dri_screen);
 	DRI2DestroyDrawable(dri_screen->display, drawable);
 	return 0;
 }
+
+int dri2CopyDrawable(dri_screen_t *dri_screen, XID drawable, int dest, int src)
+{
+	XserverRegion region;
+
+	assert(dri_screen);
+	assert(dest >= DRI_BUFFER_FRONT_LEFT && dest <= DRI_BUFFER_DEPTH_STENCIL);
+	assert(src >= DRI_BUFFER_FRONT_LEFT && src <= DRI_BUFFER_DEPTH_STENCIL);
+
+	region = XFixesCreateRegionFromWindow(dri_screen->display, drawable, WindowRegionBounding);
+	DRI2CopyRegion(dri_screen->display, drawable, region, dest, src);
+	XFixesDestroyRegion(dri_screen->display, region);
+
+	return 0;
+}
diff --git a/src/gallium/winsys/g3dvl/dri/driclient.h b/src/gallium/winsys/g3dvl/dri/driclient.h
index c71b6c2..4e4fd36 100644
--- a/src/gallium/winsys/g3dvl/dri/driclient.h
+++ b/src/gallium/winsys/g3dvl/dri/driclient.h
@@ -100,6 +100,7 @@ int dri2CreateScreen(Display *display, int screen, dri_screen_t **dri_screen);
 int dri2DestroyScreen(dri_screen_t *dri_screen);
 int dri2CreateDrawable(dri_screen_t *dri_screen, XID drawable);
 int dri2DestroyDrawable(dri_screen_t *dri_screen, XID drawable);
+int dri2CopyDrawable(dri_screen_t *dri_screen, XID drawable, int dest, int src);
 
 #define DRI_BUFFER_FRONT_LEFT		0
 #define DRI_BUFFER_BACK_LEFT		1
diff --git a/src/gallium/winsys/g3dvl/vl_winsys.h b/src/gallium/winsys/g3dvl/vl_winsys.h
index c75ff9f..3814786 100644
--- a/src/gallium/winsys/g3dvl/vl_winsys.h
+++ b/src/gallium/winsys/g3dvl/vl_winsys.h
@@ -34,11 +34,10 @@
 
 struct pipe_screen;
 struct pipe_video_context;
+struct pipe_surface;
 
 struct vl_screen
 {
-   Display *display;
-   enum pipe_format format;
    struct pipe_screen *pscreen;
 };
 
@@ -61,8 +60,10 @@ vl_video_create(struct vl_screen *vscreen,
 
 void vl_video_destroy(struct vl_context *vctx);
 
+struct pipe_surface*
+vl_drawable_surface_get(struct vl_screen *vscreen, Drawable drawable);
+
 void*
-vl_displaytarget_get(struct vl_screen *vscreen, Drawable drawable,
-                     unsigned *width, unsigned *height);
+vl_contextprivate_get(struct vl_context *vctx, struct pipe_surface *drawable_surface);
 
 #endif
diff --git a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c
index 95c2af1..0a7f324 100644
--- a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c
+++ b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c
@@ -26,81 +26,136 @@
  **************************************************************************/
 
 #include <vl_winsys.h>
+#include <X11/Xlibint.h>
 #include <state_tracker/xlib_sw_winsys.h>
 #include <util/u_memory.h>
+#include <util/u_format.h>
 #include <softpipe/sp_public.h>
 #include <softpipe/sp_video_context.h>
 
-/* TODO: Find a good way to calculate this */
-static enum pipe_format VisualToPipe(Visual *visual)
+struct vl_xsp_screen
 {
-   assert(visual);
-   return PIPE_FORMAT_B8G8R8X8_UNORM;
-}
-
-/* XXX: Not thread-safe */
-static struct xlib_drawable xdraw;
-
-void*
-vl_displaytarget_get(struct vl_screen *vscreen, Drawable drawable,
-                     unsigned *width_out, unsigned *height_out)
+   struct vl_screen base;
+   Display *display;
+   int screen;
+   Visual visual;
+   struct xlib_drawable xdraw;
+   struct pipe_surface *drawable_surface;
+};
+
+struct pipe_surface*
+vl_drawable_surface_get(struct vl_screen *vscreen, Drawable drawable)
 {
+   struct vl_xsp_screen *xsp_screen = (struct vl_xsp_screen*)vscreen;
    Window root;
    int x, y;
    unsigned int width, height;
    unsigned int border_width;
    unsigned int depth;
+   struct pipe_resource templat, *drawable_tex;
+   struct pipe_surface *drawable_surface = NULL;
 
    assert(vscreen);
+   assert(drawable != None);
+
+   if (XGetGeometry(xsp_screen->display, drawable, &root, &x, &y, &width, &height, &border_width, &depth) == BadDrawable)
+      return NULL;
+
+   xsp_screen->xdraw.drawable = drawable;
+
+   if (xsp_screen->drawable_surface) {
+      if (xsp_screen->drawable_surface->width == width &&
+          xsp_screen->drawable_surface->height == height) {
+         pipe_surface_reference(&drawable_surface, xsp_screen->drawable_surface);
+         return drawable_surface;
+      }
+      else
+         pipe_surface_reference(&xsp_screen->drawable_surface, NULL);
+   }
+
+   memset(&templat, 0, sizeof(struct pipe_resource));
+   templat.target = PIPE_TEXTURE_2D;
+   /* XXX: Need to figure out drawable's format */
+   templat.format = PIPE_FORMAT_B8G8R8X8_UNORM;
+   templat.last_level = 0;
+   templat.width0 = width;
+   templat.height0 = height;
+   templat.depth0 = 1;
+   templat.usage = PIPE_USAGE_DEFAULT;
+   templat.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_BLIT_SOURCE;
+   templat.flags = 0;
+
+   drawable_tex = vscreen->pscreen->resource_create(vscreen->pscreen, &templat);
+   if (!drawable_tex)
+      return NULL;
+
+   xsp_screen->drawable_surface = vscreen->pscreen->get_tex_surface(vscreen->pscreen, drawable_tex,
+                                                                    0, 0, 0,
+                                                                    templat.bind);
+   pipe_resource_reference(&drawable_tex, NULL);
 
-   if (XGetGeometry(vscreen->display, drawable, &root, &x, &y, &width, &height, &border_width, &depth) == BadDrawable)
+   if (!xsp_screen->drawable_surface)
       return NULL;
 
-   if (width_out) *width_out = width;
-   if (height_out) *height_out = height;
+   pipe_surface_reference(&drawable_surface, xsp_screen->drawable_surface);
+
+   xsp_screen->xdraw.depth = 24/*util_format_get_blocksizebits(templat.format) /
+                             util_format_get_blockwidth(templat.format)*/;
+
+   return drawable_surface;
+}
+
+void*
+vl_contextprivate_get(struct vl_context *vctx, struct pipe_surface *drawable_surface)
+{
+   struct vl_xsp_screen *xsp_screen = (struct vl_xsp_screen*)vctx->vscreen;
 
-   xdraw.depth = depth;
-   xdraw.drawable = drawable;
+   assert(vctx);
+   assert(drawable_surface);
+   assert(xsp_screen->drawable_surface == drawable_surface);
 
-   return &xdraw;
+   return &xsp_screen->xdraw;
 }
 
 struct vl_screen*
 vl_screen_create(Display *display, int screen)
 {
-   struct vl_screen *vscreen;
+   struct vl_xsp_screen *xsp_screen;
    struct sw_winsys *winsys;
 
    assert(display);
 
-   vscreen = CALLOC_STRUCT(vl_screen);
-   if (!vscreen)
+   xsp_screen = CALLOC_STRUCT(vl_xsp_screen);
+   if (!xsp_screen)
       return NULL;
 
    winsys = xlib_create_sw_winsys(display);
    if (!winsys) {
-      FREE(vscreen);
+      FREE(xsp_screen);
       return NULL;
    }
 
-   vscreen->pscreen = softpipe_create_screen(winsys);
-   if (!vscreen->pscreen) {
+   xsp_screen->base.pscreen = softpipe_create_screen(winsys);
+   if (!xsp_screen->base.pscreen) {
       winsys->destroy(winsys);
-      FREE(vscreen);
+      FREE(xsp_screen);
       return NULL;
    }
 
-   vscreen->display = display;
-   xdraw.visual = XDefaultVisual(display, screen);
-   vscreen->format = VisualToPipe(xdraw.visual);
+   xsp_screen->display = display;
+   xsp_screen->screen = screen;
+   xsp_screen->xdraw.visual = XDefaultVisual(display, screen);
 
-   return vscreen;
+   return &xsp_screen->base;
 }
 
 void vl_screen_destroy(struct vl_screen *vscreen)
 {
+   struct vl_xsp_screen *xsp_screen = (struct vl_xsp_screen*)vscreen;
+
    assert(vscreen);
 
+   pipe_surface_reference(&xsp_screen->drawable_surface, NULL);
    vscreen->pscreen->destroy(vscreen->pscreen);
    FREE(vscreen);
 }
@@ -142,8 +197,6 @@ void vl_video_destroy(struct vl_context *vctx)
 {
    assert(vctx);
 
-#if 1
    vctx->vpipe->destroy(vctx->vpipe);
-#endif
    FREE(vctx);
 }



More information about the mesa-commit mailing list