Skip to content

VRR flicker mitigations - #2326

Merged
matte-schwartz merged 2 commits into
ValveSoftware:masterfrom
matte-schwartz:vrr-flicker-mitigations
Oct 20, 2026
Merged

matte-schwartz merged 2 commits into
ValveSoftware:masterfrom
matte-schwartz:vrr-flicker-mitigations

Conversation

@matte-schwartz

Copy link
Copy Markdown
Collaborator

At present, when VRR is enabled but Steam is idle, displays drop to the bottom of their VRR-supported range on every idle. Then, when Steam exits an idle state, the refresh rate spikes back up to its maximum value, and on panels which are prone to VRR flicker, this process causes some pretty nasty flickering while navigating the Steam UI.

Mitigate this by holding the refresh rate while the Steam UI is focused. I checked power readings and there is minimal difference by doing this compared to keeping monitors at their minimum value, but the visible flicker still completely disappears. It's targeted only while the Steam UI is focused, as we want to make sure games still interact with VRR as cleanly as possible and keep LFC functioning correctly. The last commit skips recompositing for these repeated frames and presents the last composited image again, which is what keeps the power cost minimal.

Also, clamp the cursor to active content refresh rate when it's above a minimum threshold while VRR is enabled, mimicking KWin's implementation, as it offers a better user experience than spiking to max refresh rate every time the cursor moves while VRR is active in-game.

With adaptive sync active, cursor motion forces a flip on the next
wakeup, so moving the mouse over a game drives the panel to its maximum
refresh rate between the game's own frames. The refresh rate then swings
between the game rate and the maximum, which flickers visibly on some
VRR panels. The cursor auto-hide does the same a fixed timeout after the
last motion.

Cursor damage waits for the next content frame and only flips on its own
once no content has been painted for 1/adaptive_sync_cursor_min_fps
seconds. The 30 fps default matches KWin's threshold for deferring
repaints outside the active window. KWin checks the window's frame time
estimate instead. Here, slower content holds a cursor update back by at
most 1/30 s.
The Steam UI only presents when something changes, so with adaptive sync
active the panel stretches toward its minimum refresh rate whenever the
screen goes still and snaps back to the maximum on the next update.
Every swing shifts the panel's effective gamma, which shows as
whole-screen brightness flicker on OLED and VA panels. Turning VRR off
for the UI instead would take the full modeset path.

While the Steam UI is focused, present on every vblank timer wakeup.
Holding a 48-120 Hz desktop panel at 120 Hz costs about 1 W of SoC power
at idle over 48 Hz, and adaptive_sync_idle_hold turns the hold off. On
DRM, an unchanged frame scans out the last composite again rather than
paying for an identical full-screen composite every vblank. Nested
sessions on a VRR host hold as well, committing on every host refresh.
@matte-schwartz
matte-schwartz force-pushed the vrr-flicker-mitigations branch from d90212c to 1222d46 Compare October 19, 2026 20:37
@matte-schwartz
matte-schwartz merged commit 8e0a5be into ValveSoftware:master Oct 20, 2026
1 check passed
@matte-schwartz
matte-schwartz deleted the vrr-flicker-mitigations branch October 20, 2026 01:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant