Wrapper class to create an xcb_xfixes_region_t from a QRegion

Replaces the previously existing method to convert a QRegion which did
not take care of freeing the region again.

Usages are ported over.
This commit is contained in:
Martin Gräßlin 2013-02-06 07:58:33 +01:00
parent 97ba1ebd1e
commit 368de6842a
6 changed files with 64 additions and 38 deletions

View file

@ -3,7 +3,8 @@ kde4_no_enable_final(kwineffects)
macro( KWIN4_ADD_EFFECT_BACKEND name )
kde4_add_plugin( ${name} ${ARGN} )
target_link_libraries( ${name} kwineffects ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS} ${X11_Xfixes_LIB} ${X11_Xcursor_LIB} ${X11_LIBRARIES} ${XCB_XCB_LIBRARIES} ${X11_XCB_LIBRARIES})
target_link_libraries( ${name} kwineffects ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS} ${X11_Xfixes_LIB} ${X11_Xcursor_LIB} ${X11_LIBRARIES} ${XCB_XCB_LIBRARIES} ${X11_XCB_LIBRARIES}
${XCB_XFIXES_LIBRARIES})
endmacro( KWIN4_ADD_EFFECT_BACKEND )
# Adds effect plugin with given name. Sources are given after the name

View file

@ -16,6 +16,10 @@ target_link_libraries(kwineffects ${KDE4_KDEUI_LIBS} ${QT_QTGUI_LIBRARY}
${X11_Xrandr_LIB}
${X11_Xdamage_LIB}
${X11_Xfixes_LIB}
${XCB_XCB_LIBRARIES}
${X11_XCB_LIBRARIES}
${XCB_XFIXES_LIBRARIES}
${XCB_RENDER_LIBRARIES}
)
set_target_properties(kwineffects PROPERTIES VERSION 1.0.0 SOVERSION 1 )
set_target_properties(kwineffects PROPERTIES OUTPUT_NAME ${KWIN_NAME}effects)

View file

@ -43,6 +43,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
#include <X11/extensions/Xrender.h>
#include <X11/extensions/Xfixes.h>
#include <xcb/xfixes.h>
#endif
namespace KWin
@ -1215,9 +1216,8 @@ PaintClipper::Iterator::Iterator()
}
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
if (clip() && effects->compositingType() == XRenderCompositing) {
XserverRegion region = toXserverRegion(paintArea());
XFixesSetPictureClipRegion(display(), effects->xrenderBufferPicture(), 0, 0, region);
XFixesDestroyRegion(display(), region); // it's ref-counted
XFixesRegion region(paintArea());
xcb_xfixes_set_picture_clip_region(connection(), effects->xrenderBufferPicture(), region, 0, 0);
}
#endif
}
@ -1226,7 +1226,7 @@ PaintClipper::Iterator::~Iterator()
{
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
if (clip() && effects->compositingType() == XRenderCompositing)
XFixesSetPictureClipRegion(display(), effects->xrenderBufferPicture(), 0, 0, None);
xcb_xfixes_set_picture_clip_region(connection(), effects->xrenderBufferPicture(), XCB_XFIXES_REGION_NONE, 0, 0);
#endif
delete data;
}

View file

@ -22,7 +22,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "kwinglobals.h"
#include <QStack>
#include <QVector>
#include <QPixmap>
#include <QPainter>
#include <kdebug.h>
@ -30,26 +29,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
namespace KWin
{
// Convert QRegion to XserverRegion. All code uses XserverRegion
// only when really necessary as the shared implementation uses
// QRegion.
XserverRegion toXserverRegion(QRegion region)
{
QVector< QRect > rects = region.rects();
XRectangle* xr = new XRectangle[ rects.count()];
for (int i = 0;
i < rects.count();
++i) {
xr[ i ].x = rects[ i ].x();
xr[ i ].y = rects[ i ].y();
xr[ i ].width = rects[ i ].width();
xr[ i ].height = rects[ i ].height();
}
XserverRegion ret = XFixesCreateRegion(display(), xr, rects.count());
delete[] xr;
return ret;
}
// adapted from Qt, because this really sucks ;)
XRenderColor preMultiply(const QColor &c, float opacity)
{

View file

@ -25,23 +25,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QtCore/QSharedData>
#include <QtGui/QColor>
#include <QVector>
#include <ksharedptr.h>
#include <kwinglobals.h>
#include <X11/extensions/Xfixes.h>
#include <X11/extensions/Xrender.h>
#include <xcb/xfixes.h>
/** @addtogroup kwineffects */
/** @{ */
namespace KWin
{
/**
* Convert QRegion to XserverRegion.
*/
KWIN_EXPORT XserverRegion toXserverRegion(QRegion region);
/**
* draws a round box on the renderscene
*/
@ -82,6 +79,17 @@ private:
KSharedPtr< XRenderPictureData > d;
};
class KWIN_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(Picture pic)
: picture(pic)
@ -113,6 +121,38 @@ XRenderPicture::operator Picture()
return d->value();
}
inline
XFixesRegion::XFixesRegion(const QRegion &region)
{
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()
{
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

View file

@ -32,6 +32,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "kwinxrenderutils.h"
#include <X11/extensions/Xcomposite.h>
#include <xcb/xfixes.h>
#include <kxerrorhandler.h>
@ -181,17 +182,18 @@ void SceneXrender::present(int mask, QRegion damage)
{
if (mask & PAINT_SCREEN_REGION) {
// Use the damage region as the clip region for the root window
XserverRegion front_region = toXserverRegion(damage);
XFixesSetPictureClipRegion(display(), front, 0, 0, front_region);
XFixesDestroyRegion(display(), front_region);
XFixesRegion frontRegion(damage);
xcb_xfixes_set_picture_clip_region(connection(), front, frontRegion, 0, 0);
// copy composed buffer to the root window
XFixesSetPictureClipRegion(display(), buffer, 0, 0, None);
XRenderComposite(display(), PictOpSrc, buffer, None, front, 0, 0, 0, 0, 0, 0, displayWidth(), displayHeight());
XFixesSetPictureClipRegion(display(), front, 0, 0, None);
xcb_xfixes_set_picture_clip_region(connection(), buffer, XCB_XFIXES_REGION_NONE, 0, 0);
xcb_render_composite(connection(), XCB_RENDER_PICT_OP_SRC, buffer, XCB_RENDER_PICTURE_NONE,
front, 0, 0, 0, 0, 0, 0, displayWidth(), displayHeight());
xcb_xfixes_set_picture_clip_region(connection(), front, XCB_XFIXES_REGION_NONE, 0, 0);
XSync(display(), false);
} else {
// copy composed buffer to the root window
XRenderComposite(display(), PictOpSrc, buffer, None, front, 0, 0, 0, 0, 0, 0, displayWidth(), displayHeight());
xcb_render_composite(connection(), XCB_RENDER_PICT_OP_SRC, buffer, XCB_RENDER_PICTURE_NONE,
front, 0, 0, 0, 0, 0, 0, displayWidth(), displayHeight());
XSync(display(), false);
}
}