From 44122bd44dacada10367bc000a91dec534163ba6 Mon Sep 17 00:00:00 2001 From: Daniel Samson <12231216+daniel-samson@users.noreply.github.com> Date: Wed, 22 Jul 2026 21:02:31 +0100 Subject: [PATCH] reorg: move display + scanout protocols to library/protocol display-protocol -> library/protocol/display/, scanout-protocol -> library/protocol/scanout/. Consumers import both directly, killing the cryptic dp/sp aliases in virtio-gpu (now display_protocol / scanout_protocol) and the runtime.display_protocol / runtime.scanout_protocol re-exports. runtime.display (the client) still imports display-protocol by name; scanout has no runtime client, so its runtime module import is dropped too. zig build + test green; display-service, virtio-gpu, display-native, display-reattach pass. --- build.zig | 14 +++++--- .../protocol/display/display-protocol.zig | 0 .../protocol/scanout}/scanout-protocol.zig | 0 library/runtime/runtime.zig | 5 --- system/drivers/display/display.zig | 4 +-- .../intel-integrated/intel-integrated.zig | 4 +-- system/drivers/virtio-gpu/virtio-gpu.zig | 36 +++++++++---------- system/services/display/backend.zig | 2 +- system/services/display/display.zig | 2 +- 9 files changed, 33 insertions(+), 34 deletions(-) rename system/services/display/protocol.zig => library/protocol/display/display-protocol.zig (100%) rename {system/services/display => library/protocol/scanout}/scanout-protocol.zig (100%) diff --git a/build.zig b/build.zig index 1ad55b0..1db227b 100644 --- a/build.zig +++ b/build.zig @@ -409,16 +409,16 @@ pub fn build(b: *std.Build) void { // The display protocol, so runtime.display (the compositor client) and the display // service both speak it through the runtime, like the other protocol modules. const display_protocol_module = b.addModule("display-protocol", .{ - .root_source_file = b.path("system/services/display/protocol.zig"), + .root_source_file = b.path("library/protocol/display/display-protocol.zig"), }); - runtime_module.addImport("display-protocol", display_protocol_module); + runtime_module.addImport("display-protocol", display_protocol_module); // runtime.display client speaks it // The scanout protocol: the compositor's outbound present channel to a native scanout // driver (virtio-gpu), separate from the client-facing display protocol (docs/display-v2.md). + // No runtime client speaks it — imported directly by the compositor and the scanout driver. const scanout_protocol_module = b.addModule("scanout-protocol", .{ - .root_source_file = b.path("system/services/display/scanout-protocol.zig"), + .root_source_file = b.path("library/protocol/scanout/scanout-protocol.zig"), }); - runtime_module.addImport("scanout-protocol", scanout_protocol_module); // The power protocol: system power's domain-named surface (docs/power.md). const power_protocol_module = b.addModule("power-protocol", .{ @@ -581,9 +581,13 @@ pub fn build(b: *std.Build) void { // Threaded: the display runs a mouse-listener thread alongside its compositor loop // (docs/threading.md, docs/display.md), so it opts into real atomics/TLS. const display_exe = addThreadedUserBinary(b, kernel_target, runtime_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "display", "system/services/display/display.zig"); + programModule(display_exe).addImport("display-protocol", display_protocol_module); + programModule(display_exe).addImport("scanout-protocol", scanout_protocol_module); const display_demo_exe = addUserBinary(b, kernel_target, runtime_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "display-demo", "system/services/display-demo/display-demo.zig"); const virtio_gpu_exe = addUserBinary(b, kernel_target, runtime_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "virtio-gpu", "system/drivers/virtio-gpu/virtio-gpu.zig"); programModule(virtio_gpu_exe).addImport("pci", pci_module); // library/device/pci — the claimed-function view + programModule(virtio_gpu_exe).addImport("display-protocol", display_protocol_module); + programModule(virtio_gpu_exe).addImport("scanout-protocol", scanout_protocol_module); const shared_memory_server_exe = addUserBinary(b, kernel_target, runtime_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "shared-memory-server", "system/services/shared-memory-server/shared-memory-server.zig"); const shared_memory_client_exe = addUserBinary(b, kernel_target, runtime_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "shared-memory-client", "system/services/shared-memory-client/shared-memory-client.zig"); const fat_test_exe = addUserBinary(b, kernel_target, runtime_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "fat-test", "system/services/fat/fat-test.zig"); @@ -973,7 +977,7 @@ pub fn build(b: *std.Build) void { "system/services/fat/on-disk.zig", // FAT on-disk struct sizes + type detection "system/services/fat/engine.zig", // FAT read/write over a RAM-backed image "system/services/display/compositor.zig", // Rect math + fill/composite/blit-tile - "system/services/display/protocol.zig", // pack(): native pixel encoding per format + "library/protocol/display/display-protocol.zig", // pack(): native pixel encoding per format "system/drivers/virtio-gpu/virtio-gpu-protocol.zig", // virtio-gpu command struct sizes "system/drivers/virtio-gpu/virtio-pci.zig", // virtio 1.0 PCI transport struct sizes }) |root| { diff --git a/system/services/display/protocol.zig b/library/protocol/display/display-protocol.zig similarity index 100% rename from system/services/display/protocol.zig rename to library/protocol/display/display-protocol.zig diff --git a/system/services/display/scanout-protocol.zig b/library/protocol/scanout/scanout-protocol.zig similarity index 100% rename from system/services/display/scanout-protocol.zig rename to library/protocol/scanout/scanout-protocol.zig diff --git a/library/runtime/runtime.zig b/library/runtime/runtime.zig index 873ac2c..effe046 100644 --- a/library/runtime/runtime.zig +++ b/library/runtime/runtime.zig @@ -53,11 +53,6 @@ pub const block = @import("block.zig"); /// Display-service client: query the mode, and (from D3) create layers, draw, and /// present frames. See library/runtime/display.zig and system/services/display/. pub const display = @import("display.zig"); -/// The display wire protocol (shared with the display service and its clients). -pub const display_protocol = @import("display-protocol"); -/// The scanout wire protocol: the compositor's present channel to a native scanout driver -/// (virtio-gpu). See system/services/display/scanout-protocol.zig and docs/display-v2.md. -pub const scanout_protocol = @import("scanout-protocol"); /// The danos-native file API (open/read/write/list over the user-space VFS) — the /// layer danos programs use directly, and where the operations that later become diff --git a/system/drivers/display/display.zig b/system/drivers/display/display.zig index ee76ffc..6fffc21 100644 --- a/system/drivers/display/display.zig +++ b/system/drivers/display/display.zig @@ -19,8 +19,8 @@ const dma = runtime.dma; const shared_memory = runtime.shared_memory; const system = runtime.system; const ipc = runtime.ipc; -const display_protocol = runtime.display_protocol; -const scanout_protocol = runtime.scanout_protocol; +const display_protocol = @import("display-protocol"); +const scanout_protocol = @import("scanout-protocol"); var device_id: u64 = 0; fn initialise(endpoint: ipc.Handle) bool { diff --git a/system/drivers/display/intel-integrated/intel-integrated.zig b/system/drivers/display/intel-integrated/intel-integrated.zig index 6ff23d2..9dddaf3 100644 --- a/system/drivers/display/intel-integrated/intel-integrated.zig +++ b/system/drivers/display/intel-integrated/intel-integrated.zig @@ -7,8 +7,8 @@ const dma = runtime.dma; const shared_memory = runtime.shared_memory; const system = runtime.system; const ipc = runtime.ipc; -const display_protocol = runtime.display_protocol; -const scanout_protocol = runtime.scanout_protocol; +const display_protocol = @import("display-protocol"); +const scanout_protocol = @import("scanout-protocol"); const device_manager_protocol = @import("device-manager-protocol"); var device_id: u64 = 0; diff --git a/system/drivers/virtio-gpu/virtio-gpu.zig b/system/drivers/virtio-gpu/virtio-gpu.zig index 86a55f2..4d101cf 100644 --- a/system/drivers/virtio-gpu/virtio-gpu.zig +++ b/system/drivers/virtio-gpu/virtio-gpu.zig @@ -22,8 +22,8 @@ const dma = runtime.dma; const shared_memory = runtime.shared_memory; const system = runtime.system; const ipc = runtime.ipc; -const dp = runtime.display_protocol; -const sp = runtime.scanout_protocol; +const display_protocol = @import("display-protocol"); +const scanout_protocol = @import("scanout-protocol"); const vp = @import("virtio-pci.zig"); const vg = @import("virtio-gpu-protocol.zig"); @@ -479,15 +479,15 @@ fn announce() void { std.log.info("no display service to announce to (scanout-only)", .{}); return; }; - var request = dp.Request{ - .operation = @intFromEnum(dp.Operation.attach_scanout), + var request = display_protocol.Request{ + .operation = @intFromEnum(display_protocol.Operation.attach_scanout), .x = max_width, // the shared surface's row stride in pixels (it is sized to the max mode) .y = edid_refresh_hz, // the panel refresh from EDID (0 = unknown) — the frame-clock seed .width = current_width, .height = current_height, .colour = display_format_bgrx, }; - var reply: [dp.reply_size]u8 = undefined; + var reply: [display_protocol.reply_size]u8 = undefined; _ = ipc.callCap(display, std.mem.asBytes(&request), &reply, surface.handle) catch { std.log.info("announce to display failed", .{}); return; @@ -495,11 +495,11 @@ fn announce() void { std.log.info("announced scanout to display", .{}); } -/// A `sp.Reply{status}` written into `reply`. +/// A `scanout_protocol.Reply{status}` written into `reply`. fn scanoutStatus(reply: []u8, ok: bool) usize { - const response = sp.Reply{ .status = if (ok) 0 else -1 }; - @memcpy(reply[0..sp.reply_size], std.mem.asBytes(&response)); - return sp.reply_size; + const response = scanout_protocol.Reply{ .status = if (ok) 0 else -1 }; + @memcpy(reply[0..scanout_protocol.reply_size], std.mem.asBytes(&response)); + return scanout_protocol.reply_size; } /// The `.scanout` service: the compositor drives present / mode queries here. The pixels are @@ -508,22 +508,22 @@ fn scanoutStatus(reply: []u8, ok: bool) usize { fn onMessage(message: []const u8, reply: []u8, sender: u32, capability: ?ipc.Handle) usize { _ = sender; _ = capability; - if (message.len < sp.request_size) return 0; - const request = std.mem.bytesToValue(sp.Request, message[0..sp.request_size]); + if (message.len < scanout_protocol.request_size) return 0; + const request = std.mem.bytesToValue(scanout_protocol.Request, message[0..scanout_protocol.request_size]); switch (request.operation) { - @intFromEnum(sp.Operation.present) => return scanoutStatus(reply, presentFull()), - @intFromEnum(sp.Operation.get_modes) => { - var response = sp.ModesReply{ .status = 0, .count = offered_modes.len, .modes = undefined }; - for (0..sp.max_modes) |i| { + @intFromEnum(scanout_protocol.Operation.present) => return scanoutStatus(reply, presentFull()), + @intFromEnum(scanout_protocol.Operation.get_modes) => { + var response = scanout_protocol.ModesReply{ .status = 0, .count = offered_modes.len, .modes = undefined }; + for (0..scanout_protocol.max_modes) |i| { response.modes[i] = if (i < offered_modes.len) .{ .width = offered_modes[i].width, .height = offered_modes[i].height } else .{ .width = 0, .height = 0 }; } - @memcpy(reply[0..sp.modes_reply_size], std.mem.asBytes(&response)); - return sp.modes_reply_size; + @memcpy(reply[0..scanout_protocol.modes_reply_size], std.mem.asBytes(&response)); + return scanout_protocol.modes_reply_size; }, - @intFromEnum(sp.Operation.set_mode) => { + @intFromEnum(scanout_protocol.Operation.set_mode) => { const w = request.width; const h = request.height; if (w == 0 or h == 0 or w > max_width or h > max_height) return scanoutStatus(reply, false); diff --git a/system/services/display/backend.zig b/system/services/display/backend.zig index a5697e9..a1428a0 100644 --- a/system/services/display/backend.zig +++ b/system/services/display/backend.zig @@ -12,7 +12,7 @@ const compositor = @import("compositor.zig"); const system = runtime.system; const device = runtime.device; const ipc = runtime.ipc; -const scanout_protocol = runtime.scanout_protocol; +const scanout_protocol = @import("scanout-protocol"); const Rect = compositor.Rect; const Surface = compositor.Surface; diff --git a/system/services/display/display.zig b/system/services/display/display.zig index 480bad8..1fd9c13 100644 --- a/system/services/display/display.zig +++ b/system/services/display/display.zig @@ -20,7 +20,7 @@ const runtime = @import("runtime"); const compositor = @import("compositor.zig"); const backend_mod = @import("backend.zig"); -const protocol = runtime.display_protocol; +const protocol = @import("display-protocol"); const ipc = runtime.ipc; const system = runtime.system; const input = runtime.input;