xf86-video-intel: uxa/uxa-render.c

Chris Wilson ickle at kemper.freedesktop.org
Sat Sep 19 17:17:31 PDT 2009


 uxa/uxa-render.c |   68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

New commits:
commit 57fc09cef28bad2e3e8455b93ef2927118f8a3a3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Sep 20 01:02:39 2009 +0100

    Avoid fallbacks for a1 src/mask
    
    Carl Worth did the hard work in identifying that the regression in
    cairo between X.org 1.6 and 1.7 was caused by cairo sending an a1
    mask to the server in 1.7 whereas in 1.6 cairo used local fallbacks
    (as the source was using RepeatPad, which triggers cairo's
    'buggy_pad_reflect' fallback for X.org 1.6). This was causing the driver
    to do a fallback to handle the a1 mask instead, which due to the GPU
    pipeline stall is much more expensive than the equivalent fallback in
    cairo.
    
    Reference:
      cairo's performance downgrades 4X with server master than server-1.6.
      https://bugs.freedesktop.org/show_bug.cgi?id=23184
    
    The fix is a relatively simple extension of the current
    uxa_picture_from_pixman_image() to use CompositePicture() instead of
    CopyArea() when we need to convert to a new format.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/uxa/uxa-render.c b/uxa/uxa-render.c
index e071fc4..8eee6a6 100644
--- a/uxa/uxa-render.c
+++ b/uxa/uxa-render.c
@@ -315,6 +315,68 @@ uxa_try_driver_solid_fill(PicturePtr	pSrc,
     return 1;
 }
 
+/* In order to avoid fallbacks when using an a1 source/mask,
+ * for example with non-antialiased trapezoids, we need to
+ * expand the bitmap into an a8 Picture. We do so by using the generic
+ * composition routines, which while may not be perfect is far faster
+ * than causing a fallback.
+ */
+static PicturePtr
+uxa_picture_from_a1_pixman_image (ScreenPtr pScreen,
+				  pixman_image_t *image)
+{
+    PicturePtr pPicture;
+    PicturePtr pSrc;
+    PixmapPtr pPixmap;
+    int width, height;
+    int error;
+
+    width = pixman_image_get_width (image);
+    height = pixman_image_get_height (image);
+
+    pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 8,
+					UXA_CREATE_PIXMAP_FOR_MAP);
+    if (!pPixmap)
+	return 0;
+
+    pPicture = CreatePicture (0, &pPixmap->drawable,
+			      PictureMatchFormat (pScreen, 8, PICT_a8),
+			      0, 0, serverClient, &error);
+    (*pScreen->DestroyPixmap) (pPixmap);
+    if (!pPicture)
+	return 0;
+
+    ValidatePicture (pPicture);
+
+    pPixmap = GetScratchPixmapHeader(pScreen, width, height, 1,
+				     BitsPerPixel (1),
+				     pixman_image_get_stride (image),
+				     pixman_image_get_data (image));
+    if (!pPixmap) {
+	FreePicture (pPicture, 0);
+	return 0;
+    }
+
+    pSrc = CreatePicture (0, &pPixmap->drawable,
+			  PictureMatchFormat (pScreen, 1, PICT_a1),
+			  0, 0, serverClient, &error);
+    FreeScratchPixmapHeader (pPixmap);
+    if (!pPicture) {
+	FreePicture (pPicture, 0);
+	return 0;
+    }
+
+    CompositePicture (PictOpSrc, pSrc, NULL, pPicture,
+		      0, 0,
+		      0, 0,
+		      0, 0,
+		      width, height);
+
+    FreePicture (pSrc, 0);
+
+    return pPicture;
+}
+
 static PicturePtr
 uxa_picture_from_pixman_image (ScreenPtr pScreen,
 			       pixman_image_t *image,
@@ -326,6 +388,9 @@ uxa_picture_from_pixman_image (ScreenPtr pScreen,
     int width, height, depth;
     int error;
 
+    if (format == PICT_a1)
+	return uxa_picture_from_a1_pixman_image (pScreen, image);
+
     width = pixman_image_get_width (image);
     height = pixman_image_get_height (image);
     depth = pixman_image_get_depth (image);
@@ -339,6 +404,9 @@ uxa_picture_from_pixman_image (ScreenPtr pScreen,
 			      PictureMatchFormat (pScreen, depth, format),
 			      0, 0, serverClient, &error);
     (*pScreen->DestroyPixmap) (pPixmap);
+    if (!pPicture)
+	return 0;
+
     ValidatePicture (pPicture);
 
     pPixmap = GetScratchPixmapHeader(pScreen, width, height, depth,


More information about the xorg-commit mailing list