Commit fe4329a2 authored by Martin Flöser's avatar Martin Flöser

Only call active effects in the effect chain

Each effect is able to declare itself as currently being active,
that is transforming windows or painting or screen or doing anything
during the current rendered frame.

This change eliminates the hottest path inside KWin identified by
callgrind.

REVIEW: 102449
parent 5b0d1739
......@@ -97,7 +97,6 @@ EffectsHandlerImpl::EffectsHandlerImpl(CompositingType type)
, fullscreen_effect(0)
, next_window_quad_type(EFFECT_QUAD_TYPE_START)
, mouse_poll_ref_count(0)
, current_paint_effectframe(0)
{
Workspace *ws = Workspace::self();
connect(ws, SIGNAL(currentDesktopChanged(int)), this, SLOT(slotDesktopChanged(int)));
......@@ -203,54 +202,54 @@ void EffectsHandlerImpl::reconfigure()
// the idea is that effects call this function again which calls the next one
void EffectsHandlerImpl::prePaintScreen(ScreenPrePaintData& data, int time)
{
if (current_paint_screen < loaded_effects.size()) {
loaded_effects[current_paint_screen++].second->prePaintScreen(data, time);
--current_paint_screen;
if (m_currentPaintScreenIterator != m_activeEffects.end()) {
(*m_currentPaintScreenIterator++)->prePaintScreen(data, time);
--m_currentPaintScreenIterator;
}
// no special final code
}
void EffectsHandlerImpl::paintScreen(int mask, QRegion region, ScreenPaintData& data)
{
if (current_paint_screen < loaded_effects.size()) {
loaded_effects[current_paint_screen++].second->paintScreen(mask, region, data);
--current_paint_screen;
if (m_currentPaintScreenIterator != m_activeEffects.end()) {
(*m_currentPaintScreenIterator++)->paintScreen(mask, region, data);
--m_currentPaintScreenIterator;
} else
scene->finalPaintScreen(mask, region, data);
}
void EffectsHandlerImpl::postPaintScreen()
{
if (current_paint_screen < loaded_effects.size()) {
loaded_effects[current_paint_screen++].second->postPaintScreen();
--current_paint_screen;
if (m_currentPaintScreenIterator != m_activeEffects.end()) {
(*m_currentPaintScreenIterator++)->postPaintScreen();
--m_currentPaintScreenIterator;
}
// no special final code
}
void EffectsHandlerImpl::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
{
if (current_paint_window < loaded_effects.size()) {
loaded_effects[current_paint_window++].second->prePaintWindow(w, data, time);
--current_paint_window;
if (m_currentPaintWindowIterator != m_activeEffects.end()) {
(*m_currentPaintWindowIterator++)->prePaintWindow(w, data, time);
--m_currentPaintWindowIterator;
}
// no special final code
}
void EffectsHandlerImpl::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
{
if (current_paint_window < loaded_effects.size()) {
loaded_effects[current_paint_window++].second->paintWindow(w, mask, region, data);
--current_paint_window;
if (m_currentPaintWindowIterator != m_activeEffects.end()) {
(*m_currentPaintWindowIterator++)->paintWindow(w, mask, region, data);
--m_currentPaintWindowIterator;
} else
scene->finalPaintWindow(static_cast<EffectWindowImpl*>(w), mask, region, data);
}
void EffectsHandlerImpl::paintEffectFrame(EffectFrame* frame, QRegion region, double opacity, double frameOpacity)
{
if (current_paint_effectframe < loaded_effects.size()) {
loaded_effects[current_paint_effectframe++].second->paintEffectFrame(frame, region, opacity, frameOpacity);
--current_paint_effectframe;
if (m_currentPaintEffectFrameIterator != m_activeEffects.end()) {
(*m_currentPaintEffectFrameIterator++)->paintEffectFrame(frame, region, opacity, frameOpacity);
--m_currentPaintEffectFrameIterator;
} else {
const EffectFrameImpl* frameImpl = static_cast<const EffectFrameImpl*>(frame);
frameImpl->finalRender(region, opacity, frameOpacity);
......@@ -259,9 +258,9 @@ void EffectsHandlerImpl::paintEffectFrame(EffectFrame* frame, QRegion region, do
void EffectsHandlerImpl::postPaintWindow(EffectWindow* w)
{
if (current_paint_window < loaded_effects.size()) {
loaded_effects[current_paint_window++].second->postPaintWindow(w);
--current_paint_window;
if (m_currentPaintWindowIterator != m_activeEffects.end()) {
(*m_currentPaintWindowIterator++)->postPaintWindow(w);
--m_currentPaintWindowIterator;
}
// no special final code
}
......@@ -276,18 +275,18 @@ bool EffectsHandlerImpl::provides(Effect::Feature ef)
void EffectsHandlerImpl::drawWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
{
if (current_draw_window < loaded_effects.size()) {
loaded_effects[current_draw_window++].second->drawWindow(w, mask, region, data);
--current_draw_window;
if (m_currentDrawWindowIterator != m_activeEffects.end()) {
(*m_currentDrawWindowIterator++)->drawWindow(w, mask, region, data);
--m_currentDrawWindowIterator;
} else
scene->finalDrawWindow(static_cast<EffectWindowImpl*>(w), mask, region, data);
}
void EffectsHandlerImpl::buildQuads(EffectWindow* w, WindowQuadList& quadList)
{
if (current_build_quads < loaded_effects.size()) {
loaded_effects[current_build_quads++].second->buildQuads(w, quadList);
--current_build_quads;
if (m_currentBuildQuadsIterator != m_activeEffects.end()) {
(*m_currentBuildQuadsIterator++)->buildQuads(w, quadList);
--m_currentBuildQuadsIterator;
}
}
......@@ -309,10 +308,17 @@ bool EffectsHandlerImpl::decorationSupportsBlurBehind() const
// start another painting pass
void EffectsHandlerImpl::startPaint()
{
assert(current_paint_screen == 0);
assert(current_paint_window == 0);
assert(current_draw_window == 0);
assert(current_build_quads == 0);
m_activeEffects.clear();
for(QVector< KWin::EffectPair >::iterator it = loaded_effects.begin(); it != loaded_effects.end(); ++it) {
if (it->second->isActive()) {
m_activeEffects << it->second;
}
}
m_currentDrawWindowIterator = m_activeEffects.begin();
m_currentPaintWindowIterator = m_activeEffects.begin();
m_currentPaintScreenIterator = m_activeEffects.begin();
m_currentPaintEffectFrameIterator = m_activeEffects.begin();
m_currentBuildQuadsIterator = m_activeEffects.begin();
}
void EffectsHandlerImpl::slotClientMaximized(KWin::Client *c, KDecorationDefines::MaximizeMode maxMode)
......@@ -1087,10 +1093,6 @@ QStringList EffectsHandlerImpl::listOfEffects() const
bool EffectsHandlerImpl::loadEffect(const QString& name, bool checkDefault)
{
Workspace::self()->addRepaintFull();
assert(current_paint_screen == 0);
assert(current_paint_window == 0);
assert(current_draw_window == 0);
assert(current_build_quads == 0);
if (!name.startsWith(QLatin1String("kwin4_effect_")))
kWarning(1212) << "Effect names usually have kwin4_effect_ prefix" ;
......@@ -1201,10 +1203,6 @@ bool EffectsHandlerImpl::loadEffect(const QString& name, bool checkDefault)
void EffectsHandlerImpl::unloadEffect(const QString& name)
{
Workspace::self()->addRepaintFull();
assert(current_paint_screen == 0);
assert(current_paint_window == 0);
assert(current_draw_window == 0);
assert(current_build_quads == 0);
for (QMap< int, EffectPair >::iterator it = effect_order.begin(); it != effect_order.end(); ++it) {
if (it.value().first == name) {
......
......@@ -208,7 +208,14 @@ protected:
QHash< long, int > registered_atoms;
int next_window_quad_type;
int mouse_poll_ref_count;
int current_paint_effectframe;
private:
QList< Effect* > m_activeEffects;
QList< Effect* >::iterator m_currentDrawWindowIterator;
QList< Effect* >::iterator m_currentPaintWindowIterator;
QList< Effect* >::iterator m_currentPaintEffectFrameIterator;
QList< Effect* >::iterator m_currentPaintScreenIterator;
QList< Effect* >::iterator m_currentBuildQuadsIterator;
};
class EffectWindowImpl : public EffectWindow
......
......@@ -947,6 +947,11 @@ void BoxSwitchEffect::activateFromProxy(int mode, bool animate, bool showText, f
}
}
bool BoxSwitchEffect::isActive() const
{
return mActivated;
}
BoxSwitchEffect::ItemInfo::ItemInfo()
: iconFrame(NULL)
{
......
......@@ -55,6 +55,7 @@ public:
virtual void windowInputMouseEvent(Window w, QEvent* e);
virtual void* proxy();
virtual bool isActive() const;
void activateFromProxy(int mode, bool animate, bool showText, float positioningFactor);
void paintWindowsBox(const QRegion& region);
......
......@@ -995,4 +995,9 @@ void CoverSwitchEffect::slotWindowClosed(EffectWindow* c)
}
}
bool CoverSwitchEffect::isActive() const
{
return mActivated || stop || stopRequested;
}
} // namespace
......@@ -48,6 +48,7 @@ public:
virtual void postPaintScreen();
virtual void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data);
virtual void windowInputMouseEvent(Window w, QEvent* e);
virtual bool isActive() const;
static bool supported();
......
......@@ -2087,4 +2087,9 @@ void CubeEffect::unregisterCubeInsideEffect(CubeInsideEffect* effect)
m_cubeInsideEffects.removeAll(effect);
}
bool CubeEffect::isActive() const
{
return activated;
}
} // namespace
......@@ -50,6 +50,7 @@ public:
virtual bool borderActivated(ElectricBorder border);
virtual void grabbedKeyboardEvent(QKeyEvent* e);
virtual void windowInputMouseEvent(Window w, QEvent* e);
virtual bool isActive() const;
// proxy functions
virtual void* proxy();
......
......@@ -617,4 +617,9 @@ void CubeSlideEffect::windowMovingChanged(float progress, RotationDirection dire
effects->addRepaintFull();
}
bool CubeSlideEffect::isActive() const
{
return !slideRotations.isEmpty();
}
} // namespace
......@@ -42,6 +42,7 @@ public:
virtual void postPaintScreen();
virtual void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time);
virtual void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data);
virtual bool isActive() const;
static bool supported();
......
......@@ -199,4 +199,9 @@ void DashboardEffect::slotWindowClosed(EffectWindow* w)
}
}
bool DashboardEffect::isActive() const
{
return transformWindow;
}
} // namespace
......@@ -43,6 +43,7 @@ public:
virtual void propagate();
virtual void reconfigure(ReconfigureFlags);
virtual void unpropagate();
virtual bool isActive() const;
public Q_SLOTS:
void slotWindowAdded(EffectWindow* c);
......
......@@ -1221,10 +1221,10 @@ void DesktopGridEffect::globalShortcutChanged(const QKeySequence& seq)
shortcut = KShortcut(seq);
}
bool DesktopGridEffect::isMotionManagerMovingWindows()
bool DesktopGridEffect::isMotionManagerMovingWindows() const
{
if (isUsingPresentWindows()) {
QList<WindowMotionManager>::iterator it;
QList<WindowMotionManager>::const_iterator it;
for (it = m_managers.begin(); it != m_managers.end(); ++it) {
if ((*it).areWindowsMoving())
return true;
......@@ -1372,6 +1372,11 @@ void DesktopGridEffect::desktopsRemoved(int old)
effects->addRepaintFull();
}
bool DesktopGridEffect::isActive() const
{
return timeline.currentValue() != 0 || (isUsingPresentWindows() && isMotionManagerMovingWindows());
}
/************************************************
* DesktopButtonView
************************************************/
......
......@@ -75,6 +75,7 @@ public:
virtual void windowInputMouseEvent(Window w, QEvent* e);
virtual void grabbedKeyboardEvent(QKeyEvent* e);
virtual bool borderActivated(ElectricBorder border);
virtual bool isActive() const;
enum { LayoutPager, LayoutAutomatic, LayoutCustom }; // Layout modes
......@@ -106,7 +107,7 @@ private:
void setup();
void setupGrid();
void finish();
bool isMotionManagerMovingWindows();
bool isMotionManagerMovingWindows() const;
bool isUsingPresentWindows() const;
QRectF moveGeometryToDesktop(int desktop) const;
void desktopsAdded(int old);
......
......@@ -95,4 +95,9 @@ void DialogParentEffect::slotWindowClosed(EffectWindow* w)
effectStrength.remove(w);
}
bool DialogParentEffect::isActive() const
{
return !effectStrength.isEmpty();
}
} // namespace
......@@ -46,6 +46,8 @@ public:
virtual void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data);
virtual void postPaintWindow(EffectWindow* w);
virtual bool isActive() const;
public Q_SLOTS:
void slotWindowClosed(EffectWindow *c);
void slotWindowActivated(EffectWindow *c);
......
......@@ -108,4 +108,10 @@ void DimScreenEffect::slotWindowActivated(EffectWindow *w)
}
}
}
bool DimScreenEffect::isActive() const
{
return mActivated;
}
} // namespace
......@@ -39,6 +39,7 @@ public:
virtual void prePaintScreen(ScreenPrePaintData& data, int time);
virtual void postPaintScreen();
virtual void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data);
virtual bool isActive() const;
public Q_SLOTS:
void slotWindowActivated(EffectWindow *w);
......
......@@ -202,5 +202,10 @@ void ExplosionEffect::slotWindowDeleted(EffectWindow* c)
mWindows.remove(c);
}
bool ExplosionEffect::isActive() const
{
return mActiveAnimations > 0;
}
} // namespace
......@@ -47,6 +47,7 @@ public:
virtual void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time);
virtual void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data);
virtual void postPaintScreen();
virtual bool isActive() const;
static bool supported();
......
......@@ -199,4 +199,9 @@ bool FadeEffect::isFadeWindow(EffectWindow* w)
return (!w->isDesktop() && !w->isUtility());
}
bool FadeEffect::isActive() const
{
return !windows.isEmpty();
}
} // namespace
......@@ -36,6 +36,7 @@ public:
virtual void prePaintScreen(ScreenPrePaintData& data, int time);
virtual void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time);
virtual void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data);
virtual bool isActive() const;
// TODO react also on virtual desktop changes
......
......@@ -107,6 +107,11 @@ void FadeDesktopEffect::slotDesktopChanged(int old)
effects->addRepaintFull();
}
bool FadeDesktopEffect::isActive() const
{
return m_fading;
}
} // namespace
#include "fadedesktop.moc"
......@@ -39,6 +39,7 @@ public:
virtual void postPaintScreen();
virtual void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time);
virtual void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data);
virtual bool isActive() const;
private Q_SLOTS:
void slotDesktopChanged(int old);
......
......@@ -160,4 +160,9 @@ void FallApartEffect::slotWindowDeleted(EffectWindow* c)
windows.remove(c);
}
bool FallApartEffect::isActive() const
{
return !windows.isEmpty();
}
} // namespace
......@@ -37,6 +37,7 @@ public:
virtual void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time);
virtual void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data);
virtual void postPaintScreen();
virtual bool isActive() const;
public Q_SLOTS:
void slotWindowClosed(EffectWindow *c);
......
......@@ -934,6 +934,11 @@ void FlipSwitchEffect::grabbedKeyboardEvent(QKeyEvent* e)
}
}
bool FlipSwitchEffect::isActive() const
{
return m_active;
}
//*************************************************************
// Item Info
//*************************************************************
......
......@@ -47,6 +47,7 @@ public:
virtual void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data);
virtual bool borderActivated(ElectricBorder border);
virtual void grabbedKeyboardEvent(QKeyEvent* e);
virtual bool isActive() const;
static bool supported();
private Q_SLOTS:
......
......@@ -226,6 +226,11 @@ bool GlideEffect::isGlideWindow(EffectWindow* w)
return true;
}
bool GlideEffect::isActive() const
{
return !windows.isEmpty();
}
GlideEffect::WindowInfo::WindowInfo()
: deleted(false)
, added(false)
......
......@@ -41,6 +41,7 @@ public:
virtual void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time);
virtual void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data);
virtual void postPaintWindow(EffectWindow* w);
virtual bool isActive() const;
static bool supported();
public Q_SLOTS:
......
......@@ -257,4 +257,9 @@ void HighlightWindowEffect::finishHighlighting()
m_windowOpacity.constBegin().key()->addRepaintFull();
}
bool HighlightWindowEffect::isActive() const
{
return !m_windowOpacity.isEmpty();
}
} // namespace
......@@ -36,6 +36,7 @@ public:
virtual void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time);
virtual void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data);
virtual bool isActive() const;
public Q_SLOTS:
void slotWindowAdded(EffectWindow* w);
......
......@@ -161,6 +161,11 @@ void InvertEffect::toggleWindow()
effects->activeWindow()->addRepaintFull();
}
bool InvertEffect::isActive() const
{
return m_valid && (m_allWindows || !m_windows.isEmpty());
}
} // namespace
#include "invert.moc"
......@@ -44,6 +44,7 @@ public:
virtual void prePaintScreen(ScreenPrePaintData &data, int time);
virtual void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time);
virtual void paintEffectFrame(KWin::EffectFrame* frame, QRegion region, double opacity, double frameOpacity);
virtual bool isActive() const;
static bool supported();
......
......@@ -117,4 +117,9 @@ bool LoginEffect::isLoginSplash(EffectWindow* w)
return false;
}
bool LoginEffect::isActive() const
{
return login_window != NULL;
}
} // namespace
......@@ -38,6 +38,7 @@ public:
virtual void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time);
virtual void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data);
virtual void reconfigure(ReconfigureFlags);
virtual bool isActive() const;
public Q_SLOTS:
void slotWindowClosed(EffectWindow *w);
......
......@@ -400,4 +400,9 @@ void LogoutEffect::slotPropertyNotify(EffectWindow* w, long a)
canDoPersistent = true;
}
bool LogoutEffect::isActive() const
{
return progress != 0;
}
} // namespace
......@@ -44,6 +44,7 @@ public:
virtual void paintScreen(int mask, QRegion region, ScreenPaintData& data);
virtual void postPaintScreen();
virtual void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data);
virtual bool isActive() const;
public Q_SLOTS:
void slotWindowAdded(EffectWindow* w);
void slotWindowClosed(EffectWindow *w);
......
......@@ -247,6 +247,11 @@ void LookingGlassEffect::postPaintScreen()
}
}
bool LookingGlassEffect::isActive() const
{
return m_valid && m_enabled;
}
} // namespace
#include "lookingglass.moc"