diff --git a/libkwineffects/kwinxrenderutils.cpp b/libkwineffects/kwinxrenderutils.cpp index 9c53182903..8d383b041f 100644 --- a/libkwineffects/kwinxrenderutils.cpp +++ b/libkwineffects/kwinxrenderutils.cpp @@ -27,6 +27,19 @@ along with this program. If not, see . namespace KWin { +namespace XRenderUtils +{ +static xcb_connection_t *s_connection = nullptr; +static xcb_window_t s_rootWindow = XCB_WINDOW_NONE; + +void init(xcb_connection_t *connection, xcb_window_t rootWindow) +{ + s_connection = connection; + s_rootWindow = rootWindow; +} + +} // namespace + // adapted from Qt, because this really sucks ;) xcb_render_color_t preMultiply(const QColor &c, float opacity) { @@ -44,16 +57,16 @@ xcb_render_color_t preMultiply(const QColor &c, float opacity) XRenderPicture xRenderFill(const xcb_render_color_t &c) { - xcb_pixmap_t pixmap = xcb_generate_id(connection()); - xcb_create_pixmap(connection(), 32, pixmap, rootWindow(), 1, 1); + xcb_pixmap_t pixmap = xcb_generate_id(XRenderUtils::s_connection); + xcb_create_pixmap(XRenderUtils::s_connection, 32, pixmap, XRenderUtils::s_rootWindow, 1, 1); XRenderPicture fill(pixmap, 32); - xcb_free_pixmap(connection(), pixmap); + xcb_free_pixmap(XRenderUtils::s_connection, pixmap); uint32_t values[] = {true}; - xcb_render_change_picture(connection(), fill, XCB_RENDER_CP_REPEAT, values); + xcb_render_change_picture(XRenderUtils::s_connection, fill, XCB_RENDER_CP_REPEAT, values); xcb_rectangle_t rect = {0, 0, 1, 1}; - xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, fill, c, 1, &rect); + xcb_render_fill_rectangles(XRenderUtils::s_connection, XCB_RENDER_PICT_OP_SRC, fill, c, 1, &rect); return fill; } @@ -71,7 +84,7 @@ XRenderPicture xRenderBlendPicture(double opacity) s_blendPicture = xRenderFill(s_blendColor); } else { xcb_rectangle_t rect = {0, 0, 1, 1}; - xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, s_blendPicture, s_blendColor, 1, &rect); + xcb_render_fill_rectangles(XRenderUtils::s_connection, XCB_RENDER_PICT_OP_SRC, s_blendPicture, s_blendColor, 1, &rect); } return s_blendPicture; } @@ -80,9 +93,10 @@ static xcb_render_picture_t createPicture(xcb_pixmap_t pix, int depth) { if (pix == XCB_PIXMAP_NONE) return XCB_RENDER_PICTURE_NONE; + xcb_connection_t *c = XRenderUtils::s_connection; static QHash s_renderFormats; if (!s_renderFormats.contains(depth)) { - xcb_render_query_pict_formats_reply_t *formats = xcb_render_query_pict_formats_reply(connection(), xcb_render_query_pict_formats_unchecked(connection()), nullptr); + xcb_render_query_pict_formats_reply_t *formats = xcb_render_query_pict_formats_reply(c, xcb_render_query_pict_formats_unchecked(c), nullptr); if (!formats) { return XCB_RENDER_PICTURE_NONE; } @@ -101,8 +115,8 @@ static xcb_render_picture_t createPicture(xcb_pixmap_t pix, int depth) qWarning() << "Could not find XRender format for depth" << depth; return XCB_RENDER_PICTURE_NONE; } - xcb_render_picture_t pic = xcb_generate_id(connection()); - xcb_render_create_picture(connection(), pic, pix, it.value(), 0, nullptr); + xcb_render_picture_t pic = xcb_generate_id(c); + xcb_render_create_picture(c, pic, pix, it.value(), 0, nullptr); return pic; } @@ -113,18 +127,19 @@ XRenderPicture::XRenderPicture(const QImage &img) void XRenderPicture::fromImage(const QImage &img) { + xcb_connection_t *c = XRenderUtils::s_connection; 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_pixmap_t xpix = xcb_generate_id(c); + xcb_create_pixmap(c, depth, xpix, XRenderUtils::s_rootWindow, img.width(), img.height()); - xcb_gcontext_t cid = xcb_generate_id(connection()); - xcb_create_gc(connection(), cid, xpix, 0, nullptr); - xcb_put_image(connection(), XCB_IMAGE_FORMAT_Z_PIXMAP, xpix, cid, img.width(), img.height(), + xcb_gcontext_t cid = xcb_generate_id(c); + xcb_create_gc(c, cid, xpix, 0, nullptr); + xcb_put_image(c, XCB_IMAGE_FORMAT_Z_PIXMAP, xpix, cid, img.width(), img.height(), 0, 0, 0, depth, img.byteCount(), img.constBits()); - xcb_free_gc(connection(), cid); + xcb_free_gc(c, cid); d = new XRenderPictureData(createPicture(xpix, depth)); - xcb_free_pixmap(connection(), xpix); + xcb_free_pixmap(c, xpix); } XRenderPicture::XRenderPicture(xcb_pixmap_t pix, int depth) @@ -132,6 +147,36 @@ XRenderPicture::XRenderPicture(xcb_pixmap_t pix, int depth) { } +XRenderPictureData::~XRenderPictureData() +{ + if (picture != XCB_RENDER_PICTURE_NONE) + xcb_render_free_picture(XRenderUtils::s_connection, picture); +} + +XFixesRegion::XFixesRegion(const QRegion ®ion) +{ + m_region = xcb_generate_id(XRenderUtils::s_connection); + QVector< QRect > rects = region.rects(); + QVector< xcb_rectangle_t > xrects(rects.count()); + for (int i = 0; + i < rects.count(); + ++i) { + const QRect &rect = rects.at(i); + xcb_rectangle_t xrect; + xrect.x = rect.x(); + xrect.y = rect.y(); + xrect.width = rect.width(); + xrect.height = rect.height(); + xrects[i] = xrect; + } + xcb_xfixes_create_region(XRenderUtils::s_connection, m_region, xrects.count(), xrects.constData()); +} + +XFixesRegion::~XFixesRegion() +{ + xcb_xfixes_destroy_region(XRenderUtils::s_connection, m_region); +} + static xcb_render_picture_t s_offscreenTarget = XCB_RENDER_PICTURE_NONE; static QStack s_scene_offscreenTargetStack; static int s_renderOffscreen = 0; diff --git a/libkwineffects/kwinxrenderutils.h b/libkwineffects/kwinxrenderutils.h index e1334de407..039cc202c7 100644 --- a/libkwineffects/kwinxrenderutils.h +++ b/libkwineffects/kwinxrenderutils.h @@ -22,7 +22,6 @@ along with this program. If not, see . #define KWIN_XRENDERUTILS_H // KWin -#include #include // Qt #include @@ -93,13 +92,6 @@ XRenderPictureData::XRenderPictureData(xcb_render_picture_t pic) { } -inline -XRenderPictureData::~XRenderPictureData() -{ - if (picture != XCB_RENDER_PICTURE_NONE) - xcb_render_free_picture(connection(), picture); -} - inline xcb_render_picture_t XRenderPictureData::value() { @@ -118,32 +110,6 @@ XRenderPicture::operator xcb_render_picture_t() return d->value(); } -inline -XFixesRegion::XFixesRegion(const QRegion ®ion) -{ - m_region = xcb_generate_id(connection()); - QVector< QRect > rects = region.rects(); - QVector< xcb_rectangle_t > xrects(rects.count()); - for (int i = 0; - i < rects.count(); - ++i) { - const QRect &rect = rects.at(i); - xcb_rectangle_t xrect; - xrect.x = rect.x(); - xrect.y = rect.y(); - xrect.width = rect.width(); - xrect.height = rect.height(); - xrects[i] = xrect; - } - xcb_xfixes_create_region(connection(), m_region, xrects.count(), xrects.constData()); -} - -inline -XFixesRegion::~XFixesRegion() -{ - xcb_xfixes_destroy_region(connection(), m_region); -} - inline XFixesRegion::operator xcb_xfixes_region_t() { @@ -197,6 +163,14 @@ KWINEFFECTS_EXPORT void scene_setXRenderOffscreenTarget(xcb_render_picture_t pix */ KWINEFFECTS_EXPORT XRenderPicture *scene_xRenderOffscreenTarget(); +namespace XRenderUtils +{ +/** + * @internal + **/ +KWINEFFECTS_EXPORT void init(xcb_connection_t *connection, xcb_window_t rootWindow); +} + } // namespace /** @} */ diff --git a/workspace.cpp b/workspace.cpp index 3d2c672752..2ebf21d04a 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -23,6 +23,7 @@ along with this program. If not, see . // kwin libs #include #include +#include // kwin #ifdef KWIN_BUILD_ACTIVITIES #include "activities.h" @@ -211,6 +212,8 @@ Workspace::Workspace(bool restore) TabBox::TabBox::create(this); #endif + // init XRenderUtils + XRenderUtils::init(connection(), rootWindow()); m_compositor = Compositor::create(this); connect(this, SIGNAL(currentDesktopChanged(int,KWin::Client*)), m_compositor, SLOT(addRepaintFull())); connect(m_compositor, &Compositor::compositingToggled, decorationPlugin(), &DecorationPlugin::compositingToggled);