go-xrkit

Several screens floating on a 360° ribbon inside AR glasses, turned from the keyboard. Pure Go, no vendor SDK, and one screen is exactly one full view of the glasses.

CGO_ENABLED=0 no vendor SDK anywhere in the path macOS · Linux · Windows · Android one screen = one full view of the glasses the warp table is built once amd64 · arm64 · riscv64 · loong64 · ppc64le · s390x 100% coverage on everything portable
Documentation GitHub

XR glasses show one screen. This puts a ring of them around you — real displays the desktop extends onto, so ordinary applications run there, captured and drawn as curved panels on a band at eye level. The keyboard turns the band; one key changes what a panel shows.

The numbers are not configured, they follow from the optics. A VITURE Beast in its side-by-side mode gets six screens of 1920x1080, each spanning 51.57°; an XREAL 1S gets seven of 46.06°. Manufacturers publish a diagonal field of view and a projection needs the horizontal, so the diagonal is stored exactly as published and the rest derived — and a headset whose figure cannot be sourced carries no figure at all. A wrong field of view has no symptom: everything renders, in the wrong place.

The distortion table is never rebuilt. Building one costs 56.5 ms and a frame has 16.6 — but on an equirectangular panorama a yaw is exactly a horizontal shift, so turning the ribbon happens where the screens are composited, where it costs nothing.

Repositories

xrkit libgeometry

pose, stereo, projection, warp, ribbon, glasses

both eyes of a 4K panorama reproject in 2.8 ms, with zero allocations

The geometry an immersive display needs, and nothing else: orientation as a quaternion, how a frame packs two eyes, the flat, equirectangular and fisheye projections, and a lookup table that turns any of them into a copy rather than a per-pixel computation. On top of those, a ribbon that places screens round a 360° band and composites them by yaw, and a catalogue that names a headset and derives its field of view. The catalogue refuses to guess: a model whose figure cannot be sourced carries none, because a wrong field of view renders everything, in the wrong place, with no symptom. Placement is checked against a per-pixel brute-force reference that reuses nothing of the fast path, and the derived angles are checked by recomposing them back into the diagonal they came from rather than against numbers typed out of a calculator. 100% coverage.

CI coverage 100%

desk appapplication

the ribbon of screens, the compositor, and the loop that draws it

it ran on a VITURE Beast — window at (-7680,0), the panorama reaching 100% of the view

One screen is exactly one full view of the glasses: a display is created at one eye's resolution and given exactly the arc that eye can see, so looking straight at it shows it edge to edge at one source pixel per output pixel. The core has no operating system in it — the same loop runs on macOS, Linux, Windows and Android, and only getting the screens and their pixels arrives by different roads. Compositing a frame costs 0.9 ms because the columns are decomposed into runs and copied as blocks; gathering them one at a time cost 8.7 ms and was not the arithmetic. Where a platform cannot create displays the ribbon carries the ones the machine already has, and says so — a fallback that looks like the feature is worse than one that announces itself. <strong>-3d, or ''3D on'' in the menu, turns WHATEVER the glasses are showing into a stereo pair</strong> — a browser, a terminal, a film in a window. The renderer already drew one eye at a time into a wide frame and simply gave both the same picture, so the seam is one branch and nothing is copied. It is answered before the ribbon and the gallery, because how the picture is shown has nothing to do with which screen is focused, and a frame the converter refuses falls back to the FLAT picture rather than to black.

CI coverage 100% portable logic

android libplatform

the two-process Android host: capture, and a wall of displays to render onto

a Presentation on a display the app itself made delivers its own pixels — 0 black of 307 200

Android hands no drawable surface to a process that is not the app, and every path to one is behind JNI, which needs cgo. So this is two processes: a small Java host owning the Activity and the Surface, and an ordinary CGO_ENABLED=0 binary speaking to it over a socket with pixels through a shared buffer. An ordinary application cannot put OTHER apps on a display it creates — asked four ways, refused four ways, and the refusals are quoted in the repository. But it may render its own content on such a display and read the pixels back, with no permission, no consent dialog and no screen-recording chip in the status bar. That is a ring of panels carrying what Android can draw and a Go process cannot: a WebView, a decoder, a map.

CI coverage 100%

player appapplication

xrplay — an immersive video player for the glasses' own display, and a 2D film turned into 3D as it plays

694 frames of a 7200x3600 VR180 file in 12 s, with 100% of the view covered

Hardware decode, per-eye reprojection, borderless full screen on the panel itself. There is no XR SDK in the stereo path: the glasses expose their 3D mode as an ordinary display mode, so stereo output is one eye per half of a wide window. Geometry is detected from the file rather than declared — a name, a shape, a marker — and a decoder is accepted only once it has actually produced a picture, because opening is not working. Transport controls appear on movement and hide again, and the sound is the clock. <strong>-3d turns an ordinary FLAT film into 3D frame by frame</strong>: depth from a real network on the Neural Engine, both eyes synthesised by compute kernels on the GPU, 36 frames a second for 3.6 ms of processor time. It all happens BEFORE the renderer — a converter wraps the source and presents side-by-side frames, so the warp, the control bar and the snapshot path never learn the feature exists — and it is refused with a reason for a film that is already stereoscopic, or on a display showing one eye. Without a model, depth is guessed from the picture itself (go-images/depth), which works anywhere and is visibly not as good; the log always says which path ran.

CI coverage 100% portable logic

depth3d liblibrary

one flat picture in, two eyes out — the best path the machine has

0 bytes different out of 86999040 between the GPU synthesis and the portable one, on a real photograph with a real network's depth map

With a Core ML depth model, depth from a real network on the Neural Engine and both views from compute kernels on the GPU: 0.4 ms of processor time a frame, which is what leaves the rest of the machine to a compositor. Without one, depth guessed from cues in the picture itself — runs everywhere including a browser, and is visibly worse. It always says which, because a converter that quietly took the cheap path would look identical from the outside except for being worse. The two eyes may be the two halves of one side-by-side frame or two separate pictures, so the player and the desk each get the shape they want without paying for the other's. The arithmetic is INTEGER throughout and a depth curve travels as a table both sides index: floating point would agree almost always, which is the worst kind of agreement.

CI coverage 100% portable layer

How any of this is known

Nothing here is claimed from reading a header. The field of view a manufacturer prints without saying which axis it is on was pinned down from their own arithmetic — a 171-inch screen at 4 metres subtends 57.00° on its diagonal, and XREAL publishes both numbers. The compositor is checked against an independent per-pixel reference that reuses nothing of the fast path. A capture is checked against an instrument that is not this code at all: a Windows desktop, read through DXGI and through GDI, agrees with QEMU's own framebuffer dump in 0 of 480 000 pixels. And where a platform refuses something, the refusal is quoted rather than paraphrased — Android was asked four different ways whether an ordinary application may put other apps on a display it creates, and the answer is in the repository, in Android's words.

What is not proven is written down too. Every repository that makes a hardware claim says which hardware was connected and exercised, which was only partially observed, and which is known solely from documentation — and never rounds one up to the next. If you want a headset supported and verified rather than quoted, send us one.