From 09fb54dcb648f71843b40ea50cf13b2de88717b4 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Tue, 8 Aug 2023 18:49:09 +0300 Subject: [PATCH] plugins/blur: Enable strict blurring for all windows At the moment, the blur effect operates in two modes: - generic where the blur effect samples from pixels outside the window - and a more strict version where the blur effect only blurs what's behind the window The latter mode is preferred for panels and its popup. However, it also makes sense to enable this mode for normal windows too. This simplifies the blur effect a bit. --- src/plugins/blur/blur.cpp | 56 +++++++++++---------------------------- src/plugins/blur/blur.h | 2 +- 2 files changed, 16 insertions(+), 42 deletions(-) diff --git a/src/plugins/blur/blur.cpp b/src/plugins/blur/blur.cpp index 31a20167b5..d9f3b0d024 100644 --- a/src/plugins/blur/blur.cpp +++ b/src/plugins/blur/blur.cpp @@ -584,20 +584,19 @@ void BlurEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std:: // in case this window has regions to be blurred const QRect screen = effects->virtualScreenGeometry(); const QRegion blurArea = blurRegion(w).translated(w->pos().toPoint()) & screen; - const QRegion expandedBlur = (w->isDock() ? blurArea : expand(blurArea)) & screen; // if this window or a window underneath the blurred area is painted again we have to // blur everything - if (m_paintedArea.intersects(expandedBlur) || data.paint.intersects(blurArea)) { - data.paint |= expandedBlur; + if (m_paintedArea.intersects(blurArea) || data.paint.intersects(blurArea)) { + data.paint |= blurArea; // we have to check again whether we do not damage a blurred area // of a window - if (expandedBlur.intersects(m_currentBlur)) { + if (blurArea.intersects(m_currentBlur)) { data.paint |= m_currentBlur; } } - m_currentBlur |= expandedBlur; + m_currentBlur |= blurArea; m_paintedArea -= data.opaque; m_paintedArea |= data.paint; @@ -663,13 +662,10 @@ void BlurEffect::drawWindow(const RenderTarget &renderTarget, const RenderViewpo shape = translated; } - EffectWindow *modal = w->transientFor(); - const bool transientForIsDock = (modal ? modal->isDock() : false); - shape &= region; if (!shape.isEmpty()) { - doBlur(renderTarget, viewport, shape, screen, data.opacity(), w->isDock() || transientForIsDock, w->frameGeometry().toRect()); + doBlur(renderTarget, viewport, shape, screen, data.opacity(), w->frameGeometry().toRect()); } } @@ -707,7 +703,7 @@ void BlurEffect::generateNoiseTexture() m_noiseTexture->setWrapMode(GL_REPEAT); } -void BlurEffect::doBlur(const RenderTarget &renderTarget, const RenderViewport &viewport, const QRegion &shape, const QRect &screen, const float opacity, bool isDock, QRect windowRect) +void BlurEffect::doBlur(const RenderTarget &renderTarget, const RenderViewport &viewport, const QRegion &shape, const QRect &screen, const float opacity, QRect windowRect) { const auto &outputData = m_screenData[m_currentScreen]; const QRegion expandedBlurRegion = expand(shape) & expand(screen); @@ -729,41 +725,19 @@ void BlurEffect::doBlur(const RenderTarget &renderTarget, const RenderViewport & projection.ortho(viewport.renderRect().x(), viewport.renderRect().x() + viewport.renderRect().width(), viewport.renderRect().y() + viewport.renderRect().height(), viewport.renderRect().y(), 0, 65535); - /* - * If the window is a dock or panel we avoid the "extended blur" effect. - * Extended blur is when windows that are not under the blurred area affect - * the final blur result. - * We want to avoid this on panels, because it looks really weird and ugly - * when maximized windows or windows near the panel affect the dock blur. - */ - if (isDock) { - // This assumes the source frame buffer is in device coordinates, while - // our target framebuffer is in logical coordinates. It's a bit ugly but - // to fix it properly we probably need to do blits in normalized - // coordinates. - outputData.renderTargets.back()->blitFromRenderTarget(renderTarget, viewport, logicalSourceRect, logicalSourceRect.translated(-screen.topLeft())); - GLFramebuffer::pushFramebuffers(outputData.renderTargetStack); + // This assumes the source frame buffer is in device coordinates, while + // our target framebuffer is in logical coordinates. It's a bit ugly but + // to fix it properly we probably need to do blits in normalized + // coordinates. + outputData.renderTargets.back()->blitFromRenderTarget(renderTarget, viewport, logicalSourceRect, logicalSourceRect.translated(-screen.topLeft())); + GLFramebuffer::pushFramebuffers(outputData.renderTargetStack); - if (useSRGB) { - glEnable(GL_FRAMEBUFFER_SRGB); - } - - vbo->bindArrays(); - copyScreenSampleTexture(outputData, viewport, outputData.renderTargetStack.top()->size(), vbo, blurRectCount, shape.boundingRect().translated(-screen.topLeft()), projection); - } else { - RenderTarget offscreenRT(outputData.renderTargetStack.top()); - outputData.renderTargetStack.top()->blitFromRenderTarget(renderTarget, viewport, logicalSourceRect, logicalSourceRect.translated(-screen.topLeft())); - GLFramebuffer::pushFramebuffers(outputData.renderTargetStack); - - if (useSRGB) { - glEnable(GL_FRAMEBUFFER_SRGB); - } - - // Remove the m_renderTargets[0] from the top of the stack that we will not use - GLFramebuffer::popFramebuffer(); + if (useSRGB) { + glEnable(GL_FRAMEBUFFER_SRGB); } vbo->bindArrays(); + copyScreenSampleTexture(outputData, viewport, outputData.renderTargetStack.top()->size(), vbo, blurRectCount, shape.boundingRect().translated(-screen.topLeft()), projection); downSampleTexture(outputData, vbo, blurRectCount, projection); upSampleTexture(outputData, vbo, blurRectCount, projection); diff --git a/src/plugins/blur/blur.h b/src/plugins/blur/blur.h index 13b047ebb9..a2eb521f08 100644 --- a/src/plugins/blur/blur.h +++ b/src/plugins/blur/blur.h @@ -85,7 +85,7 @@ private: bool decorationSupportsBlurBehind(const EffectWindow *w) const; bool shouldBlur(const EffectWindow *w, int mask, const WindowPaintData &data) const; void updateBlurRegion(EffectWindow *w); - void doBlur(const RenderTarget &renderTarget, const RenderViewport &viewport, const QRegion &shape, const QRect &screen, const float opacity, bool isDock, QRect windowRect); + void doBlur(const RenderTarget &renderTarget, const RenderViewport &viewport, const QRegion &shape, const QRect &screen, const float opacity, QRect windowRect); void uploadRegion(const std::span map, size_t &index, const QRegion ®ion); Q_REQUIRED_RESULT bool uploadGeometry(GLVertexBuffer *vbo, const QRegion &expandedBlurRegion, const QRegion &blurRegion); void generateNoiseTexture();