// F04 — vsync / frame pacing, X11 edition (../../../features/f04-frame-pacing.md).
// Derived from the X11 scaffold (../scaffold/app.d). Core X11 has no frame
// clock at all; the platform primitive is the PRESENT EXTENSION, which is
// xcb-only (no Xlib binding exists). This demo therefore uses the documented
// Xlib/XCB interop: the window/setup side stays Xlib like every other demo in
// this tree, XGetXCBConnection exposes the shared xcb_connection_t, and
// XSetEventQueueOwner(XCBOwnsEventQueue) — called immediately after
// XOpenDisplay, before any event-generating request — routes ALL events to
// xcb_poll_for_event so Present's GenericEvents can be read.
//
// The pacing chain (the "draw only when the display says so" contract):
//
// xcb_present_select_input(eid, win, COMPLETE_NOTIFY) — subscribe
// xcb_present_notify_msc(win, serial, target_msc, 0, 0) — "wake me at msc"
// PresentCompleteNotify(kind=NOTIFY_MSC) → ust,msc — the frame clock
// draw a trivially cheap solid-color flip, request msc+1, repeat
//
// Per frame: `frame_callback t=<ust> msc=<msc> mode=<mode>` (ust is the
// server's CLOCK_MONOTONIC microseconds; msc the media stream counter). After
// WSI_FRAMES frames (default 600): min/median/p99/max inter-frame delta and a
// coarse jitter histogram on STDOUT (the F04 contract), then an occlusion
// probe — XUnmapWindow for 3 s while the notify_msc chain keeps running, to
// answer "does the clock stop when hidden?" — then remap and exit.
//
// Fallback path (Present absent, or forced with WSI_NO_PRESENT=1): a 16.67 ms
// timerfd drives the same redraw + logging with mode=timer and msc=0 — the
// "no frame clock" degradation the F04 spec asks to be recorded as a finding.
//
// Headless-safe: no display prints `SKIP:` and exits 0. Under Xvfb there is
// no real vblank — Present still works, but its msc/ust come from a software
// fallback timer; the observed cadence IS the finding (../../f04-frame-pacing.md).
module (module) appapp;
import (module) cc; // ImportC: Xlib + Xlib-xcb + xcb + xcb/present + timerfd + poll
import (module) instrumentinstrument;
import (package) corecore.(package) core.stdcstdc.(module) core.stdc.configD compatible types that correspond to various basic types in associated
C and C++ compilers.
Source
core/stdc/config.d
config : c_long, c_ulong;
import (package) corecore.(package) core.stdcstdc.(module) core.stdc.stdioD header file for C99 <stdio.h>
pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html, stdio.h
Source
core/stdc/stdio.d
stdio : (alias) app.printf = int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogcprintf;
import (package) corecore.(package) core.stdcstdc.(module) core.stdc.stdlibD header file for C99.
pubs.opengroup.org/onlinepubs/009695399/basedefs/stdlib.h.html, stdlib.h
Source
core/stdc/stdlib.d
stdlib : (alias) app.free = void core.stdc.stdlib.free(void* ptr) nothrow @nogcfree, (alias) app.getenv = char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogcgetenv, (alias) app.qsort = void core.stdc.stdlib.qsort(void* base, ulong nmemb, ulong size, extern (C) int function(const(void*), const(void*)) compar) nothrow @nogcqsort;
import (package) corecore.(package) core.syssys.(package) core.sys.posixposix.(module) core.sys.posix.unistdD header file for POSIX.
unistd : (alias) app.read = long core.sys.posix.unistd.read(int, void*, ulong) nothrow @nogcread;
// Constants Xlib/xcb expose only as macros (not ImportC-able); re-declared
// per the ImportC guide. The XCB_* event codes are #defines in xproto.h.
enum : c_long
{
(enum value) app.KeyPressMask = 1LKeyPressMask = 1L << 0,
(enum value) app.ExposureMask = 32768LExposureMask = 1L << 15,
(enum value) app.StructureNotifyMask = 131072LStructureNotifyMask = 1L << 17,
}
enum // xcb response_type discriminators (#defines in xcb/xproto.h)
{
(enum value) app.XCB_KEY_PRESS = 2XCB_KEY_PRESS = 2,
(enum value) app.XCB_EXPOSE = 12XCB_EXPOSE = 12,
(enum value) app.XCB_UNMAP_NOTIFY = 18XCB_UNMAP_NOTIFY = 18,
(enum value) app.XCB_MAP_NOTIFY = 19XCB_MAP_NOTIFY = 19,
(enum value) app.XCB_CONFIGURE_NOTIFY = 22XCB_CONFIGURE_NOTIFY = 22,
(enum value) app.XCB_CLIENT_MESSAGE = 33XCB_CLIENT_MESSAGE = 33,
(enum value) app.XCB_GE_GENERIC = 35XCB_GE_GENERIC = 35,
}
enum (constant) int app.XCB_PRESENT_COMPLETE_NOTIFY_EVTYPE = 1XCB_PRESENT_COMPLETE_NOTIFY_EVTYPE = 1; // #define XCB_PRESENT_COMPLETE_NOTIFY
enum (constant) int app.False = 0False = 0;
enum (constant) int app.POLLIN = 1POLLIN = 0x001;
enum (constant) int app.CLOCK_MONOTONIC = 1CLOCK_MONOTONIC = 1;
// xcb declares xcb_present_complete_notify_event_t XCB_PACKED
// (__attribute__((__packed__))): on the wire `msc` sits at byte offset 36,
// unaligned for a uint64. ImportC (ldc 1.41) IGNORES the packed attribute —
// the imported struct is 48 bytes with msc naturally aligned to offset 40,
// so reading msc through it yields garbage. Re-declare the exact wire layout
// in D with align(1), the same re-declaration discipline as the macro
// constants above.
struct (struct) app.PresentCompleteNotifyPresentCompleteNotify // = xcb_present_complete_notify_event_t, packed
{
align(1):
ubyte (field) ubyte app.PresentCompleteNotify.response_typeresponse_type;
ubyte (field) ubyte app.PresentCompleteNotify.extensionextension;
ushort (field) ushort app.PresentCompleteNotify.sequencesequence;
uint (field) uint app.PresentCompleteNotify.lengthlength;
ushort (field) ushort app.PresentCompleteNotify.event_typeevent_type;
ubyte (field) ubyte app.PresentCompleteNotify.kindkind;
ubyte (field) ubyte app.PresentCompleteNotify.modemode;
uint (field) uint app.PresentCompleteNotify.eventevent;
uint (field) uint app.PresentCompleteNotify.windowwindow;
uint (field) uint app.PresentCompleteNotify.serialserial;
ulong (field) ulong app.PresentCompleteNotify.ustust;
uint (field) uint app.PresentCompleteNotify.full_sequencefull_sequence;
ulong (field) ulong app.PresentCompleteNotify.mscmsc;
}
static assert((struct) app.PresentCompleteNotifyPresentCompleteNotify.(constant) ulong app.PresentCompleteNotify.sizeof = 44LUsizeof == 44);
static assert((struct) app.PresentCompleteNotifyPresentCompleteNotify.(field) ulong app.PresentCompleteNotify.mscmsc.offsetof == 36);
static assert(xcb_present_complete_notify_event_t.(field) _error_ xcb_present_complete_notify_event_t.sizeofsizeof == 48); // the ImportC trap
// ---------------------------------------------------------------------------
// Inter-frame-delta bookkeeping + the exit report the F04 spec mandates.
enum (constant) int app.maxFrames = 4096maxFrames = 4096;
__gshared long[(constant) int app.maxFrames = 4096maxFrames] (__gshared global) long[4096] app.g_deltasg_deltas;
__gshared int (__gshared global) int app.g_nDeltasg_nDeltas = 0;
extern (C) int int app.cmpLong(const(void*) a, const(void*) b) nothrow @nogccmpLong(const void* (parameter) const(void*) aa, const void* (parameter) const(void*) bb) @nogc nothrow
{
const (local variable) const(long) xx = *cast(const long*) (parameter) const(void*) aa, (local variable) const(long) yy = *cast(const long*) (parameter) const(void*) bb;
return (local variable) const(long) xx < (local variable) const(long) yy ? -1 : (local variable) const(long) xx > (local variable) const(long) yy ? 1 : 0;
}
void void app.recordDelta(long d) nothrow @nogcrecordDelta(long (parameter) long dd) @nogc nothrow
{
if ((__gshared global) int app.g_nDeltasg_nDeltas < (constant) int app.maxFrames = 4096maxFrames)
(__gshared global) long[4096] app.g_deltasg_deltas[(__gshared global) int app.g_nDeltasg_nDeltas++] = (parameter) long dd;
}
/// min/median/p99/max + coarse histogram, printed to STDOUT (spec req. 2).
void void app.printStats(const(char)* path, int frames) nothrow @nogcmin/median/p99/max + coarse histogram, printed to STDOUT (spec req. 2).
printStats(const(char)* (parameter) const(char)* pathpath, int (parameter) int framesframes) @nogc nothrow
{
if ((__gshared global) int app.g_nDeltasg_nDeltas == 0)
return;
void core.stdc.stdlib.qsort(void* base, ulong nmemb, ulong size, extern (C) int function(const(void*), const(void*)) compar) nothrow @nogcqsort((__gshared global) long[4096] app.g_deltasg_deltas.(constant) long* long[4096].ptr = &g_deltasptr, (__gshared global) int app.g_nDeltasg_nDeltas, long.(constant) ulong long.sizeof = 8LUsizeof, &int app.cmpLong(const(void*) a, const(void*) b) nothrow @nogccmpLong);
const (local variable) const(long) lolo = (__gshared global) long[4096] app.g_deltasg_deltas[0], (local variable) const(long) hihi = (__gshared global) long[4096] app.g_deltasg_deltas[(__gshared global) int app.g_nDeltasg_nDeltas - 1];
const (local variable) const(long) medmed = (__gshared global) long[4096] app.g_deltasg_deltas[(__gshared global) int app.g_nDeltasg_nDeltas / 2];
const (local variable) const(long) p99p99 = (__gshared global) long[4096] app.g_deltasg_deltas[((__gshared global) int app.g_nDeltasg_nDeltas * 99) / 100 < (__gshared global) int app.g_nDeltasg_nDeltas
? ((__gshared global) int app.g_nDeltasg_nDeltas * 99) / 100 : (__gshared global) int app.g_nDeltasg_nDeltas - 1];
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogcprintf("stats path=%s frames=%d deltas=%d min_us=%lld median_us=%lld p99_us=%lld max_us=%lld\n",
(parameter) const(char)* pathpath, (parameter) int framesframes, (__gshared global) int app.g_nDeltasg_nDeltas, (local variable) const(long) lolo, (local variable) const(long) medmed, (local variable) const(long) p99p99, (local variable) const(long) hihi);
static immutable long[8] (immutable global) immutable(long[8]) app.printStats.edgesedges = [1_000, 4_000, 8_000, 12_000, 16_000,
20_000, 33_000, 100_000];
static immutable (alias) object.string = stringstring[9] (immutable global) immutable(string[9]) app.printStats.labelslabels = [
"<1ms", "1-4ms", "4-8ms", "8-12ms", "12-16ms", "16-20ms", "20-33ms",
"33-100ms", ">=100ms",
];
int[9] (local variable) int[9] countscounts = 0;
foreach ((local variable) int ii; 0 .. (__gshared global) int app.g_nDeltasg_nDeltas)
{
(alias) object.size_t = ulongsize_t (local variable) ulong bb = (immutable global) immutable(long[8]) app.printStats.edgesedges.(constant) ulong immutable(long[8]).length = 8LUlength; // overflow bucket
foreach ((parameter) ulong jj, (parameter) immutable(long) ee; (immutable global) immutable(long[8]) app.printStats.edgesedges)
if ((__gshared global) long[4096] app.g_deltasg_deltas[(local variable) int ii] < (local variable) immutable(long) ee)
{
(local variable) ulong bb = (local variable) ulong jj;
break;
}
++(local variable) int[9] countscounts[(local variable) ulong bb];
}
foreach ((parameter) ulong jj, (parameter) immutable(string) labellabel; (immutable global) immutable(string[9]) app.printStats.labelslabels)
if ((local variable) int[9] countscounts[(local variable) ulong jj] > 0)
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogcprintf("histogram bucket=%s count=%d\n", (local variable) immutable(string) labellabel.(field) immutable(char)* immutable(string).ptrptr, (local variable) int[9] countscounts[(local variable) ulong jj]);
}
int int D main()main()
{
void instrument.initInstrument(const(char)* demoName) nothrow @nogcNames the demo, starts the monotonic clock, and emits init_start.
Call this first, before any platform API call.
initInstrument("f04_x11");
const (local variable) const(char*) envFramesenvFrames = char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogcgetenv("WSI_FRAMES");
int (local variable) int targetFramestargetFrames = 600;
if ((local variable) const(char*) envFramesenvFrames !is null)
{
import (package) corecore.(package) core.stdcstdc.(module) core.stdc.stdlibD header file for C99.
pubs.opengroup.org/onlinepubs/009695399/basedefs/stdlib.h.html, stdlib.h
Source
core/stdc/stdlib.d
stdlib : (alias) atoi = int core.stdc.stdlib.atoi(scope const(char*) nptr) nothrow @nogcatoi;
const (local variable) const(int) vv = int core.stdc.stdlib.atoi(scope const(char*) nptr) nothrow @nogcatoi((local variable) const(char*) envFramesenvFrames);
if ((local variable) const(int) vv > 0 && (local variable) const(int) vv < (constant) int app.maxFrames = 4096maxFrames)
(local variable) int targetFramestargetFrames = (local variable) const(int) vv;
}
// -- Connect; hand the event queue to xcb BEFORE any other Xlib call ------
Display* (local variable) _error_ dpydpy = XOpenDisplay(null);
if (dpy is null)
{
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogcprintf("SKIP: no X11 display (XOpenDisplay returned null)\n");
return 0;
}
XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
xcb_connection_t* (local variable) _error_ connconn = XGetXCBConnection(dpy);
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogcEmit an event with a printf-formatted key=value ... payload.
emitf("step", "name=XGetXCBConnection fd=%d queue_owner=xcb",
xcb_get_file_descriptor(conn));
const (local variable) const(_error_) screenscreen = XDefaultScreen(dpy);
const (local variable) const(_error_) rootroot = XRootWindow(dpy, screen);
// -- Present availability + version (round-trips) -------------------------
auto (local variable) _error_ extDataextData = xcb_get_extension_data(conn, &xcb_present_id);
const (local variable) const(_error_) havePresentExthavePresentExt = extData !is null && extData.present != 0;
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogcEmit an event with a printf-formatted key=value ... payload.
emitf("step", "name=xcb_get_extension_data ext=Present present=%d major_opcode=%d first_event=%d",
cast(int) havePresentExt,
havePresentExt ? extData.major_opcode : -1,
havePresentExt ? extData.first_event : -1);
uint (local variable) uint presentMajorpresentMajor = 0, (local variable) uint presentMinorpresentMinor = 0;
if (havePresentExt)
{
auto (local variable) _error_ ckck = xcb_present_query_version(conn, 1, 4);
auto (local variable) _error_ replyreply = xcb_present_query_version_reply(conn, ck, null);
if (reply !is null)
{
(local variable) uint presentMajorpresentMajor = reply.major_version;
(local variable) uint presentMinorpresentMinor = reply.minor_version;
void core.stdc.stdlib.free(void* ptr) nothrow @nogcfree(reply);
}
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogcEmit an event with a printf-formatted key=value ... payload.
emitf("step", "name=xcb_present_query_version version=%u.%u",
(local variable) uint presentMajorpresentMajor, (local variable) uint presentMinorpresentMinor);
}
bool (local variable) bool usePresentusePresent = havePresentExt;
if ((local variable) bool usePresentusePresent && char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogcgetenv("WSI_NO_PRESENT") !is null)
{
(local variable) bool usePresentusePresent = false;
void instrument.emit(scope const(char)* kind) nothrow @nogcEmit an event with no key=value payload.
emit("step name=fallback reason=WSI_NO_PRESENT");
}
else if (!(local variable) bool usePresentusePresent)
void instrument.emit(scope const(char)* kind) nothrow @nogcEmit an event with no key=value payload.
emit("step name=fallback reason=present_absent");
// -- Window (Xlib side, scaffold-style) ------------------------------------
int (local variable) int widthwidth = 480, (local variable) int heightheight = 320;
Window (local variable) _error_ winwin = XCreateSimpleWindow(dpy, root, 0, 0, width, height, 1,
XBlackPixel(dpy, screen), XWhitePixel(dpy, screen));
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogcEmit an event with a printf-formatted key=value ... payload.
emitf("step", "name=XCreateSimpleWindow xid=0x%lx", win);
XStoreName(dpy, win, "Sparkles · X11 F04");
Atom (local variable) _error_ wmDeletewmDelete = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
XSetWMProtocols(dpy, win, &wmDelete, 1);
XSelectInput(dpy, win, ExposureMask | KeyPressMask | StructureNotifyMask);
XMapWindow(dpy, win);
// Interop gotcha: with the queue owned by xcb the event loop below reads
// via xcb_poll_for_event, which — unlike XPending — does NOT flush Xlib's
// output buffer. Without this flush the MapWindow request never leaves
// the client on the fallback path and the demo deadlocks waiting for its
// first Expose. (On the Present path the first xcb_present_* call rescues
// it by accident: xcb takes the socket back from libX11, forcing a flush.)
XFlush(dpy);
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogcEmit an event with a printf-formatted key=value ... payload.
emitf("window_created", "xid=0x%lx size=%dx%d", win, (local variable) int widthwidth, (local variable) int heightheight);
GC (local variable) _error_ gcgc = XDefaultGC(dpy, screen);
// -- Present event subscription --------------------------------------------
if ((local variable) bool usePresentusePresent)
{
const (local variable) const(_error_) eideid = xcb_generate_id(conn);
xcb_present_select_input(conn, eid, cast(uint) win,
XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY);
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogcEmit an event with a printf-formatted key=value ... payload.
emitf("step", "name=xcb_present_select_input eid=0x%x mask=COMPLETE_NOTIFY", eid);
}
// -- Fallback clock: 16.67 ms timerfd (armed only on the fallback path) ----
const (local variable) const(_error_) tfdtfd = timerfd_create(CLOCK_MONOTONIC, 0);
if (!(local variable) bool usePresentusePresent)
{
itimerspec (local variable) _error_ itsits;
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 16_666_667;
its.it_value = its.it_interval;
timerfd_settime(tfd, 0, &its, null);
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogcEmit an event with a printf-formatted key=value ... payload.
emitf("step", "name=timerfd_create fd=%d interval_us=16667", tfd);
}
scope (exit)
{
XDestroyWindow(dpy, win);
XCloseDisplay(dpy); // owns conn: closes the shared xcb connection too
}
/// One trivially cheap frame: a solid-color flip (alternating fill).
int (local variable) int framesOne trivially cheap frame: a solid-color flip (alternating fill).
frames = 0;
void void app.main.drawFrame() pure nothrow @nogc @safedrawFrame() @nogc nothrow
{
const c_ulong (local variable) const(ulong) colorcolor = ((local variable) int framesOne trivially cheap frame: a solid-color flip (alternating fill).
frames & 1) ? 0xff_60_30 : 0x20_50_c0;
XSetForeground(dpy, gc, color);
XFillRectangle(dpy, win, gc, 0, 0, cast(uint) width, cast(uint) height);
}
const (local variable) const(_error_) fdfd = xcb_get_file_descriptor(conn);
bool (local variable) bool runningrunning = true, (local variable) bool chainStartedchainStarted = false, (local variable) bool exposedexposed = false;
bool (local variable) bool occludingoccluding = false, (local variable) bool occlusionDoneocclusionDone = false;
long (local variable) long lastUstlastUst = 0, (local variable) long occlusionEndUsocclusionEndUs = 0;
ulong (local variable) ulong lastMsclastMsc = 0;
uint (local variable) uint notifySerialnotifySerial = 0;
int (local variable) int occlFramesocclFrames = 0;
/// Schedule the next frame-clock wakeup. target=0 means "at the current
/// msc" (used once to seed the chain); afterwards we ask for lastMsc+1.
void void app.main.requestNotify(ulong targetMsc) pure nothrow @nogc @safeSchedule the next frame-clock wakeup. target=0 means "at the current
msc" (used once to seed the chain); afterwards we ask for lastMsc+1.
requestNotify(ulong (parameter) ulong targetMsctargetMsc) @nogc nothrow
{
xcb_present_notify_msc(conn, cast(uint) win, ++notifySerial,
targetMsc, 0, 0);
xcb_flush(conn);
}
while ((local variable) bool runningrunning)
{
// Drain everything xcb has already read or can read without blocking.
for (;;)
{
xcb_generic_event_t* (local variable) _error_ evev = xcb_poll_for_event(conn);
if (ev is null)
break;
scope (exit)
void core.stdc.stdlib.free(void* ptr) nothrow @nogcfree(ev); // xcb events are malloc'd; the caller frees
const (local variable) const(_error_) rtrt = ev.(field) _error_ ev.response_typeresponse_type & 0x7f;
switch (rt)
{
case XCB_EXPOSE:
const _error_ xexe = cast(xcb_expose_event_t*) ev;
if (xe.count == 0 && !exposed)
{
exposed = true;
drawFrame();
XFlush(dpy);
emit("first_pixel_presented method=XFillRectangle note=no_confirmation_without_Present");
if (usePresent && !chainStarted)
{
chainStarted = true;
requestNotify(0); // seed: complete at the current msc
emit("step name=xcb_present_notify_msc target=current note=chain_seed");
}
}
break;
case XCB_GE_GENERIC:
const _error_ gege = cast(xcb_present_generic_event_t*) ev;
if (!havePresentExt || ge.ge.extensionextension != extData.major_opcode)
break;
if (ge.evtype != XCB_PRESENT_COMPLETE_NOTIFY_EVTYPE)
break;
const _error_ cncn = cast((unresolved type) PresentCompleteNotifyPresentCompleteNotify*) ev;
if (cn.cn.kindkind != XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC)
break;
// The frame clock tick: ust/msc straight from the server.
lastMsc = cn.cn.mscmsc;
if (occluding)
{
++occlFrames;
emitf("frame_callback", "t=%llu msc=%llu mode=%d occluded=1",
cast(ulong) cn.cn.ustust, cast(ulong) cn.cn.mscmsc, cast(int) cn.cn.modemode);
requestNotify(cn.cn.mscmsc + 1);
break;
}
++frames;
if (lastUst != 0)
recordDelta(cast(long)(cn.cn.ustust - lastUst));
lastUst = cast(long) cn.cn.ustust;
emitf("frame_callback", "t=%llu msc=%llu mode=%d frame=%d",
cast(ulong) cn.cn.ustust, cast(ulong) cn.cn.mscmsc, cast(int) cn.cn.modemode, frames);
if (frames < targetFrames)
{
drawFrame();
XFlush(dpy);
requestNotify(cn.cn.mscmsc + 1);
}
break;
case XCB_UNMAP_NOTIFY:
emit("vis_change state=unmapped");
break;
case XCB_MAP_NOTIFY:
emit("vis_change state=mapped");
break;
case XCB_CLIENT_MESSAGE:
const _error_ cmcm = cast(xcb_client_message_event_t*) ev;
if (cm.data.data32[0] == cast(uint) wmDelete)
{
emit("close_requested via=WM_DELETE_WINDOW");
running = false;
}
break;
case XCB_KEY_PRESS:
emit("close_requested via=KeyPress");
running = false;
break;
default:
break;
}
}
if (xcb_connection_has_error(conn))
{
void instrument.emit(scope const(char)* kind) nothrow @nogcEmit an event with no key=value payload.
emit("x_error connection_lost=1");
return 1;
}
// -- Occlusion probe (spec req. 3): unmap for 3 s, keep the chain up --
if ((local variable) int framesOne trivially cheap frame: a solid-color flip (alternating fill).
frames >= (local variable) int targetFramestargetFrames && !(local variable) bool occludingoccluding && !(local variable) bool occlusionDoneocclusionDone)
{
(local variable) bool occludingoccluding = true;
(local variable) long occlusionEndUsocclusionEndUs = long instrument.nowUs() nothrow @nogcMicroseconds elapsed since initInstrument.
nowUs() + 3_000_000;
XUnmapWindow(dpy, win);
XFlush(dpy);
void instrument.emit(scope const(char)* kind) nothrow @nogcEmit an event with no key=value payload.
emit("step name=XUnmapWindow note=occlusion_probe_3s");
if ((local variable) bool usePresentusePresent)
void app.main.requestNotify(ulong targetMsc) pure nothrow @nogc @safeSchedule the next frame-clock wakeup. target=0 means "at the current
msc" (used once to seed the chain); afterwards we ask for lastMsc+1.
requestNotify((local variable) ulong lastMsclastMsc + 1); // does the clock still tick?
}
if ((local variable) bool occludingoccluding && long instrument.nowUs() nothrow @nogcMicroseconds elapsed since initInstrument.
nowUs() >= (local variable) long occlusionEndUsocclusionEndUs)
{
(local variable) bool occludingoccluding = false;
(local variable) bool occlusionDoneocclusionDone = true;
XMapWindow(dpy, win);
XFlush(dpy);
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogcEmit an event with a printf-formatted key=value ... payload.
emitf("occlusion", "frames_while_unmapped=%d duration_ms=3000 clock=%s",
(local variable) int occlFramesocclFrames, (local variable) bool usePresentusePresent ? "present".(constant) immutable(char)* "present".ptr = "present"ptr : "timer".(constant) immutable(char)* "timer".ptr = "timer"ptr);
(local variable) bool runningrunning = false; // measured + probed: done
}
if ((local variable) bool runningrunning)
{
pollfd[2] (local variable) _error_ pfdspfds;
pfds[0].(__error)[0].fdfd = fd;
pfds[0].events = POLLIN;
pfds[0].revents = 0;
pfds[1].(__error)[1].fdfd = tfd;
pfds[1].events = POLLIN;
pfds[1].revents = 0;
// Bounded sleep so the occlusion deadline fires even when the
// (unmapped, Present-less) connection goes silent.
poll(pfds.pfds.ptrptr, 2, 200);
if (!(local variable) bool usePresentusePresent && (pfds[1].revents & POLLIN))
{
ulong (local variable) ulong expirationsexpirations;
long core.sys.posix.unistd.read(int, void*, ulong) nothrow @nogcread(tfd, &(local variable) ulong expirationsexpirations, (local variable) ulong expirationsexpirations.(constant) ulong ulong.sizeof = 8LUsizeof);
if ((local variable) bool exposedexposed && ((local variable) int framesOne trivially cheap frame: a solid-color flip (alternating fill).
frames < (local variable) int targetFramestargetFrames || (local variable) bool occludingoccluding))
{
const (local variable) const(long) nownow = long instrument.nowUs() nothrow @nogcMicroseconds elapsed since initInstrument.
nowUs();
if ((local variable) bool occludingoccluding)
{
++(local variable) int occlFramesocclFrames;
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogcEmit an event with a printf-formatted key=value ... payload.
emitf("frame_callback", "t=%lld msc=0 mode=timer occluded=1", (local variable) const(long) nownow);
}
else
{
++(local variable) int framesOne trivially cheap frame: a solid-color flip (alternating fill).
frames;
if ((local variable) long lastUstlastUst != 0)
void app.recordDelta(long d) nothrow @nogcrecordDelta((local variable) const(long) nownow - (local variable) long lastUstlastUst);
(local variable) long lastUstlastUst = (local variable) const(long) nownow;
void app.main.drawFrame() pure nothrow @nogc @safedrawFrame();
XFlush(dpy);
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogcEmit an event with a printf-formatted key=value ... payload.
emitf("frame_callback", "t=%lld msc=0 mode=timer frame=%d", (local variable) const(long) nownow, (local variable) int framesOne trivially cheap frame: a solid-color flip (alternating fill).
frames);
}
}
}
}
}
void app.printStats(const(char)* path, int frames) nothrow @nogcmin/median/p99/max + coarse histogram, printed to STDOUT (spec req. 2).
printStats((local variable) bool usePresentusePresent ? "present".(constant) immutable(char)* "present".ptr = "present"ptr : "timer".(constant) immutable(char)* "timer".ptr = "timer"ptr, (local variable) int framesOne trivially cheap frame: a solid-color flip (alternating fill).
frames);
void instrument.emit(scope const(char)* kind) nothrow @nogcEmit an event with no key=value payload.
emit("teardown");
return 0;
}