This patch speeds up a simple test app that maps a 1x1 ARGB window from 11 seconds to 0.005 seconds. This patch needs to be applied after http://cvs.fedora.redhat.com/viewvc/rpms/xorg-x11-server/F-12/xserver-1.7.1-window-pictures.patch?revision=1.4&view=markup or the server will still be subject to the corruption and crash bugs that e9aa61e introduced. fb/fbpict.c | 27 ++++++++++++++++++++++++++- 1 files changed, 26 insertions(+), 1 deletions(-) diff --git a/fb/fbpict.c b/fb/fbpict.c index 5c96427..5799e37 100644 --- a/fb/fbpict.c +++ b/fb/fbpict.c @@ -317,6 +317,27 @@ destroy_drawable (pixman_image_t *image, void *data) pScreen->DestroyPixmap ((PixmapPtr)pDrawable); } +/* + * Returns TRUE when the specified window is fully contained within its bounding + * pixmap. + */ +static Bool +window_is_fully_contained(WindowPtr pWin) +{ + PixmapPtr pBoundingPix = (*pWin->drawable.pScreen->GetWindowPixmap)(pWin); + int x = pWin->drawable.x, y = pWin->drawable.y; + +#ifdef COMPOSITE + /* Translate from screen coordinates to pixmap coordinates */ + x -= pBoundingPix->screen_x; + y -= pBoundingPix->screen_y; +#endif + + return x >= 0 && y >= 0 && + x + pWin->drawable.width <= pBoundingPix->drawable.width && + y + pWin->drawable.height <= pBoundingPix->drawable.height; +} + static pixman_image_t * create_bits_picture (PicturePtr pict, Bool has_clip, @@ -328,7 +349,11 @@ create_bits_picture (PicturePtr pict, pixman_image_t *image; DrawablePtr drawable; - if (is_src && pict->pDrawable->type == DRAWABLE_WINDOW) + /* Copy the source window if part of it lies outside its bounding pixmap to + * avoid reading outside that pixmap' bounds, since Pixman doesn't clip the + * source image per pixel */ + if (is_src && pict->pDrawable->type == DRAWABLE_WINDOW && + !window_is_fully_contained((WindowPtr)pict->pDrawable)) drawable = copy_drawable (pict->pDrawable); else drawable = pict->pDrawable; -- 1.6.3.3