From a163ca92377a56c196222a48c0a5676a7bb4ac3b Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Sun, 18 Dec 2022 12:41:13 +0000 Subject: [PATCH] fix blur damage spam on no blurred windows --- src/render/OpenGL.cpp | 86 ++++++++++++++++++++----------------------- src/render/OpenGL.hpp | 31 ++++++++-------- 2 files changed, 56 insertions(+), 61 deletions(-) diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 7ef64bd6..9840821f 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -720,51 +720,9 @@ void CHyprOpenGLImpl::preRender(CMonitor* pMonitor) { if (!*PBLURNEWOPTIMIZE || !m_mMonitorRenderResources[pMonitor].blurFBDirty || !*PBLUR) return; - bool has = false; - - for (auto& w : g_pCompositor->m_vWindows) { - if (w->m_iWorkspaceID == pMonitor->activeWorkspace && w->m_bIsMapped && !w->isHidden() && (!w->m_bIsFloating || *PBLURXRAY)) { - has = true; - break; - } - } - - if (has) - g_pHyprRenderer->damageMonitor(pMonitor); -} - -void CHyprOpenGLImpl::preBlurForCurrentMonitor() { - - // make the fake dmg - pixman_region32_t fakeDamage; - pixman_region32_init_rect(&fakeDamage, 0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y); - wlr_box wholeMonitor = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; - const auto POUTFB = blurMainFramebufferWithDamage(255, &wholeMonitor, &fakeDamage); - - // render onto blurFB - m_RenderData.pCurrentMonData->blurFB.alloc(m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y); - m_RenderData.pCurrentMonData->blurFB.bind(); - - clear(CColor(0, 0, 0, 0)); - - m_bEndFrame = true; // fix transformed - renderTextureInternalWithDamage(POUTFB->m_cTex, &wholeMonitor, 255, &fakeDamage, 0, false, true, false); - m_bEndFrame = false; - - pixman_region32_fini(&fakeDamage); - - m_RenderData.pCurrentMonData->primaryFB.bind(); - - m_RenderData.pCurrentMonData->blurFBDirty = false; -} - -void CHyprOpenGLImpl::preWindowPass() { - static auto* const PBLURNEWOPTIMIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_new_optimizations")->intValue; - static auto* const PBLURXRAY = &g_pConfigManager->getConfigValuePtr("decoration:blur_xray")->intValue; - static auto* const PBLUR = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue; - - if (!m_RenderData.pCurrentMonData->blurFBDirty || !*PBLURNEWOPTIMIZE || !*PBLUR) - return; + // check if we need to update the blur fb + // if there are no windows that would benefit from it, + // we will ignore that the blur FB is dirty. auto windowShouldBeBlurred = [&](CWindow* pWindow) -> bool { if (!pWindow) @@ -802,7 +760,7 @@ void CHyprOpenGLImpl::preWindowPass() { bool hasWindows = false; for (auto& w : g_pCompositor->m_vWindows) { - if (w->m_iWorkspaceID == m_RenderData.pMonitor->activeWorkspace && !w->isHidden() && w->m_bIsMapped && (!w->m_bIsFloating || *PBLURXRAY)) { + if (w->m_iWorkspaceID == pMonitor->activeWorkspace && !w->isHidden() && w->m_bIsMapped && (!w->m_bIsFloating || *PBLURXRAY)) { // check if window is valid if (!windowShouldBeBlurred(w.get())) @@ -816,6 +774,42 @@ void CHyprOpenGLImpl::preWindowPass() { if (!hasWindows) return; + g_pHyprRenderer->damageMonitor(pMonitor); + m_mMonitorRenderResources[pMonitor].blurFBShouldRender = true; +} + +void CHyprOpenGLImpl::preBlurForCurrentMonitor() { + + // make the fake dmg + pixman_region32_t fakeDamage; + pixman_region32_init_rect(&fakeDamage, 0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y); + wlr_box wholeMonitor = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; + const auto POUTFB = blurMainFramebufferWithDamage(255, &wholeMonitor, &fakeDamage); + + // render onto blurFB + m_RenderData.pCurrentMonData->blurFB.alloc(m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y); + m_RenderData.pCurrentMonData->blurFB.bind(); + + clear(CColor(0, 0, 0, 0)); + + m_bEndFrame = true; // fix transformed + renderTextureInternalWithDamage(POUTFB->m_cTex, &wholeMonitor, 255, &fakeDamage, 0, false, true, false); + m_bEndFrame = false; + + pixman_region32_fini(&fakeDamage); + + m_RenderData.pCurrentMonData->primaryFB.bind(); + + m_RenderData.pCurrentMonData->blurFBDirty = false; +} + +void CHyprOpenGLImpl::preWindowPass() { + static auto* const PBLURNEWOPTIMIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_new_optimizations")->intValue; + static auto* const PBLUR = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue; + + if (!m_RenderData.pCurrentMonData->blurFBDirty || !*PBLURNEWOPTIMIZE || !*PBLUR || !m_RenderData.pCurrentMonData->blurFBShouldRender) + return; + // blur the main FB, it will be rendered onto the mirror preBlurForCurrentMonitor(); } diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index d550ca0a..c716590a 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -32,20 +32,21 @@ struct SMonitorRenderData { CTexture stencilTex; CFramebuffer blurFB; - bool blurFBDirty = true; + bool blurFBDirty = true; + bool blurFBShouldRender = false; wlr_box backgroundTexBox; // Shaders - bool m_bShadersInitialized = false; - CShader m_shQUAD; - CShader m_shRGBA; - CShader m_shRGBX; - CShader m_shEXT; - CShader m_shBLUR1; - CShader m_shBLUR2; - CShader m_shSHADOW; - CShader m_shBORDER1; + bool m_bShadersInitialized = false; + CShader m_shQUAD; + CShader m_shRGBA; + CShader m_shRGBX; + CShader m_shEXT; + CShader m_shBLUR1; + CShader m_shBLUR2; + CShader m_shSHADOW; + CShader m_shBORDER1; // }; @@ -142,13 +143,13 @@ class CHyprOpenGLImpl { void initShaders(); // returns the out FB, can be either Mirror or MirrorSwap - CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage); + CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage); - void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool noAA = false, - bool allowCustomUV = false, bool allowDim = false); - void renderSplash(cairo_t* const, cairo_surface_t* const, double); + void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool noAA = false, + bool allowCustomUV = false, bool allowDim = false); + void renderSplash(cairo_t* const, cairo_surface_t* const, double); - void preBlurForCurrentMonitor(); + void preBlurForCurrentMonitor(); friend class CHyprRenderer; };