From 070d7699a71cf5fd00379daea4442db3852a747c Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Mon, 1 Aug 2022 12:16:33 +0200 Subject: [PATCH] added decoration:blur_new_optimizations --- src/Compositor.cpp | 4 ++++ src/config/ConfigManager.cpp | 1 + src/events/Layers.cpp | 6 ++++++ src/managers/AnimationManager.cpp | 3 +++ src/render/OpenGL.cpp | 36 +++++++++++++++++++++++++++++-- src/render/OpenGL.hpp | 7 ++++++ 6 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 8cb57db9..52dd634c 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -926,6 +926,10 @@ void CCompositor::cleanupFadingOut(const int& monid) { if (ls->monitorID != monid) continue; + // mark blur for recalc + if (ls->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND || ls->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM) + g_pHyprOpenGL->markBlurDirtyForMonitor(getMonitorFromID(monid)); + if (ls->fadingOut && ls->readyToDelete && !ls->alpha.isBeingAnimated()) { g_pHyprOpenGL->m_mLayerFramebuffers[ls].release(); g_pHyprOpenGL->m_mLayerFramebuffers.erase(ls); diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index f327c0aa..61427e80 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -66,6 +66,7 @@ void CConfigManager::setDefaultVars() { configValues["decoration:blur_size"].intValue = 8; configValues["decoration:blur_passes"].intValue = 1; configValues["decoration:blur_ignore_opacity"].intValue = 0; + configValues["decoration:blur_new_optimizations"].intValue = 1; configValues["decoration:active_opacity"].floatValue = 1; configValues["decoration:inactive_opacity"].floatValue = 1; configValues["decoration:fullscreen_opacity"].floatValue = 1; diff --git a/src/events/Layers.cpp b/src/events/Layers.cpp index 2ee242c3..d41821a8 100644 --- a/src/events/Layers.cpp +++ b/src/events/Layers.cpp @@ -219,6 +219,9 @@ void Events::listener_commitLayerSurface(void* owner, void* data) { if (!PMONITOR) return; + if (layersurface->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND || layersurface->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM) + g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR); // so that blur is recalc'd + wlr_box geomFixed = {layersurface->geometry.x, layersurface->geometry.y, layersurface->geometry.width, layersurface->geometry.height}; g_pHyprRenderer->damageBox(&geomFixed); @@ -251,6 +254,9 @@ void Events::listener_commitLayerSurface(void* owner, void* data) { } layersurface->layer = layersurface->layerSurface->current.layer; + + if (layersurface->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND || layersurface->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM) + g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR); // so that blur is recalc'd } g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID); diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index 4cebaab5..85258003 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -159,6 +159,9 @@ void CAnimationManager::tick() { w->updateWindowDecos(); } + } else if (PLAYER) { + if (PLAYER->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND || PLAYER->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM) + g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR); } break; } diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 90f72066..83ced53d 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -575,11 +575,37 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p return currentRenderToFB; } +void CHyprOpenGLImpl::markBlurDirtyForMonitor(CMonitor* pMonitor) { + m_mMonitorRenderResources[pMonitor].blurFBDirty = 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)); + + renderTextureInternalWithDamage(POUTFB->m_cTex, &wholeMonitor, 255, &fakeDamage, 0, false, true, false); + + m_RenderData.pCurrentMonData->primaryFB.bind(); + + m_RenderData.pCurrentMonData->blurFBDirty = false; +} + void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox, float a, wlr_surface* pSurface, int round) { RASSERT(m_RenderData.pMonitor, "Tried to render texture with blur without begin()!"); static auto *const PBLURENABLED = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue; - static auto* const PNOBLUROVERSIZED = &g_pConfigManager->getConfigValuePtr("decoration:no_blur_on_oversized")->intValue; + static auto *const PNOBLUROVERSIZED = &g_pConfigManager->getConfigValuePtr("decoration:no_blur_on_oversized")->intValue; + static auto* const PBLURNEWOPTIMIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_new_optimizations")->intValue; if (*PBLURENABLED == 0 || (*PNOBLUROVERSIZED && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) || (m_pCurrentWindow && m_pCurrentWindow->m_sAdditionalConfigData.forceNoBlur)) { renderTexture(tex, pBox, a, round, false, true); @@ -610,7 +636,13 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox, } // blur the main FB, it will be rendered onto the mirror - const auto POUTFB = blurMainFramebufferWithDamage(a, pBox, &inverseOpaque); + if (*PBLURNEWOPTIMIZE && m_RenderData.pCurrentMonData->blurFBDirty) { + // redraw the blur. Since this resets the dirty flag, it will be drawn before the first window. + preBlurForCurrentMonitor(); + } + + // vvv TODO: layered blur fbs? + const auto POUTFB = (*PBLURNEWOPTIMIZE && m_pCurrentWindow && !m_pCurrentWindow->m_bIsFloating) ? &m_RenderData.pCurrentMonData->blurFB : blurMainFramebufferWithDamage(a, pBox, &inverseOpaque); pixman_region32_fini(&inverseOpaque); diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 57160787..4fd16612 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -38,6 +38,9 @@ struct SMonitorRenderData { CTexture stencilTex; + CFramebuffer blurFB; + bool blurFBDirty = true; + wlr_box backgroundTexBox; }; @@ -82,6 +85,8 @@ public: void destroyMonitorResources(CMonitor*); + void markBlurDirtyForMonitor(CMonitor*); + SCurrentRenderData m_RenderData; GLint m_iCurrentOutputFb = 0; @@ -127,6 +132,8 @@ private: 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); void renderSplash(cairo_t *const, cairo_surface_t *const); + + void preBlurForCurrentMonitor(); }; inline std::unique_ptr g_pHyprOpenGL; \ No newline at end of file