Find a file
Sc4r3Cr0w f5cdaa8801
drm: CRTC starvation recovery + clear stale page-flip state after suspend (#254)
* drm: handle CRTC starvation recovery when outputs are disabled

When more displays are connected than CRTCs available, connectors that
arrive after all CRTCs are claimed become starved.  The compositor can
free a CRTC by disabling an output, but nothing reclaimed that CRTC for
the starved connector.

Restructure recheckCRTCs() into two passes: first, disabled outputs
release their CRTCs and enabled connectors get priority assignment;
second, any remaining free CRTCs are given to disabled connectors as
backup slots for quick re-enable.

When applyCommit() detects an enabledState transition, schedule
recheckOutputs() via addIdleEvent so starved connectors pick up the
freed CRTC on the next event loop iteration, without reentrancy or
blocking the event loop.

* drm: clear stale page-flip state after suspend/resume

My laptop (i915, 3 external monitors) would go permanently black after
S3 or suspend-then-hibernate. The only recovery was a hard restart.

The root cause: when display hardware powers off during suspend, any
in-flight page-flip completion event is lost. handlePF() never fires,
so isPageFlipPending stays true from the last frame before suspend. On
resume, scheduleFrame() sees the stale flag and bails, commitState()
rejects every frame with "Cannot commit when a page-flip is awaiting",
and nothing ever clears it. Screens stay dark forever.

VT switch doesn't hit this because the kernel preserves DRM state and
queues pending events in the fd buffer. Suspend kills the hardware, so
there's nothing to deliver.

Fix in two places:

1. restoreAfterVT(): clear isPageFlipPending, isFrameRunning, and
   frameEventScheduled for all connectors before recheckOutputs(). For
   VT switch this is harmless (the events arrive anyway and handlePF
   would set them false). For suspend it unblocks frame scheduling.

2. commitState(): record a CLOCK_BOOTTIME timestamp when
   isPageFlipPending is set. If a modeset finds a flip pending for
   >500ms (well past any vblank), treat it as stale and clear the
   flags. CLOCK_BOOTTIME instead of CLOCK_MONOTONIC because MONOTONIC
   freezes during suspend on Linux, making elapsed time look like zero
   after resume.

Timestamp recorded in both atomic and legacy commit paths.

Relates to Hyprland#8312, Hyprland#6289.

---------

Co-authored-by: j4kuuu <j4kuuu>
2026-04-27 21:02:14 +01:00
.github/workflows CI: use org-wide actions 2026-04-17 14:35:26 +03:00
data drm: implement edid parsing 2024-07-02 13:15:56 +02:00
docs drm: add AQ_NO_MODIFIERS to try to mitigate hardware limitations (#77) 2024-09-06 01:00:39 +01:00
include/aquamarine drm: CRTC starvation recovery + clear stale page-flip state after suspend (#254) 2026-04-27 21:02:14 +01:00
nix nix: separate overlay with deps 2026-03-02 16:11:18 +02:00
protocols Wayland: Initial progress 2024-06-18 18:45:05 +02:00
src drm: CRTC starvation recovery + clear stale page-flip state after suspend (#254) 2026-04-27 21:02:14 +01:00
tests drm: Avoid unnecessary modeset (fixed) (#184) 2025-07-07 16:19:52 +02:00
.clang-format core: Initial stuff 2024-06-18 11:38:26 +02:00
.clang-tidy clang-tidy: fix some errors (#166) 2025-04-22 23:23:23 +02:00
.gitignore Wayland: Initial progress 2024-06-18 18:45:05 +02:00
aquamarine.pc.in core: Initial stuff 2024-06-18 11:38:26 +02:00
CMakeLists.txt version: bump to 0.11.0 2026-04-26 00:25:11 +01:00
flake.lock flake.lock: update 2026-03-02 16:11:18 +02:00
flake.nix nix: separate overlay with deps 2026-03-02 16:11:18 +02:00
LICENSE Initial commit 2024-06-18 10:56:51 +02:00
README.md README: drop todo list 2026-03-05 13:15:49 +00:00
VERSION version: bump to 0.11.0 2026-04-26 00:25:11 +01:00

Aquamarine

Aquamarine is a very light linux rendering backend library. It provides basic abstractions for an application to render on a Wayland session (in a window) or a native DRM session.

It is agnostic of the rendering API (Vulkan/OpenGL) and designed to be lightweight, performant, and minimal.

Aquamarine provides no bindings for other languages. It is C++-only.

Stability

Aquamarine depends on the ABI stability of the stdlib implementation of your compiler. Sover bumps will be done only for aquamarine ABI breaks, not stdlib.

Building

cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf _NPROCESSORS_CONF`