diff options
| author | thejch <66577496+thejch@users.noreply.github.com> | 2024-03-30 18:14:26 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-31 02:14:26 +0100 |
| commit | 16a9c16d9f99bd8be9f1bb15442b001fdf2ea759 (patch) | |
| tree | f9cb60dc2d92519079699e9cb6e71e562b55a8a5 /src/render/Renderer.cpp | |
| parent | 1cc9a44318e53a34f41cc36483502de985b88cf8 (diff) | |
renderer/animations: Fix various inaccurate damage tracking issues and offsets (#5297)
Diffstat (limited to 'src/render/Renderer.cpp')
| -rw-r--r-- | src/render/Renderer.cpp | 97 |
1 files changed, 42 insertions, 55 deletions
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 960add70..18110256 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -211,7 +211,7 @@ static void renderSurface(struct wlr_surface* surface, int x, int y, void* data) g_pHyprOpenGL->m_RenderData.useNearestNeighbor = NEARESTNEIGHBORSET; } -bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor, CWorkspace* pWorkspace) { +bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor) { CBox geometry = pWindow->getFullWindowBoundingBox(); if (!wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, pMonitor->output, geometry.pWlr())) @@ -234,9 +234,12 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor, CWo } } - if (pWindow->m_iWorkspaceID == pWorkspace->m_iID && pWorkspace->m_iMonitorID == pMonitor->ID) + if (pWindow->m_iMonitorID == pMonitor->ID) return true; + if (!g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) && pWindow->m_iMonitorID != pMonitor->ID) + return false; + // if not, check if it maybe is active on a different monitor. if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) && pWindow->m_bIsFloating /* tiled windows can't be multi-ws */) return !pWindow->m_bIsFullscreen; // Do not draw fullscreen windows on other monitors @@ -244,12 +247,20 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor, CWo if (pMonitor->specialWorkspaceID == pWindow->m_iWorkspaceID) return true; + // if window is tiled and it's flying in, don't render on other mons (for slide) + if (!pWindow->m_bIsFloating && pWindow->m_vRealPosition.isBeingAnimated() && pWindow->m_bAnimatingIn && pWindow->m_iMonitorID != pMonitor->ID) + return false; + if (pWindow->m_vRealPosition.isBeingAnimated()) { if (PWINDOWWORKSPACE && !PWINDOWWORKSPACE->m_bIsSpecialWorkspace && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated()) return false; // render window if window and monitor intersect // (when moving out of or through a monitor) - CBox windowBox = pWindow->getFullWindowBoundingBox(); + CBox windowBox = pWindow->getFullWindowBoundingBox(); + if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated()) + windowBox.translate(PWINDOWWORKSPACE->m_vRenderOffset.value()); + windowBox.translate(pWindow->m_vFloatingOffset); + const CBox monitorBox = {pMonitor->vecPosition, pMonitor->vecSize}; if (!windowBox.intersection(monitorBox).empty()) return true; @@ -292,7 +303,7 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(CMonitor* pMonitor, CWorksp // loop over the tiled windows that are fading out for (auto& w : g_pCompositor->m_vWindows) { - if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace)) + if (!shouldRenderWindow(w.get(), pMonitor)) continue; if (w->m_fAlpha.value() == 0.f) @@ -309,7 +320,7 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(CMonitor* pMonitor, CWorksp // and floating ones too for (auto& w : g_pCompositor->m_vWindows) { - if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace)) + if (!shouldRenderWindow(w.get(), pMonitor)) continue; if (w->m_fAlpha.value() == 0.f) @@ -345,7 +356,7 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(CMonitor* pMonitor, CWorksp if (w->m_iMonitorID == pWorkspace->m_iMonitorID && pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) continue; - if (shouldRenderWindow(w.get(), pMonitor, pWorkspace)) + if (shouldRenderWindow(w.get(), pMonitor)) renderWindow(w.get(), pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL, RENDER_PASS_ALL); if (w->m_iWorkspaceID != pWorkspace->m_iID) @@ -388,7 +399,7 @@ void CHyprRenderer::renderWorkspaceWindows(CMonitor* pMonitor, CWorkspace* pWork if (w->m_bIsFloating) continue; // floating are in the second pass - if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace)) + if (!shouldRenderWindow(w.get(), pMonitor)) continue; if (pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) @@ -418,7 +429,7 @@ void CHyprRenderer::renderWorkspaceWindows(CMonitor* pMonitor, CWorkspace* pWork if (pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) continue; - if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace)) + if (!shouldRenderWindow(w.get(), pMonitor)) continue; // render the bad boy @@ -433,7 +444,7 @@ void CHyprRenderer::renderWorkspaceWindows(CMonitor* pMonitor, CWorkspace* pWork if (!w->m_bIsFloating || w->m_bPinned) continue; - if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace)) + if (!shouldRenderWindow(w.get(), pMonitor)) continue; if (pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) @@ -510,47 +521,16 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* g_pHyprOpenGL->renderRect(&monbox, CColor(0, 0, 0, *PDIMAROUND * renderdata.alpha * renderdata.fadeAlpha)); } - // clip box for animated offsets - const Vector2D PREOFFSETPOS = {renderdata.x, renderdata.y}; - if (!ignorePosition && pWindow->m_bIsFloating && !pWindow->m_bPinned && !pWindow->m_bIsFullscreen) { - Vector2D offset; - - if (PWORKSPACE->m_vRenderOffset.value().x != 0) { - const auto PWSMON = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID); - const auto PROGRESS = PWORKSPACE->m_vRenderOffset.value().x / PWSMON->vecSize.x; - const auto WINBB = pWindow->getFullWindowBoundingBox(); - - if (WINBB.x < PWSMON->vecPosition.x) { - offset.x = (PWSMON->vecPosition.x - WINBB.x) * PROGRESS; - } else if (WINBB.x + WINBB.width > PWSMON->vecPosition.x + PWSMON->vecSize.x) { - offset.x = (WINBB.x + WINBB.width - PWSMON->vecPosition.x - PWSMON->vecSize.x) * PROGRESS; - } - } else if (PWORKSPACE->m_vRenderOffset.value().y != 0) { - const auto PWSMON = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID); - const auto PROGRESS = PWORKSPACE->m_vRenderOffset.value().y / PWSMON->vecSize.y; - const auto WINBB = pWindow->getFullWindowBoundingBox(); - - if (WINBB.y < PWSMON->vecPosition.y) { - offset.y = (PWSMON->vecPosition.y - WINBB.y) * PROGRESS; - } else if (WINBB.y + WINBB.height > PWSMON->vecPosition.y + PWSMON->vecSize.y) { - offset.y = (WINBB.y + WINBB.width - PWSMON->vecPosition.y - PWSMON->vecSize.y) * PROGRESS; - } - } - - renderdata.x += offset.x; - renderdata.y += offset.y; - } + renderdata.x += pWindow->m_vFloatingOffset.x; + renderdata.y += pWindow->m_vFloatingOffset.y; // if window is floating and we have a slide animation, clip it to its full bb if (!ignorePosition && pWindow->m_bIsFloating && !pWindow->m_bIsFullscreen && PWORKSPACE->m_vRenderOffset.isBeingAnimated() && !pWindow->m_bPinned) { - CRegion rg = pWindow->getFullWindowBoundingBox().translate(-pMonitor->vecPosition + PWORKSPACE->m_vRenderOffset.value()).scale(pMonitor->scale); + CRegion rg = + pWindow->getFullWindowBoundingBox().translate(-pMonitor->vecPosition + PWORKSPACE->m_vRenderOffset.value() + pWindow->m_vFloatingOffset).scale(pMonitor->scale); g_pHyprOpenGL->m_RenderData.clipBox = rg.getExtents(); } - // if window is tiled and it's flying in, don't render on other mons (for slide) - if (!ignorePosition && !pWindow->m_bIsFloating && pWindow->m_vRealPosition.isBeingAnimated() && pWindow->m_bAnimatingIn && pWindow->m_iMonitorID != pMonitor->ID) - return; - // render window decorations first, if not fullscreen full if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_MAIN) { @@ -569,14 +549,14 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* if (wd->getDecorationLayer() != DECORATION_LAYER_BOTTOM) continue; - wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha, Vector2D{renderdata.x, renderdata.y} - PREOFFSETPOS); + wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha); } for (auto& wd : pWindow->m_dWindowDecorations) { if (wd->getDecorationLayer() != DECORATION_LAYER_UNDER) continue; - wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha, Vector2D{renderdata.x, renderdata.y} - PREOFFSETPOS); + wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha); } } @@ -601,7 +581,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* if (wd->getDecorationLayer() != DECORATION_LAYER_OVER) continue; - wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha, Vector2D{renderdata.x, renderdata.y} - PREOFFSETPOS); + wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha); } } @@ -662,7 +642,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* if (wd->getDecorationLayer() != DECORATION_LAYER_OVERLAY) continue; - wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha, Vector2D{renderdata.x, renderdata.y} - PREOFFSETPOS); + wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha); } } } @@ -861,7 +841,7 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace* if (!w->m_bPinned || !w->m_bIsFloating) continue; - if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace)) + if (!shouldRenderWindow(w.get(), pMonitor)) continue; // render the bad boy @@ -1739,15 +1719,22 @@ void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y, dou damageBox.pixman()->extents.x2 - damageBox.pixman()->extents.x1, damageBox.pixman()->extents.y2 - damageBox.pixman()->extents.y1); } -void CHyprRenderer::damageWindow(CWindow* pWindow) { +void CHyprRenderer::damageWindow(CWindow* pWindow, bool forceFull) { if (g_pCompositor->m_bUnsafeState) return; - CBox damageBox = pWindow->getFullWindowBoundingBox(); + CBox windowBox = pWindow->getFullWindowBoundingBox(); + const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); + if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() && !pWindow->m_bPinned) + windowBox.translate(PWINDOWWORKSPACE->m_vRenderOffset.value()); + windowBox.translate(pWindow->m_vFloatingOffset); + for (auto& m : g_pCompositor->m_vMonitors) { - CBox fixedDamageBox = {damageBox.x - m->vecPosition.x, damageBox.y - m->vecPosition.y, damageBox.width, damageBox.height}; - fixedDamageBox.scale(m->scale); - m->addDamage(&fixedDamageBox); + if (g_pHyprRenderer->shouldRenderWindow(pWindow, m.get()) || forceFull) { // only damage if window is rendered on monitor + CBox fixedDamageBox = {windowBox.x - m->vecPosition.x, windowBox.y - m->vecPosition.y, windowBox.width, windowBox.height}; + fixedDamageBox.scale(m->scale); + m->addDamage(&fixedDamageBox); + } } for (auto& wd : pWindow->m_dWindowDecorations) @@ -1756,7 +1743,7 @@ void CHyprRenderer::damageWindow(CWindow* pWindow) { static auto PLOGDAMAGE = CConfigValue<Hyprlang::INT>("debug:log_damage"); if (*PLOGDAMAGE) - Debug::log(LOG, "Damage: Window ({}): xy: {}, {} wh: {}, {}", pWindow->m_szTitle, damageBox.x, damageBox.y, damageBox.width, damageBox.height); + Debug::log(LOG, "Damage: Window ({}): xy: {}, {} wh: {}, {}", pWindow->m_szTitle, windowBox.x, windowBox.y, windowBox.width, windowBox.height); } void CHyprRenderer::damageMonitor(CMonitor* pMonitor) { |
