summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorvaxerski <vaxry@vaxry.net>2024-02-19 11:24:54 +0000
committervaxerski <vaxry@vaxry.net>2024-02-19 11:24:54 +0000
commite4790e3f8e8f3693d924c3d8fc9012e3ab7bbf8f (patch)
tree45d88aee67b0529d3d7c11e875bbb6f7653bb06d /src
parent69a4f08dbee6dc08d1e2ce498ce80ab20844e4f3 (diff)
surface: fix invalid damage tracking in damageSurface
ref #4744
Diffstat (limited to 'src')
-rw-r--r--src/helpers/Region.cpp5
-rw-r--r--src/helpers/Region.hpp3
-rw-r--r--src/helpers/WLSurface.cpp14
-rw-r--r--src/helpers/WLSurface.hpp2
-rw-r--r--src/render/Renderer.cpp21
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<pixman_box32_t> CRegion::getRects() const {
std::vector<pixman_box32_t> 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<pixman_box32_t> 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);
}