56 lines
2.3 KiB
Zig
56 lines
2.3 KiB
Zig
//! The scanout wire protocol — what the compositor says to a native scanout driver (e.g.
|
|
//! virtio-gpu) over `/protocol/scanout` to put a composited frame on screen. The driver owns
|
|
//! the panel and the shared scanout surface it handed the compositor (via the display
|
|
//! service's `attach_scanout`); the compositor composites into that surface, then asks the
|
|
//! driver to present a damaged rectangle. Tiny by design — one present request. Separate from
|
|
//! the display protocol because the directions differ: clients call the compositor over
|
|
//! `/protocol/display`; the compositor calls the driver over `/protocol/scanout`. See
|
|
//! docs/display-v2.md.
|
|
//!
|
|
//! One scanout per driver instance, so `Header.target` is always 0.
|
|
|
|
const envelope = @import("envelope");
|
|
|
|
/// `present(rect)`: put the given rectangle of the shared scanout surface on the panel (on
|
|
/// virtio-gpu: transfer-to-host of the region, then a fenced resource flush).
|
|
pub const Present = extern struct {
|
|
x: u32 = 0,
|
|
y: u32 = 0,
|
|
width: u32 = 0,
|
|
height: u32 = 0,
|
|
};
|
|
|
|
/// `set_mode(width, height)`: change the scanout resolution — the shared surface is sized to
|
|
/// the largest mode, so this just re-points the scanout rectangle; the surface is unchanged.
|
|
pub const SetMode = extern struct { width: u32, height: u32 };
|
|
|
|
/// One offered display mode.
|
|
pub const Mode = extern struct { width: u32, height: u32 };
|
|
pub const max_modes = 4;
|
|
|
|
/// The answer to `get_modes`: a small fixed list of modes. The success/failure verdict is
|
|
/// the reply's `Status`, so this carries only the modes.
|
|
pub const Modes = extern struct {
|
|
count: u32 = 0,
|
|
_padding: u32 = 0,
|
|
modes: [max_modes]Mode = @splat(.{ .width = 0, .height = 0 }),
|
|
};
|
|
|
|
pub const Protocol = envelope.Define(.{
|
|
.name = "scanout",
|
|
.version = 1,
|
|
.operations = &.{
|
|
.{ .name = "present", .request = Present },
|
|
.{ .name = "get_modes", .reply = Modes },
|
|
.{ .name = "set_mode", .request = SetMode },
|
|
},
|
|
});
|
|
|
|
pub const Operation = Protocol.Operation;
|
|
|
|
/// The call floor, like every synchronous protocol. This module used to declare
|
|
/// 64 — the *push* floor — which was simply wrong: nothing here is pushed, and a
|
|
/// provider sizing its receive buffer to 64 refuses (`-E2BIG`) any caller that
|
|
/// sends up to the floor it is entitled to.
|
|
pub const message_maximum: usize = Protocol.message_maximum;
|