diff --git a/effects/blur/blur.cpp b/effects/blur/blur.cpp index fb2380ae19..12aa72a002 100644 --- a/effects/blur/blur.cpp +++ b/effects/blur/blur.cpp @@ -273,11 +273,10 @@ void BlurEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int t // we don't have to blur a region we don't see m_currentBlur -= newClip; // if we have to paint a non-opaque part of this window that intersects with the - // currently blurred region we have to redraw the whole region + // currently blurred region (which is not cached) we have to redraw the whole region if ((data.paint-oldClip).intersects(m_currentBlur)) { data.paint |= m_currentBlur; } - // TODO: make m_currentBlur a list of connected regions // in case this window has regions to be blurred const QRegion blurArea = blurRegion(w).translated(w->pos()); @@ -287,11 +286,19 @@ void BlurEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int t // we are caching the horizontally blurred background texture // if a window underneath the blurred area is damaged we have to - // blur everything + // update the cached texture if (m_damagedArea.intersects(blurArea)) { + // This is the area of the blurry window which really can change. + // TODO: damagedArea can be a bit bigger than it needs to be + // if m_damagedArea intersects with the boundary of blurArea, but this + // only results in a slightly bigger repaint. At the moment I don't think it + // is worth to clip once more against blurArea after the expansion. const QRegion damagedArea = expand(blurArea & m_damagedArea); + // In order to be able to recalculate this area we have to make sure the + // background area is painted before. data.paint |= expand(damagedArea); if (windows.contains(w)) { + // In case we already have a texture cache mark the dirty regions invalid. windows[w].damagedRegion |= damagedArea; } // we keep track of the "damage propagation" @@ -301,11 +308,6 @@ void BlurEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int t if (expandedBlur.intersects(m_currentBlur)) { data.paint |= m_currentBlur; } - - // Normally we would have shrink the clip of the following windows to get a - // full cached copy of the background of this window. But we do not do a full - // cache of the background and rely on the KWin behavior that transformed windows - // are painted with paintGenericScreen. } } else { // we are not caching the window @@ -487,10 +489,7 @@ void BlurEffect::doCachedBlur(EffectWindow *w, const QRegion& region, const floa const QRegion expanded = expand(blurredRegion) & screen; const QRect r = expanded.boundingRect(); - // The background texture we get is only partially valid, because we might be - // painting opaque areas top to bottom such that we accidentally blur these areas. - // Anyway this behavior is more performant than shrinking the clipping area of the - // higher windows in order to get a fully valid background texture. + // The background texture we get is only partially valid. if (!windows.contains(w)) { BlurWindowInfo bwi; @@ -520,6 +519,7 @@ void BlurEffect::doCachedBlur(EffectWindow *w, const QRegion& region, const floa pushMatrix(); #endif + // We only update that part of the background texture that is visible and marked as dirty. const QRegion updateBackground = windows[w].damagedRegion & region; if (!updateBackground.isEmpty()) { @@ -561,6 +561,7 @@ void BlurEffect::doCachedBlur(EffectWindow *w, const QRegion& region, const floa GLRenderTarget::popRenderTarget(); scratch.unbind(); + // mark the updated region as valid windows[w].damagedRegion -= updateBackground; } diff --git a/effects/blur/blur.h b/effects/blur/blur.h index a1d13c600d..313f311357 100644 --- a/effects/blur/blur.h +++ b/effects/blur/blur.h @@ -71,7 +71,7 @@ private: long net_wm_blur_region; QRegion m_damagedArea; // keeps track of the area which has been damaged (from bottom to top) QRegion m_paintedArea; // actually painted area which is greater than m_damagedArea - QRegion m_currentBlur; // keeps track of the currently blured area (from bottom to top) + QRegion m_currentBlur; // keeps track of the currently blured area of non-caching windows(from bottom to top) bool m_shouldCache; struct BlurWindowInfo {