// Cross-thread architecture and data-visibility handoff. // Render: dot -Tsvg thread-handoff.dot -o thread-handoff.svg // // One direction of data flow: the Proactor thread reads file blocks into the // ring of buffers and publishes a ready frame through the single atomic baton // `toDisplay_`; the GUI thread picks it up, uploads it to the GPU, and hands // the slot back. The release/acquire pairs on the baton carry buffer-content // visibility in both directions. digraph handoff { rankdir=LR; bgcolor="transparent"; compound=true; fontname="sans-serif"; node [fontname="sans-serif", fontsize=11]; edge [fontname="sans-serif", fontsize=10]; file [shape=cylinder, fillcolor="#eeeeee", style=filled, label="demovideo.raw"]; subgraph cluster_proactor { label=" »Proactor« thread — playVideo() loop "; labeljust="l"; style="filled,rounded"; fillcolor="#eef4ff"; color="#7092c0"; fontsize=12; wait [shape=box, style="rounded,filled", fillcolor="#ffffff", label="io_uring_wait_cqe()\n(blocking)"]; timer [shape=box, style="rounded,filled", fillcolor="#ffedcc", label="frame-beat timer\n20 ms · multishot"]; ring [shape=record, style=filled, fillcolor="#ffffff", label="ring buffers\ (RING_SIZ)|slot|slot|slot|…"]; } subgraph cluster_gui { label=" GTK / GUI thread "; labeljust="l"; style="filled,rounded"; fillcolor="#eefaee"; color="#6bab6b"; fontsize=12; disp [shape=box, style="rounded,filled", fillcolor="#ffffff", label="EglDisplay::displayFrame()\nretrieveFrame() / completedFrame()"]; gpu [shape=box, style="rounded,filled", fillcolor="#ffffff", label="GPU texture\n(glTexImage2D → draw)"]; } baton [shape=box, style="filled", fillcolor="#e7d8ff", penwidth=1.6, label="toDisplay_\nstd::atomic"]; file -> ring [label="io_uring read", lhead=cluster_proactor]; timer -> wait [style=dotted, label="CQE (TICK_TAG)"]; ring -> baton [label="publish\nstore(release)", color="#5a2ca0", fontcolor="#5a2ca0"]; baton -> disp [label="retrieveFrame\nload(acquire)", color="#5a2ca0", fontcolor="#5a2ca0"]; disp -> gpu [label="upload + draw"]; disp -> baton [label="completedFrame\nstore(nullptr, release)", style=dashed, color="#3a7a3a", fontcolor="#3a7a3a"]; { rank=same; baton; } }