diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 1963a548a..eaea31bef 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -701,6 +701,7 @@ void CHyprOpenGLImpl::beginSimple(PHLMONITOR pMonitor, const CRegion& damage, SP initShaders(); m_RenderData.damage.set(damage); + m_RenderData.finalDamage.set(damage); m_bFakeFrame = true; @@ -714,7 +715,7 @@ void CHyprOpenGLImpl::beginSimple(PHLMONITOR pMonitor, const CRegion& damage, SP m_RenderData.simplePass = true; } -void CHyprOpenGLImpl::begin(PHLMONITOR pMonitor, const CRegion& damage_, CFramebuffer* fb) { +void CHyprOpenGLImpl::begin(PHLMONITOR pMonitor, const CRegion& damage_, CFramebuffer* fb, std::optional finalDamage) { m_RenderData.pMonitor = pMonitor; #ifndef GLES2 @@ -765,6 +766,7 @@ void CHyprOpenGLImpl::begin(PHLMONITOR pMonitor, const CRegion& damage_, CFrameb m_RenderData.pCurrentMonData->monitorMirrorFB.release(); m_RenderData.damage.set(damage_); + m_RenderData.finalDamage.set(finalDamage.value_or(damage_)); m_bFakeFrame = fb; @@ -789,7 +791,8 @@ void CHyprOpenGLImpl::end() { // end the render, copy the data to the main framebuffer if (m_bOffloadedFramebuffer) { - m_bEndFrame = true; + m_RenderData.damage = m_RenderData.finalDamage; + m_bEndFrame = true; CBox monbox = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; @@ -860,8 +863,9 @@ void CHyprOpenGLImpl::end() { RASSERT(false, "glGetError at Opengl::end() returned GL_CONTEXT_LOST. Cannot continue until proper GPU reset handling is implemented."); } -void CHyprOpenGLImpl::setDamage(const CRegion& damage_) { +void CHyprOpenGLImpl::setDamage(const CRegion& damage_, std::optional finalDamage) { m_RenderData.damage.set(damage_); + m_RenderData.finalDamage.set(finalDamage.value_or(damage_)); } // TODO notify user if bundled shader is newer than ~/.config override diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 539d2444f..ab091f24b 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -125,6 +125,7 @@ struct SCurrentRenderData { CFramebuffer* outFB = nullptr; // out to render to (if offloaded, etc) CRegion damage; + CRegion finalDamage; // damage used for funal off -> main SRenderModifData renderModif; float mouseZoomFactor = 1.f; @@ -171,7 +172,7 @@ class CHyprOpenGLImpl { CHyprOpenGLImpl(); ~CHyprOpenGLImpl(); - void begin(PHLMONITOR, const CRegion& damage, CFramebuffer* fb = nullptr); + void begin(PHLMONITOR, const CRegion& damage, CFramebuffer* fb = nullptr, std::optional finalDamage = {}); void beginSimple(PHLMONITOR, const CRegion& damage, SP rb = nullptr, CFramebuffer* fb = nullptr); void end(); @@ -226,7 +227,7 @@ class CHyprOpenGLImpl { SP loadAsset(const std::string& file); SP renderText(const std::string& text, CHyprColor col, int pt, bool italic = false, const std::string& fontFamily = "", int maxWidth = 0); - void setDamage(const CRegion& damage); + void setDamage(const CRegion& damage, std::optional finalDamage = {}); void ensureBackgroundTexturePresence(); diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 742528333..dc5c1284c 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1292,7 +1292,7 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) { pMonitor->forceFullFrames = 10; } - CRegion damage; + CRegion damage, finalDamage; if (!beginRender(pMonitor, damage, RENDER_MODE_NORMAL)) { Debug::log(ERR, "renderer: couldn't beginRender()!"); return; @@ -1302,8 +1302,10 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) { if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR || pMonitor->forceFullFrames > 0 || damageBlinkCleanup > 0) damage = {0, 0, (int)pMonitor->vecTransformedSize.x * 10, (int)pMonitor->vecTransformedSize.y * 10}; + finalDamage = damage; + // update damage in renderdata as we modified it - g_pHyprOpenGL->setDamage(damage); + g_pHyprOpenGL->setDamage(damage, finalDamage); if (pMonitor->forceFullFrames > 0) { pMonitor->forceFullFrames -= 1; @@ -1315,7 +1317,7 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) { bool renderCursor = true; - if (!damage.empty()) { + if (!finalDamage.empty()) { if (pMonitor->solitaryClient.expired()) { if (pMonitor->isMirror()) { g_pHyprOpenGL->blend(false); diff --git a/src/render/pass/Pass.cpp b/src/render/pass/Pass.cpp index 02c86a461..60c1bc305 100644 --- a/src/render/pass/Pass.cpp +++ b/src/render/pass/Pass.cpp @@ -119,7 +119,8 @@ CRegion CRenderPass::render(const CRegion& damage_) { } if (damage.empty()) { - g_pHyprOpenGL->m_RenderData.damage = damage; + g_pHyprOpenGL->m_RenderData.damage = damage; + g_pHyprOpenGL->m_RenderData.finalDamage = damage; return damage; } @@ -149,13 +150,16 @@ CRegion CRenderPass::render(const CRegion& damage_) { blurRegion.intersect(damage).expand(oneBlurRadius()); + g_pHyprOpenGL->m_RenderData.finalDamage = blurRegion.copy().add(damage); + // FIXME: why does this break on * 1.F ? // used to work when we expand all the damage... I think? Well, before pass. // moving a window over blur shows the edges being wonk. blurRegion.expand(oneBlurRadius() * 1.5F); damage = blurRegion.copy().add(damage); - } + } else + g_pHyprOpenGL->m_RenderData.finalDamage = damage; if (std::ranges::any_of(m_vPassElements, [](const auto& el) { return el->element->disableSimplification(); })) { for (auto& el : m_vPassElements) {