git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commitd2af53e7ea075e0e3b210f69e34d97d5a60b5af5
parenta6abc7d72b
authorLucas Galante <[email protected]>
date2026-08-13 00:04
perf: gate the dirty_windowing backtrace behind CCE_DIRTY_BACKTRACE

Capturing and symbolizing a std::backtrace costs far more than the event it
annotates, and dirty_windowing fires on routine commits. Keying it on
log_enabled!(Debug) meant it ran constantly in this session (which launches with
--log-level debug): ~160 log lines/second and the bulk of a 19MB session log.
It now has its own switch, so debug logging no longer implies paying for it.

Not the hover-lag root cause — that was an O(n^2) coverage scan in cce-ui
(cce-ui@2f8b6d8) — but it was found while chasing it and is worth not paying.

Co-Authored-By: Claude Opus 5 <[email protected]>

 src/server/window_manager.rs | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/src/server/window_manager.rs b/src/server/window_manager.rs
index 1ab11f9..5d59747 100644
--- a/src/server/window_manager.rs
+++ b/src/server/window_manager.rs
@@ -174,6 +174,13 @@ pub struct WindowManager {
     pub rounded_apps: Vec<String>,
 }
 
+/// `CCE_DIRTY_BACKTRACE=1` — who called `dirty_windowing`. Separate from the
+/// log level because the capture is expensive enough to distort what it measures.
+fn dirty_backtrace_debug() -> bool {
+    static FLAG: std::sync::OnceLock<bool> = std::sync::OnceLock::new();
+    *FLAG.get_or_init(|| std::env::var_os("CCE_DIRTY_BACKTRACE").is_some())
+}
+
 impl WindowManager {
     pub unsafe fn init(&mut self) -> Result<(), ()> {
         // This is a stub for the 0-arg struct instantiation.
@@ -1177,7 +1184,11 @@ impl WindowManager {
     }
 
     pub unsafe fn dirty_windowing(&mut self) {
-        if log::log_enabled!(log::Level::Debug) {
+        // Capturing and symbolizing a backtrace costs far more than the event it
+        // annotates, and this fires on routine commits — the session runs at
+        // --log-level debug, so keying it on Debug meant ~160 log lines/second
+        // and most of a 19MB session log. Behind its own switch now.
+        if dirty_backtrace_debug() {
             let bt = std::backtrace::Backtrace::force_capture();
             log::debug!("dirty_windowing called from backtrace:\n{}", bt);
         }