mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-22 21:45:58 +01:00
damageRing: move to hyprland impl
A small wlroots utility we were still using.
This commit is contained in:
parent
65f04f265c
commit
def5fcb212
6 changed files with 111 additions and 38 deletions
52
src/helpers/DamageRing.cpp
Normal file
52
src/helpers/DamageRing.cpp
Normal file
|
@ -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();
|
||||||
|
}
|
22
src/helpers/DamageRing.hpp
Normal file
22
src/helpers/DamageRing.hpp
Normal file
|
@ -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;
|
||||||
|
};
|
|
@ -17,12 +17,10 @@ int ratHandler(void* data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CMonitor::CMonitor() : state(this) {
|
CMonitor::CMonitor() : state(this) {
|
||||||
wlr_damage_ring_init(&damage);
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
CMonitor::~CMonitor() {
|
CMonitor::~CMonitor() {
|
||||||
wlr_damage_ring_finish(&damage);
|
|
||||||
|
|
||||||
hyprListener_monitorDestroy.removeCallback();
|
hyprListener_monitorDestroy.removeCallback();
|
||||||
hyprListener_monitorFrame.removeCallback();
|
hyprListener_monitorFrame.removeCallback();
|
||||||
hyprListener_monitorStateRequest.removeCallback();
|
hyprListener_monitorStateRequest.removeCallback();
|
||||||
|
@ -162,7 +160,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||||
if (!state.commit())
|
if (!state.commit())
|
||||||
Debug::log(WARN, "wlr_output_commit_state failed in CMonitor::onCommit");
|
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);
|
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) {
|
void CMonitor::addDamage(const pixman_region32_t* rg) {
|
||||||
static auto PZOOMFACTOR = CConfigValue<Hyprlang::FLOAT>("cursor:zoom_factor");
|
static auto PZOOMFACTOR = CConfigValue<Hyprlang::FLOAT>("cursor:zoom_factor");
|
||||||
if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == this) {
|
if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == this) {
|
||||||
wlr_damage_ring_add_whole(&damage);
|
damage.damageEntire();
|
||||||
g_pCompositor->scheduleFrameForMonitor(this);
|
g_pCompositor->scheduleFrameForMonitor(this);
|
||||||
} else if (wlr_damage_ring_add(&damage, rg))
|
} else if (damage.damage(rg))
|
||||||
g_pCompositor->scheduleFrameForMonitor(this);
|
g_pCompositor->scheduleFrameForMonitor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,13 +356,11 @@ void CMonitor::addDamage(const CRegion* rg) {
|
||||||
void CMonitor::addDamage(const CBox* box) {
|
void CMonitor::addDamage(const CBox* box) {
|
||||||
static auto PZOOMFACTOR = CConfigValue<Hyprlang::FLOAT>("cursor:zoom_factor");
|
static auto PZOOMFACTOR = CConfigValue<Hyprlang::FLOAT>("cursor:zoom_factor");
|
||||||
if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == this) {
|
if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == this) {
|
||||||
wlr_damage_ring_add_whole(&damage);
|
damage.damageEntire();
|
||||||
g_pCompositor->scheduleFrameForMonitor(this);
|
g_pCompositor->scheduleFrameForMonitor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_box damageBox = {(int)box->x, (int)box->y, (int)box->w, (int)box->h};
|
if (damage.damage(*box))
|
||||||
|
|
||||||
if (wlr_damage_ring_add_box(&damage, &damageBox))
|
|
||||||
g_pCompositor->scheduleFrameForMonitor(this);
|
g_pCompositor->scheduleFrameForMonitor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,7 +375,7 @@ bool CMonitor::shouldSkipScheduleFrameOnMouseEvent() {
|
||||||
// keep requested minimum refresh rate
|
// keep requested minimum refresh rate
|
||||||
if (shouldSkip && *PMINRR && lastPresentationTimer.getMillis() > 1000 / *PMINRR) {
|
if (shouldSkip && *PMINRR && lastPresentationTimer.getMillis() > 1000 / *PMINRR) {
|
||||||
// damage whole screen because some previous cursor box damages were skipped
|
// damage whole screen because some previous cursor box damages were skipped
|
||||||
wlr_damage_ring_add_whole(&damage);
|
damage.damageEntire();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "math/Math.hpp"
|
#include "math/Math.hpp"
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include "signal/Signal.hpp"
|
#include "signal/Signal.hpp"
|
||||||
|
#include "DamageRing.hpp"
|
||||||
|
|
||||||
// Enum for the different types of auto directions, e.g. auto-left, auto-up.
|
// Enum for the different types of auto directions, e.g. auto-left, auto-up.
|
||||||
enum eAutoDirs {
|
enum eAutoDirs {
|
||||||
|
@ -60,33 +61,32 @@ class CMonitor {
|
||||||
CMonitor();
|
CMonitor();
|
||||||
~CMonitor();
|
~CMonitor();
|
||||||
|
|
||||||
Vector2D vecPosition = Vector2D(-1, -1); // means unset
|
Vector2D vecPosition = Vector2D(-1, -1); // means unset
|
||||||
Vector2D vecXWaylandPosition = Vector2D(-1, -1); // means unset
|
Vector2D vecXWaylandPosition = Vector2D(-1, -1); // means unset
|
||||||
Vector2D vecSize = Vector2D(0, 0);
|
Vector2D vecSize = Vector2D(0, 0);
|
||||||
Vector2D vecPixelSize = Vector2D(0, 0);
|
Vector2D vecPixelSize = Vector2D(0, 0);
|
||||||
Vector2D vecTransformedSize = Vector2D(0, 0);
|
Vector2D vecTransformedSize = Vector2D(0, 0);
|
||||||
|
|
||||||
bool primary = false;
|
bool primary = false;
|
||||||
|
|
||||||
uint64_t ID = -1;
|
uint64_t ID = -1;
|
||||||
PHLWORKSPACE activeWorkspace = nullptr;
|
PHLWORKSPACE activeWorkspace = nullptr;
|
||||||
PHLWORKSPACE activeSpecialWorkspace = nullptr;
|
PHLWORKSPACE activeSpecialWorkspace = nullptr;
|
||||||
float setScale = 1; // scale set by cfg
|
float setScale = 1; // scale set by cfg
|
||||||
float scale = 1; // real scale
|
float scale = 1; // real scale
|
||||||
|
|
||||||
std::string szName = "";
|
std::string szName = "";
|
||||||
std::string szDescription = "";
|
std::string szDescription = "";
|
||||||
std::string szShortDescription = "";
|
std::string szShortDescription = "";
|
||||||
|
|
||||||
Vector2D vecReservedTopLeft = Vector2D(0, 0);
|
Vector2D vecReservedTopLeft = Vector2D(0, 0);
|
||||||
Vector2D vecReservedBottomRight = 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;
|
wlr_output* output = nullptr;
|
||||||
float refreshRate = 60;
|
float refreshRate = 60;
|
||||||
int framesToSkip = 0;
|
int framesToSkip = 0;
|
||||||
|
|
|
@ -53,7 +53,6 @@ extern "C" {
|
||||||
#include <wlr/types/wlr_primary_selection_v1.h>
|
#include <wlr/types/wlr_primary_selection_v1.h>
|
||||||
#include <wlr/types/wlr_viewporter.h>
|
#include <wlr/types/wlr_viewporter.h>
|
||||||
#include <wlr/types/wlr_subcompositor.h>
|
#include <wlr/types/wlr_subcompositor.h>
|
||||||
#include <wlr/types/wlr_damage_ring.h>
|
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include <wlr/util/region.h>
|
#include <wlr/util/region.h>
|
||||||
#include <wlr/util/edges.h>
|
#include <wlr/util/edges.h>
|
||||||
|
|
|
@ -1246,7 +1246,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
|
||||||
// check the damage
|
// 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)
|
if (!hasChanged && *PDAMAGETRACKINGMODE != DAMAGE_TRACKING_NONE && pMonitor->forceFullFrames == 0 && damageBlinkCleanup == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -1414,7 +1414,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
|
||||||
pMonitor->state.wlr()->tearing_page_flip = shouldTear;
|
pMonitor->state.wlr()->tearing_page_flip = shouldTear;
|
||||||
|
|
||||||
if (!pMonitor->state.commit()) {
|
if (!pMonitor->state.commit()) {
|
||||||
wlr_damage_ring_add_whole(&pMonitor->damage);
|
pMonitor->damage.damageEntire();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2245,7 +2245,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||||
// updato wlroots
|
// updato wlroots
|
||||||
g_pCompositor->arrangeMonitors();
|
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
|
// Set scale for all surfaces on this monitor, needed for some clients
|
||||||
// but not on unsafe state to avoid crashes
|
// but not on unsafe state to avoid crashes
|
||||||
|
@ -2609,13 +2609,15 @@ bool CHyprRenderer::beginRender(CMonitor* pMonitor, CRegion& damage, eRenderMode
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bufferAge = 0;
|
||||||
|
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
if (!wlr_output_configure_primary_swapchain(pMonitor->output, pMonitor->state.wlr(), &pMonitor->output->swapchain)) {
|
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);
|
Debug::log(ERR, "Failed to configure primary swapchain for {}", pMonitor->szName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pCurrentWlrBuffer = wlr_swapchain_acquire(pMonitor->output->swapchain, nullptr);
|
m_pCurrentWlrBuffer = wlr_swapchain_acquire(pMonitor->output->swapchain, &bufferAge);
|
||||||
if (!m_pCurrentWlrBuffer) {
|
if (!m_pCurrentWlrBuffer) {
|
||||||
Debug::log(ERR, "Failed to acquire swapchain buffer for {}", pMonitor->szName);
|
Debug::log(ERR, "Failed to acquire swapchain buffer for {}", pMonitor->szName);
|
||||||
return false;
|
return false;
|
||||||
|
@ -2634,8 +2636,10 @@ bool CHyprRenderer::beginRender(CMonitor* pMonitor, CRegion& damage, eRenderMode
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == RENDER_MODE_NORMAL)
|
if (mode == RENDER_MODE_NORMAL) {
|
||||||
wlr_damage_ring_rotate_buffer(&pMonitor->damage, m_pCurrentWlrBuffer, damage.pixman());
|
damage = pMonitor->damage.getBufferDamage(bufferAge);
|
||||||
|
pMonitor->damage.rotate();
|
||||||
|
}
|
||||||
|
|
||||||
m_pCurrentRenderbuffer->bind();
|
m_pCurrentRenderbuffer->bind();
|
||||||
if (simple)
|
if (simple)
|
||||||
|
|
Loading…
Reference in a new issue