diff --git a/libkwineffects/kwinxrenderutils.cpp b/libkwineffects/kwinxrenderutils.cpp
index 2ea6b9dc1d..41a864163b 100644
--- a/libkwineffects/kwinxrenderutils.cpp
+++ b/libkwineffects/kwinxrenderutils.cpp
@@ -73,64 +73,6 @@ XRenderPicture xRenderBlendPicture(double opacity)
return _blendPicture;
}
-
-static XRenderPicture *_circle[4] = {NULL, NULL, NULL, NULL};
-
-#define DUMP_CNR(_SECT_, _W_, _H_, _XOFF_, _YOFF_)\
- dump = QPixmap(_W_, _H_);\
- dump.fill(Qt::transparent);\
- p.begin(&dump);\
- p.drawPixmap( 0, 0, tmp, _XOFF_, _YOFF_, _W_, _H_ );\
- p.end();\
- _circle[_SECT_] = new XRenderPicture(dump);
-
-#define CS 8
-
-static XRenderPicture *circle(int i)
-{
- if (!_circle[0]) {
- QPixmap tmp(2 * CS, 2 * CS);
- tmp.fill(Qt::transparent);
- QPainter p(&tmp);
- p.setRenderHint(QPainter::Antialiasing);
- p.setPen(Qt::NoPen); p.setBrush(Qt::black);
- p.drawEllipse(tmp.rect());
- p.end();
- QPixmap dump;
- DUMP_CNR(0, CS, CS, 0, 0);
- DUMP_CNR(1, CS, CS, CS, 0);
- DUMP_CNR(2, CS, CS, CS, CS);
- DUMP_CNR(3, CS, CS, 0, CS);
- }
- return _circle[i];
-}
-
-void xRenderRoundBox(Picture pict, const QRect &rect, int , const QColor &c)
-{
- XRenderPicture fill = xRenderFill(c);
- int op = c.alpha() == 255 ? PictOpSrc : PictOpOver;
- // TODO: implement second paramenter "roundness"
- // so rather use ?? XRenderCompositeTriFan (dpy, op, src, dst, maskFormat, xSrc, ySrc,
- //XPointFixed *points, npoint);
- // this will require "points on a circle" calculation, however...
-
- int s = qMin(CS, qMin(rect.height() / 2, rect.width() / 2));
- int x, y, b, r;
- rect.getCoords(&x, &y, &r, &b);
- r -= (s - 1);
- b -= (s - 1);
- XRenderComposite(display(), PictOpOver, fill, *circle(0), pict, 0, 0, 0, 0, x, y, CS, CS);
- XRenderComposite(display(), PictOpOver, fill, *circle(1), pict, 0, 0, CS - s, 0, r, y, s, s);
- XRenderComposite(display(), PictOpOver, fill, *circle(2), pict, 0, 0, CS - s, CS - s, r, b, s, s);
- XRenderComposite(display(), PictOpOver, fill, *circle(3), pict, 0, 0, 0, CS - s, x, b, s, s);
- XRenderComposite(display(), op, fill, 0, pict, 0, 0, 0, 0, x + s, y, rect.width() - 2 * s, s);
- XRenderComposite(display(), op, fill, 0, pict, 0, 0, 0, 0, x, y + s, rect.width(), rect.height() - 2 * s);
- XRenderComposite(display(), op, fill, 0, pict, 0, 0, 0, 0, x + s, b, rect.width() - 2 * s, s);
-}
-
-#undef CS
-#undef DUMP_CNR
-
// XRenderFind(Standard)Format() is a roundtrip, so cache the results
static XRenderPictFormat* renderformats[ 33 ];
diff --git a/libkwineffects/kwinxrenderutils.h b/libkwineffects/kwinxrenderutils.h
index 4218f8ba81..7069e8201f 100644
--- a/libkwineffects/kwinxrenderutils.h
+++ b/libkwineffects/kwinxrenderutils.h
@@ -39,10 +39,6 @@ along with this program. If not, see .
namespace KWin
{
-/**
- * draws a round box on the renderscene
- */
-KWIN_EXPORT void xRenderRoundBox(Picture pict, const QRect &rect, int round, const QColor &c);
/**
* dumps a QColor into a XRenderColor
*/
diff --git a/scene_xrender.cpp b/scene_xrender.cpp
index 140470a168..dc40f66137 100644
--- a/scene_xrender.cpp
+++ b/scene_xrender.cpp
@@ -37,6 +37,7 @@ along with this program. If not, see .
#include
#include
+#include
namespace KWin
{
@@ -93,6 +94,7 @@ SceneXrender::~SceneXrender()
m_overlayWindow->destroy();
return;
}
+ SceneXrender::EffectFrame::cleanup();
XRenderFreePicture(display(), front);
XRenderFreePicture(display(), buffer);
buffer = None;
@@ -727,6 +729,8 @@ void SceneXrender::screenGeometryChanged(const QSize &size)
// SceneXrender::EffectFrame
//****************************************
+XRenderPicture *SceneXrender::EffectFrame::s_effectFrameCircle = NULL;
+
SceneXrender::EffectFrame::EffectFrame(EffectFrameImpl* frame)
: Scene::EffectFrame(frame)
{
@@ -744,6 +748,12 @@ SceneXrender::EffectFrame::~EffectFrame()
delete m_selectionPicture;
}
+void SceneXrender::EffectFrame::cleanup()
+{
+ delete s_effectFrameCircle;
+ s_effectFrameCircle = NULL;
+}
+
void SceneXrender::EffectFrame::free()
{
delete m_picture;
@@ -792,10 +802,9 @@ void SceneXrender::EffectFrame::render(QRegion region, double opacity, double fr
}
// Render the actual frame
- if (m_effectFrame->style() == EffectFrameUnstyled)
- xRenderRoundBox(effects->xrenderBufferPicture(), m_effectFrame->geometry().adjusted(-5, -5, 5, 5),
- 5, QColor(0, 0, 0, int(opacity * frameOpacity * 255)));
- else if (m_effectFrame->style() == EffectFrameStyled) {
+ if (m_effectFrame->style() == EffectFrameUnstyled) {
+ renderUnstyled(effects->xrenderBufferPicture(), m_effectFrame->geometry(), opacity * frameOpacity);
+ } else if (m_effectFrame->style() == EffectFrameStyled) {
if (!m_picture) { // Lazy creation
updatePicture();
}
@@ -844,6 +853,95 @@ void SceneXrender::EffectFrame::render(QRegion region, double opacity, double fr
}
}
+void SceneXrender::EffectFrame::renderUnstyled(xcb_render_picture_t pict, const QRect &rect, qreal opacity)
+{
+ const int roundness = 5;
+ const QRect area = rect.adjusted(-roundness, -roundness, roundness, roundness);
+ xcb_rectangle_t rects[3];
+ // center
+ rects[0].x = area.left();
+ rects[0].y = area.top() + roundness;
+ rects[0].width = area.width();
+ rects[0].height = area.height() - roundness * 2;
+ // top
+ rects[1].x = area.left() + roundness;
+ rects[1].y = area.top();
+ rects[1].width = area.width() - roundness * 2;
+ rects[1].height = roundness;
+ // bottom
+ rects[2].x = area.left() + roundness;
+ rects[2].y = area.top() + area.height() - roundness;
+ rects[2].width = area.width() - roundness * 2;
+ rects[2].height = roundness;
+ xcb_render_color_t color = {0, 0, 0, uint16_t(opacity * 0xffff)};
+ xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_OVER, pict, color, 3, rects);
+
+ if (!s_effectFrameCircle) {
+ // create the circle
+ const int diameter = roundness * 2;
+ xcb_pixmap_t pix = xcb_generate_id(connection());
+ xcb_create_pixmap(connection(), 32, pix, rootWindow(), diameter, diameter);
+ s_effectFrameCircle = new XRenderPicture(pix, 32);
+ xcb_free_pixmap(connection(), pix);
+
+ // clear it with transparent
+ xcb_rectangle_t xrect = {0, 0, diameter, diameter};
+ xcb_render_color_t tranparent = {0, 0, 0, 0};
+ xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, *s_effectFrameCircle, tranparent, 1, &xrect);
+
+ static int num_segments = 80;
+ static qreal theta = 2 * M_PI / qreal(num_segments);
+ static qreal c = qCos(theta); //precalculate the sine and cosine
+ static qreal s = qSin(theta);
+ qreal t;
+
+ qreal x = roundness;//we start at angle = 0
+ qreal y = 0;
+ #define DOUBLE_TO_FIXED(d) ((xcb_render_fixed_t) ((d) * 65536))
+ QVector points;
+ xcb_render_pointfix_t point;
+ point.x = DOUBLE_TO_FIXED(roundness);
+ point.y = DOUBLE_TO_FIXED(roundness);
+ points << point;
+ for (int ii = 0; ii <= num_segments; ++ii) {
+ point.x = DOUBLE_TO_FIXED(x + roundness);
+ point.y = DOUBLE_TO_FIXED(y + roundness);
+ points << point;
+ //apply the rotation matrix
+ t = x;
+ x = c * x - s * y;
+ y = s * t + c * y;
+ }
+ XRenderPicture fill = xRenderFill(Qt::black);
+ xcb_render_tri_fan(connection(), XCB_RENDER_PICT_OP_OVER, fill, *s_effectFrameCircle,
+ 0, 0, 0, points.count(), points.constData());
+ #undef DOUBLE_TO_FIXED
+ }
+ // TODO: merge alpha mask with SceneXrender::Window::alphaMask
+ // alpha mask
+ xcb_pixmap_t pix = xcb_generate_id(connection());
+ xcb_create_pixmap(connection(), 8, pix, rootWindow(), 1, 1);
+ XRenderPicture alphaMask(pix, 8);
+ xcb_free_pixmap(connection(), pix);
+ const uint32_t values[] = {true};
+ xcb_render_change_picture(connection(), alphaMask, XCB_RENDER_CP_REPEAT, values);
+ color.alpha = int(opacity * 0xffff);
+ xcb_rectangle_t xrect = {0, 0, 1, 1};
+ xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, alphaMask, color, 1, &xrect);
+
+ // TODO: replace by lambda
+#define RENDER_CIRCLE(srcX, srcY, destX, destY) \
+xcb_render_composite(connection(), XCB_RENDER_PICT_OP_OVER, *s_effectFrameCircle, alphaMask, \
+ pict, srcX, srcY, 0, 0, destX, destY, roundness, roundness)
+
+ RENDER_CIRCLE(0, 0, area.left(), area.top());
+ RENDER_CIRCLE(0, roundness, area.left(), area.top() + area.height() - roundness);
+ RENDER_CIRCLE(roundness, 0, area.left() + area.width() - roundness, area.top());
+ RENDER_CIRCLE(roundness, roundness,
+ area.left() + area.width() - roundness, area.top() + area.height() - roundness);
+#undef RENDER_CIRCLE
+}
+
void SceneXrender::EffectFrame::updatePicture()
{
delete m_picture;
diff --git a/scene_xrender.h b/scene_xrender.h
index cfcb81416c..9f55ebd834 100644
--- a/scene_xrender.h
+++ b/scene_xrender.h
@@ -113,15 +113,18 @@ public:
virtual void crossFadeIcon();
virtual void crossFadeText();
virtual void render(QRegion region, double opacity, double frameOpacity);
+ static void cleanup();
private:
void updatePicture();
void updateTextPicture();
+ void renderUnstyled(xcb_render_picture_t pict, const QRect &rect, qreal opacity);
XRenderPicture* m_picture;
XRenderPicture* m_textPicture;
XRenderPicture* m_iconPicture;
XRenderPicture* m_selectionPicture;
+ static XRenderPicture* s_effectFrameCircle;
};
inline