From 7faede41c73a28603d0615af73d4fc0f5589eff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Tue, 12 Feb 2013 08:16:27 +0100 Subject: [PATCH] Use PutImage to convert QPixmap to XRenderPicture In case of native graphics system nothing is changed for the moment - the X11Pixmap-QPixmap bridge is continued to be used. But in case of graphics system raster (or Qt5) this relationship is no longer used. Instead the QPixmap is converted to a QImage and the image bits are put into the created X11Pixmap for this XRenderPicture. Note: Qt5 uses shm to transfer image data to drawables. This seems unsuited in this case as it's only a one time transformation. For Qt5 the native pixmap block needs to be removed and the ctor might be changed to taking an QImage as argument to make more clear that there is no mapping from QPixmap to X11Pixmap. --- libkwineffects/kwinxrenderutils.cpp | 26 +++++++++++++++----------- libkwineffects/kwinxrenderutils.h | 1 + 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/libkwineffects/kwinxrenderutils.cpp b/libkwineffects/kwinxrenderutils.cpp index 21d5167cdd..84d51d9236 100644 --- a/libkwineffects/kwinxrenderutils.cpp +++ b/libkwineffects/kwinxrenderutils.cpp @@ -23,7 +23,6 @@ along with this program. If not, see . #include #include -#include #include namespace KWin @@ -113,18 +112,23 @@ static Picture createPicture(Pixmap pix, int depth) XRenderPicture::XRenderPicture(QPixmap pix) { - if (Extensions::nonNativePixmaps()) { - Pixmap xPix = XCreatePixmap(display(), rootWindow(), pix.width(), pix.height(), pix.depth()); - QPixmap tempPix = QPixmap::fromX11Pixmap(xPix, QPixmap::ExplicitlyShared); - tempPix.fill(Qt::transparent); - QPainter p(&tempPix); - p.drawPixmap(QPoint(0, 0), pix); - p.end(); - d = new XRenderPictureData(createPicture(tempPix.handle(), tempPix.depth())); - XFreePixmap(display(), xPix); - } else { + if (!Extensions::nonNativePixmaps()) { d = new XRenderPictureData(createPicture(pix.handle(), pix.depth())); + return; } + QImage img(pix.toImage()); + const int depth = img.depth(); + xcb_pixmap_t xpix = xcb_generate_id(connection()); + xcb_create_pixmap(connection(), depth, xpix, rootWindow(), img.width(), img.height()); + + xcb_gcontext_t cid = xcb_generate_id(connection()); + xcb_create_gc(connection(), cid, xpix, 0, NULL); + xcb_put_image(connection(), XCB_IMAGE_FORMAT_Z_PIXMAP, xpix, cid, img.width(), img.height(), + 0, 0, 0, depth, img.byteCount(), img.constBits()); + xcb_free_gc(connection(), cid); + + d = new XRenderPictureData(createPicture(xpix, depth)); + xcb_free_pixmap(connection(), xpix); } XRenderPicture::XRenderPicture(Pixmap pix, int depth) diff --git a/libkwineffects/kwinxrenderutils.h b/libkwineffects/kwinxrenderutils.h index 9a11c16ab8..2037dcca3c 100644 --- a/libkwineffects/kwinxrenderutils.h +++ b/libkwineffects/kwinxrenderutils.h @@ -68,6 +68,7 @@ class KWIN_EXPORT XRenderPicture { public: explicit XRenderPicture(Picture pic = None); + // TODO: Qt5 - replace QPixmap by QImage to make it more obvious that it uses PutImage explicit XRenderPicture(QPixmap pix); XRenderPicture(Pixmap pix, int depth); operator Picture();