From e4790e3f8e8f3693d924c3d8fc9012e3ab7bbf8f Mon Sep 17 00:00:00 2001 From: vaxerski Date: Mon, 19 Feb 2024 11:24:54 +0000 Subject: [PATCH] surface: fix invalid damage tracking in damageSurface ref #4744 --- src/helpers/Region.cpp | 5 +++++ src/helpers/Region.hpp | 3 ++- src/helpers/WLSurface.cpp | 14 ++++++++++++++ src/helpers/WLSurface.hpp | 2 ++ src/render/Renderer.cpp | 21 ++++++++++----------- 5 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/helpers/Region.cpp b/src/helpers/Region.cpp index 8f180416..502bc198 100644 --- a/src/helpers/Region.cpp +++ b/src/helpers/Region.cpp @@ -112,6 +112,11 @@ CRegion& CRegion::scale(float scale) { return *this; } +CRegion& CRegion::scale(const Vector2D& scale) { + wlr_region_scale_xy(&m_rRegion, &m_rRegion, scale.x, scale.y); + return *this; +} + std::vector CRegion::getRects() const { std::vector result; diff --git a/src/helpers/Region.hpp b/src/helpers/Region.hpp index 972a2ba7..0c3e21ad 100644 --- a/src/helpers/Region.hpp +++ b/src/helpers/Region.hpp @@ -49,6 +49,7 @@ class CRegion { CRegion& invert(pixman_box32_t* box); CRegion& invert(const CBox& box); CRegion& scale(float scale); + CRegion& scale(const Vector2D& scale); CBox getExtents(); bool containsPoint(const Vector2D& vec) const; bool empty() const; @@ -58,7 +59,7 @@ class CRegion { std::vector getRects() const; pixman_region32_t* pixman() { - return &m_rRegion; + return &m_rRegion; } private: diff --git a/src/helpers/WLSurface.cpp b/src/helpers/WLSurface.cpp index 3528a72d..99771d0d 100644 --- a/src/helpers/WLSurface.cpp +++ b/src/helpers/WLSurface.cpp @@ -52,6 +52,20 @@ Vector2D CWLSurface::getViewporterCorrectedSize() const { Vector2D{m_pWLRSurface->current.buffer_width, m_pWLRSurface->current.buffer_height}; } +CRegion CWLSurface::logicalDamage() const { + CRegion damage{&m_pWLRSurface->buffer_damage}; + damage.transform(m_pWLRSurface->current.transform, m_pWLRSurface->current.buffer_width, m_pWLRSurface->current.buffer_height); + damage.scale(1.0 / m_pWLRSurface->current.scale); + + const auto VPSIZE = getViewporterCorrectedSize() / m_pWLRSurface->current.scale; + const auto CORRECTVEC = correctSmallVec(); + + damage.scale({VPSIZE.x / m_pWLRSurface->current.width, VPSIZE.y / m_pWLRSurface->current.height}); + damage.translate(CORRECTVEC); + + return damage; +} + void CWLSurface::destroy() { if (!m_pWLRSurface) return; diff --git a/src/helpers/WLSurface.hpp b/src/helpers/WLSurface.hpp index 03714bbf..eab4ac48 100644 --- a/src/helpers/WLSurface.hpp +++ b/src/helpers/WLSurface.hpp @@ -1,6 +1,7 @@ #pragma once #include "../defines.hpp" +#include "Region.hpp" class CWindow; @@ -23,6 +24,7 @@ class CWLSurface { bool small() const; // means surface is smaller than the requested size Vector2D correctSmallVec() const; // returns a corrective vector for small() surfaces Vector2D getViewporterCorrectedSize() const; + CRegion logicalDamage() const; // allow stretching. Useful for plugins. bool m_bFillIgnoreSmall = false; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index fc676ad9..7b40f646 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1588,31 +1588,30 @@ void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y, dou y += CORRECTION.y; } - CRegion damageBox{&pSurface->buffer_damage}; + const auto WLSURF = CWLSurface::surfaceFromWlr(pSurface); + if (!WLSURF) + Debug::log(ERR, "BUG THIS: No CWLSurface for surface in damageSurface!!!"); + CRegion damageBox = WLSURF ? WLSURF->logicalDamage() : CRegion{&pSurface->buffer_damage}; if (scale != 1.0) - wlr_region_scale(damageBox.pixman(), damageBox.pixman(), scale); + damageBox.scale(scale); // schedule frame events - if (!wl_list_empty(&pSurface->current.frame_callback_list)) { + if (!wl_list_empty(&pSurface->current.frame_callback_list)) g_pCompositor->scheduleFrameForMonitor(g_pCompositor->getMonitorFromVector(Vector2D(x, y))); - } if (damageBox.empty()) return; + damageBox.translate({x, y}); + CRegion damageBoxForEach; for (auto& m : g_pCompositor->m_vMonitors) { if (!m->output) continue; - double lx = 0, ly = 0; - wlr_output_layout_output_coords(g_pCompositor->m_sWLROutputLayout, m->output, &lx, &ly); - - damageBoxForEach = damageBox; - damageBoxForEach.translate({x - m->vecPosition.x, y - m->vecPosition.y}); - wlr_region_scale(damageBoxForEach.pixman(), damageBoxForEach.pixman(), m->scale); - damageBoxForEach.translate({lx + m->vecPosition.x, ly + m->vecPosition.y}); + damageBoxForEach.set(damageBox); + damageBoxForEach.translate({-m->vecPosition.x, -m->vecPosition.y}).scale(m->scale); m->addDamage(&damageBoxForEach); }