Skip to content

renderer: add windowrule type suppressvrr #10300

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 54 additions & 34 deletions src/config/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1683,33 +1683,15 @@ void CConfigManager::ensureVRR(PHLMONITOR pMonitor) {
if (!m->m_output || m->m_createdByUser)
return;

const auto OLDVRRSTATUS = m->m_vrrActive;
auto NEWVRRSTATUS = m->m_vrrActive;

const auto USEVRR = m->m_activeMonitorRule.vrr.has_value() ? m->m_activeMonitorRule.vrr.value() : **PVRR;

if (USEVRR == 0) {
if (m->m_vrrActive) {
m->m_output->state->resetExplicitFences();
m->m_output->state->setAdaptiveSync(false);

if (!m->m_state.commit())
Debug::log(ERR, "Couldn't commit output {} in ensureVRR -> false", m->m_output->name);
}
m->m_vrrActive = false;
return;
NEWVRRSTATUS = false;
} else if (USEVRR == 1) {
if (!m->m_vrrActive) {
m->m_output->state->resetExplicitFences();
m->m_output->state->setAdaptiveSync(true);

if (!m->m_state.test()) {
Debug::log(LOG, "Pending output {} does not accept VRR.", m->m_output->name);
m->m_output->state->setAdaptiveSync(false);
}

if (!m->m_state.commit())
Debug::log(ERR, "Couldn't commit output {} in ensureVRR -> true", m->m_output->name);
}
m->m_vrrActive = true;
return;
NEWVRRSTATUS = true;
} else if (USEVRR == 2 || USEVRR == 3) {
const auto PWORKSPACE = m->m_activeWorkspace;

Expand All @@ -1722,23 +1704,61 @@ void CConfigManager::ensureVRR(PHLMONITOR pMonitor) {
wantVRR = contentType == CONTENT_TYPE_GAME || contentType == CONTENT_TYPE_VIDEO;
}

if (wantVRR) {
/* fullscreen */
m->m_vrrActive = true;
NEWVRRSTATUS = wantVRR;
}

if (!m->m_output->state->state().adaptiveSync) {
m->m_output->state->setAdaptiveSync(true);
// search for windows within workspace that should suppress VRR
const auto PWORKSPACE = m->m_activeWorkspace;
if (PWORKSPACE) {
auto vrrSuppressingWindows = 0;
std::optional<bool> fullscreenWindowSuppressing = std::nullopt;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can just be a bool = false and set to true in the loop if a matching window is found


if (!m->m_state.test()) {
Debug::log(LOG, "Pending output {} does not accept VRR.", m->m_output->name);
m->m_output->state->setAdaptiveSync(false);
}
for (auto const& w : g_pCompositor->m_windows) {
if (w->m_isMapped && w->workspaceID() == PWORKSPACE->m_id && !w->isHidden()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer guards

if (w->m_suppressVrr)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

other windows dont matter, only the fs one

vrrSuppressingWindows++;

if (w->isFullscreen())
fullscreenWindowSuppressing = w->m_suppressVrr;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can break afterwards

}
} else {
m->m_vrrActive = false;
}

auto FSWINDOW = PWORKSPACE->getFullscreenWindow();

// * if there exists a fullscreen window in the workspace, disable VRR solely based on
// whether that window is `suppressvrr` or not;
// * if there doesn't exist one, then disable VRR for at least one visible window that is `suppressvrr`

if (fullscreenWindowSuppressing == true || (fullscreenWindowSuppressing == std::nullopt && vrrSuppressingWindows > 0)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no {}

NEWVRRSTATUS = false;
}
}

if (OLDVRRSTATUS && !NEWVRRSTATUS) { // VRR ON ~> OFF transition
Debug::log(LOG, "VRR ON ~> OFF on output {}", m->m_output->name);
m->m_output->state->resetExplicitFences();
m->m_output->state->setAdaptiveSync(false);

if (!m->m_state.commit())
Debug::log(ERR, "Couldn't commit output {} in ensureVRR -> false", m->m_output->name);

m->m_vrrActive = NEWVRRSTATUS;
return;
} else if (!OLDVRRSTATUS && NEWVRRSTATUS) { // VRR OFF ~> ON transition
Debug::log(LOG, "VRR OFF ~> ON on output {}", m->m_output->name);
m->m_output->state->resetExplicitFences();
m->m_output->state->setAdaptiveSync(true);

if (!m->m_state.test()) {
Debug::log(LOG, "Pending output {} does not accept VRR.", m->m_output->name);
m->m_output->state->setAdaptiveSync(false);
}

if (!m->m_state.commit())
Debug::log(ERR, "Couldn't commit output {} in ensureVRR -> true", m->m_output->name);

m->m_vrrActive = NEWVRRSTATUS;
return;
}
};

Expand Down
3 changes: 3 additions & 0 deletions src/desktop/Window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,9 @@ class CWindow {
// For the noclosefor windowrule
Time::steady_tp m_closeableSince = Time::steadyNow();

// VRR
bool m_suppressVrr = false;

// For the list lookup
bool operator==(const CWindow& rhs) const {
return m_xdgSurface == rhs.m_xdgSurface && m_xwaylandSurface == rhs.m_xwaylandSurface && m_position == rhs.m_position && m_size == rhs.m_size &&
Expand Down
4 changes: 3 additions & 1 deletion src/desktop/WindowRule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "../config/ConfigManager.hpp"

static const auto RULES = std::unordered_set<std::string>{
"float", "fullscreen", "maximize", "noinitialfocus", "pin", "stayfocused", "tile", "renderunfocused", "persistentsize",
"float", "fullscreen", "maximize", "noinitialfocus", "pin", "stayfocused", "tile", "renderunfocused", "persistentsize", "suppressvrr",
};
static const auto RULES_PREFIX = std::unordered_set<std::string>{
"animation", "bordercolor", "bordersize", "center", "content", "fullscreenstate", "group", "idleinhibit", "maxsize", "minsize", "monitor",
Expand Down Expand Up @@ -41,6 +41,8 @@ CWindowRule::CWindowRule(const std::string& rule, const std::string& value, bool
m_ruleType = RULE_RENDERUNFOCUSED;
else if (rule == "persistentsize")
m_ruleType = RULE_PERSISTENTSIZE;
else if (rule == "suppressvrr")
m_ruleType = RULE_SUPPRESSVRR;
else if (rule.starts_with("animation"))
m_ruleType = RULE_ANIMATION;
else if (rule.starts_with("bordercolor"))
Expand Down
1 change: 1 addition & 0 deletions src/desktop/WindowRule.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class CWindowRule {
RULE_CONTENT,
RULE_PERSISTENTSIZE,
RULE_NOCLOSEFOR,
RULE_SUPPRESSVRR,
};

eRuleType m_ruleType = RULE_INVALID;
Expand Down
11 changes: 11 additions & 0 deletions src/events/Windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,11 @@ void Events::listener_mapWindow(void* owner, void* data) {
try {
PWINDOW->m_closeableSince = Time::steadyNow() + std::chrono::milliseconds(std::stoull(VARS[1]));
} catch (std::exception& e) { Debug::log(ERR, "Rule \"{}\" failed with: {}", r->m_rule, e.what()); }
break;
}
case CWindowRule::RULE_SUPPRESSVRR: {
PWINDOW->m_suppressVrr = true;
break;
}
default: break;
}
Expand Down Expand Up @@ -710,6 +715,9 @@ void Events::listener_mapWindow(void* owner, void* data) {

if (PMONITOR && PWINDOW->isX11OverrideRedirect())
PWINDOW->m_X11SurfaceScaledBy = PMONITOR->m_scale;

// VRR should update
g_pConfigManager->ensureVRR(PWINDOW->m_monitor.lock());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

redundant

}

void Events::listener_unmapWindow(void* owner, void* data) {
Expand Down Expand Up @@ -847,6 +855,9 @@ void Events::listener_unmapWindow(void* owner, void* data) {

// update lastwindow after focus
PWINDOW->onUnmap();

// VRR should update
g_pConfigManager->ensureVRR(PMONITOR);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

redundant

}

void Events::listener_commitWindow(void* owner, void* data) {
Expand Down