Commit a2c91f94 authored by Kai Uwe Broulik's avatar Kai Uwe Broulik Committed by Vlad Zahorodnii
Browse files

backends/x11: Cleanup KWinXRenderUtils and move it to eglx11common



The XRender backend has been removed, leaving most of KWinXRenderUtils unused.

The few features that are still used, notable `XRenderPicture` and pict format
are moved into the x11/common directory.

Signed-off-by: default avatarVictoria Fischer <victoria.fischer@mbition.io>
parent 3b46067f
Pipeline #178550 passed with stage
in 30 minutes and 50 seconds
add_definitions(-DKWIN_UNIT_TEST)
remove_definitions(-DQT_USE_QSTRINGBUILDER)
add_subdirectory(libkwineffects)
add_subdirectory(libxrenderutils)
add_subdirectory(integration)
add_subdirectory(libinput)
add_subdirectory(tabbox)
......
add_executable(blendPictureTest blendpicture_test.cpp)
set_target_properties(blendPictureTest PROPERTIES COMPILE_DEFINITIONS "NO_NONE_WINDOW")
add_test(NAME xrenderutils-blendPictureTest COMMAND blendPictureTest)
target_link_libraries(blendPictureTest
kwinxrenderutils
Qt::Test
Qt::Gui
XCB::XCB
XCB::RENDER
XCB::XFIXES
)
if (QT_MAJOR_VERSION EQUAL "5")
target_link_libraries(blendPictureTest Qt::X11Extras)
else()
target_link_libraries(blendPictureTest Qt::GuiPrivate)
endif()
ecm_mark_as_test(blendPictureTest)
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <QLoggingCategory>
#include <QtTest>
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
#include <private/qtx11extras_p.h>
#else
#include <QX11Info>
#endif
#include "../testutils.h"
#include "kwinxrenderutils.h"
class BlendPictureTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void cleanupTestCase();
void testDontCrashOnTeardown();
};
void BlendPictureTest::initTestCase()
{
KWin::XRenderUtils::init(QX11Info::connection(), QX11Info::appRootWindow());
}
void BlendPictureTest::cleanupTestCase()
{
KWin::XRenderUtils::cleanup();
}
void BlendPictureTest::testDontCrashOnTeardown()
{
// this test uses xrenderBlendPicture - the only idea is to trigger the creation
// closing the application should not crash
// see BUG 363251
const auto picture = KWin::xRenderBlendPicture(0.5);
// and a second one
const auto picture2 = KWin::xRenderBlendPicture(0.6);
Q_UNUSED(picture)
Q_UNUSED(picture2)
}
Q_CONSTRUCTOR_FUNCTION(forceXcb)
QTEST_MAIN(BlendPictureTest)
#include "blendpicture_test.moc"
......@@ -4,5 +4,9 @@ endif()
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-int-to-void-pointer-cast")
endif()
add_library(eglx11common STATIC eglonxbackend.cpp)
add_library(eglx11common STATIC
eglonxbackend.cpp
kwinxrenderutils.cpp
logging.cpp
)
target_link_libraries(eglx11common kwin)
......@@ -3,96 +3,28 @@
This file is part of the KDE project.
SPDX-FileCopyrightText: 2008 Lubos Lunak <l.lunak@kde.org>
SPDX-FileCopyrightText: 2022 MBition GmbH
SPDX-FileContributor: Kai Uwe Broulik <kai_uwe.broulik@mbition.io>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "kwinxrenderutils.h"
#include "logging_p.h"
#include "main.h"
#include <QCoreApplication>
#include <QGlobalStatic>
#include <QPixmap>
#include <QStack>
#include <QImage>
namespace KWin
{
namespace XRenderUtils
{
static xcb_connection_t *s_connection = nullptr;
static xcb_window_t s_rootWindow = XCB_WINDOW_NONE;
static XRenderPicture s_blendPicture(XCB_RENDER_PICTURE_NONE);
void init(xcb_connection_t *connection, xcb_window_t rootWindow)
{
s_connection = connection;
s_rootWindow = rootWindow;
}
void cleanup()
{
s_blendPicture = XRenderPicture(XCB_RENDER_PICTURE_NONE);
s_connection = nullptr;
s_rootWindow = XCB_WINDOW_NONE;
}
} // namespace
// adapted from Qt, because this really sucks ;)
xcb_render_color_t preMultiply(const QColor &c, float opacity)
{
xcb_render_color_t color;
const uint A = c.alpha() * opacity,
R = c.red(),
G = c.green(),
B = c.blue();
color.alpha = (A | A << 8);
color.red = (R | R << 8) * color.alpha / 0x10000;
color.green = (G | G << 8) * color.alpha / 0x10000;
color.blue = (B | B << 8) * color.alpha / 0x10000;
return color;
}
XRenderPicture xRenderFill(const xcb_render_color_t &c)
{
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(XRenderUtils::s_connection, pixmap);
uint32_t values[] = {true};
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(XRenderUtils::s_connection, XCB_RENDER_PICT_OP_SRC, fill, c, 1, &rect);
return fill;
}
XRenderPicture xRenderFill(const QColor &c)
{
return xRenderFill(preMultiply(c));
}
XRenderPicture xRenderBlendPicture(double opacity)
{
static xcb_render_color_t s_blendColor = {0, 0, 0, 0};
s_blendColor.alpha = uint16_t(opacity * 0xffff);
if (XRenderUtils::s_blendPicture == XCB_RENDER_PICTURE_NONE) {
XRenderUtils::s_blendPicture = xRenderFill(s_blendColor);
} else {
xcb_rectangle_t rect = {0, 0, 1, 1};
xcb_render_fill_rectangles(XRenderUtils::s_connection, XCB_RENDER_PICT_OP_SRC, XRenderUtils::s_blendPicture, s_blendColor, 1, &rect);
}
return XRenderUtils::s_blendPicture;
}
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;
xcb_connection_t *c = kwinApp()->x11Connection();
static QHash<int, xcb_render_pictformat_t> s_renderFormats;
if (!s_renderFormats.contains(depth)) {
xcb_render_query_pict_formats_reply_t *formats = xcb_render_query_pict_formats_reply(c, xcb_render_query_pict_formats_unchecked(c), nullptr);
......@@ -126,10 +58,10 @@ XRenderPicture::XRenderPicture(const QImage &img)
void XRenderPicture::fromImage(const QImage &img)
{
xcb_connection_t *c = XRenderUtils::s_connection;
xcb_connection_t *c = kwinApp()->x11Connection();
const int depth = img.depth();
xcb_pixmap_t xpix = xcb_generate_id(c);
xcb_create_pixmap(c, depth, xpix, XRenderUtils::s_rootWindow, img.width(), img.height());
xcb_create_pixmap(c, depth, xpix, kwinApp()->x11RootWindow(), img.width(), img.height());
xcb_gcontext_t cid = xcb_generate_id(c);
xcb_create_gc(c, cid, xpix, 0, nullptr);
......@@ -150,80 +82,10 @@ XRenderPictureData::~XRenderPictureData()
{
if (picture != XCB_RENDER_PICTURE_NONE) {
Q_ASSERT(qApp);
xcb_render_free_picture(XRenderUtils::s_connection, picture);
}
}
XFixesRegion::XFixesRegion(const QRegion &region)
{
m_region = xcb_generate_id(XRenderUtils::s_connection);
QVector<xcb_rectangle_t> xrects;
xrects.reserve(region.rectCount());
for (const QRect &rect : region) {
xcb_rectangle_t xrect;
xrect.x = rect.x();
xrect.y = rect.y();
xrect.width = rect.width();
xrect.height = rect.height();
xrects.append(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<XRenderPicture *> s_scene_offscreenTargetStack;
static int s_renderOffscreen = 0;
void scene_setXRenderOffscreenTarget(xcb_render_picture_t pix)
{
s_offscreenTarget = pix;
}
XRenderPicture *scene_xRenderOffscreenTarget()
{
return s_scene_offscreenTargetStack.isEmpty() ? nullptr : s_scene_offscreenTargetStack.top();
}
void setXRenderOffscreen(bool b)
{
b ? ++s_renderOffscreen : --s_renderOffscreen;
if (s_renderOffscreen < 0) {
s_renderOffscreen = 0;
qCWarning(LIBKWINXRENDERUTILS) << "*** SOMETHING IS MESSED UP WITH YOUR setXRenderOffscreen() USAGE ***";
}
}
void xRenderPushTarget(XRenderPicture *pic)
{
s_scene_offscreenTargetStack.push(pic);
++s_renderOffscreen;
}
void xRenderPopTarget()
{
s_scene_offscreenTargetStack.pop();
--s_renderOffscreen;
if (s_renderOffscreen < 0) {
s_renderOffscreen = 0;
qCWarning(LIBKWINXRENDERUTILS) << "*** SOMETHING IS MESSED UP WITH YOUR xRenderPopTarget() USAGE ***";
xcb_render_free_picture(kwinApp()->x11Connection(), picture);
}
}
bool xRenderOffscreen()
{
return s_renderOffscreen;
}
xcb_render_picture_t xRenderOffscreenTarget()
{
return s_offscreenTarget;
}
namespace XRenderUtils
{
......@@ -232,8 +94,8 @@ struct PictFormatData
PictFormatData()
{
// Fetch the render pict formats
reply = xcb_render_query_pict_formats_reply(s_connection,
xcb_render_query_pict_formats_unchecked(s_connection), nullptr);
reply = xcb_render_query_pict_formats_reply(kwinApp()->x11Connection(),
xcb_render_query_pict_formats_unchecked(kwinApp()->x11Connection()), nullptr);
// Init the visual ID -> format ID hash table
for (auto screens = xcb_render_query_pict_formats_screens_iterator(reply); screens.rem; xcb_render_pictscreen_next(&screens)) {
......
......@@ -3,6 +3,8 @@
This file is part of the KDE project.
SPDX-FileCopyrightText: 2008 Lubos Lunak <l.lunak@kde.org>
SPDX-FileCopyrightText: 2022 MBition GmbH
SPDX-FileContributor: Kai Uwe Broulik <kai_uwe.broulik@mbition.io>
SPDX-License-Identifier: GPL-2.0-or-later
*/
......@@ -11,29 +13,22 @@
#define KWIN_XRENDERUTILS_H
// KWin
#include <kwinxrenderutils_export.h>
#include <kwin_export.h>
// Qt
#include <QExplicitlySharedDataPointer>
#include <QRegion>
#include <QVector>
// XCB
#include <xcb/xfixes.h>
#include <xcb/render.h>
class QColor;
class QPixmap;
class QImage;
/** @addtogroup kwineffects */
/** @{ */
namespace KWin
{
/**
* dumps a QColor into a xcb_render_color_t
*/
KWINXRENDERUTILS_EXPORT xcb_render_color_t preMultiply(const QColor &c, float opacity = 1.0);
/** @internal */
class KWINXRENDERUTILS_EXPORT XRenderPictureData
class KWIN_EXPORT XRenderPictureData
: public QSharedData
{
public:
......@@ -53,7 +48,7 @@ private:
* convenience constructors and freeing of resources.
* It should otherwise act exactly like the Picture type.
*/
class KWINXRENDERUTILS_EXPORT XRenderPicture
class KWIN_EXPORT XRenderPicture
{
public:
explicit XRenderPicture(xcb_render_picture_t pic = XCB_RENDER_PICTURE_NONE);
......@@ -66,18 +61,6 @@ private:
QExplicitlySharedDataPointer<XRenderPictureData> d;
};
class KWINXRENDERUTILS_EXPORT XFixesRegion
{
public:
explicit XFixesRegion(const QRegion &region);
virtual ~XFixesRegion();
operator xcb_xfixes_region_t();
private:
xcb_xfixes_region_t m_region;
};
inline XRenderPictureData::XRenderPictureData(xcb_render_picture_t pic)
: picture(pic)
{
......@@ -98,79 +81,17 @@ inline XRenderPicture::operator xcb_render_picture_t()
return d->value();
}
inline XFixesRegion::operator xcb_xfixes_region_t()
{
return m_region;
}
/**
* Static 1x1 picture used to deliver a black pixel with given opacity (for blending performance)
* Call and Use, the PixelPicture will stay, but may change it's opacity meanwhile. It's NOT threadsafe either
*/
KWINXRENDERUTILS_EXPORT XRenderPicture xRenderBlendPicture(double opacity);
/**
* Creates a 1x1 Picture filled with c
*/
KWINXRENDERUTILS_EXPORT XRenderPicture xRenderFill(const xcb_render_color_t &c);
KWINXRENDERUTILS_EXPORT XRenderPicture xRenderFill(const QColor &c);
/**
* Allows to render a window into a (transparent) pixmap
* NOTICE: the result can be queried as xRenderWindowOffscreenTarget()
* NOTICE: it may be 0
* NOTICE: when done call setXRenderWindowOffscreen(false) to continue normal render process
*/
KWINXRENDERUTILS_EXPORT void setXRenderOffscreen(bool b);
/**
* Allows to define a persistent effect member as render target
* The window (including shadows) is rendered into the top left corner
* NOTICE: do NOT call setXRenderOffscreen(true) in addition!
* NOTICE: do not forget to xRenderPopTarget once you're done to continue the normal render process
*/
KWINXRENDERUTILS_EXPORT void xRenderPushTarget(XRenderPicture *pic);
KWINXRENDERUTILS_EXPORT void xRenderPopTarget();
/**
* Whether windows are currently rendered into an offscreen target buffer
*/
KWINXRENDERUTILS_EXPORT bool xRenderOffscreen();
/**
* The offscreen buffer as set by the renderer because of setXRenderWindowOffscreen(true)
*/
KWINXRENDERUTILS_EXPORT xcb_render_picture_t xRenderOffscreenTarget();
/**
* NOTICE: HANDS OFF!!!
* scene_setXRenderWindowOffscreenTarget() is ONLY to be used by the renderer - DO NOT TOUCH!
*/
KWINXRENDERUTILS_EXPORT void scene_setXRenderOffscreenTarget(xcb_render_picture_t pix);
/**
* scene_xRenderWindowOffscreenTarget() is used by the scene to figure the target set by an effect
*/
KWINXRENDERUTILS_EXPORT XRenderPicture *scene_xRenderOffscreenTarget();
namespace XRenderUtils
{
/**
* @internal
*/
KWINXRENDERUTILS_EXPORT void init(xcb_connection_t *connection, xcb_window_t rootWindow);
/**
* Returns the Xrender format that corresponds to the given visual ID.
*/
KWINXRENDERUTILS_EXPORT xcb_render_pictformat_t findPictFormat(xcb_visualid_t visual);
KWIN_EXPORT xcb_render_pictformat_t findPictFormat(xcb_visualid_t visual);
/**
* Returns the xcb_render_directformat_t for the given Xrender format.
*/
KWINXRENDERUTILS_EXPORT const xcb_render_directformat_t *findPictFormatInfo(xcb_render_pictformat_t format);
/**
* @internal
*/
KWINXRENDERUTILS_EXPORT void cleanup();
KWIN_EXPORT const xcb_render_directformat_t *findPictFormatInfo(xcb_render_pictformat_t format);
} // namespace XRenderUtils
......
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "logging_p.h"
Q_LOGGING_CATEGORY(LIBKWINXRENDERUTILS, "libkwinxrenderutils", QtWarningMsg)
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef KWIN_KWINXRENDERUTILS_LOGGING_P_H
#define KWIN_KWINXRENDERUTILS_LOGGING_P_H
#include <QDebug>
#include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(LIBKWINXRENDERUTILS)
#endif
......@@ -17,7 +17,7 @@ set(X11PLATFORM_SOURCES
add_library(KWinX11Platform MODULE ${X11PLATFORM_SOURCES})
set_target_properties(KWinX11Platform PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/org.kde.kwin.platforms/")
target_link_libraries(KWinX11Platform eglx11common kwin kwinxrenderutils KF5::Crash X11::X11)
target_link_libraries(KWinX11Platform eglx11common kwin KF5::Crash X11::X11)
if (QT_MAJOR_VERSION EQUAL "5")
target_link_libraries(KWinX11Platform Qt::X11Extras)
endif()
......
......@@ -36,8 +36,6 @@
#include "workspace.h"
#include "x11_output.h"
#include <kwinxrenderutils.h>
#include <KConfigGroup>
#include <KCrash>
#include <KGlobalAccel>
......@@ -131,9 +129,6 @@ X11StandalonePlatform::~X11StandalonePlatform()
if (sceneEglDisplay() != EGL_NO_DISPLAY) {
eglTerminate(sceneEglDisplay());
}
if (isReady()) {
XRenderUtils::cleanup();
}
}
bool X11StandalonePlatform::initialize()
......@@ -141,7 +136,6 @@ bool X11StandalonePlatform::initialize()
if (!QX11Info::isPlatformX11()) {
return false;
}
XRenderUtils::init(kwinApp()->x11Connection(), kwinApp()->x11RootWindow());
setReady(true);
initOutputs();
......
......@@ -8,7 +8,7 @@ set(X11BACKEND_SOURCES
add_library(KWinWaylandX11Backend MODULE ${X11BACKEND_SOURCES})
set_target_properties(KWinWaylandX11Backend PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/org.kde.kwin.waylandbackends/")
target_link_libraries(KWinWaylandX11Backend eglx11common kwin kwinxrenderutils X11::XCB X11::X11)
target_link_libraries(KWinWaylandX11Backend eglx11common kwin X11::XCB X11::X11)
if (X11_Xi_FOUND)
target_link_libraries(KWinWaylandX11Backend X11::Xi)
endif()
......
......@@ -210,7 +210,6 @@ bool X11WindowedBackend::initialize()
}
}
initXInput();
XRenderUtils::init(m_connection, m_screen->root);
createOutputs();
connect(kwinApp(), &Application::workspaceCreated, this, &X11WindowedBackend::startEventReading);
connect(Cursors::self(), &Cursors::currentCursorChanged, this, [this]() {
......
......@@ -8,32 +8,6 @@ ecm_setup_version(${PROJECT_VERSION}
SOVERSION 13
)
### xrenderutils lib ###
set(kwin_XRENDERUTILS_SRCS
kwinxrenderutils.cpp
logging.cpp
)
add_library(kwinxrenderutils SHARED ${kwin_XRENDERUTILS_SRCS})
generate_export_header(kwinxrenderutils EXPORT_FILE_NAME kwinxrenderutils_export.h)
target_link_libraries(kwinxrenderutils
PUBLIC
Qt::Core
Qt::Gui
XCB::RENDER
XCB::XCB
XCB::XFIXES
)
set_target_properties(kwinxrenderutils PROPERTIES
VERSION ${KWINEFFECTS_VERSION}
SOVERSION ${KWINEFFECTS_SOVERSION}
)
set_target_properties(kwinxrenderutils PROPERTIES OUTPUT_NAME ${KWIN_NAME}xrenderutils)
install(TARGETS kwinxrenderutils EXPORT KWinEffectsTargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
### effects lib ###
set(kwin_EFFECTSLIB_SRCS
anidata.cpp
......@@ -95,7 +69,6 @@ install(FILES
${CMAKE_CURRENT_BINARY_DIR}/kwinconfig.h
${CMAKE_CURRENT_BINARY_DIR}/kwineffects_export.h
${CMAKE_CURRENT_BINARY_DIR}/kwinglutils_export.h
${CMAKE_CURRENT_BINARY_DIR}/kwinxrenderutils_export.h
kwinanimationeffect.h
kwindeformeffect.h
kwineffects.h
......@@ -106,7 +79,6 @@ install(FILES
kwinglutils_funcs.h
kwinoffscreenquickview.h
kwinquickeffect.h
kwinxrenderutils.h
DESTINATION ${KDE_INSTALL_INCLUDEDIR} COMPONENT Devel)
set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/KWinEffects")
......
......@@ -9,4 +9,3 @@
#include "logging_p.h"
Q_LOGGING_CATEGORY(LIBKWINEFFECTS, "libkwineffects", QtWarningMsg)
Q_LOGGING_CATEGORY(LIBKWINGLUTILS, "libkwinglutils", QtWarningMsg)
Q_LOGGING_CATEGORY(LIBKWINXRENDERUTILS, "libkwinxrenderutils", QtWarningMsg)
......@@ -14,6 +14,5 @@
Q_DECLARE_LOGGING_CATEGORY(LIBKWINEFFECTS)
Q_DECLARE_LOGGING_CATEGORY(LIBKWINGLUTILS)
Q_DECLARE_LOGGING_CATEGORY(LIBKWINXRENDERUTILS)
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment