From 46148b6c80783c101e607949483b70a325ca6b19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Tue, 12 May 2009 14:12:46 +0000 Subject: [PATCH] slight performance for xrender shadows svn path=/trunk/KDE/kdebase/workspace/; revision=967093 --- effects/shadow/shadow.cpp | 20 ++++++++++++++------ effects/shadow/shadow.h | 3 ++- lib/kwineffects.cpp | 5 ++--- lib/kwinxrenderutils.cpp | 12 ++++++++++++ lib/kwinxrenderutils.h | 5 +++++ 5 files changed, 35 insertions(+), 10 deletions(-) diff --git a/effects/shadow/shadow.cpp b/effects/shadow/shadow.cpp index 0aab471db5..3040b1a77e 100644 --- a/effects/shadow/shadow.cpp +++ b/effects/shadow/shadow.cpp @@ -41,6 +41,7 @@ KWIN_EFFECT( shadow, ShadowEffect ) ShadowEffect::ShadowEffect() : shadowSize( 0 ) { + cachedBlendPicture = X::None; reconfigure( ReconfigureAll ); connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()), this, SLOT(updateShadowColor())); @@ -685,12 +686,20 @@ void ShadowEffect::drawShadowQuadXRender( XRenderPicture *picture, QRect rect, f QColor color, float opacity, float brightness, float saturation ) { #ifdef KWIN_HAVE_XRENDER_COMPOSITING - XRenderColor xc; + XRenderPicture fill; if( color.isValid() ) - xc = preMultiply( color, opacity ); + { + if ( color == cachedColor && cachedBlendPicture != X::None ) + fill = cachedBlendPicture; + else + { + XRenderColor xc = preMultiply( color, opacity ); + cachedBlendPicture = fill = xRenderFill( &xc ); + cachedColor = color; + } + } else - xc = preMultiply( QColor( 255, 255, 255 ), opacity ); - XRenderPicture fill = xRenderFill( &xc ); + fill = xRenderBlendPicture(opacity); // Scale if required if( xScale != 1.0 || yScale != 1.0 ) @@ -714,8 +723,7 @@ void ShadowEffect::drawShadowQuadXRender( XRenderPicture *picture, QRect rect, f // Fake brightness by overlaying black // Cannot use XRenderFillRectangle() due to ARGB - XRenderColor col = { 0, 0, 0, 0xffff * ( 1 - brightness ) * opacity }; - fill = xRenderFill( &col ); + fill = xRenderBlendPicture(( 1 - brightness ) * opacity); XRenderComposite( display(), PictOpOver, fill, *picture, effects->xrenderBufferPicture(), 0, 0, 0, 0, rect.x(), rect.y(), rect.width(), rect.height() ); diff --git a/effects/shadow/shadow.h b/effects/shadow/shadow.h index fb1a48195d..205c720f04 100644 --- a/effects/shadow/shadow.h +++ b/effects/shadow/shadow.h @@ -70,7 +70,7 @@ class ShadowEffect int shadowFuzzyness; int shadowSize; bool intensifyActiveShadow; - QColor shadowColor; + QColor shadowColor, cachedColor; bool forceDecorated; bool forceUndecorated; bool forceOther; @@ -81,6 +81,7 @@ class ShadowEffect #ifdef KWIN_HAVE_XRENDER_COMPOSITING QList< QList > mShadowPics; QList mDefaultShadowPics; + XRenderPicture cachedBlendPicture; #endif QList mShadowQuadTypes; diff --git a/lib/kwineffects.cpp b/lib/kwineffects.cpp index d3329d67ab..e52dd2b185 100644 --- a/lib/kwineffects.cpp +++ b/lib/kwineffects.cpp @@ -1520,9 +1520,8 @@ void EffectFrame::render( QRegion region, double opacity, double frameOpacity ) 0, 0, 0, 0, geom.x(), geom.y(), geom.width(), geom.height() ); } - // Opacity, TODO: Can we further optimize this? - XRenderPicture fill = xRenderFill( QColor( 255, 255, 255, int( opacity * 255 ))); - + XRenderPicture fill = xRenderBlendPicture(opacity); + // Render icon if( !m_icon.isNull() && !m_iconSize.isEmpty() ) { diff --git a/lib/kwinxrenderutils.cpp b/lib/kwinxrenderutils.cpp index 585f2deea2..95556628d1 100644 --- a/lib/kwinxrenderutils.cpp +++ b/lib/kwinxrenderutils.cpp @@ -83,6 +83,18 @@ XRenderPicture xRenderFill( const QColor &c ) return xRenderFill( &xc ); } +static XRenderPicture _blendPicture = X::None; +static XRenderColor _blendColor; +XRenderPicture xRenderBlendPicture(double opacity) + { + _blendColor.alpha = ushort(opacity * 0xffff); + if (_blendPicture == X::None) + _blendPicture = xRenderFill(&_blendColor); + else + XRenderFillRectangle(display(), PictOpSrc, _blendPicture, &_blendColor, 0, 0, 1, 1); + return _blendPicture; + } + static XRenderPicture *_circle[4] = {NULL, NULL, NULL, NULL}; diff --git a/lib/kwinxrenderutils.h b/lib/kwinxrenderutils.h index 5caafa78d4..c75117d9f1 100644 --- a/lib/kwinxrenderutils.h +++ b/lib/kwinxrenderutils.h @@ -115,6 +115,11 @@ XRenderPicture::operator Picture() return d->value(); } +/** + * 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 + */ +KWIN_EXPORT XRenderPicture xRenderBlendPicture( double opacity ); /** * Creates a 1x1 Picture filled with c */