git.lucas.co / cce-ui
GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git

commita73777c9981afcc03604c81eb452ead3106d667e
parent7caaa66fe6
authorLucas Galante <[email protected]>
date2026-08-12 18:27
chore: CCE_PRESENT_DEBUG traces the frame-callback lifecycle

Armed / frame-done (with wait time) / starvation-fallback lines join
the present tracer. These pinned down cce-fx withholding frame-done
from surfaces for 100-430ms while the pointer moves over them (idle
delivery: 2-5ms) — the root cause of laggy hover in demand-driven
clients. A client-side pacer (33ms fallback) was tried and reverted:
irregular forced presents judder; the fix belongs in the compositor's
frame scheduling.

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

 src/backend/window_runner.rs | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/backend/window_runner.rs b/src/backend/window_runner.rs
index 7d52c52..1e64174 100644
--- a/src/backend/window_runner.rs
+++ b/src/backend/window_runner.rs
@@ -3212,6 +3212,10 @@ impl<A: Application> EngineState<A> {
             let _callback = surface.frame(&self.qh, ());
             self.frame_callback_pending = true;
             self.frame_callback_armed_at = Some(std::time::Instant::now());
+            if std::env::var("CCE_PRESENT_DEBUG").is_ok() {
+                let t = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_millis() % 100000;
+                eprintln!("[vk] t={} armed frame callback", t);
+            }
         }
 
         // Direct renderer staging (3D scenes, RT panes, app-shaped text).
@@ -4063,6 +4067,11 @@ impl<A: Application> wayland_client::Dispatch<wl_callback::WlCallback, ()> for E
     ) {
         if let wl_callback::Event::Done { .. } = event {
             state.frame_callback_pending = false;
+            if std::env::var("CCE_PRESENT_DEBUG").is_ok() {
+                let t = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_millis() % 100000;
+                let waited = state.frame_callback_armed_at.map(|a| a.elapsed().as_millis()).unwrap_or(0);
+                eprintln!("[vk] t={} frame-done (waited {}ms)", t, waited);
+            }
         }
     }
 }
@@ -4447,6 +4456,10 @@ pub fn run<A: Application>() {
                 .is_none_or(|t| t.elapsed().as_millis() > 250)
         {
             engine_state.frame_callback_pending = false;
+            if std::env::var("CCE_PRESENT_DEBUG").is_ok() {
+                let t = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_millis() % 100000;
+                eprintln!("[vk] t={} starvation fallback fired (callback never came)", t);
+            }
         }
 
         if engine_state.redraw && !engine_state.frame_callback_pending {