surface: fix invalid damage tracking in damageSurface

ref #4744
This commit is contained in:
Vaxry 2024-02-19 11:24:54 +00:00
parent 69a4f08dbe
commit e4790e3f8e
5 changed files with 33 additions and 12 deletions

View file

@ -112,6 +112,11 @@ CRegion& CRegion::scale(float scale) {
return *this; 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> CRegion::getRects() const {
std::vector<pixman_box32_t> result; std::vector<pixman_box32_t> result;

View file

@ -49,6 +49,7 @@ class CRegion {
CRegion& invert(pixman_box32_t* box); CRegion& invert(pixman_box32_t* box);
CRegion& invert(const CBox& box); CRegion& invert(const CBox& box);
CRegion& scale(float scale); CRegion& scale(float scale);
CRegion& scale(const Vector2D& scale);
CBox getExtents(); CBox getExtents();
bool containsPoint(const Vector2D& vec) const; bool containsPoint(const Vector2D& vec) const;
bool empty() const; bool empty() const;
@ -58,7 +59,7 @@ class CRegion {
std::vector<pixman_box32_t> getRects() const; std::vector<pixman_box32_t> getRects() const;
pixman_region32_t* pixman() { pixman_region32_t* pixman() {
return &m_rRegion; return &m_rRegion;
} }
private: private:

View file

@ -52,6 +52,20 @@ Vector2D CWLSurface::getViewporterCorrectedSize() const {
Vector2D{m_pWLRSurface->current.buffer_width, m_pWLRSurface->current.buffer_height}; 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() { void CWLSurface::destroy() {
if (!m_pWLRSurface) if (!m_pWLRSurface)
return; return;

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "../defines.hpp" #include "../defines.hpp"
#include "Region.hpp"
class CWindow; class CWindow;
@ -23,6 +24,7 @@ class CWLSurface {
bool small() const; // means surface is smaller than the requested size bool small() const; // means surface is smaller than the requested size
Vector2D correctSmallVec() const; // returns a corrective vector for small() surfaces Vector2D correctSmallVec() const; // returns a corrective vector for small() surfaces
Vector2D getViewporterCorrectedSize() const; Vector2D getViewporterCorrectedSize() const;
CRegion logicalDamage() const;
// allow stretching. Useful for plugins. // allow stretching. Useful for plugins.
bool m_bFillIgnoreSmall = false; bool m_bFillIgnoreSmall = false;

View file

@ -1588,31 +1588,30 @@ void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y, dou
y += CORRECTION.y; 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) if (scale != 1.0)
wlr_region_scale(damageBox.pixman(), damageBox.pixman(), scale); damageBox.scale(scale);
// schedule frame events // 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))); g_pCompositor->scheduleFrameForMonitor(g_pCompositor->getMonitorFromVector(Vector2D(x, y)));
}
if (damageBox.empty()) if (damageBox.empty())
return; return;
damageBox.translate({x, y});
CRegion damageBoxForEach; CRegion damageBoxForEach;
for (auto& m : g_pCompositor->m_vMonitors) { for (auto& m : g_pCompositor->m_vMonitors) {
if (!m->output) if (!m->output)
continue; continue;
double lx = 0, ly = 0; damageBoxForEach.set(damageBox);
wlr_output_layout_output_coords(g_pCompositor->m_sWLROutputLayout, m->output, &lx, &ly); damageBoxForEach.translate({-m->vecPosition.x, -m->vecPosition.y}).scale(m->scale);
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});
m->addDamage(&damageBoxForEach); m->addDamage(&damageBoxForEach);
} }