[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-video-qxl: Changes to 'upstream-experimental'



 configure.ac           |    4 
 src/Makefile.am        |    7 
 src/mspace.h           |    2 
 src/qxl.h              |   64 +
 src/qxl_cursor.c       |    4 
 src/qxl_driver.c       | 2420 +++++++++++++++++++++++++++++++++----------------
 src/qxl_edid.c         |  209 ++++
 src/qxl_image.c        |   20 
 src/qxl_mem.c          |   31 
 src/qxl_ring.c         |   20 
 src/qxl_surface.c      |  275 +++++
 src/spiceqxl_inputs.c  |   28 
 src/spiceqxl_io_port.c |    4 
 src/uxa/uxa-glyphs.c   |    9 
 src/uxa/uxa-priv.h     |    2 
 src/uxa/uxa.c          |    7 
 16 files changed, 2277 insertions(+), 829 deletions(-)

New commits:
commit d8bb331784792bfd35bf158875b434243f0fe019
Author: Søren Sandmann Pedersen <ssp@redhat.com>
Date:   Thu Sep 20 19:11:55 2012 -0400

    Version bump to 0.1.0

diff --git a/configure.ac b/configure.ac
index 11ef73c..48904a2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,7 +23,7 @@
 # Initialize Autoconf
 AC_PREREQ([2.60])
 AC_INIT([xf86-video-qxl],
-        [0.0.17],
+        [0.1.0],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         [xf86-video-qxl])
 AC_CONFIG_SRCDIR([Makefile.am])

commit 6520293e1e1f57bafbcf99592e766f810ce3ad2d
Author: Søren Sandmann Pedersen <ssp@redhat.com>
Date:   Thu Sep 20 16:26:36 2012 -0400

    Make the checks for composite and a8 return FALSE for Xspice
    
    They depend on the PCI revision which is not available for Xspice.

diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index 531c761..f52fec6 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -1385,17 +1385,27 @@ can_accelerate_picture (PicturePtr pict)
 static Bool
 qxl_has_composite (qxl_screen_t *qxl)
 {
+#ifndef XSPICE
     return
 	qxl->pci->revision >= 4			&&
 	QXL_HAS_CAP (qxl, SPICE_DISPLAY_CAP_COMPOSITE);
+#else
+    /* FIXME */
+    return FALSE;
+#endif
 }
 
 static Bool
 qxl_has_a8_surfaces (qxl_screen_t *qxl)
 {
+#ifndef XSPICE
     return
 	qxl->pci->revision >= 4			&&
 	QXL_HAS_CAP (qxl, SPICE_DISPLAY_CAP_A8_SURFACE);
+#else
+    /* FIXME */
+    return FALSE;
+#endif
 }
 
 static Bool

commit 7f0b820d919eb944eae201de03b186bd247b0324
Author: Jeremy White <jwhite@codeweavers.com>
Date:   Wed Sep 12 10:38:41 2012 -0500

    Only use dixScreenSpecificPrivatesSize if we have a new enough Xorg.
    
    This lets us continue to support older Xorg releases.
    This reverts 4f37cd85 and partially reverts 4a43bd4.

diff --git a/configure.ac b/configure.ac
index b8a4b35..11ef73c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -60,7 +60,7 @@ XORG_DRIVER_CHECK_EXT(XV, videoproto)
 XORG_DRIVER_CHECK_EXT(XFreeXDGA, xf86dgaproto)
 
 # Obtain compiler/linker options for the driver dependencies
-PKG_CHECK_MODULES(XORG, [xorg-server >= 1.12.99.901] xproto fontsproto $REQUIRED_MODULES)
+PKG_CHECK_MODULES(XORG, [xorg-server >= 1.0.99.901] xproto fontsproto $REQUIRED_MODULES)
 
 save_CFLAGS="$CFLAGS"
 CFLAGS="$XORG_CFLAGS"
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index 04a9aa8..531c761 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -1821,10 +1821,14 @@ qxl_screen_init (SCREEN_INIT_ARGS_DECL)
     DamageSetup (pScreen);
     
     /* We need to set totalPixmapSize after setup_uxa and Damage,
-     * as the privatssize is not computed correctly until then
+       as the privates size is not computed correctly until then
      */
+#if (XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 12, 99, 901, 0))
+    pScreen->totalPixmapSize = BitmapBytePad ((sizeof (PixmapRec) + dixPrivatesSize (PRIVATE_PIXMAP) ) * 8);
+#else
     pScreen->totalPixmapSize = BitmapBytePad((sizeof(PixmapRec) +
 			    dixScreenSpecificPrivatesSize(pScreen, PRIVATE_PIXMAP) ) * 8);
+#endif
 
     miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
     if (!miCreateDefColormap (pScreen))

commit fb038eb37906eba9a88e0cb6622a59f06dcc2a68
Author: Søren Sandmann <ssp@redhat.com>
Date:   Wed Sep 12 12:54:06 2012 -0400

    Don't issue composite commands or create a8 surfaces when not available
    
    When the device or the client are not capable of composite commands or a8
    surfaces, don't issue these commands.

diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index c7b8486..04a9aa8 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -47,6 +47,7 @@
 #include "qxl.h"
 #include "assert.h"
 #include "qxl_option_helpers.h"
+#include <spice/protocol.h>
 
 #ifdef XSPICE
 #include "spiceqxl_driver.h"
@@ -1378,6 +1379,25 @@ can_accelerate_picture (PicturePtr pict)
     return TRUE;
 }
 
+#define QXL_HAS_CAP(qxl, cap)						\
+    (((qxl)->rom->client_capabilities[(cap) / 8]) & (1 << ((cap) % 8)))
+
+static Bool
+qxl_has_composite (qxl_screen_t *qxl)
+{
+    return
+	qxl->pci->revision >= 4			&&
+	QXL_HAS_CAP (qxl, SPICE_DISPLAY_CAP_COMPOSITE);
+}
+
+static Bool
+qxl_has_a8_surfaces (qxl_screen_t *qxl)
+{
+    return
+	qxl->pci->revision >= 4			&&
+	QXL_HAS_CAP (qxl, SPICE_DISPLAY_CAP_A8_SURFACE);
+}
+
 static Bool
 qxl_check_composite (int op,
 		     PicturePtr pSrcPicture,
@@ -1386,7 +1406,10 @@ qxl_check_composite (int op,
 		     int width, int height)
 {
     int i;
-
+    ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
+    ScrnInfoPtr pScrn = xf86ScreenToScrn (pScreen);
+    qxl_screen_t *qxl = pScrn->driverPrivate;
+    
     static const int accelerated_ops[] =
     {
 	PictOpClear, PictOpSrc, PictOpDst, PictOpOver, PictOpOverReverse,
@@ -1397,6 +1420,9 @@ qxl_check_composite (int op,
 	PictOpHardLight, PictOpSoftLight, PictOpDifference, PictOpExclusion,
 	PictOpHSLHue, PictOpHSLSaturation, PictOpHSLColor, PictOpHSLLuminosity,
     };
+
+    if (!qxl_has_composite (qxl))
+	return FALSE;
     
     if (!can_accelerate_picture (pSrcPicture)	||
 	!can_accelerate_picture (pMaskPicture)	||
@@ -1502,6 +1528,15 @@ qxl_create_pixmap (ScreenPtr screen, int w, int h, int depth, unsigned usage)
     
     if (uxa_swapped_out (screen))
 	goto fallback;
+
+    if (depth == 8 && !qxl_has_a8_surfaces (qxl))
+    {
+	/* FIXME: When we detect a _change_ in the property of having a8
+	 * surfaces, we should copy all existing a8 surface to host memory
+	 * and then destroy the ones on the device.
+	 */
+	goto fallback;
+    }
     
     surface = qxl_surface_create (qxl->surface_cache, w, h, depth);
     

commit 4f37cd854f128714b8fcf3c0ab8afd72986407a0
Author: Johannes Obermayr <johannesobermayr@gmx.de>
Date:   Fri Sep 7 18:05:21 2012 +0200

    Require XServer >= 1.12.99.901 in conjunction with commit 4a43bd4.

diff --git a/configure.ac b/configure.ac
index 11ef73c..b8a4b35 100644
--- a/configure.ac
+++ b/configure.ac
@@ -60,7 +60,7 @@ XORG_DRIVER_CHECK_EXT(XV, videoproto)
 XORG_DRIVER_CHECK_EXT(XFreeXDGA, xf86dgaproto)
 
 # Obtain compiler/linker options for the driver dependencies
-PKG_CHECK_MODULES(XORG, [xorg-server >= 1.0.99.901] xproto fontsproto $REQUIRED_MODULES)
+PKG_CHECK_MODULES(XORG, [xorg-server >= 1.12.99.901] xproto fontsproto $REQUIRED_MODULES)
 
 save_CFLAGS="$CFLAGS"
 CFLAGS="$XORG_CFLAGS"

commit 7059cff787eef80f3d3345de705e912b292a9f97
Author: Søren Sandmann <ssp@redhat.com>
Date:   Thu Jul 12 09:53:31 2012 -0400

    Add Render support
    
    This commit adds support for using the new Composite command in spice
    protocol 0.12.0. This command is similar to the Composite request in
    the X Render protocol.
    
    By implementing the UXA composite stubs, we get acceleration for most
    common Composite requests, including glyphs.

diff --git a/src/qxl.h b/src/qxl.h
index d976fd5..8494550 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -392,7 +392,21 @@ Bool		    qxl_surface_put_image    (qxl_surface_t *dest,
 					      const char *src, int src_pitch);
 void		    qxl_surface_unref        (surface_cache_t *cache,
 					      uint32_t surface_id);
-					      
+
+/* composite */
+Bool		    qxl_surface_prepare_composite (int op,
+						   PicturePtr	src_picture,
+						   PicturePtr	mask_picture,
+						   PicturePtr   dst_picture,
+						   qxl_surface_t *src,
+						   qxl_surface_t *mask,
+						   qxl_surface_t *dest);
+void		   qxl_surface_composite (qxl_surface_t *dest,
+					  int src_x, int src_y,
+					  int mask_x, int mask_y,
+					  int dst_x, int dst_y,
+					  int width, int height);
+
 #if HAS_DEVPRIVATEKEYREC
 extern DevPrivateKeyRec uxa_pixmap_index;
 #else
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index 634f181..c7b8486 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -339,14 +339,14 @@ qxl_garbage_collect_internal (qxl_screen_t *qxl, uint64_t id)
     int is_cursor = FALSE;
     int is_surface = FALSE;
     int is_drawable = FALSE;
-
+    
     if ((id & POINTER_MASK) == 1)
 	is_cursor = TRUE;
     else if ((id & POINTER_MASK) == 2)
 	is_surface = TRUE;
     else
 	is_drawable = TRUE;
-
+    
     if (is_cursor && cmd->type == QXL_CURSOR_SET)
     {
 	struct QXLCursor *cursor = (void *)virtual_address (
@@ -358,7 +358,7 @@ qxl_garbage_collect_internal (qxl_screen_t *qxl, uint64_t id)
     {
 	struct QXLImage *image = virtual_address (
 	    qxl, u64_to_pointer (drawable->u.copy.src_bitmap), qxl->main_mem_slot);
-
+	
 	if (image->descriptor.type == SPICE_IMAGE_TYPE_SURFACE)
 	{
 	    qxl_surface_unref (qxl->surface_cache, image->surface_image.surface_id);
@@ -370,16 +370,50 @@ qxl_garbage_collect_internal (qxl_screen_t *qxl, uint64_t id)
 	    qxl_image_destroy (qxl, image);
 	}
     }
+    else if (is_drawable && drawable->type == QXL_DRAW_COMPOSITE)
+    {
+	struct QXLTransform *src_trans, *mask_trans;
+	struct QXLImage *src_img, *mask_img;
+	struct QXLComposite *composite = &drawable->u.composite;
+	
+	/* Source */
+	src_img = virtual_address (
+	    qxl, u64_to_pointer (drawable->u.composite.src), qxl->main_mem_slot);
+	qxl_free (qxl->mem, src_img, "image struct");
+	
+	if (composite->src_transform)
+	{
+	    src_trans = virtual_address (
+		qxl, u64_to_pointer (composite->src_transform), qxl->main_mem_slot);
+	    qxl_free (qxl->mem, src_trans, "transform");
+	}
+	
+	/* Mask */
+	if (drawable->u.composite.mask)
+	{
+	    if (drawable->u.composite.mask_transform)
+	    {
+		mask_trans = virtual_address (
+		    qxl, u64_to_pointer (drawable->u.composite.mask_transform), qxl->main_mem_slot);
+		
+		qxl_free (qxl->mem, mask_trans, "transform");
+	    }
+	    
+	    mask_img = virtual_address (
+		qxl, u64_to_pointer (drawable->u.composite.mask), qxl->main_mem_slot);
+	    qxl_free (qxl->mem, mask_img, "image struct");
+	}
+    }
     else if (is_surface && surface_cmd->type == QXL_SURFACE_CMD_DESTROY)
     {
 	qxl_surface_recycle (qxl->surface_cache, surface_cmd->surface_id);
 	qxl_surface_cache_sanity_check (qxl->surface_cache);
     }
-	    
+    
     id = info->next;
-	    
+    
     qxl_free (qxl->mem, info, "command");
-
+    
     return id;
 }
 
@@ -1198,12 +1232,6 @@ int uxa_pixmap_index;
 #endif
 
 static Bool
-unaccel (void)
-{
-    return FALSE;
-}
-
-static Bool
 qxl_prepare_access (PixmapPtr pixmap, RegionPtr region, uxa_access_t access)
 {
     return qxl_surface_prepare_access (get_surface (pixmap),
@@ -1312,6 +1340,131 @@ qxl_done_copy (PixmapPtr dest)
 {
 }
 
+/*
+ * Composite
+ */
+static Bool
+can_accelerate_picture (PicturePtr pict)
+{
+    if (!pict)
+	return TRUE;
+
+    if (pict->format != PICT_a8r8g8b8		&&
+	pict->format != PICT_x8r8g8b8		&&
+	pict->format != PICT_a8)
+    {
+	return FALSE;
+    }
+
+    if (!pict->pDrawable)
+	return FALSE;
+
+    if (pict->transform)
+    {
+	if (pict->transform->matrix[2][0] != 0	||
+	    pict->transform->matrix[2][1] != 0	||
+	    pict->transform->matrix[2][2] != pixman_int_to_fixed (1))
+	{
+	    return FALSE;
+	}
+    }
+
+    if (pict->filter != PictFilterBilinear	&&
+	pict->filter != PictFilterNearest)
+    {
+	return FALSE;
+    }
+    
+    return TRUE;
+}
+
+static Bool
+qxl_check_composite (int op,
+		     PicturePtr pSrcPicture,
+		     PicturePtr pMaskPicture,
+		     PicturePtr pDstPicture,
+		     int width, int height)
+{
+    int i;
+
+    static const int accelerated_ops[] =
+    {
+	PictOpClear, PictOpSrc, PictOpDst, PictOpOver, PictOpOverReverse,
+	PictOpIn, PictOpInReverse, PictOpOut, PictOpOutReverse,
+	PictOpAtop, PictOpAtopReverse, PictOpXor, PictOpAdd,
+	PictOpSaturate, PictOpMultiply, PictOpScreen, PictOpOverlay,
+	PictOpDarken, PictOpLighten, PictOpColorDodge, PictOpColorBurn,
+	PictOpHardLight, PictOpSoftLight, PictOpDifference, PictOpExclusion,
+	PictOpHSLHue, PictOpHSLSaturation, PictOpHSLColor, PictOpHSLLuminosity,
+    };
+    
+    if (!can_accelerate_picture (pSrcPicture)	||
+	!can_accelerate_picture (pMaskPicture)	||
+	!can_accelerate_picture (pDstPicture))
+    {
+	return FALSE;
+    }
+
+    for (i = 0; i < sizeof (accelerated_ops) / sizeof (accelerated_ops[0]); ++i)
+    {
+	if (accelerated_ops[i] == op)
+	    goto found;
+    }
+    return FALSE;
+
+found:
+    return TRUE;
+}
+
+static Bool
+qxl_check_composite_target (PixmapPtr pixmap)
+{
+    return TRUE;
+}
+
+static Bool
+qxl_check_composite_texture (ScreenPtr screen,
+			     PicturePtr pPicture)
+{
+    return TRUE;
+}
+
+static Bool
+qxl_prepare_composite (int op,
+		       PicturePtr pSrcPicture,
+		       PicturePtr pMaskPicture,
+		       PicturePtr pDstPicture,
+		       PixmapPtr pSrc,
+		       PixmapPtr pMask,
+		       PixmapPtr pDst)
+{
+    return qxl_surface_prepare_composite (
+	op, pSrcPicture, pMaskPicture, pDstPicture,
+	get_surface (pSrc),
+	pMask? get_surface (pMask) : NULL,
+	get_surface (pDst));
+}
+
+static void
+qxl_composite (PixmapPtr pDst,
+	       int src_x, int src_y,
+	       int mask_x, int mask_y,
+	       int dst_x, int dst_y,
+	       int width, int height)
+{
+    qxl_surface_composite (
+	get_surface (pDst),
+	src_x, src_y,
+	mask_x, mask_y,
+	dst_x, dst_y, width, height);
+}
+
+static void
+qxl_done_composite (PixmapPtr pDst)
+{
+    ;
+}
+
 static Bool
 qxl_put_image (PixmapPtr pDst, int x, int y, int w, int h,
                char *src, int src_pitch)
@@ -1453,12 +1606,12 @@ setup_uxa (qxl_screen_t *qxl, ScreenPtr screen)
     qxl->uxa->done_copy = qxl_done_copy;
     
     /* Composite */
-    qxl->uxa->check_composite = (typeof (qxl->uxa->check_composite))unaccel;
-    qxl->uxa->check_composite_target = (typeof (qxl->uxa->check_composite_target))unaccel;
-    qxl->uxa->check_composite_texture = (typeof (qxl->uxa->check_composite_texture))unaccel;
-    qxl->uxa->prepare_composite = (typeof (qxl->uxa->prepare_composite))unaccel;
-    qxl->uxa->composite = (typeof (qxl->uxa->composite))unaccel;
-    qxl->uxa->done_composite = (typeof (qxl->uxa->done_composite))unaccel;
+    qxl->uxa->check_composite = qxl_check_composite;
+    qxl->uxa->check_composite_target = qxl_check_composite_target;
+    qxl->uxa->check_composite_texture = qxl_check_composite_texture;
+    qxl->uxa->prepare_composite = qxl_prepare_composite;
+    qxl->uxa->composite = qxl_composite;
+    qxl->uxa->done_composite = qxl_done_composite;
     
     /* PutImage */
     qxl->uxa->put_image = qxl_put_image;
@@ -1625,6 +1778,10 @@ qxl_screen_init (SCREEN_INIT_ARGS_DECL)
     pScreen->SaveScreen = qxl_blank_screen;
     
     setup_uxa (qxl, pScreen);
+
+#if 0
+    uxa_set_fallback_debug(pScreen, TRUE);
+#endif
     
     DamageSetup (pScreen);
     
diff --git a/src/qxl_image.c b/src/qxl_image.c
index 4d9bc77..fcecf8a 100644
--- a/src/qxl_image.c
+++ b/src/qxl_image.c
@@ -138,7 +138,7 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
 	struct QXLImage *image;
 	struct QXLDataChunk *head;
 	struct QXLDataChunk *tail;
-	int dest_stride = width * Bpp;
+	int dest_stride = (width * Bpp + 3) & (~3);
 	int h;
 
 	data += y * stride + x * Bpp;
@@ -216,7 +216,7 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
 	image->bitmap.flags = SPICE_BITMAP_FLAGS_TOP_DOWN;
 	image->bitmap.x = width;
 	image->bitmap.y = height;
-	image->bitmap.stride = width * Bpp;
+	image->bitmap.stride = dest_stride;
 	image->bitmap.palette = 0;
 	image->bitmap.data = physical_address (qxl, head, qxl->main_mem_slot);
 
diff --git a/src/qxl_surface.c b/src/qxl_surface.c
index 0169350..e88675f 100644
--- a/src/qxl_surface.c
+++ b/src/qxl_surface.c
@@ -89,6 +89,17 @@ struct qxl_surface_t
     {
 	qxl_surface_t *copy_src;
 	Pixel	       solid_pixel;
+
+	struct
+	{
+	    int			op;
+	    PicturePtr		src_picture;
+	    PicturePtr		mask_picture;
+	    PicturePtr		dest_picture;
+	    qxl_surface_t	*src;
+	    qxl_surface_t	*mask;
+	    qxl_surface_t	*dest;
+	} composite;
     } u;
 };
 
@@ -302,7 +313,7 @@ get_formats (int bpp, SpiceBitmapFmt *format, pixman_format_code_t *pformat)
 	break;
     }
 }
-		 
+
 static qxl_surface_t *
 surface_get_from_cache (surface_cache_t *cache, int width, int height, int bpp)
 {
@@ -674,7 +685,8 @@ retry:
 
     push_surface_cmd (cache, cmd);
 
-    dev_addr = (uint32_t *)((uint8_t *)surface->address + stride * (height - 1));
+    dev_addr
+	= (uint32_t *)((uint8_t *)surface->address + stride * (height - 1));
 
     surface->dev_image = pixman_image_create_bits (
 	pformat, width, height, dev_addr, - stride);
@@ -735,7 +747,7 @@ qxl_surface_create (surface_cache_t *    cache,
     if (!(surface = surface_get_from_cache (cache, width, height, bpp)))
 	if (!(surface = surface_send_create (cache, width, height, bpp)))
 	    return NULL;
-    
+
     surface->next = cache->live_surfaces;
     surface->prev = NULL;
     if (cache->live_surfaces)
@@ -1367,6 +1379,189 @@ qxl_surface_copy (qxl_surface_t *dest,
     push_drawable (qxl, drawable);
 }
 
+/* composite */
+Bool
+qxl_surface_prepare_composite (int op,
+			       PicturePtr	src_picture,
+			       PicturePtr	mask_picture,
+			       PicturePtr	dest_picture,
+			       qxl_surface_t *	src,
+			       qxl_surface_t *	mask,
+			       qxl_surface_t *	dest)
+{
+    dest->u.composite.op = op;
+    dest->u.composite.src_picture = src_picture;
+    dest->u.composite.mask_picture = mask_picture;
+    dest->u.composite.dest_picture = dest_picture;
+    dest->u.composite.src = src;
+    dest->u.composite.mask = mask;
+    dest->u.composite.dest = dest;
+    
+    return TRUE;
+}
+
+static QXLImage *
+image_from_picture (qxl_screen_t *qxl,
+		    PicturePtr picture,
+		    qxl_surface_t *surface,
+		    int *force_opaque)
+{
+    struct QXLImage *image = qxl_allocnf (qxl, sizeof *image, "image struct for picture");
+
+    image->descriptor.id = 0;
+    image->descriptor.type = SPICE_IMAGE_TYPE_SURFACE;
+    image->descriptor.width = 0;
+    image->descriptor.height = 0;
+    image->surface_image.surface_id = surface->id;
+
+    if (picture->format == PICT_x8r8g8b8)
+	*force_opaque = TRUE;
+    else
+	*force_opaque = FALSE;
+    
+    return image;
+}
+
+static QXLTransform *
+get_transform (qxl_screen_t *qxl, PictTransform *transform)
+{
+    if (transform)
+    {
+	QXLTransform *qxform = qxl_allocnf (qxl, sizeof (QXLTransform), "transform");
+
+	qxform->t00 = transform->matrix[0][0];
+	qxform->t01 = transform->matrix[0][1];
+	qxform->t02 = transform->matrix[0][2];
+	qxform->t10 = transform->matrix[1][0];
+	qxform->t11 = transform->matrix[1][1];
+	qxform->t12 = transform->matrix[1][2];
+
+	return qxform;
+    }
+    else
+    {
+	return NULL;
+    }
+}
+
+static QXLRect
+full_rect (qxl_surface_t *surface)
+{
+    QXLRect r;
+    int w = pixman_image_get_width (surface->host_image);
+    int h = pixman_image_get_height (surface->host_image);
+	    
+    r.left = r.top = 0;
+    r.right = w;
+    r.bottom = h;
+
+    return r;
+}
+
+void
+qxl_surface_composite (qxl_surface_t *dest,
+		       int src_x, int src_y,
+		       int mask_x, int mask_y,
+		       int dest_x, int dest_y,
+		       int width, int height)
+{
+    qxl_screen_t *qxl = dest->cache->qxl;
+    PicturePtr src = dest->u.composite.src_picture;
+    qxl_surface_t *qsrc = dest->u.composite.src;
+    PicturePtr mask = dest->u.composite.mask_picture;
+    qxl_surface_t *qmask = dest->u.composite.mask;
+    int op = dest->u.composite.op;
+    struct QXLDrawable *drawable;
+    QXLComposite *composite;
+    QXLRect rect;
+    QXLImage *img;
+    QXLTransform *trans;
+    int n_deps = 0;
+    int force_opaque;
+
+#if 0
+    ErrorF ("QXL Composite: src:       %x (%d %d) id: %d; \n"
+	    "               mask:      id: %d\n"
+	    "               dest:      %x %d %d %d %d (id: %d)\n",
+	    dest->u.composite.src_picture->format,
+	    dest->u.composite.src_picture->pDrawable->width,
+	    dest->u.composite.src_picture->pDrawable->height,
+	    dest->u.composite.src->id,
+	    dest->u.composite.mask? dest->u.composite.mask->id : -1,
+	    dest->u.composite.dest_picture->format,
+	    dest_x, dest_y, width, height,
+	    dest->id
+	);
+#endif
+
+    rect.left = dest_x;
+    rect.right = dest_x + width;
+    rect.top = dest_y;
+    rect.bottom = dest_y + height;
+    
+    drawable = make_drawable (qxl, dest->id, QXL_DRAW_COMPOSITE, &rect);
+
+    composite = &drawable->u.composite;
+
+    composite->flags = 0;
+
+    if (dest->u.composite.dest_picture->format == PICT_x8r8g8b8)
+	composite->flags |= SPICE_COMPOSITE_DEST_OPAQUE;
+    
+    composite->flags |= (op & 0xff);
+
+    img = image_from_picture (qxl, src, qsrc, &force_opaque);
+    if (force_opaque)
+	composite->flags |= SPICE_COMPOSITE_SOURCE_OPAQUE;
+    composite->src = physical_address (qxl, img, qxl->main_mem_slot);
+    composite->flags |= (src->filter << 8);
+    composite->flags |= (src->repeat << 14);
+    trans = get_transform (qxl, src->transform);
+    composite->src_transform = trans?
+	physical_address (qxl, trans, qxl->main_mem_slot) : 0x00000000;
+
+    drawable->surfaces_dest[n_deps] = qsrc->id;
+    drawable->surfaces_rects[n_deps] = full_rect (qsrc);
+
+    n_deps++;
+    
+    if (mask)
+    {
+	img = image_from_picture (qxl, mask, qmask, &force_opaque);
+	if (force_opaque)
+	    composite->flags |= SPICE_COMPOSITE_MASK_OPAQUE;
+	composite->mask = physical_address (qxl, img, qxl->main_mem_slot);
+	composite->flags |= (mask->filter << 11);
+	composite->flags |= (mask->repeat << 16);
+	composite->flags |= (mask->componentAlpha << 18);
+
+	drawable->surfaces_dest[n_deps] = qmask->id;
+	drawable->surfaces_rects[n_deps] = full_rect (qmask);
+	n_deps++;
+	
+	trans = get_transform (qxl, src->transform);
+	composite->mask_transform = trans?
+	    physical_address (qxl, trans, qxl->main_mem_slot) : 0x00000000;
+    }
+    else
+    {
+	composite->mask = 0x00000000;
+	composite->mask_transform = 0x00000000;
+    }
+
+    drawable->surfaces_dest[n_deps] = dest->id;
+    drawable->surfaces_rects[n_deps] = full_rect (dest);
+    
+    composite->src_origin.x = src_x;
+    composite->src_origin.y = src_y;
+    composite->mask_origin.x = mask_x;
+    composite->mask_origin.y = mask_y;
+
+    drawable->effect = QXL_EFFECT_BLEND;
+    
+    push_drawable (qxl, drawable);
+}
+
 Bool
 qxl_surface_put_image (qxl_surface_t *dest,
 		       int x, int y, int width, int height,

commit 2fecf3a171e64ca0dad5653ed740409dc5af2edf
Author: Søren Sandmann <ssp@redhat.com>
Date:   Tue Dec 20 09:01:17 2011 -0500

    Enable 8 bit pixmaps.
    
    a8 surfaces are now supported with the 8BIT_A format in spice, so we
    can have support 8 bit pixmaps.

diff --git a/src/qxl_image.c b/src/qxl_image.c
index 6211035..4d9bc77 100644
--- a/src/qxl_image.c
+++ b/src/qxl_image.c
@@ -202,7 +202,7 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
 	}
 	else if (Bpp == 1)
 	{
-	    image->bitmap.format = SPICE_BITMAP_FMT_8BIT;
+	    image->bitmap.format = SPICE_BITMAP_FMT_8BIT_A;
 	}
 	else if (Bpp == 4)
 	{
diff --git a/src/qxl_surface.c b/src/qxl_surface.c
index 579a284..0169350 100644
--- a/src/qxl_surface.c
+++ b/src/qxl_surface.c
@@ -706,6 +706,7 @@ qxl_surface_create (surface_cache_t *    cache,
 	return NULL;
     }
 
+#if 0
     if (bpp == 8)
       {
 	static int warned;
@@ -717,6 +718,7 @@ qxl_surface_create (surface_cache_t *    cache,
 	
 	return NULL;
       }
+#endif
     
     if (bpp != 8 && bpp != 16 && bpp != 32 && bpp != 24)
     {

commit 37c97620da959d9214abfc760835aa3031d54daa
Author: Søren Sandmann <ssp@redhat.com>
Date:   Sun Aug 12 11:03:16 2012 -0400

    Use an RGBA format for 32 bit images
    
    With the upcoming Render changes, we can no longer assume that the
    fourth channel of images is unused.

diff --git a/src/qxl_image.c b/src/qxl_image.c
index 68d063e..6211035 100644
--- a/src/qxl_image.c
+++ b/src/qxl_image.c
@@ -206,7 +206,7 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
 	}
 	else if (Bpp == 4)
 	{
-	    image->bitmap.format = SPICE_BITMAP_FMT_32BIT;
+	    image->bitmap.format = SPICE_BITMAP_FMT_RGBA;
 	}
 	else
 	{
@@ -220,10 +220,6 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
 	image->bitmap.palette = 0;
 	image->bitmap.data = physical_address (qxl, head, qxl->main_mem_slot);
 
-#if 0
-	ErrorF ("%p has size %d %d\n", image, width, height);
-#endif
-	
 	/* Add to hash table if caching is enabled */
 	if ((fallback && qxl->enable_fallback_cache)	||
 	    (!fallback && qxl->enable_image_cache))

commit 1e89aab2dc0beb01f43a2397faa05a8cd01a7547
Author: Søren Sandmann <ssp@redhat.com>
Date:   Wed Aug 22 15:27:09 2012 -0400

    uxa: Plug leak in uxa_glyphs_via_masks
    
    If prepare_composite() fails, we need to free the temporary mask
    before returning.

diff --git a/src/uxa/uxa-glyphs.c b/src/uxa/uxa-glyphs.c
index 997feb7..6dd8e58 100644
--- a/src/uxa/uxa-glyphs.c
+++ b/src/uxa/uxa-glyphs.c
@@ -992,8 +992,10 @@ uxa_glyphs_via_mask(CARD8 op,
 
 				if (!uxa_screen->info->prepare_composite(PictOpAdd,
 									 this_atlas, NULL, mask,
-									 src_pixmap, NULL, pixmap))
+									 src_pixmap, NULL, pixmap)) {
+				        FreePicture(mask, 0);
 					return -1;
+				}
 
 				glyph_atlas = this_atlas;
 			}

commit afd8d20b84a4b4e9b22483e379d594517333e8c7
Author: Søren Sandmann <ssp@redhat.com>
Date:   Tue Aug 14 14:20:11 2012 -0400

    uxa-glyphs: don't prepare composite when dest is not offscreen
    
    It is possbible for a pixmap to not be in video memory after
    uxa_clear_pixmap() was called. When this happens, we need to destroy
    the pixmap and return 1 to indicate that the operation can't be
    accelerated.

diff --git a/src/uxa/uxa-glyphs.c b/src/uxa/uxa-glyphs.c
index dd50dfc..997feb7 100644
--- a/src/uxa/uxa-glyphs.c
+++ b/src/uxa/uxa-glyphs.c
@@ -932,6 +932,11 @@ uxa_glyphs_via_mask(CARD8 op,
 
 	uxa_clear_pixmap(screen, uxa_screen, pixmap);
 
+	if (!uxa_pixmap_is_offscreen(pixmap)) {
+		screen->DestroyPixmap(pixmap);
+		return 1;
+	}
+	
 	component_alpha = NeedsComponent(maskFormat->format);
 	mask = CreatePicture(0, &pixmap->drawable,
 			      maskFormat, CPComponentAlpha,

commit e738d00e1fb3cd469f850765e2b42976c2a85764
Author: Søren Sandmann <ssp@redhat.com>
Date:   Tue Aug 21 12:56:52 2012 -0400

    Improved support for memory debugging.
    
    Make all memory allocation functions take a string that will explain
    what the memory will be used for. This allows debug print statements
    to be added to the allocation functions and could later potentially be
    used for more detailed statistics.

diff --git a/src/qxl.h b/src/qxl.h
index 1d9ca75..d976fd5 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -446,12 +446,15 @@ struct qxl_mem *  qxl_mem_create       (void                   *base,
 void              qxl_mem_dump_stats   (struct qxl_mem         *mem,
 					const char             *header);
 void *            qxl_alloc            (struct qxl_mem         *mem,
-					unsigned long           n_bytes);
+					unsigned long           n_bytes,
+					const char *            name);
 void              qxl_free             (struct qxl_mem         *mem,
-					void                   *d);
+					void                   *d,
+					const char *            name);
 void              qxl_mem_free_all     (struct qxl_mem         *mem);
 void *            qxl_allocnf          (qxl_screen_t           *qxl,
-					unsigned long           size);
+					unsigned long           size,
+					const char *            name);
 int		   qxl_garbage_collect (qxl_screen_t *qxl);
 
 #ifdef DEBUG_QXL_MEM
diff --git a/src/qxl_cursor.c b/src/qxl_cursor.c
index 72c6c9f..459cbd7 100644
--- a/src/qxl_cursor.c
+++ b/src/qxl_cursor.c
@@ -50,7 +50,7 @@ static struct QXLCursorCmd *
 qxl_alloc_cursor_cmd(qxl_screen_t *qxl)
 {
     struct QXLCursorCmd *cmd =
-	qxl_allocnf (qxl, sizeof(struct QXLCursorCmd));
+	qxl_allocnf (qxl, sizeof(struct QXLCursorCmd), "cursor command");
 
     cmd->release_info.id = pointer_to_u64 (cmd) | 1;
     
@@ -94,7 +94,7 @@ qxl_load_cursor_argb (ScrnInfoPtr pScrn, CursorPtr pCurs)
 
     struct QXLCursorCmd *cmd = qxl_alloc_cursor_cmd (qxl);
     struct QXLCursor *cursor =
-	qxl_allocnf(qxl, sizeof(struct QXLCursor) + size);
+	qxl_allocnf(qxl, sizeof(struct QXLCursor) + size, "cursor data");
 
     cursor->header.unique = 0;
     cursor->header.type = SPICE_CURSOR_TYPE_ALPHA;
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index 7535e11..634f181 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -331,7 +331,7 @@ qxl_garbage_collect_internal (qxl_screen_t *qxl, uint64_t id)
      * question is a cursor command
      */
 #define POINTER_MASK ((1 << 2) - 1)
-    
+	    
     union QXLReleaseInfo *info = u64_to_pointer (id & ~POINTER_MASK);
     struct QXLCursorCmd *cmd = (struct QXLCursorCmd *)info;
     struct QXLDrawable *drawable = (struct QXLDrawable *)info;
@@ -339,34 +339,31 @@ qxl_garbage_collect_internal (qxl_screen_t *qxl, uint64_t id)
     int is_cursor = FALSE;
     int is_surface = FALSE;
     int is_drawable = FALSE;
-    
+
     if ((id & POINTER_MASK) == 1)
 	is_cursor = TRUE;
     else if ((id & POINTER_MASK) == 2)


Reply to: