diff --git a/effects/screenedge/screenedgeeffect.cpp b/effects/screenedge/screenedgeeffect.cpp
index 365045a8ed..b410cf1038 100644
--- a/effects/screenedge/screenedgeeffect.cpp
+++ b/effects/screenedge/screenedgeeffect.cpp
@@ -21,11 +21,16 @@ along with this program. If not, see .
// KWin
#include
#include
+#include
// KDE
#include
// Qt
#include
#include
+// xcb
+#ifdef KWIN_HAVE_XRENDER_COMPOSITING
+#include
+#endif
namespace KWin {
@@ -101,6 +106,33 @@ void ScreenEdgeEffect::paintScreen(int mask, QRegion region, ScreenPaintData &da
}
texture->unbind();
glDisable(GL_BLEND);
+ } else if (effects->compositingType() == XRenderCompositing) {
+#ifdef KWIN_HAVE_XRENDER_COMPOSITING
+ const QRect &rect = (*it)->geometry;
+ const QSize &size = (*it)->pictureSize;
+ int x = rect.x();
+ int y = rect.y();
+ int width = rect.width();
+ int height = rect.height();
+ switch ((*it)->border) {
+ case ElectricTopRight:
+ x = rect.x() + rect.width() - size.width();
+ break;
+ case ElectricBottomRight:
+ x = rect.x() + rect.width() - size.width();
+ y = rect.y() + rect.height() - size.height();
+ break;
+ case ElectricBottomLeft:
+ y = rect.y() + rect.height() - size.height();
+ break;
+ default:
+ // nothing
+ break;
+ }
+ xcb_render_composite(connection(), XCB_RENDER_PICT_OP_OVER, *(*it)->picture.data(),
+ xRenderBlendPicture(opacity), effects->xrenderBufferPicture(),
+ 0, 0, 0, 0, x, y, width, height);
+#endif
}
}
}
@@ -116,7 +148,13 @@ void ScreenEdgeEffect::edgeApproaching(ElectricBorder border, qreal factor, cons
(*it)->geometry = geometry;
effects->addRepaint((*it)->geometry);
if (border == ElectricLeft || border == ElectricRight || border == ElectricTop || border == ElectricBottom) {
- (*it)->texture.reset(createEdgeGlow(border, geometry.size()));
+ if (effects->isOpenGLCompositing()) {
+ (*it)->texture.reset(createEdgeGlow(border, geometry.size()));
+ } else if (effects->compositingType() == XRenderCompositing) {
+#ifdef KWIN_HAVE_XRENDER_COMPOSITING
+ (*it)->picture.reset(createEdgeGlow(border, geometry.size()));
+#endif
+ }
}
}
if (factor == 0.0) {
@@ -137,41 +175,74 @@ void ScreenEdgeEffect::edgeApproaching(ElectricBorder border, qreal factor, cons
Glow *ScreenEdgeEffect::createGlow(ElectricBorder border, qreal factor, const QRect &geometry)
{
Glow *glow = new Glow();
+ glow->border = border;
glow->strength = factor;
glow->geometry = geometry;
// render the glow image
- if (border == ElectricTopLeft || border == ElectricTopRight || border == ElectricBottomRight || border == ElectricBottomLeft) {
- glow->texture.reset(createCornerGlow(border));
- } else {
- glow->texture.reset(createEdgeGlow(border, geometry.size()));
+ if (effects->isOpenGLCompositing()) {
+ if (border == ElectricTopLeft || border == ElectricTopRight || border == ElectricBottomRight || border == ElectricBottomLeft) {
+ glow->texture.reset(createCornerGlow(border));
+ } else {
+ glow->texture.reset(createEdgeGlow(border, geometry.size()));
+ }
+ if (!glow->texture.isNull()) {
+ glow->texture->setWrapMode(GL_CLAMP_TO_EDGE);
+ }
+ } else if (effects->compositingType() == XRenderCompositing) {
+#ifdef KWIN_HAVE_XRENDER_COMPOSITING
+ if (border == ElectricTopLeft || border == ElectricTopRight || border == ElectricBottomRight || border == ElectricBottomLeft) {
+ glow->pictureSize = cornerGlowSize(border);
+ glow->picture.reset(createCornerGlow(border));
+ } else {
+ glow->pictureSize = geometry.size();
+ glow->picture.reset(createEdgeGlow(border, geometry.size()));
+ }
+#endif
}
- if (glow->texture.isNull()) {
+ if (glow->texture.isNull() && glow->picture.isNull()) {
delete glow;
return NULL;
}
- glow->texture->setWrapMode(GL_CLAMP_TO_EDGE);
return glow;
}
-GLTexture *ScreenEdgeEffect::createCornerGlow(ElectricBorder border)
+template
+T *ScreenEdgeEffect::createCornerGlow(ElectricBorder border)
{
switch (border) {
case ElectricTopLeft:
- return new GLTexture(m_glow->pixmap("bottomright"));
+ return new T(m_glow->pixmap("bottomright"));
case ElectricTopRight:
- return new GLTexture(m_glow->pixmap("bottomleft"));
+ return new T(m_glow->pixmap("bottomleft"));
case ElectricBottomRight:
- return new GLTexture(m_glow->pixmap("topleft"));
+ return new T(m_glow->pixmap("topleft"));
case ElectricBottomLeft:
- return new GLTexture(m_glow->pixmap("topright"));
+ return new T(m_glow->pixmap("topright"));
default:
return NULL;
}
}
-GLTexture *ScreenEdgeEffect::createEdgeGlow(ElectricBorder border, const QSize &size)
+QSize ScreenEdgeEffect::cornerGlowSize(ElectricBorder border) const
+{
+ switch (border) {
+ case ElectricTopLeft:
+ return m_glow->elementSize("bottomright");
+ case ElectricTopRight:
+ return m_glow->elementSize("bottomleft");
+ case ElectricBottomRight:
+ return m_glow->elementSize("topleft");
+ case ElectricBottomLeft:
+ return m_glow->elementSize("topright");
+ default:
+ return QSize();
+ }
+}
+
+template
+T *ScreenEdgeEffect::createEdgeGlow(ElectricBorder border, const QSize &size)
{
QPoint pixmapPosition(0, 0);
QPixmap l, r, c;
@@ -201,7 +272,7 @@ GLTexture *ScreenEdgeEffect::createEdgeGlow(ElectricBorder border, const QSize &
default:
return NULL;
}
- QImage image(size, QImage::Format_ARGB32);
+ QPixmap image(size);
image.fill(Qt::transparent);
QPainter p;
p.begin(&image);
@@ -215,7 +286,7 @@ GLTexture *ScreenEdgeEffect::createEdgeGlow(ElectricBorder border, const QSize &
p.drawPixmap(QPoint(pixmapPosition.x(), size.height() - r.height()), r);
}
p.end();
- return new GLTexture(image);
+ return new T(image);
}
bool ScreenEdgeEffect::isActive() const
diff --git a/effects/screenedge/screenedgeeffect.h b/effects/screenedge/screenedgeeffect.h
index 7f3b5c9f2a..ccbacd103c 100644
--- a/effects/screenedge/screenedgeeffect.h
+++ b/effects/screenedge/screenedgeeffect.h
@@ -44,8 +44,11 @@ private Q_SLOTS:
void cleanup();
private:
Glow *createGlow(ElectricBorder border, qreal factor, const QRect &geometry);
- GLTexture *createCornerGlow(ElectricBorder border);
- GLTexture *createEdgeGlow(ElectricBorder border, const QSize &size);
+ template
+ T *createCornerGlow(ElectricBorder border);
+ template
+ T *createEdgeGlow(ElectricBorder border, const QSize &size);
+ QSize cornerGlowSize(ElectricBorder border) const;
Plasma::Svg *m_glow;
QHash m_borders;
QTimer *m_cleanupTimer;
@@ -55,8 +58,11 @@ class Glow
{
public:
QScopedPointer texture;
+ QScopedPointer picture;
qreal strength;
QRect geometry;
+ QSize pictureSize;
+ ElectricBorder border;
};
}