aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorVaxry <[email protected]>2024-06-19 18:25:20 +0200
committerVaxry <[email protected]>2024-06-19 18:25:25 +0200
commitdef5fcb2128304392e9e76bcc081d088b316a197 (patch)
tree9cbaf0621bc541eec13699c433fd3bd6be0fbe24
parent65f04f265c268d9752d6c2534c2b078d0e54a150 (diff)
downloadHyprland-def5fcb2128304392e9e76bcc081d088b316a197.tar.gz
Hyprland-def5fcb2128304392e9e76bcc081d088b316a197.zip
damageRing: move to hyprland impl
A small wlroots utility we were still using.
-rw-r--r--src/helpers/DamageRing.cpp52
-rw-r--r--src/helpers/DamageRing.hpp22
-rw-r--r--src/helpers/Monitor.cpp18
-rw-r--r--src/helpers/Monitor.hpp40
-rw-r--r--src/includes.hpp1
-rw-r--r--src/render/Renderer.cpp16
6 files changed, 111 insertions, 38 deletions
diff --git a/src/helpers/DamageRing.cpp b/src/helpers/DamageRing.cpp
new file mode 100644
index 00000000..093e7ca6
--- /dev/null
+++ b/src/helpers/DamageRing.cpp
@@ -0,0 +1,52 @@
+#include "DamageRing.hpp"
+
+void CDamageRing::setSize(const Vector2D& size_) {
+ if (size_ == size)
+ return;
+
+ size = size_;
+
+ damageEntire();
+}
+
+bool CDamageRing::damage(const CRegion& rg) {
+ CRegion clipped = rg.copy().intersect(CBox{{}, size});
+ if (clipped.empty())
+ return false;
+
+ current.add(clipped);
+ return true;
+}
+
+void CDamageRing::damageEntire() {
+ damage(CBox{{}, size});
+}
+
+void CDamageRing::rotate() {
+ previousIdx = (previousIdx + DAMAGE_RING_PREVIOUS_LEN - 1) % DAMAGE_RING_PREVIOUS_LEN;
+
+ previous[previousIdx] = current;
+ current.clear();
+}
+
+CRegion CDamageRing::getBufferDamage(int age) {
+ if (age <= 0 || age > DAMAGE_RING_PREVIOUS_LEN + 1)
+ return CBox{{}, size};
+
+ CRegion damage = current;
+
+ for (int i = 0; i < age - 1; ++i) {
+ int j = (previousIdx + i) % DAMAGE_RING_PREVIOUS_LEN;
+ damage.add(previous.at(j));
+ }
+
+ // don't return a ludicrous amount of rects
+ if (damage.getRects().size() > 8)
+ return damage.getExtents();
+
+ return damage;
+}
+
+bool CDamageRing::hasChanged() {
+ return !current.empty();
+}
diff --git a/src/helpers/DamageRing.hpp b/src/helpers/DamageRing.hpp
new file mode 100644
index 00000000..ae85c453
--- /dev/null
+++ b/src/helpers/DamageRing.hpp
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "./math/Math.hpp"
+#include <array>
+
+constexpr static int DAMAGE_RING_PREVIOUS_LEN = 2;
+
+class CDamageRing {
+ public:
+ void setSize(const Vector2D& size_);
+ bool damage(const CRegion& rg);
+ void damageEntire();
+ void rotate();
+ CRegion getBufferDamage(int age);
+ bool hasChanged();
+
+ private:
+ Vector2D size;
+ CRegion current;
+ std::array<CRegion, DAMAGE_RING_PREVIOUS_LEN> previous;
+ size_t previousIdx = 0;
+};
diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp
index e99e16ef..7ebd2539 100644
--- a/src/helpers/Monitor.cpp
+++ b/src/helpers/Monitor.cpp
@@ -17,12 +17,10 @@ int ratHandler(void* data) {
}
CMonitor::CMonitor() : state(this) {
- wlr_damage_ring_init(&damage);
+ ;
}
CMonitor::~CMonitor() {
- wlr_damage_ring_finish(&damage);
-
hyprListener_monitorDestroy.removeCallback();
hyprListener_monitorFrame.removeCallback();
hyprListener_monitorStateRequest.removeCallback();
@@ -162,7 +160,7 @@ void CMonitor::onConnect(bool noRule) {
if (!state.commit())
Debug::log(WARN, "wlr_output_commit_state failed in CMonitor::onCommit");
- wlr_damage_ring_set_bounds(&damage, vecTransformedSize.x, vecTransformedSize.y);
+ damage.setSize(vecTransformedSize);
Debug::log(LOG, "Added new monitor with name {} at {:j0} with size {:j0}, pointer {:x}", output->name, vecPosition, vecPixelSize, (uintptr_t)output);
@@ -345,9 +343,9 @@ void CMonitor::onDisconnect(bool destroy) {
void CMonitor::addDamage(const pixman_region32_t* rg) {
static auto PZOOMFACTOR = CConfigValue<Hyprlang::FLOAT>("cursor:zoom_factor");
if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == this) {
- wlr_damage_ring_add_whole(&damage);
+ damage.damageEntire();
g_pCompositor->scheduleFrameForMonitor(this);
- } else if (wlr_damage_ring_add(&damage, rg))
+ } else if (damage.damage(rg))
g_pCompositor->scheduleFrameForMonitor(this);
}
@@ -358,13 +356,11 @@ void CMonitor::addDamage(const CRegion* rg) {
void CMonitor::addDamage(const CBox* box) {
static auto PZOOMFACTOR = CConfigValue<Hyprlang::FLOAT>("cursor:zoom_factor");
if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == this) {
- wlr_damage_ring_add_whole(&damage);
+ damage.damageEntire();
g_pCompositor->scheduleFrameForMonitor(this);
}
- wlr_box damageBox = {(int)box->x, (int)box->y, (int)box->w, (int)box->h};
-
- if (wlr_damage_ring_add_box(&damage, &damageBox))
+ if (damage.damage(*box))
g_pCompositor->scheduleFrameForMonitor(this);
}
@@ -379,7 +375,7 @@ bool CMonitor::shouldSkipScheduleFrameOnMouseEvent() {
// keep requested minimum refresh rate
if (shouldSkip && *PMINRR && lastPresentationTimer.getMillis() > 1000 / *PMINRR) {
// damage whole screen because some previous cursor box damages were skipped
- wlr_damage_ring_add_whole(&damage);
+ damage.damageEntire();
return false;
}
diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp
index b8902197..8a2acdaf 100644
--- a/src/helpers/Monitor.hpp
+++ b/src/helpers/Monitor.hpp
@@ -11,6 +11,7 @@
#include "math/Math.hpp"
#include <optional>
#include "signal/Signal.hpp"
+#include "DamageRing.hpp"
// Enum for the different types of auto directions, e.g. auto-left, auto-up.
enum eAutoDirs {
@@ -60,33 +61,32 @@ class CMonitor {
CMonitor();
~CMonitor();
- Vector2D vecPosition = Vector2D(-1, -1); // means unset
- Vector2D vecXWaylandPosition = Vector2D(-1, -1); // means unset
- Vector2D vecSize = Vector2D(0, 0);
- Vector2D vecPixelSize = Vector2D(0, 0);
- Vector2D vecTransformedSize = Vector2D(0, 0);
+ Vector2D vecPosition = Vector2D(-1, -1); // means unset
+ Vector2D vecXWaylandPosition = Vector2D(-1, -1); // means unset
+ Vector2D vecSize = Vector2D(0, 0);
+ Vector2D vecPixelSize = Vector2D(0, 0);
+ Vector2D vecTransformedSize = Vector2D(0, 0);
- bool primary = false;
+ bool primary = false;
- uint64_t ID = -1;
- PHLWORKSPACE activeWorkspace = nullptr;
- PHLWORKSPACE activeSpecialWorkspace = nullptr;
- float setScale = 1; // scale set by cfg
- float scale = 1; // real scale
+ uint64_t ID = -1;
+ PHLWORKSPACE activeWorkspace = nullptr;
+ PHLWORKSPACE activeSpecialWorkspace = nullptr;
+ float setScale = 1; // scale set by cfg
+ float scale = 1; // real scale
- std::string szName = "";
- std::string szDescription = "";
- std::string szShortDescription = "";
+ std::string szName = "";
+ std::string szDescription = "";
+ std::string szShortDescription = "";
- Vector2D vecReservedTopLeft = Vector2D(0, 0);
- Vector2D vecReservedBottomRight = Vector2D(0, 0);
+ Vector2D vecReservedTopLeft = Vector2D(0, 0);
+ Vector2D vecReservedBottomRight = Vector2D(0, 0);
- drmModeModeInfo customDrmMode = {};
+ drmModeModeInfo customDrmMode = {};
- CMonitorState state;
+ CMonitorState state;
+ CDamageRing damage;
- // WLR stuff
- wlr_damage_ring damage;
wlr_output* output = nullptr;
float refreshRate = 60;
int framesToSkip = 0;
diff --git a/src/includes.hpp b/src/includes.hpp
index 87bd21f8..afec078a 100644
--- a/src/includes.hpp
+++ b/src/includes.hpp
@@ -53,7 +53,6 @@ extern "C" {
#include <wlr/types/wlr_primary_selection_v1.h>
#include <wlr/types/wlr_viewporter.h>
#include <wlr/types/wlr_subcompositor.h>
-#include <wlr/types/wlr_damage_ring.h>
#include <wlr/util/log.h>
#include <wlr/util/region.h>
#include <wlr/util/edges.h>
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index d44f4cd5..b783ab81 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -1246,7 +1246,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
clock_gettime(CLOCK_MONOTONIC, &now);
// check the damage
- bool hasChanged = pMonitor->output->needs_frame || pixman_region32_not_empty(&pMonitor->damage.current);
+ bool hasChanged = pMonitor->output->needs_frame || pMonitor->damage.hasChanged();
if (!hasChanged && *PDAMAGETRACKINGMODE != DAMAGE_TRACKING_NONE && pMonitor->forceFullFrames == 0 && damageBlinkCleanup == 0)
return;
@@ -1414,7 +1414,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
pMonitor->state.wlr()->tearing_page_flip = shouldTear;
if (!pMonitor->state.commit()) {
- wlr_damage_ring_add_whole(&pMonitor->damage);
+ pMonitor->damage.damageEntire();
return;
}
@@ -2245,7 +2245,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
// updato wlroots
g_pCompositor->arrangeMonitors();
- wlr_damage_ring_set_bounds(&pMonitor->damage, pMonitor->vecTransformedSize.x, pMonitor->vecTransformedSize.y);
+ pMonitor->damage.setSize(pMonitor->vecTransformedSize);
// Set scale for all surfaces on this monitor, needed for some clients
// but not on unsafe state to avoid crashes
@@ -2609,13 +2609,15 @@ bool CHyprRenderer::beginRender(CMonitor* pMonitor, CRegion& damage, eRenderMode
return true;
}
+ int bufferAge = 0;
+
if (!buffer) {
if (!wlr_output_configure_primary_swapchain(pMonitor->output, pMonitor->state.wlr(), &pMonitor->output->swapchain)) {
Debug::log(ERR, "Failed to configure primary swapchain for {}", pMonitor->szName);
return false;
}
- m_pCurrentWlrBuffer = wlr_swapchain_acquire(pMonitor->output->swapchain, nullptr);
+ m_pCurrentWlrBuffer = wlr_swapchain_acquire(pMonitor->output->swapchain, &bufferAge);
if (!m_pCurrentWlrBuffer) {
Debug::log(ERR, "Failed to acquire swapchain buffer for {}", pMonitor->szName);
return false;
@@ -2634,8 +2636,10 @@ bool CHyprRenderer::beginRender(CMonitor* pMonitor, CRegion& damage, eRenderMode
return false;
}
- if (mode == RENDER_MODE_NORMAL)
- wlr_damage_ring_rotate_buffer(&pMonitor->damage, m_pCurrentWlrBuffer, damage.pixman());
+ if (mode == RENDER_MODE_NORMAL) {
+ damage = pMonitor->damage.getBufferDamage(bufferAge);
+ pMonitor->damage.rotate();
+ }
m_pCurrentRenderbuffer->bind();
if (simple)