11c921d
From 8940385270d2752e03117fa6c24adafff7586422 Mon Sep 17 00:00:00 2001
11c921d
From: Aaron Plattner <aaronp@nvidia.com>
11c921d
Date: Tue, 24 Nov 2009 11:08:42 -0500
11c921d
Subject: [PATCH] Patch over performance regression in KDE
11c921d
11c921d
---
11c921d
 fb/fbpict.c |   27 ++++++++++++++++++++++++++-
11c921d
 1 files changed, 26 insertions(+), 1 deletions(-)
11c921d
11c921d
diff --git a/fb/fbpict.c b/fb/fbpict.c
11c921d
index 5c96427..5799e37 100644
11c921d
--- a/fb/fbpict.c
11c921d
+++ b/fb/fbpict.c
11c921d
@@ -317,6 +317,27 @@ destroy_drawable (pixman_image_t *image, void *data)
11c921d
     pScreen->DestroyPixmap ((PixmapPtr)pDrawable);
11c921d
 }
11c921d
 
11c921d
+/*
11c921d
+ * Returns TRUE when the specified window is fully contained within its bounding
11c921d
+ * pixmap.
11c921d
+ */
11c921d
+static Bool
11c921d
+window_is_fully_contained(WindowPtr pWin)
11c921d
+{
11c921d
+    PixmapPtr pBoundingPix = (*pWin->drawable.pScreen->GetWindowPixmap)(pWin);
11c921d
+    int x = pWin->drawable.x, y = pWin->drawable.y;
11c921d
+
11c921d
+#ifdef COMPOSITE
11c921d
+    /* Translate from screen coordinates to pixmap coordinates */
11c921d
+    x -= pBoundingPix->screen_x;
11c921d
+    y -= pBoundingPix->screen_y;
11c921d
+#endif
11c921d
+
11c921d
+    return x >= 0 && y >= 0 &&
11c921d
+	   x + pWin->drawable.width <= pBoundingPix->drawable.width &&
11c921d
+	   y + pWin->drawable.height <= pBoundingPix->drawable.height;
11c921d
+}
11c921d
+
11c921d
 static pixman_image_t *
11c921d
 create_bits_picture (PicturePtr pict,
11c921d
 		     Bool	has_clip,
11c921d
@@ -328,7 +349,11 @@ create_bits_picture (PicturePtr pict,
11c921d
     pixman_image_t *image;
11c921d
     DrawablePtr drawable;
11c921d
 
11c921d
-    if (is_src && pict->pDrawable->type == DRAWABLE_WINDOW)
11c921d
+    /* Copy the source window if part of it lies outside its bounding pixmap to
11c921d
+     * avoid reading outside that pixmap's bounds, since Pixman doesn't clip the
11c921d
+     * source image per pixel */
11c921d
+    if (is_src && pict->pDrawable->type == DRAWABLE_WINDOW &&
11c921d
+	    !window_is_fully_contained((WindowPtr)pict->pDrawable))
11c921d
 	drawable = copy_drawable (pict->pDrawable);
11c921d
     else
11c921d
 	drawable = pict->pDrawable;
11c921d
-- 
11c921d
1.6.5.2
11c921d