The display contract, and the two helpers both displays share.
A display puts a canvas on a screen: gfx.drm on a DRM/KMS card at a
console, gfx.x11 in a window on an X server. gfx.loop calls update;
a game calls the rest. Every display has:
| method | description |
|---|---|
d:update() | wait for the previous frame to land, then show the canvas; paces a frame loop at the screen's refresh |
d:focused() | true while the display is in view: its VT shown, or its window holding the keyboard |
d:activate(n) | switch to VT n; nil and an error off a VT |
d:set_filter(name) | switch the look while open; true, or nil and an error |
d:destroy() | close the screen and give back what was held for it; safe to call twice |
d.cfg holds scale, the integer factor; x and y, the 1-indexed
device position of the canvas's top-left; filter, the look in effect,
nearest, smooth or scanline; scaler, the engine that scales, cpu,
plane or server; and on_focus, the fn(focused) the open was given,
called on a change of focused.
A display opens with factory(canvas, opts) and answers nil and an error,
the screen untouched, for an option it does not take. opts.filter names
the look. opts.scaler = "cpu" is the console's, and the window refuses it:
a window scales on the server. Each display's own block lists the options
and the methods it adds.
The canvas's size is taken at the open and fixed for the display's life. A canvas resized after is clipped to that size, and the rest of its place stays black.
A frame loop runs inside lev.run: update's wait for the previous frame
yields to LEV there. Before lev.run the window's wait blocks in C, and
the console's first update has nothing to wait for; the console's later
ones want the loop. A frame whose completion is lost costs one wait of a
second.
A display that cannot show a frame raises from update: the console after
three flips refused in a row, the window on a lost connection or an X
error. gfx.loop stops on the raise, and its run returns the error. The
two refusals before the third are dropped frames.
| Name | Signature |
|---|---|
| filter_err | filter_err(filters, name) -> err |
| layout | layout(dev_w, dev_h, cw, ch) -> k, dx, dy |
filter_err(
filters,name) ->err
The refusal of a filter name
filters is a core's list, gfx.drm_core.filters or gfx.x11_core.filters.
Returns nil for a name on it, and the refusal otherwise, worded once for the
open and the switch.
layout(
dev_w,dev_h,cw,ch) ->k,dx,dy
Compute the integer-upscale layout of a canvas on a display mode
Returns the largest integer scale k at which a cw x ch canvas fits a
dev_w x dev_h mode. Also returns the 0-indexed offsets dx, dy that
centre it. Returns nil and an error when the mode is smaller than the
canvas; the window's layout (gfx.x11) crops instead.