mach: correct vsync mode setting
This correctly sets presentation modes for vsync, both at startup and at runtime via a `setOptions` request. Note: There may still be platforms where setting vsync is not enough, and a frame rate limiter is needed to achieve proper synchronization. This is tracked in hexops/mach#444 and not fixed by this change. Fixes hexops/mach#307 Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
parent
edc3b5d60e
commit
eb0eceb707
3 changed files with 19 additions and 11 deletions
|
|
@ -34,15 +34,11 @@ target_desc: gpu.SwapChain.Descriptor,
|
||||||
|
|
||||||
internal: platform.Type,
|
internal: platform.Type,
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator) !Core {
|
pub fn init(allocator: std.mem.Allocator, core: *Core) !void {
|
||||||
var core: Core = undefined;
|
|
||||||
core.allocator = allocator;
|
core.allocator = allocator;
|
||||||
core.options = structs.Options{};
|
core.options = structs.Options{};
|
||||||
core.timer = try Timer.start();
|
core.timer = try Timer.start();
|
||||||
|
core.internal = try platform.Type.init(allocator, core);
|
||||||
core.internal = try platform.Type.init(allocator, &core);
|
|
||||||
|
|
||||||
return core;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set runtime options for application, like title, window size etc.
|
/// Set runtime options for application, like title, window size etc.
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ pub const log_level = if (@hasDecl(App, "log_level")) App.log_level else std.log
|
||||||
|
|
||||||
pub const Platform = struct {
|
pub const Platform = struct {
|
||||||
window: glfw.Window,
|
window: glfw.Window,
|
||||||
|
core: *Core,
|
||||||
backend_type: gpu.BackendType,
|
backend_type: gpu.BackendType,
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
events: EventQueue = .{},
|
events: EventQueue = .{},
|
||||||
|
|
@ -129,7 +130,11 @@ pub const Platform = struct {
|
||||||
.format = core.swap_chain_format,
|
.format = core.swap_chain_format,
|
||||||
.width = framebuffer_size.width,
|
.width = framebuffer_size.width,
|
||||||
.height = framebuffer_size.height,
|
.height = framebuffer_size.height,
|
||||||
.present_mode = .fifo,
|
.present_mode = switch (options.vsync) {
|
||||||
|
.none => .immediate,
|
||||||
|
.double => .fifo,
|
||||||
|
.triple => .mailbox,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
device.?.setUncapturedErrorCallback({}, util.printUnhandledErrorCallback);
|
device.?.setUncapturedErrorCallback({}, util.printUnhandledErrorCallback);
|
||||||
|
|
@ -144,6 +149,7 @@ pub const Platform = struct {
|
||||||
|
|
||||||
return Platform{
|
return Platform{
|
||||||
.window = window,
|
.window = window,
|
||||||
|
.core = core,
|
||||||
.backend_type = backend_type,
|
.backend_type = backend_type,
|
||||||
.allocator = core.allocator,
|
.allocator = core.allocator,
|
||||||
.last_window_size = .{ .width = window_size.width, .height = window_size.height },
|
.last_window_size = .{ .width = window_size.width, .height = window_size.height },
|
||||||
|
|
@ -338,6 +344,11 @@ pub const Platform = struct {
|
||||||
@bitCast(glfw.Window.SizeOptional, options.size_min),
|
@bitCast(glfw.Window.SizeOptional, options.size_min),
|
||||||
@bitCast(glfw.Window.SizeOptional, options.size_max),
|
@bitCast(glfw.Window.SizeOptional, options.size_max),
|
||||||
);
|
);
|
||||||
|
platform.core.target_desc.present_mode = switch (options.vsync) {
|
||||||
|
.none => .immediate,
|
||||||
|
.double => .fifo,
|
||||||
|
.triple => .mailbox,
|
||||||
|
};
|
||||||
if (options.fullscreen) {
|
if (options.fullscreen) {
|
||||||
platform.last_position = try platform.window.getPos();
|
platform.last_position = try platform.window.getPos();
|
||||||
|
|
||||||
|
|
@ -406,8 +417,9 @@ pub const Platform = struct {
|
||||||
|
|
||||||
pub fn pollEvent(platform: *Platform) ?structs.Event {
|
pub fn pollEvent(platform: *Platform) ?structs.Event {
|
||||||
if (platform.events.popFirst()) |n| {
|
if (platform.events.popFirst()) |n| {
|
||||||
defer platform.allocator.destroy(n);
|
const data = n.data;
|
||||||
return n.data;
|
platform.allocator.destroy(n);
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -607,7 +619,7 @@ pub fn main() !void {
|
||||||
pub fn coreInit(allocator: std.mem.Allocator) !*Core {
|
pub fn coreInit(allocator: std.mem.Allocator) !*Core {
|
||||||
const core: *Core = try allocator.create(Core);
|
const core: *Core = try allocator.create(Core);
|
||||||
errdefer allocator.destroy(core);
|
errdefer allocator.destroy(core);
|
||||||
core.* = try Core.init(allocator);
|
try Core.init(allocator, core);
|
||||||
|
|
||||||
// Glfw specific: initialize the user pointer used in callbacks
|
// Glfw specific: initialize the user pointer used in callbacks
|
||||||
core.*.internal.initCallback();
|
core.*.internal.initCallback();
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,7 @@ export fn wasmInit() void {
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
const allocator = gpa.allocator();
|
const allocator = gpa.allocator();
|
||||||
|
|
||||||
core = Core.init(allocator) catch unreachable;
|
Core.init(allocator, &core) catch unreachable;
|
||||||
app.init(&core) catch {};
|
app.init(&core) catch {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue