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: Victoria Fischer <victoria.fischer@mbition.io>
This commit is contained in:
Kai Uwe Broulik 2022-04-26 11:53:01 +02:00 committed by Vlad Zahorodnii
parent 3b46067fc1
commit a2c91f9434
17 changed files with 285 additions and 581 deletions

View file

@ -1,7 +1,6 @@
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)

View file

@ -1,17 +0,0 @@
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)

View file

@ -1,55 +0,0 @@
/*
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"

View file

@ -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)

View file

@ -0,0 +1,149 @@
/*
KWin - the KDE window manager
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 <QImage>
namespace KWin
{
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 = 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);
if (!formats) {
return XCB_RENDER_PICTURE_NONE;
}
for (xcb_render_pictforminfo_iterator_t it = xcb_render_query_pict_formats_formats_iterator(formats);
it.rem;
xcb_render_pictforminfo_next(&it)) {
if (it.data->depth == depth) {
s_renderFormats.insert(depth, it.data->id);
break;
}
}
free(formats);
}
QHash<int, xcb_render_pictformat_t>::const_iterator it = s_renderFormats.constFind(depth);
if (it == s_renderFormats.constEnd()) {
qCWarning(LIBKWINXRENDERUTILS) << "Could not find XRender format for depth" << depth;
return XCB_RENDER_PICTURE_NONE;
}
xcb_render_picture_t pic = xcb_generate_id(c);
xcb_render_create_picture(c, pic, pix, it.value(), 0, nullptr);
return pic;
}
XRenderPicture::XRenderPicture(const QImage &img)
{
fromImage(img);
}
void XRenderPicture::fromImage(const QImage &img)
{
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, kwinApp()->x11RootWindow(), 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.sizeInBytes(), img.constBits());
xcb_free_gc(c, cid);
d = new XRenderPictureData(createPicture(xpix, depth));
xcb_free_pixmap(c, xpix);
}
XRenderPicture::XRenderPicture(xcb_pixmap_t pix, int depth)
: d(new XRenderPictureData(createPicture(pix, depth)))
{
}
XRenderPictureData::~XRenderPictureData()
{
if (picture != XCB_RENDER_PICTURE_NONE) {
Q_ASSERT(qApp);
xcb_render_free_picture(kwinApp()->x11Connection(), picture);
}
}
namespace XRenderUtils
{
struct PictFormatData
{
PictFormatData()
{
// Fetch the render pict formats
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)) {
for (auto depths = xcb_render_pictscreen_depths_iterator(screens.data); depths.rem; xcb_render_pictdepth_next(&depths)) {
const xcb_render_pictvisual_t *visuals = xcb_render_pictdepth_visuals(depths.data);
const int len = xcb_render_pictdepth_visuals_length(depths.data);
for (int i = 0; i < len; i++) {
visualHash.insert(visuals[i].visual, visuals[i].format);
}
}
}
// Init the format ID -> xcb_render_directformat_t* hash table
const xcb_render_pictforminfo_t *formats = xcb_render_query_pict_formats_formats(reply);
const int len = xcb_render_query_pict_formats_formats_length(reply);
for (int i = 0; i < len; i++) {
if (formats[i].type == XCB_RENDER_PICT_TYPE_DIRECT) {
formatInfoHash.insert(formats[i].id, &formats[i].direct);
}
}
}
~PictFormatData()
{
free(reply);
}
xcb_render_query_pict_formats_reply_t *reply;
QHash<xcb_visualid_t, xcb_render_pictformat_t> visualHash;
QHash<xcb_render_pictformat_t, const xcb_render_directformat_t *> formatInfoHash;
};
Q_GLOBAL_STATIC(PictFormatData, g_pictFormatData)
xcb_render_pictformat_t findPictFormat(xcb_visualid_t visual)
{
PictFormatData *d = g_pictFormatData;
return d->visualHash.value(visual);
}
const xcb_render_directformat_t *findPictFormatInfo(xcb_render_pictformat_t format)
{
PictFormatData *d = g_pictFormatData;
return d->formatInfoHash.value(format);
}
} // namespace XRenderUtils
} // namespace KWin

View file

@ -0,0 +1,102 @@
/*
KWin - the KDE window manager
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
*/
#ifndef KWIN_XRENDERUTILS_H
#define KWIN_XRENDERUTILS_H
// KWin
#include <kwin_export.h>
// Qt
#include <QExplicitlySharedDataPointer>
// XCB
#include <xcb/render.h>
class QImage;
/** @addtogroup kwineffects */
/** @{ */
namespace KWin
{
/** @internal */
class KWIN_EXPORT XRenderPictureData
: public QSharedData
{
public:
explicit XRenderPictureData(xcb_render_picture_t pic = XCB_RENDER_PICTURE_NONE);
~XRenderPictureData();
xcb_render_picture_t value();
private:
xcb_render_picture_t picture;
Q_DISABLE_COPY(XRenderPictureData)
};
/**
* @short Wrapper around XRender Picture.
*
* This class wraps XRender's Picture, providing proper initialization,
* convenience constructors and freeing of resources.
* It should otherwise act exactly like the Picture type.
*/
class KWIN_EXPORT XRenderPicture
{
public:
explicit XRenderPicture(xcb_render_picture_t pic = XCB_RENDER_PICTURE_NONE);
explicit XRenderPicture(const QImage &img);
XRenderPicture(xcb_pixmap_t pix, int depth);
operator xcb_render_picture_t();
private:
void fromImage(const QImage &img);
QExplicitlySharedDataPointer<XRenderPictureData> d;
};
inline XRenderPictureData::XRenderPictureData(xcb_render_picture_t pic)
: picture(pic)
{
}
inline xcb_render_picture_t XRenderPictureData::value()
{
return picture;
}
inline XRenderPicture::XRenderPicture(xcb_render_picture_t pic)
: d(new XRenderPictureData(pic))
{
}
inline XRenderPicture::operator xcb_render_picture_t()
{
return d->value();
}
namespace XRenderUtils
{
/**
* Returns the Xrender format that corresponds to the given visual ID.
*/
KWIN_EXPORT xcb_render_pictformat_t findPictFormat(xcb_visualid_t visual);
/**
* Returns the xcb_render_directformat_t for the given Xrender format.
*/
KWIN_EXPORT const xcb_render_directformat_t *findPictFormatInfo(xcb_render_pictformat_t format);
} // namespace XRenderUtils
} // namespace KWin
/** @} */
#endif

View file

@ -0,0 +1,10 @@
/*
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)

View file

@ -0,0 +1,17 @@
/*
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

View file

@ -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()

View file

@ -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();

View file

@ -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()

View file

@ -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]() {

View file

@ -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")

View file

@ -1,287 +0,0 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2008 Lubos Lunak <l.lunak@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "kwinxrenderutils.h"
#include "logging_p.h"
#include <QCoreApplication>
#include <QGlobalStatic>
#include <QPixmap>
#include <QStack>
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;
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);
if (!formats) {
return XCB_RENDER_PICTURE_NONE;
}
for (xcb_render_pictforminfo_iterator_t it = xcb_render_query_pict_formats_formats_iterator(formats);
it.rem;
xcb_render_pictforminfo_next(&it)) {
if (it.data->depth == depth) {
s_renderFormats.insert(depth, it.data->id);
break;
}
}
free(formats);
}
QHash<int, xcb_render_pictformat_t>::const_iterator it = s_renderFormats.constFind(depth);
if (it == s_renderFormats.constEnd()) {
qCWarning(LIBKWINXRENDERUTILS) << "Could not find XRender format for depth" << depth;
return XCB_RENDER_PICTURE_NONE;
}
xcb_render_picture_t pic = xcb_generate_id(c);
xcb_render_create_picture(c, pic, pix, it.value(), 0, nullptr);
return pic;
}
XRenderPicture::XRenderPicture(const QImage &img)
{
fromImage(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(c);
xcb_create_pixmap(c, depth, xpix, XRenderUtils::s_rootWindow, 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.sizeInBytes(), img.constBits());
xcb_free_gc(c, cid);
d = new XRenderPictureData(createPicture(xpix, depth));
xcb_free_pixmap(c, xpix);
}
XRenderPicture::XRenderPicture(xcb_pixmap_t pix, int depth)
: d(new XRenderPictureData(createPicture(pix, depth)))
{
}
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 ***";
}
}
bool xRenderOffscreen()
{
return s_renderOffscreen;
}
xcb_render_picture_t xRenderOffscreenTarget()
{
return s_offscreenTarget;
}
namespace XRenderUtils
{
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);
// 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)) {
for (auto depths = xcb_render_pictscreen_depths_iterator(screens.data); depths.rem; xcb_render_pictdepth_next(&depths)) {
const xcb_render_pictvisual_t *visuals = xcb_render_pictdepth_visuals(depths.data);
const int len = xcb_render_pictdepth_visuals_length(depths.data);
for (int i = 0; i < len; i++) {
visualHash.insert(visuals[i].visual, visuals[i].format);
}
}
}
// Init the format ID -> xcb_render_directformat_t* hash table
const xcb_render_pictforminfo_t *formats = xcb_render_query_pict_formats_formats(reply);
const int len = xcb_render_query_pict_formats_formats_length(reply);
for (int i = 0; i < len; i++) {
if (formats[i].type == XCB_RENDER_PICT_TYPE_DIRECT) {
formatInfoHash.insert(formats[i].id, &formats[i].direct);
}
}
}
~PictFormatData()
{
free(reply);
}
xcb_render_query_pict_formats_reply_t *reply;
QHash<xcb_visualid_t, xcb_render_pictformat_t> visualHash;
QHash<xcb_render_pictformat_t, const xcb_render_directformat_t *> formatInfoHash;
};
Q_GLOBAL_STATIC(PictFormatData, g_pictFormatData)
xcb_render_pictformat_t findPictFormat(xcb_visualid_t visual)
{
PictFormatData *d = g_pictFormatData;
return d->visualHash.value(visual);
}
const xcb_render_directformat_t *findPictFormatInfo(xcb_render_pictformat_t format)
{
PictFormatData *d = g_pictFormatData;
return d->formatInfoHash.value(format);
}
} // namespace XRenderUtils
} // namespace KWin

View file

@ -1,181 +0,0 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2008 Lubos Lunak <l.lunak@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef KWIN_XRENDERUTILS_H
#define KWIN_XRENDERUTILS_H
// KWin
#include <kwinxrenderutils_export.h>
// Qt
#include <QExplicitlySharedDataPointer>
#include <QRegion>
#include <QVector>
// XCB
#include <xcb/xfixes.h>
class QColor;
class QPixmap;
/** @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
: public QSharedData
{
public:
explicit XRenderPictureData(xcb_render_picture_t pic = XCB_RENDER_PICTURE_NONE);
~XRenderPictureData();
xcb_render_picture_t value();
private:
xcb_render_picture_t picture;
Q_DISABLE_COPY(XRenderPictureData)
};
/**
* @short Wrapper around XRender Picture.
*
* This class wraps XRender's Picture, providing proper initialization,
* convenience constructors and freeing of resources.
* It should otherwise act exactly like the Picture type.
*/
class KWINXRENDERUTILS_EXPORT XRenderPicture
{
public:
explicit XRenderPicture(xcb_render_picture_t pic = XCB_RENDER_PICTURE_NONE);
explicit XRenderPicture(const QImage &img);
XRenderPicture(xcb_pixmap_t pix, int depth);
operator xcb_render_picture_t();
private:
void fromImage(const QImage &img);
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)
{
}
inline xcb_render_picture_t XRenderPictureData::value()
{
return picture;
}
inline XRenderPicture::XRenderPicture(xcb_render_picture_t pic)
: d(new XRenderPictureData(pic))
{
}
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);
/**
* 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();
} // namespace XRenderUtils
} // namespace KWin
/** @} */
#endif

View file

@ -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)

View file

@ -14,6 +14,5 @@
Q_DECLARE_LOGGING_CATEGORY(LIBKWINEFFECTS)
Q_DECLARE_LOGGING_CATEGORY(LIBKWINGLUTILS)
Q_DECLARE_LOGGING_CATEGORY(LIBKWINXRENDERUTILS)
#endif