st/xorg: split copy operation into prepare/copy/done phases
[mesa.git] / src / gallium / state_trackers / xorg / xorg_xv.c
index b054ba806616eb6366d04b971286ac8a371dfe78..7c05c7af399f3629a2f5b5b7147a904f147f6485 100644 (file)
 
 
 /* The ITU-R BT.601 conversion matrix for SDTV. */
+/* original, matrix, but we transpose it to
+ * make the shader easier
 static const float bt_601[] = {
-    1.0, 0.0, 1.4075,   0,
+    1.0, 0.0, 1.4075,   ,
     1.0, -0.3455, -0.7169, 0,
     1.0, 1.7790, 0., 0,
+};*/
+static const float bt_601[] = {
+    1.0, 1.0, 1.0,        0.5,
+    0.0, -0.3455, 1.7790, 0,
+    1.4075, -0.7169, 0.,  0,
 };
 
 /* The ITU-R BT.709 conversion matrix for HDTV. */
+/* original, but we transpose to make the conversion
+ * in the shader easier
 static const float bt_709[] = {
     1.0, 0.0, 1.581, 0,
     1.0, -0.1881, -0.47, 0,
     1.0, 1.8629, 0., 0,
+};*/
+static const float bt_709[] = {
+    1.0,   1.0,     1.0,     0.5,
+    0.0,  -0.1881,  1.8629,  0,
+    1.581,-0.47   , 0.0,     0,
 };
 
 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
@@ -237,10 +251,12 @@ copy_packed_data(ScrnInfoPtr pScrn,
    umap = (char*)screen->transfer_map(screen, utrans);
    vmap = (char*)screen->transfer_map(screen, vtrans);
 
+   yidx = uidx = vidx = 0;
+
    switch (id) {
    case FOURCC_YV12: {
       for (i = 0; i < w; ++i) {
-         for (j = 0; i < h; ++j) {
+         for (j = 0; j < h; ++j) {
             /*XXX use src? */
             y1  = buf[j*w + i];
             u   = buf[(j/2) * (w/2) + i/2 + y_array_size];
@@ -301,21 +317,6 @@ copy_packed_data(ScrnInfoPtr pScrn,
 }
 
 
-static void
-setup_vs_video_constants(struct xorg_renderer *r, struct exa_pixmap_priv *dst)
-{
-   int width = dst->tex->width[0];
-   int height = dst->tex->height[0];
-   const int param_bytes = 8 * sizeof(float);
-   float vs_consts[8] = {
-      2.f/width, 2.f/height, 1, 1,
-      -1, -1, 0, 0
-   };
-
-   renderer_set_constants(r, PIPE_SHADER_VERTEX,
-                          vs_consts, param_bytes);
-}
-
 static void
 setup_fs_video_constants(struct xorg_renderer *r, boolean hdtv)
 {
@@ -327,19 +328,16 @@ setup_fs_video_constants(struct xorg_renderer *r, boolean hdtv)
 }
 
 static void
-draw_yuv(struct xorg_xv_port_priv *port, int src_x, int src_y,
-         int dst_x, int dst_y,
-         int w, int h)
+draw_yuv(struct xorg_xv_port_priv *port,
+         int src_x, int src_y, int src_w, int src_h,
+         int dst_x, int dst_y, int dst_w, int dst_h)
 {
-   int pos[4] = {src_x, src_y,
-                 dst_x, dst_y};
    struct pipe_texture **textures = port->yuv[port->current_set];
 
-   renderer_draw_textures(port->r,
-                          pos, w, h,
-                          textures,
-                          3, /*bound samplers/textures */
-                          NULL, NULL /* no transformations */);
+   renderer_draw_yuv(port->r,
+                     src_x, src_y, src_w, src_h,
+                     dst_x, dst_y, dst_w, dst_h,
+                     textures);
 }
 
 static void
@@ -422,8 +420,7 @@ static int
 display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
               RegionPtr dstRegion,
               int src_x, int src_y, int src_w, int src_h,
-              int dstX, int dstY,
-              short width, short height,
+              int dstX, int dstY, int dst_w, int dst_h,
               PixmapPtr pPixmap)
 {
    modesettingPtr ms = modesettingPTR(pScrn);
@@ -433,6 +430,12 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
    Bool hdtv;
    int x, y, w, h;
    struct exa_pixmap_priv *dst = exaGetPixmapDriverPrivate(pPixmap);
+   struct pipe_surface *dst_surf = xorg_gpu_surface(pPriv->r->pipe->screen, dst);
+
+   if (dst && !dst->tex) {
+       xorg_exa_set_shared_usage(pPixmap);
+       pScrn->pScreen->ModifyPixmapHeader(pPixmap, 0, 0, 0, 0, 0, NULL);
+   }
 
    if (!dst || !dst->tex)
       XORG_FALLBACK("Xv destination %s", !dst ? "!dst" : "!dst->tex");
@@ -448,31 +451,42 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
    pbox = REGION_RECTS(dstRegion);
    nbox = REGION_NUM_RECTS(dstRegion);
 
-   renderer_bind_framebuffer(pPriv->r, dst);
-   renderer_bind_viewport(pPriv->r, dst);
+   renderer_bind_destination(pPriv->r, dst_surf);
    bind_blend_state(pPriv);
-   renderer_bind_rasterizer(pPriv->r);
    bind_shaders(pPriv);
    bind_samplers(pPriv);
-   setup_vs_video_constants(pPriv->r, dst);
    setup_fs_video_constants(pPriv->r, hdtv);
 
+   exaMoveInPixmap(pPixmap);
+   DamageDamageRegion(&pPixmap->drawable, dstRegion);
+
    while (nbox--) {
       int box_x1 = pbox->x1;
       int box_y1 = pbox->y1;
       int box_x2 = pbox->x2;
       int box_y2 = pbox->y2;
+      float diff_x = (float)src_w / (float)dst_w;
+      float diff_y = (float)src_h / (float)dst_h;
+      int offset_x = box_x1 - dstX + pPixmap->screen_x;
+      int offset_y = box_y1 - dstY + pPixmap->screen_y;
+      int offset_w;
+      int offset_h;
 
       x = box_x1;
       y = box_y1;
       w = box_x2 - box_x1;
       h = box_y2 - box_y1;
 
-      draw_yuv(pPriv, x, y, x, y, w, h);
+      offset_w = dst_w - w;
+      offset_h = dst_h - h;
+
+      draw_yuv(pPriv, src_x + offset_x*diff_x, src_y + offset_y*diff_y,
+               src_w - offset_w*diff_x, src_h - offset_h*diff_x,
+               x, y, w, h);
 
       pbox++;
    }
-   DamageDamageRegion(&pPixmap->drawable, dstRegion);
+   DamageRegionProcessPending(&pPixmap->drawable);
 
    return TRUE;
 }
@@ -655,7 +669,7 @@ xorg_setup_textured_adapter(ScreenPtr pScreen)
 }
 
 void
-xorg_init_video(ScreenPtr pScreen)
+xorg_xv_init(ScreenPtr pScreen)
 {
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    /*modesettingPtr ms = modesettingPTR(pScrn);*/