core: x11: clarify X11 multi-threading (#1297)
This commit is contained in:
parent
06f61044fb
commit
2608e1313c
2 changed files with 10 additions and 19 deletions
|
|
@ -265,7 +265,11 @@ fn init(core: *Mod, entities: *mach.Entities.Mod) !void {
|
||||||
.format = .bgra8_unorm,
|
.format = .bgra8_unorm,
|
||||||
.width = @intCast(state.platform.size.width),
|
.width = @intCast(state.platform.size.width),
|
||||||
.height = @intCast(state.platform.size.height),
|
.height = @intCast(state.platform.size.height),
|
||||||
.present_mode = .mailbox,
|
.present_mode = switch (state.platform.vsync_mode) {
|
||||||
|
.none => .immediate,
|
||||||
|
.double => .fifo,
|
||||||
|
.triple => .mailbox,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
state.swap_chain = state.device.createSwapChain(state.surface, &state.descriptor);
|
state.swap_chain = state.device.createSwapChain(state.surface, &state.descriptor);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,9 +65,6 @@ hidden_cursor: c.Cursor,
|
||||||
// Mutable fields only used by main thread
|
// Mutable fields only used by main thread
|
||||||
cursors: [@typeInfo(CursorShape).@"enum".fields.len]?c.Cursor,
|
cursors: [@typeInfo(CursorShape).@"enum".fields.len]?c.Cursor,
|
||||||
|
|
||||||
// Input state; written from main thread; read from any
|
|
||||||
input_mu: std.Thread.RwLock = .{},
|
|
||||||
|
|
||||||
// Mutable state fields; read/write by any thread
|
// Mutable state fields; read/write by any thread
|
||||||
title: [:0]const u8,
|
title: [:0]const u8,
|
||||||
display_mode: DisplayMode = .windowed,
|
display_mode: DisplayMode = .windowed,
|
||||||
|
|
@ -87,9 +84,11 @@ pub fn init(
|
||||||
// TODO(core): return errors.NotSupported if not supported
|
// TODO(core): return errors.NotSupported if not supported
|
||||||
const libx11 = try LibX11.load();
|
const libx11 = try LibX11.load();
|
||||||
|
|
||||||
// Xlibx11.XInitThreads must be called first
|
// Note: X11 (at least, older versions of it definitely) have a race condition with frame submission
|
||||||
//
|
// when the Vulkan presentation mode != .none; XInitThreads() resolves this. We use XInitThreads
|
||||||
// if not, 'Unknown sequence number while processing queue' errors occur.
|
// /solely/ to ensure we can use .double and .triple presentation modes, we do not use it for
|
||||||
|
// anything else and otherwise treat all X11 API calls as if they are not thread-safe as with all
|
||||||
|
// other native GUI APIs.
|
||||||
_ = libx11.XInitThreads();
|
_ = libx11.XInitThreads();
|
||||||
const libgl: ?LibGL = LibGL.load() catch |err| switch (err) {
|
const libgl: ?LibGL = LibGL.load() catch |err| switch (err) {
|
||||||
error.LibraryNotFound => null,
|
error.LibraryNotFound => null,
|
||||||
|
|
@ -521,9 +520,7 @@ fn processEvent(x11: *X11, event: *c.XEvent) void {
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
c.KeyPress => {
|
c.KeyPress => {
|
||||||
x11.input_mu.lock();
|
|
||||||
x11.state.input_state.keys.set(@intFromEnum(key_event.key));
|
x11.state.input_state.keys.set(@intFromEnum(key_event.key));
|
||||||
x11.input_mu.unlock();
|
|
||||||
x11.state.pushEvent(.{ .key_press = key_event });
|
x11.state.pushEvent(.{ .key_press = key_event });
|
||||||
|
|
||||||
const codepoint = x11.libxkbcommon.xkb_keysym_to_utf32(@truncate(keysym));
|
const codepoint = x11.libxkbcommon.xkb_keysym_to_utf32(@truncate(keysym));
|
||||||
|
|
@ -532,9 +529,7 @@ fn processEvent(x11: *X11, event: *c.XEvent) void {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
c.KeyRelease => {
|
c.KeyRelease => {
|
||||||
x11.input_mu.lock();
|
|
||||||
x11.state.input_state.keys.unset(@intFromEnum(key_event.key));
|
x11.state.input_state.keys.unset(@intFromEnum(key_event.key));
|
||||||
x11.input_mu.unlock();
|
|
||||||
x11.state.pushEvent(.{ .key_release = key_event });
|
x11.state.pushEvent(.{ .key_release = key_event });
|
||||||
},
|
},
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
|
|
@ -560,9 +555,7 @@ fn processEvent(x11: *X11, event: *c.XEvent) void {
|
||||||
.mods = toMachMods(event.xbutton.state),
|
.mods = toMachMods(event.xbutton.state),
|
||||||
};
|
};
|
||||||
|
|
||||||
x11.input_mu.lock();
|
|
||||||
x11.state.input_state.mouse_buttons.set(@intFromEnum(mouse_button.button));
|
x11.state.input_state.mouse_buttons.set(@intFromEnum(mouse_button.button));
|
||||||
x11.input_mu.unlock();
|
|
||||||
x11.state.pushEvent(.{ .mouse_press = mouse_button });
|
x11.state.pushEvent(.{ .mouse_press = mouse_button });
|
||||||
},
|
},
|
||||||
c.ButtonRelease => {
|
c.ButtonRelease => {
|
||||||
|
|
@ -574,9 +567,7 @@ fn processEvent(x11: *X11, event: *c.XEvent) void {
|
||||||
.mods = toMachMods(event.xbutton.state),
|
.mods = toMachMods(event.xbutton.state),
|
||||||
};
|
};
|
||||||
|
|
||||||
x11.input_mu.lock();
|
|
||||||
x11.state.input_state.mouse_buttons.unset(@intFromEnum(mouse_button.button));
|
x11.state.input_state.mouse_buttons.unset(@intFromEnum(mouse_button.button));
|
||||||
x11.input_mu.unlock();
|
|
||||||
x11.state.pushEvent(.{ .mouse_release = mouse_button });
|
x11.state.pushEvent(.{ .mouse_release = mouse_button });
|
||||||
},
|
},
|
||||||
c.ClientMessage => {
|
c.ClientMessage => {
|
||||||
|
|
@ -606,17 +597,13 @@ fn processEvent(x11: *X11, event: *c.XEvent) void {
|
||||||
c.EnterNotify => {
|
c.EnterNotify => {
|
||||||
const x: f32 = @floatFromInt(event.xcrossing.x);
|
const x: f32 = @floatFromInt(event.xcrossing.x);
|
||||||
const y: f32 = @floatFromInt(event.xcrossing.y);
|
const y: f32 = @floatFromInt(event.xcrossing.y);
|
||||||
x11.input_mu.lock();
|
|
||||||
x11.state.input_state.mouse_position = .{ .x = x, .y = y };
|
x11.state.input_state.mouse_position = .{ .x = x, .y = y };
|
||||||
x11.input_mu.unlock();
|
|
||||||
x11.state.pushEvent(.{ .mouse_motion = .{ .pos = .{ .x = x, .y = y } } });
|
x11.state.pushEvent(.{ .mouse_motion = .{ .pos = .{ .x = x, .y = y } } });
|
||||||
},
|
},
|
||||||
c.MotionNotify => {
|
c.MotionNotify => {
|
||||||
const x: f32 = @floatFromInt(event.xmotion.x);
|
const x: f32 = @floatFromInt(event.xmotion.x);
|
||||||
const y: f32 = @floatFromInt(event.xmotion.y);
|
const y: f32 = @floatFromInt(event.xmotion.y);
|
||||||
x11.input_mu.lock();
|
|
||||||
x11.state.input_state.mouse_position = .{ .x = x, .y = y };
|
x11.state.input_state.mouse_position = .{ .x = x, .y = y };
|
||||||
x11.input_mu.unlock();
|
|
||||||
x11.state.pushEvent(.{ .mouse_motion = .{ .pos = .{ .x = x, .y = y } } });
|
x11.state.pushEvent(.{ .mouse_motion = .{ .pos = .{ .x = x, .y = y } } });
|
||||||
},
|
},
|
||||||
c.ConfigureNotify => {
|
c.ConfigureNotify => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue