[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kde-workspace/KDE/4.11] kwin: implement crossfading on xrender
From:       Thomas_Lübking <thomas.luebking () gmail ! com>
Date:       2013-08-06 21:25:44
Message-ID: E1V6olE-0006Jv-DQ () scm ! kde ! org
[Download RAW message or body]

Git commit 8a14a6c5ce81b1847a553177295b818f2b9307ec by Thomas Lübking.
Committed on 03/07/2013 at 19:30.
Pushed by luebking into branch 'KDE/4.11'.

implement crossfading on xrender

REVIEW: 111383

M  +42   -6    kwin/scene_xrender.cpp

http://commits.kde.org/kde-workspace/8a14a6c5ce81b1847a553177295b818f2b9307ec

diff --git a/kwin/scene_xrender.cpp b/kwin/scene_xrender.cpp
index b5c2172..8d38a2e 100644
--- a/kwin/scene_xrender.cpp
+++ b/kwin/scene_xrender.cpp
@@ -48,6 +48,10 @@ namespace KWin
 xcb_render_picture_t SceneXrender::buffer = XCB_RENDER_PICTURE_NONE;
 ScreenPaintData SceneXrender::screen_paint;
 
+#define DOUBLE_TO_FIXED(d) ((xcb_render_fixed_t) ((d) * 65536))
+#define FIXED_TO_DOUBLE(f) ((double) ((f) / 65536.0))
+
+
 static xcb_render_pictformat_t findFormatForVisual(xcb_visualid_t visual)
 {
     static QHash<xcb_visualid_t, xcb_render_pictformat_t> s_cache;
@@ -445,7 +449,6 @@ void SceneXrender::Window::performPaint(int mask, QRegion region, \
WindowPaintDat  if (toplevel->hasShadow())
         transformed_shape |= toplevel->shadow()->shadowRegion();
 
-#define DOUBLE_TO_FIXED(d) ((xcb_render_fixed_t) ((d) * 65536))
     xcb_render_transform_t xform = {
         DOUBLE_TO_FIXED(1), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0),
         DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(1), DOUBLE_TO_FIXED(0),
@@ -479,7 +482,6 @@ void SceneXrender::Window::performPaint(int mask, QRegion region, \
WindowPaintDat  }
         transformed_shape.setRects(rects.constData(), rects.count());
     }
-#undef DOUBLE_TO_FIXED
 
     transformed_shape.translate(mapToScreen(mask, data, QPoint(0, 0)));
     PaintClipper pcreg(region);   // clip by the region to paint
@@ -495,7 +497,8 @@ void SceneXrender::Window::performPaint(int mask, QRegion region, \
WindowPaintDat  // the window has border
     // This solves a number of glitches and on top of this
     // it optimizes painting quite a bit
-    const bool blitInTempPixmap = xRenderOffscreen() || (scaled && (wantShadow || \
(client && !client->noBorder()) || (deleted && !deleted->noBorder()))); +    const \
bool blitInTempPixmap = xRenderOffscreen() || (data.crossFadeProgress() < 1.0 && \
!opaque) || +                                 (scaled && (wantShadow || (client && \
!client->noBorder()) || (deleted && !deleted->noBorder())));  
     xcb_render_picture_t renderTarget = buffer;
     if (blitInTempPixmap) {
@@ -630,7 +633,38 @@ xcb_render_composite(connection(), XCB_RENDER_PICT_OP_OVER, \
m_xrenderShadow->pic  if (!opaque) {
                 clientAlpha = xRenderBlendPicture(data.opacity());
             }
-            xcb_render_composite(connection(), clientRenderOp, pic, clientAlpha, \
renderTarget, cr.x(), cr.y(), 0, 0, dr.x(), dr.y(), dr.width(), dr.height()); +       \
xcb_render_composite(connection(), clientRenderOp, pic, clientAlpha, renderTarget, +  \
cr.x(), cr.y(), 0, 0, dr.x(), dr.y(), dr.width(), dr.height()); +            if \
(data.crossFadeProgress() < 1.0 && data.crossFadeProgress() > 0.0) { +                \
XRenderWindowPixmap *previous = previousWindowPixmap<XRenderWindowPixmap>(); +        \
if (previous && previous != pixmap) { +                    static XRenderPicture \
cFadeAlpha(XCB_RENDER_PICTURE_NONE); +                    static xcb_render_color_t \
cFadeColor = {0, 0, 0, 0}; +                    cFadeColor.alpha = uint16_t((1.0 - \
data.crossFadeProgress()) * 0xffff); +                    if (cFadeAlpha == \
XCB_RENDER_PICTURE_NONE) { +                        cFadeAlpha = \
xRenderFill(cFadeColor); +                    } else {
+                        xcb_rectangle_t rect = {0, 0, 1, 1};
+                        xcb_render_fill_rectangles(connection(), \
XCB_RENDER_PICT_OP_SRC, cFadeAlpha, cFadeColor , 1, &rect); +                    }
+                    if (previous->size() != pixmap->size()) {
+                        xcb_render_transform_t xform2 = {
+                            DOUBLE_TO_FIXED(FIXED_TO_DOUBLE(xform.matrix11) * \
previous->size().width() / pixmap->size().width()), DOUBLE_TO_FIXED(0), \
DOUBLE_TO_FIXED(0), +                            DOUBLE_TO_FIXED(0), \
DOUBLE_TO_FIXED(FIXED_TO_DOUBLE(xform.matrix22) * previous->size().height() / \
pixmap->size().height()), DOUBLE_TO_FIXED(0), +                            \
DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(1) +                          \
}; +                        xcb_render_set_picture_transform(connection(), \
previous->picture(), xform2); +                    }
+
+                    xcb_render_composite(connection(), opaque ? \
XCB_RENDER_PICT_OP_OVER : XCB_RENDER_PICT_OP_ATOP, +                                  \
previous->picture(), cFadeAlpha, renderTarget, +                                      \
cr.x(), cr.y(), 0, 0, dr.x(), dr.y(), dr.width(), dr.height()); +
+                    if (previous->size() != pixmap->size()) {
+                        xcb_render_set_picture_transform(connection(), \
previous->picture(), identity); +                    }
+                }
+            }
             if (!opaque)
                 transformed_shape = QRegion();
         }
@@ -926,7 +960,7 @@ void \
SceneXrender::EffectFrame::renderUnstyled(xcb_render_picture_t pict, const  
         qreal x = roundness;//we start at angle = 0
         qreal y = 0;
-        #define DOUBLE_TO_FIXED(d) ((xcb_render_fixed_t) ((d) * 65536))
+
         QVector<xcb_render_pointfix_t> points;
         xcb_render_pointfix_t point;
         point.x = DOUBLE_TO_FIXED(roundness);
@@ -944,7 +978,6 @@ void \
SceneXrender::EffectFrame::renderUnstyled(xcb_render_picture_t pict, const  \
                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
@@ -1096,5 +1129,8 @@ xcb_render_picture_t \
SceneXRenderShadow::picture(Shadow::ShadowElements element)  return \
*m_pictures[element];  }
 
+#undef DOUBLE_TO_FIXED
+#undef FIXED_TO_DOUBLE
+
 } // namespace
 #endif


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic