summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/config/ConfigDescriptions.hpp24
-rw-r--r--src/config/ConfigManager.cpp4
-rw-r--r--src/helpers/Monitor.cpp9
-rw-r--r--src/protocols/CommitTiming.cpp8
-rw-r--r--src/protocols/Fifo.cpp45
-rw-r--r--src/protocols/core/Compositor.cpp4
-rw-r--r--src/protocols/types/SurfaceStateQueue.cpp3
-rw-r--r--src/protocols/types/SurfaceStateQueue.hpp2
-rw-r--r--src/render/Renderer.cpp74
9 files changed, 106 insertions, 67 deletions
diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp
index 6e0c2958..aaaa0704 100644
--- a/src/config/ConfigDescriptions.hpp
+++ b/src/config/ConfigDescriptions.hpp
@@ -1830,6 +1830,30 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
.type = CONFIG_OPTION_BOOL,
.data = SConfigOptionDescription::SBoolData{false},
},
+ SConfigOptionDescription{
+ .value = "debug:ds_handle_same_buffer",
+ .description = "Special case for DS with unmodified buffer",
+ .type = CONFIG_OPTION_BOOL,
+ .data = SConfigOptionDescription::SBoolData{true},
+ },
+ SConfigOptionDescription{
+ .value = "debug:ds_handle_same_buffer_fifo",
+ .description = "Special case for DS with unmodified buffer unlocks fifo",
+ .type = CONFIG_OPTION_BOOL,
+ .data = SConfigOptionDescription::SBoolData{true},
+ },
+ SConfigOptionDescription{
+ .value = "debug:fifo_pending_workaround",
+ .description = "Fifo workaround for empty pending list",
+ .type = CONFIG_OPTION_BOOL,
+ .data = SConfigOptionDescription::SBoolData{true},
+ },
+ SConfigOptionDescription{
+ .value = "debug:render_solitary_wo_damage",
+ .description = "Render solitary window with empty damage",
+ .type = CONFIG_OPTION_BOOL,
+ .data = SConfigOptionDescription::SBoolData{false},
+ },
/*
* dwindle:
diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp
index d5ffe8f2..0890cc4e 100644
--- a/src/config/ConfigManager.cpp
+++ b/src/config/ConfigManager.cpp
@@ -571,6 +571,10 @@ CConfigManager::CConfigManager() {
registerConfigVar("debug:disable_scale_checks", Hyprlang::INT{0});
registerConfigVar("debug:colored_stdout_logs", Hyprlang::INT{1});
registerConfigVar("debug:full_cm_proto", Hyprlang::INT{0});
+ registerConfigVar("debug:ds_handle_same_buffer", Hyprlang::INT{1});
+ registerConfigVar("debug:ds_handle_same_buffer_fifo", Hyprlang::INT{1});
+ registerConfigVar("debug:fifo_pending_workaround", Hyprlang::INT{1});
+ registerConfigVar("debug:render_solitary_wo_damage", Hyprlang::INT{0});
registerConfigVar("decoration:rounding", Hyprlang::INT{0});
registerConfigVar("decoration:rounding_power", {2.F});
diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp
index cee9ff1b..d3b374e7 100644
--- a/src/helpers/Monitor.cpp
+++ b/src/helpers/Monitor.cpp
@@ -1823,7 +1823,10 @@ uint16_t CMonitor::isDSBlocked(bool full) {
}
bool CMonitor::attemptDirectScanout() {
- const auto blockedReason = isDSBlocked();
+ static const auto PSAME = CConfigValue<Hyprlang::INT>("debug:ds_handle_same_buffer");
+ static const auto PSAMEFIFO = CConfigValue<Hyprlang::INT>("debug:ds_handle_same_buffer_fifo");
+
+ const auto blockedReason = isDSBlocked();
if (blockedReason)
return false;
@@ -1837,7 +1840,7 @@ bool CMonitor::attemptDirectScanout() {
auto PBUFFER = PSURFACE->m_current.buffer.m_buffer;
// #TODO this entire bit needs figuring out, vrr goes down the drain without it
- if (PBUFFER == m_output->state->state().buffer) {
+ if (PBUFFER == m_output->state->state().buffer && *PSAME) {
PSURFACE->presentFeedback(Time::steadyNow(), m_self.lock());
if (m_scanoutNeedsCursorUpdate) {
@@ -1856,7 +1859,7 @@ bool CMonitor::attemptDirectScanout() {
}
//#TODO this entire bit is bootleg deluxe, above bit is to not make vrr go down the drain, returning early here means fifo gets forever locked.
- if (PSURFACE->m_fifo)
+ if (PSURFACE->m_fifo && *PSAMEFIFO)
PSURFACE->m_stateQueue.unlockFirst(LOCK_REASON_FIFO);
return true;
diff --git a/src/protocols/CommitTiming.cpp b/src/protocols/CommitTiming.cpp
index 2fcd8e9c..bce14f6b 100644
--- a/src/protocols/CommitTiming.cpp
+++ b/src/protocols/CommitTiming.cpp
@@ -32,9 +32,7 @@ CCommitTimerResource::CCommitTimerResource(UP<CWpCommitTimerV1>&& resource_, SP<
const auto TIME_NOW = Time::steadyNow();
if (TIME_NOW > TIME) {
- // TODO: should we err here?
- // for now just do nothing I guess, thats some lag.
- m_pendingTimeout = Time::steady_dur::min();
+ m_pendingTimeout.reset();
} else
m_pendingTimeout = TIME - TIME_NOW;
});
@@ -56,6 +54,7 @@ CCommitTimerResource::CCommitTimerResource(UP<CWpCommitTimerV1>&& resource_, SP<
m_surface->m_stateQueue.unlockFirst(LOCK_REASON_TIMER);
},
nullptr);
+ g_pEventLoopManager->addTimer(timer);
} else
timer->updateTimeout(m_pendingTimeout);
@@ -64,7 +63,8 @@ CCommitTimerResource::CCommitTimerResource(UP<CWpCommitTimerV1>&& resource_, SP<
}
CCommitTimerResource::~CCommitTimerResource() {
- ;
+ if (m_timerPresent)
+ g_pEventLoopManager->removeTimer(timer);
}
bool CCommitTimerResource::good() {
diff --git a/src/protocols/Fifo.cpp b/src/protocols/Fifo.cpp
index d9f873c9..386327b5 100644
--- a/src/protocols/Fifo.cpp
+++ b/src/protocols/Fifo.cpp
@@ -34,35 +34,40 @@ CFifoResource::CFifoResource(UP<CWpFifoV1>&& resource_, SP<CWLSurfaceResource> s
});
m_listeners.surfaceStateCommit = m_surface->m_events.stateCommit.listen([this](auto state) {
+ static const auto PPEND = CConfigValue<Hyprlang::INT>("debug:fifo_pending_workaround");
+
if (!m_pending.surfaceLocked)
return;
- //#TODO:
- // this feels wrong, but if we have no pending frames, presented might never come because
- // we are waiting on the barrier to unlock and no damage is around.
- if (m_surface->m_enteredOutputs.empty() && m_surface->m_hlSurface) {
- for (auto& m : g_pCompositor->m_monitors) {
- if (!m || !m->m_enabled)
- continue;
+ if (*PPEND) {
+ //#TODO:
+ // this feels wrong, but if we have no pending frames, presented might never come because
+ // we are waiting on the barrier to unlock and no damage is around.
+ // unlock on timeout instead?
+ if (m_surface->m_enteredOutputs.empty() && m_surface->m_hlSurface) {
+ for (auto& m : g_pCompositor->m_monitors) {
+ if (!m || !m->m_enabled)
+ continue;
+
+ auto box = m_surface->m_hlSurface->getSurfaceBoxGlobal();
+ if (box && !box->intersection({m->m_position, m->m_size}).empty()) {
+ if (m->m_tearingState.activelyTearing)
+ return; // dont fifo lock on tearing.
+
+ g_pCompositor->scheduleFrameForMonitor(m, Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME);
+ }
+ }
+ } else {
+ for (auto& m : m_surface->m_enteredOutputs) {
+ if (!m)
+ continue;
- auto box = m_surface->m_hlSurface->getSurfaceBoxGlobal();
- if (box && !box->intersection({m->m_position, m->m_size}).empty()) {
if (m->m_tearingState.activelyTearing)
return; // dont fifo lock on tearing.
- g_pCompositor->scheduleFrameForMonitor(m, Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME);
+ g_pCompositor->scheduleFrameForMonitor(m.lock(), Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME);
}
}
- } else {
- for (auto& m : m_surface->m_enteredOutputs) {
- if (!m)
- continue;
-
- if (m->m_tearingState.activelyTearing)
- return; // dont fifo lock on tearing.
-
- g_pCompositor->scheduleFrameForMonitor(m.lock(), Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME);
- }
}
// only lock once its mapped.
diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp
index c897bfe8..9fc44703 100644
--- a/src/protocols/core/Compositor.cpp
+++ b/src/protocols/core/Compositor.cpp
@@ -506,13 +506,13 @@ void CWLSurfaceResource::scheduleState(WP<SSurfaceState> state) {
}
} else if (state->buffer && state->buffer->isSynchronous()) {
// synchronous (shm) buffers can be read immediately
- m_stateQueue.unlock(state);
+ m_stateQueue.unlock(state, LOCK_REASON_FENCE);
} else if (state->buffer && state->buffer->m_syncFd.isValid()) {
// async buffer and is dmabuf, then we can wait on implicit fences
g_pEventLoopManager->doOnReadable(std::move(state->buffer->m_syncFd), [state, whenReadable]() { whenReadable(state, LOCK_REASON_FENCE); });
} else {
// state commit without a buffer.
- m_stateQueue.unlock(state);
+ m_stateQueue.unlock(state, LOCK_REASON_FENCE);
}
}
diff --git a/src/protocols/types/SurfaceStateQueue.cpp b/src/protocols/types/SurfaceStateQueue.cpp
index c10b556f..348ac711 100644
--- a/src/protocols/types/SurfaceStateQueue.cpp
+++ b/src/protocols/types/SurfaceStateQueue.cpp
@@ -21,6 +21,7 @@ void CSurfaceStateQueue::dropState(const WP<SSurfaceState>& state) {
}
void CSurfaceStateQueue::lock(const WP<SSurfaceState>& weakState, eLockReason reason) {
+ ASSERT(reason != LOCK_REASON_NONE);
auto it = find(weakState);
if (it == m_queue.end())
return;
@@ -29,6 +30,7 @@ void CSurfaceStateQueue::lock(const WP<SSurfaceState>& weakState, eLockReason re
}
void CSurfaceStateQueue::unlock(const WP<SSurfaceState>& state, eLockReason reason) {
+ ASSERT(reason != LOCK_REASON_NONE);
auto it = find(state);
if (it == m_queue.end())
return;
@@ -38,6 +40,7 @@ void CSurfaceStateQueue::unlock(const WP<SSurfaceState>& state, eLockReason reas
}
void CSurfaceStateQueue::unlockFirst(eLockReason reason) {
+ ASSERT(reason != LOCK_REASON_NONE);
for (auto& it : m_queue) {
if ((it->lockMask & reason) != LOCK_REASON_NONE) {
it->lockMask &= ~reason;
diff --git a/src/protocols/types/SurfaceStateQueue.hpp b/src/protocols/types/SurfaceStateQueue.hpp
index 1841ed20..8d9db7a5 100644
--- a/src/protocols/types/SurfaceStateQueue.hpp
+++ b/src/protocols/types/SurfaceStateQueue.hpp
@@ -15,7 +15,7 @@ class CSurfaceStateQueue {
WP<SSurfaceState> enqueue(UP<SSurfaceState>&& state);
void dropState(const WP<SSurfaceState>& state);
void lock(const WP<SSurfaceState>& state, eLockReason reason);
- void unlock(const WP<SSurfaceState>& state, eLockReason reason = LOCK_REASON_NONE);
+ void unlock(const WP<SSurfaceState>& state, eLockReason reason);
void unlockFirst(eLockReason reason);
void tryProcess();
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index b3684a0e..abecb2f9 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -1268,6 +1268,7 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor, bool commit) {
static auto PDEBUGOVERLAY = CConfigValue<Hyprlang::INT>("debug:overlay");
static auto PDAMAGETRACKINGMODE = CConfigValue<Hyprlang::INT>("debug:damage_tracking");
static auto PDAMAGEBLINK = CConfigValue<Hyprlang::INT>("debug:damage_blink");
+ static auto PSOLDAMAGE = CConfigValue<Hyprlang::INT>("debug:render_solitary_wo_damage");
static auto PVFR = CConfigValue<Hyprlang::INT>("misc:vfr");
static int damageBlinkCleanup = 0; // because double-buffered
@@ -1398,46 +1399,45 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor, bool commit) {
bool renderCursor = true;
- if (!finalDamage.empty()) {
- if (pMonitor->m_solitaryClient.expired()) {
- if (pMonitor->isMirror()) {
- g_pHyprOpenGL->blend(false);
- g_pHyprOpenGL->renderMirrored();
- g_pHyprOpenGL->blend(true);
- EMIT_HOOK_EVENT("render", RENDER_POST_MIRROR);
- renderCursor = false;
- } else {
- CBox renderBox = {0, 0, sc<int>(pMonitor->m_pixelSize.x), sc<int>(pMonitor->m_pixelSize.y)};
- renderWorkspace(pMonitor, pMonitor->m_activeWorkspace, NOW, renderBox);
-
- renderLockscreen(pMonitor, NOW, renderBox);
-
- if (pMonitor == Desktop::focusState()->monitor()) {
- g_pHyprNotificationOverlay->draw(pMonitor);
- g_pHyprError->draw();
- }
+ if (pMonitor->m_solitaryClient && (!finalDamage.empty() || *PSOLDAMAGE))
+ renderWindow(pMonitor->m_solitaryClient.lock(), pMonitor, NOW, false, RENDER_PASS_MAIN /* solitary = no popups */);
+ else if (!finalDamage.empty()) {
+ if (pMonitor->isMirror()) {
+ g_pHyprOpenGL->blend(false);
+ g_pHyprOpenGL->renderMirrored();
+ g_pHyprOpenGL->blend(true);
+ EMIT_HOOK_EVENT("render", RENDER_POST_MIRROR);
+ renderCursor = false;
+ } else {
+ CBox renderBox = {0, 0, sc<int>(pMonitor->m_pixelSize.x), sc<int>(pMonitor->m_pixelSize.y)};
+ renderWorkspace(pMonitor, pMonitor->m_activeWorkspace, NOW, renderBox);
- // for drawing the debug overlay
- if (pMonitor == g_pCompositor->m_monitors.front() && *PDEBUGOVERLAY == 1) {
- renderStartOverlay = std::chrono::high_resolution_clock::now();
- g_pDebugOverlay->draw();
- endRenderOverlay = std::chrono::high_resolution_clock::now();
- }
+ renderLockscreen(pMonitor, NOW, renderBox);
- if (*PDAMAGEBLINK && damageBlinkCleanup == 0) {
- CRectPassElement::SRectData data;
- data.box = {0, 0, pMonitor->m_transformedSize.x, pMonitor->m_transformedSize.y};
- data.color = CHyprColor(1.0, 0.0, 1.0, 100.0 / 255.0);
- m_renderPass.add(makeUnique<CRectPassElement>(data));
- damageBlinkCleanup = 1;
- } else if (*PDAMAGEBLINK) {
- damageBlinkCleanup++;
- if (damageBlinkCleanup > 3)
- damageBlinkCleanup = 0;
- }
+ if (pMonitor == Desktop::focusState()->monitor()) {
+ g_pHyprNotificationOverlay->draw(pMonitor);
+ g_pHyprError->draw();
}
- } else
- renderWindow(pMonitor->m_solitaryClient.lock(), pMonitor, NOW, false, RENDER_PASS_MAIN /* solitary = no popups */);
+
+ // for drawing the debug overlay
+ if (pMonitor == g_pCompositor->m_monitors.front() && *PDEBUGOVERLAY == 1) {
+ renderStartOverlay = std::chrono::high_resolution_clock::now();
+ g_pDebugOverlay->draw();
+ endRenderOverlay = std::chrono::high_resolution_clock::now();
+ }
+
+ if (*PDAMAGEBLINK && damageBlinkCleanup == 0) {
+ CRectPassElement::SRectData data;
+ data.box = {0, 0, pMonitor->m_transformedSize.x, pMonitor->m_transformedSize.y};
+ data.color = CHyprColor(1.0, 0.0, 1.0, 100.0 / 255.0);
+ m_renderPass.add(makeUnique<CRectPassElement>(data));
+ damageBlinkCleanup = 1;
+ } else if (*PDAMAGEBLINK) {
+ damageBlinkCleanup++;
+ if (damageBlinkCleanup > 3)
+ damageBlinkCleanup = 0;
+ }
+ }
} else if (!pMonitor->isMirror()) {
sendFrameEventsToWorkspace(pMonitor, pMonitor->m_activeWorkspace, NOW);
if (pMonitor->m_activeSpecialWorkspace)