saa, vmwgfx: Fix saa_copy_composite
authorThomas Hellstrom <thellstrom@vmware.com>
Wed, 14 Dec 2011 11:38:27 +0000 (12:38 +0100)
committerThomas Hellstrom <thellstrom@vmware.com>
Thu, 15 Dec 2011 07:32:14 +0000 (08:32 +0100)
The traditional accelerated copy methods aren't format aware.
Make saa copy format aware,and pass formats on to the driver copy function
if available. If the driver can't handle format conversions it needs to
return FALSE.

This fixes format confusion in the copy composite fastpath.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
saa/saa.h
saa/saa_render.c
vmwgfx/vmwgfx_saa.c

index 3101353..c7aa3b6 100644 (file)
--- a/saa/saa.h
+++ b/saa/saa.h
@@ -74,6 +74,8 @@ struct saa_pixmap {
     void *addr;
     void *override;
     enum saa_pixmap_loc auth_loc;
+    PictFormatShort src_format;
+    PictFormatShort dst_format;
     uint32_t pad[16];
 };
 
index 3c441da..c69f2c9 100644 (file)
@@ -311,35 +311,29 @@ saa_copy_composite(CARD8 op,
        ySrc + height > pSrc->pDrawable->height)
        return FALSE;
 
-    if (saa_pixmap(saa_get_drawable_pixmap(pSrc->pDrawable))->auth_loc !=
-       saa_loc_driver)
-       return FALSE;
+    if (op == PictOpSrc ||
+       (op == PictOpOver && PICT_FORMAT_A(pSrc->format) == 0 &&
+        pMask == NULL)) {
 
-    if ((op == PictOpSrc &&
-        (pSrc->format == pDst->format ||
-         (PICT_FORMAT_COLOR(pDst->format) &&
-          PICT_FORMAT_COLOR(pSrc->format) &&
-          pDst->format == PICT_FORMAT(PICT_FORMAT_BPP(pSrc->format),
-                                      PICT_FORMAT_TYPE(pSrc->format),
-                                      0,
-                                      PICT_FORMAT_R(pSrc->format),
-                                      PICT_FORMAT_G(pSrc->format),
-                                      PICT_FORMAT_B(pSrc->format))))) ||
-       (op == PictOpOver && pSrc->format == pDst->format &&
-        !PICT_FORMAT_A(pSrc->format))) {
-       Bool ret;
        int xoff, yoff;
-       PixmapPtr pixmap = saa_get_pixmap(pDst->pDrawable, &xoff, &yoff);
-
-       if (saa_pixmap(pixmap)->auth_loc != saa_loc_driver)
+       PixmapPtr dst_pix = saa_get_pixmap(pDst->pDrawable, &xoff, &yoff);
+       struct saa_pixmap *dst_spix = saa_pixmap(dst_pix);
+       struct saa_pixmap *src_spix =
+           saa_pixmap(saa_get_drawable_pixmap(pSrc->pDrawable));
+       int ret;
+
+       if (src_spix->auth_loc != saa_loc_driver ||
+           dst_spix->auth_loc != saa_loc_driver)
            return FALSE;
 
+       src_spix->src_format = pSrc->format;
+       dst_spix->dst_format = pDst->format;
+
        xDst += pDst->pDrawable->x;
        yDst += pDst->pDrawable->y;
        xSrc += pSrc->pDrawable->x;
        ySrc += pSrc->pDrawable->y;
 
-
        /*
         * Dst region is in backing pixmap space. We need to
         * translate it.
@@ -350,6 +344,10 @@ saa_copy_composite(CARD8 op,
                               REGION_NUM_RECTS(dst_region),
                               xSrc - xDst, ySrc - yDst, FALSE, FALSE);
        REGION_TRANSLATE(pScreen, dst_region, xoff, yoff);
+
+       src_spix->src_format = 0;
+       dst_spix->dst_format = 0;
+
        if (ret)
            return TRUE;
     }
index 7788ed5..0a6b98f 100644 (file)
@@ -896,10 +896,23 @@ vmwgfx_copy_prepare(struct saa_driver *driver,
         * Determine surface formats.
         */
 
-       if (!vmwgfx_hw_accel_stage(src_pixmap, 0, XA_FLAG_RENDER_TARGET, 0))
-           return FALSE;
-       if (!vmwgfx_hw_accel_stage(dst_pixmap, 0, XA_FLAG_RENDER_TARGET, 0))
-           return FALSE;
+       if (src_vpix->base.src_format == 0) {
+           if (!vmwgfx_hw_accel_stage(src_pixmap, 0, XA_FLAG_RENDER_TARGET, 0))
+               return FALSE;
+       } else {
+           if (PICT_FORMAT_TYPE(src_vpix->base.src_format) != PICT_TYPE_ARGB ||
+               !vmwgfx_hw_composite_src_stage(src_pixmap, src_vpix->base.src_format))
+               return FALSE;
+       }
+
+       if (dst_vpix->base.dst_format == 0) {
+           if (!vmwgfx_hw_accel_stage(dst_pixmap, 0, XA_FLAG_RENDER_TARGET, 0))
+               return FALSE;
+       } else {
+           if (PICT_FORMAT_TYPE(dst_vpix->base.dst_format) != PICT_TYPE_ARGB ||
+               !vmwgfx_hw_composite_dst_stage(dst_pixmap, dst_vpix->base.dst_format))
+               return FALSE;
+       }
 
        /*
         * Create hardware surfaces.