From 376c6c0c7dc92f7eda78c7ff2fe7830c1b6bbfbc Mon Sep 17 00:00:00 2001 From: mrsaturnsan Date: Sun, 10 Nov 2024 19:29:45 -0600 Subject: [PATCH] Use afterMinimumDuration to correct frame pacing --- drivers/metal/rendering_context_driver_metal.h | 2 ++ drivers/metal/rendering_context_driver_metal.mm | 2 +- drivers/metal/rendering_device_driver_metal.h | 1 + drivers/metal/rendering_device_driver_metal.mm | 6 ++++++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/metal/rendering_context_driver_metal.h b/drivers/metal/rendering_context_driver_metal.h index 7e0b09186de..1fdc255f931 100644 --- a/drivers/metal/rendering_context_driver_metal.h +++ b/drivers/metal/rendering_context_driver_metal.h @@ -107,6 +107,7 @@ public: uint32_t height = 0; DisplayServer::VSyncMode vsync_mode = DisplayServer::VSYNC_ENABLED; bool needs_resize = false; + double present_minimum_duration = 0.0; Surface( #ifdef __OBJC__ @@ -123,6 +124,7 @@ public: virtual Error resize(uint32_t p_desired_framebuffer_count) = 0; virtual RDD::FramebufferID acquire_next_frame_buffer() = 0; virtual void present(MDCommandBuffer *p_cmd_buffer) = 0; + void set_max_fps(int p_max_fps) { present_minimum_duration = p_max_fps ? 1.0 / p_max_fps : 0.0; } }; #ifdef __OBJC__ diff --git a/drivers/metal/rendering_context_driver_metal.mm b/drivers/metal/rendering_context_driver_metal.mm index cf8c7e1c833..199ec25d793 100644 --- a/drivers/metal/rendering_context_driver_metal.mm +++ b/drivers/metal/rendering_context_driver_metal.mm @@ -172,7 +172,7 @@ public: count--; front = (front + 1) % frame_buffers.size(); - [p_cmd_buffer->get_command_buffer() presentDrawable:drawable]; + [p_cmd_buffer->get_command_buffer() presentDrawable:drawable afterMinimumDuration:present_minimum_duration]; } }; diff --git a/drivers/metal/rendering_device_driver_metal.h b/drivers/metal/rendering_device_driver_metal.h index e238de958ea..09ab7601e9c 100644 --- a/drivers/metal/rendering_device_driver_metal.h +++ b/drivers/metal/rendering_device_driver_metal.h @@ -220,6 +220,7 @@ public: virtual FramebufferID swap_chain_acquire_framebuffer(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, bool &r_resize_required) override final; virtual RenderPassID swap_chain_get_render_pass(SwapChainID p_swap_chain) override final; virtual DataFormat swap_chain_get_format(SwapChainID p_swap_chain) override final; + virtual void swap_chain_set_max_fps(SwapChainID p_swap_chain, int p_max_fps) override final; virtual void swap_chain_free(SwapChainID p_swap_chain) override final; #pragma mark - Frame Buffer diff --git a/drivers/metal/rendering_device_driver_metal.mm b/drivers/metal/rendering_device_driver_metal.mm index d90f528a146..1dec02699e1 100644 --- a/drivers/metal/rendering_device_driver_metal.mm +++ b/drivers/metal/rendering_device_driver_metal.mm @@ -982,6 +982,12 @@ RDD::DataFormat RenderingDeviceDriverMetal::swap_chain_get_format(SwapChainID p_ return swap_chain->data_format; } +void RenderingDeviceDriverMetal::swap_chain_set_max_fps(SwapChainID p_swap_chain, int p_max_fps) { + SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id); + RenderingContextDriverMetal::Surface *metal_surface = (RenderingContextDriverMetal::Surface *)(swap_chain->surface); + metal_surface->set_max_fps(p_max_fps); +} + void RenderingDeviceDriverMetal::swap_chain_free(SwapChainID p_swap_chain) { SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id); _swap_chain_release(swap_chain);