Commit e9aa61e9f0d663d5b34a397b943b4d1df44e873d added code to copy the source whenever fb is using a window as the source picture, in case the composite tries to read portions of the window that lie outside its backing pixmap. However, it does this all the time and it always reads back the entire window.
KDE sometimes maps a 32-bit 1x1 InputOutput window, which compNewPixmap tries to fill with a RENDER Composite operation using the root window as a parent. This triggers the copy-back described above for the entire contents of the screen. This copy is not necessary when the window is fully contained within its backing storage, which is trivially true of the root window. Signed-off-by: Aaron Plattner <[email protected]> --- 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's 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 _______________________________________________ xorg-devel mailing list [email protected] http://lists.x.org/mailman/listinfo/xorg-devel
