summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHendrik Brucker <hendrik.brucker@mail.de>2021-06-19 17:44:59 +0200
committerHendrik Brucker <hendrik.brucker@mail.de>2021-07-06 16:34:26 +0200
commit043ae9156086a2fc9fdb520539411123256b3aeb (patch)
tree01877890f81d6dcac21e6275d9af437397c9f5d0
parent053198a5f34b7ce680e2fd1a3287a559cc2afc94 (diff)
Restructure and reimplement vsync options
-Add a v-sync mode setting which allows to choose between DISABLED, ON, ADAPTIVE and MAILBOX -Removed the V-Sync via Compositor option
-rw-r--r--core/config/project_settings.cpp1
-rw-r--r--core/os/os.h2
-rw-r--r--doc/classes/DisplayServer.xml69
-rw-r--r--doc/classes/ProjectSettings.xml12
-rw-r--r--drivers/vulkan/vulkan_context.cpp56
-rw-r--r--drivers/vulkan/vulkan_context.h6
-rw-r--r--main/main.cpp46
-rw-r--r--misc/dist/linux/godot.66
-rw-r--r--misc/dist/shell/_godot.zsh-completion2
-rw-r--r--misc/dist/shell/godot.bash-completion2
-rw-r--r--misc/dist/shell/godot.fish2
-rw-r--r--platform/android/display_server_android.cpp25
-rw-r--r--platform/android/display_server_android.h6
-rw-r--r--platform/android/vulkan/vulkan_context_android.cpp4
-rw-r--r--platform/android/vulkan/vulkan_context_android.h2
-rw-r--r--platform/iphone/display_server_iphone.h7
-rw-r--r--platform/iphone/display_server_iphone.mm24
-rw-r--r--platform/iphone/vulkan_context_iphone.h2
-rw-r--r--platform/iphone/vulkan_context_iphone.mm4
-rw-r--r--platform/linuxbsd/display_server_x11.cpp32
-rw-r--r--platform/linuxbsd/display_server_x11.h11
-rw-r--r--platform/linuxbsd/vulkan_context_x11.cpp4
-rw-r--r--platform/linuxbsd/vulkan_context_x11.h2
-rw-r--r--platform/osx/display_server_osx.h11
-rw-r--r--platform/osx/display_server_osx.mm32
-rw-r--r--platform/osx/vulkan_context_osx.h2
-rw-r--r--platform/osx/vulkan_context_osx.mm4
-rw-r--r--platform/windows/context_gl_windows.cpp36
-rw-r--r--platform/windows/context_gl_windows.h3
-rw-r--r--platform/windows/display_server_windows.cpp32
-rw-r--r--platform/windows/display_server_windows.h14
-rw-r--r--platform/windows/vulkan_context_win.cpp5
-rw-r--r--platform/windows/vulkan_context_win.h2
-rw-r--r--scene/main/window.cpp3
-rw-r--r--servers/display_server.cpp49
-rw-r--r--servers/display_server.h31
-rw-r--r--servers/display_server_headless.h2
-rw-r--r--servers/rendering/renderer_viewport.cpp6
-rw-r--r--servers/rendering/renderer_viewport.h4
-rw-r--r--servers/rendering/rendering_server_default.h2
-rw-r--r--servers/rendering_server.h2
41 files changed, 310 insertions, 257 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index 25506e8db3..29f53482fa 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -1114,6 +1114,7 @@ ProjectSettings::ProjectSettings() {
// Keep the enum values in sync with the `DisplayServer::ScreenOrientation` enum.
custom_prop_info["display/window/handheld/orientation"] = PropertyInfo(Variant::INT, "display/window/handheld/orientation", PROPERTY_HINT_ENUM, "Landscape,Portrait,Reverse Landscape,Reverse Portrait,Sensor Landscape,Sensor Portrait,Sensor");
+ custom_prop_info["display/window/vsync/vsync_mode"] = PropertyInfo(Variant::STRING, "display/window/vsync/vsync_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled,Adaptive,Mailbox");
custom_prop_info["rendering/driver/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/driver/threads/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded");
GLOBAL_DEF("physics/2d/run_on_thread", false);
GLOBAL_DEF("physics/3d/run_on_thread", false);
diff --git a/core/os/os.h b/core/os/os.h
index 444f67431f..301718a8b3 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -58,8 +58,6 @@ class OS {
int _orientation;
bool _allow_hidpi = false;
bool _allow_layered = false;
- bool _use_vsync;
- bool _vsync_via_compositor;
bool _stdout_enabled = true;
bool _stderr_enabled = true;
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index ef20174ee6..17b51d5cbe 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -44,9 +44,11 @@
</return>
<argument index="0" name="mode" type="int" enum="DisplayServer.WindowMode">
</argument>
- <argument index="1" name="flags" type="int">
+ <argument index="1" name="vsync_mode" type="int" enum="DisplayServer.VSyncMode">
</argument>
- <argument index="2" name="rect" type="Rect2i" default="Rect2i(0, 0, 0, 0)">
+ <argument index="2" name="flags" type="int">
+ </argument>
+ <argument index="3" name="rect" type="Rect2i" default="Rect2i(0, 0, 0, 0)">
</argument>
<description>
</description>
@@ -671,34 +673,6 @@
[b]Note:[/b] This method is implemented on Android, iOS and UWP.
</description>
</method>
- <method name="vsync_is_enabled" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- </description>
- </method>
- <method name="vsync_is_using_via_compositor" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- </description>
- </method>
- <method name="vsync_set_enabled">
- <return type="void">
- </return>
- <argument index="0" name="enabled" type="bool">
- </argument>
- <description>
- </description>
- </method>
- <method name="vsync_set_use_via_compositor">
- <return type="void">
- </return>
- <argument index="0" name="enabled" type="bool">
- </argument>
- <description>
- </description>
- </method>
<method name="window_attach_instance_id">
<return type="void">
</return>
@@ -791,6 +765,15 @@
<description>
</description>
</method>
+ <method name="window_get_vsync_mode" qualifiers="const">
+ <return type="int" enum="DisplayServer.VSyncMode">
+ </return>
+ <argument index="0" name="window_id" type="int" default="0">
+ </argument>
+ <description>
+ Returns the VSync mode of the given window.
+ </description>
+ </method>
<method name="window_move_to_foreground">
<return type="void">
</return>
@@ -995,6 +978,19 @@
<description>
</description>
</method>
+ <method name="window_set_vsync_mode">
+ <return type="void">
+ </return>
+ <argument index="0" name="vsync_mode" type="int" enum="DisplayServer.VSyncMode">
+ </argument>
+ <argument index="1" name="window_id" type="int" default="0">
+ </argument>
+ <description>
+ Sets the VSync mode of the given window.
+ See [enum DisplayServer.VSyncMode] for possible values and how they affect the behavior of your application.
+ Depending on the platform and used renderer, the engine will fall back to [constant VSYNC_ENABLED], if the desired mode is not supported.
+ </description>
+ </method>
<method name="window_set_window_event_callback">
<return type="void">
</return>
@@ -1151,5 +1147,18 @@
</constant>
<constant name="WINDOW_EVENT_DPI_CHANGE" value="6" enum="WindowEvent">
</constant>
+ <constant name="VSYNC_DISABLED" value="0" enum="VSyncMode">
+ No vertical synchronization, which means the engine will display frames as fast as possible (tearing may be visible).
+ </constant>
+ <constant name="VSYNC_ENABLED" value="1" enum="VSyncMode">
+ Default vertical synchronization mode, the image is displayed only on vertical blanking intervals (no tearing is visible).
+ </constant>
+ <constant name="VSYNC_ADAPTIVE" value="2" enum="VSyncMode">
+ Behaves like [constant VSYNC_DISABLED] when the framerate drops below the screen's refresh rate to reduce stuttering (tearing may be visible), otherwise vertical synchronization is enabled to avoid tearing.
+ </constant>
+ <constant name="VSYNC_MAILBOX" value="3" enum="VSyncMode">
+ Displays the most recent image in the queue on vertical blanking intervals, while rendering to the other images (no tearing is visible).
+ Although not guaranteed, the images can be rendered as fast as possible, which may reduce input lag.
+ </constant>
</constants>
</class>
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 1847a316e1..d497e418bc 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -445,7 +445,7 @@
</member>
<member name="debug/settings/fps/force_fps" type="int" setter="" getter="" default="0">
Maximum number of frames per second allowed. The actual number of frames per second may still be below this value if the game is lagging.
- If [member display/window/vsync/use_vsync] is enabled, it takes precedence and the forced FPS number cannot exceed the monitor's refresh rate.
+ If [member display/window/vsync/vsync_mode] is set to [code]Enabled[/code] or [code]Adaptive[/code], it takes precedence and the forced FPS number cannot exceed the monitor's refresh rate.
This setting is therefore mostly relevant for lowering the maximum FPS below VSync, e.g. to perform non-real-time rendering of static frames, or test the project under lag conditions.
</member>
<member name="debug/settings/gdscript/max_call_stack" type="int" setter="" getter="" default="1024">
@@ -532,12 +532,10 @@
<member name="display/window/size/width" type="int" setter="" getter="" default="1024">
Sets the game's main viewport width. On desktop platforms, this is the default window size. Stretch mode settings also use this as a reference when enabled.
</member>
- <member name="display/window/vsync/use_vsync" type="bool" setter="" getter="" default="true">
- If [code]true[/code], enables vertical synchronization. This eliminates tearing that may appear in moving scenes, at the cost of higher input latency and stuttering at lower framerates. If [code]false[/code], vertical synchronization will be disabled, however, many platforms will enforce it regardless (such as mobile platforms and HTML5).
- </member>
- <member name="display/window/vsync/vsync_via_compositor" type="bool" setter="" getter="" default="false">
- If [code]Use Vsync[/code] is enabled and this setting is [code]true[/code], enables vertical synchronization via the operating system's window compositor when in windowed mode and the compositor is enabled. This will prevent stutter in certain situations. (Windows only.)
- [b]Note:[/b] This option is experimental and meant to alleviate stutter experienced by some users. However, some users have experienced a Vsync framerate halving (e.g. from 60 FPS to 30 FPS) when using it.
+ <member name="display/window/vsync/vsync_mode" type="String" setter="" getter="" default="&quot;Enabled&quot;">
+ Sets the VSync mode for the main game window.
+ See [enum DisplayServer.VSyncMode] for possible values and how they affect the behavior of your application.
+ Depending on the platform and used renderer, the engine will fall back to [code]Enabled[/code], if the desired mode is not supported.
</member>
<member name="editor/node_naming/name_casing" type="int" setter="" getter="" default="0">
When creating node names automatically, set the type of casing in this project. This is mostly an editor setting.
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index 74bd938822..d35c519320 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -1189,7 +1189,7 @@ bool VulkanContext::_use_validation_layers() {
return Engine::get_singleton()->is_validation_layers_enabled();
}
-Error VulkanContext::_window_create(DisplayServer::WindowID p_window_id, VkSurfaceKHR p_surface, int p_width, int p_height) {
+Error VulkanContext::_window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, VkSurfaceKHR p_surface, int p_width, int p_height) {
ERR_FAIL_COND_V(windows.has(p_window_id), ERR_INVALID_PARAMETER);
if (!queues_initialized) {
@@ -1217,6 +1217,7 @@ Error VulkanContext::_window_create(DisplayServer::WindowID p_window_id, VkSurfa
window.surface = p_surface;
window.width = p_width;
window.height = p_height;
+ window.vsync_mode = p_vsync_mode;
Error err = _update_swap_chain(&window);
ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE);
@@ -1360,7 +1361,6 @@ Error VulkanContext::_update_swap_chain(Window *window) {
}
// The FIFO present mode is guaranteed by the spec to be supported
// and to have no tearing. It's a great default present mode to use.
- VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
// There are times when you may wish to use another present mode. The
// following code shows how to select them, and the comments provide some
@@ -1389,16 +1389,41 @@ Error VulkanContext::_update_swap_chain(Window *window) {
// the application wants the late image to be immediately displayed, even
// though that may mean some tearing.
- if (window->presentMode != swapchainPresentMode) {
- for (size_t i = 0; i < presentModeCount; ++i) {
- if (presentModes[i] == window->presentMode) {
- swapchainPresentMode = window->presentMode;
- break;
- }
+ VkPresentModeKHR requested_present_mode = VkPresentModeKHR::VK_PRESENT_MODE_FIFO_KHR;
+ switch (window->vsync_mode) {
+ case DisplayServer::VSYNC_MAILBOX:
+ requested_present_mode = VkPresentModeKHR::VK_PRESENT_MODE_MAILBOX_KHR;
+ break;
+ case DisplayServer::VSYNC_ADAPTIVE:
+ requested_present_mode = VkPresentModeKHR::VK_PRESENT_MODE_FIFO_RELAXED_KHR;
+ break;
+ case DisplayServer::VSYNC_ENABLED:
+ requested_present_mode = VkPresentModeKHR::VK_PRESENT_MODE_FIFO_KHR;
+ break;
+ case DisplayServer::VSYNC_DISABLED:
+ requested_present_mode = VkPresentModeKHR::VK_PRESENT_MODE_IMMEDIATE_KHR;
+ break;
+ }
+
+ // Check if the requested mode is available.
+ bool present_mode_available = false;
+ for (uint32_t i = 0; i < presentModeCount; i++) {
+ if (presentModes[i] == requested_present_mode) {
+ present_mode_available = true;
}
}
+
+ // Set the windows present mode if it is available, otherwise FIFO is used (guaranteed supported).
+ if (present_mode_available) {
+ window->presentMode = requested_present_mode;
+ } else {
+ WARN_PRINT("Requested VSync mode is not available!");
+ window->vsync_mode = DisplayServer::VSYNC_ENABLED; //Set to default
+ }
+
+ print_verbose("Using present mode: " + String(string_VkPresentModeKHR(window->presentMode)));
+
free(presentModes);
- ERR_FAIL_COND_V_MSG(swapchainPresentMode != window->presentMode, ERR_CANT_CREATE, "Present mode specified is not supported\n");
// Determine the number of VkImages to use in the swap chain.
// Application desires to acquire 3 images at a time for triple
@@ -1455,7 +1480,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
/*pQueueFamilyIndices*/ nullptr,
/*preTransform*/ (VkSurfaceTransformFlagBitsKHR)preTransform,
/*compositeAlpha*/ compositeAlpha,
- /*presentMode*/ swapchainPresentMode,
+ /*presentMode*/ window->presentMode,
/*clipped*/ true,
/*oldSwapchain*/ VK_NULL_HANDLE,
};
@@ -2162,6 +2187,17 @@ String VulkanContext::get_device_pipeline_cache_uuid() const {
return pipeline_cache_id;
}
+DisplayServer::VSyncMode VulkanContext::get_vsync_mode(DisplayServer::WindowID p_window) const {
+ ERR_FAIL_COND_V_MSG(!windows.has(p_window), DisplayServer::VSYNC_ENABLED, "Could not get VSync mode for window with WindowID " + itos(p_window) + " because it does not exist.");
+ return windows[p_window].vsync_mode;
+}
+
+void VulkanContext::set_vsync_mode(DisplayServer::WindowID p_window, DisplayServer::VSyncMode p_mode) {
+ ERR_FAIL_COND_MSG(!windows.has(p_window), "Could not set VSync mode for window with WindowID " + itos(p_window) + " because it does not exist.");
+ windows[p_window].vsync_mode = p_mode;
+ _update_swap_chain(&windows[p_window]);
+}
+
VulkanContext::VulkanContext() {
command_buffer_queue.resize(1); // First one is always the setup command.
command_buffer_queue.write[0] = nullptr;
diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h
index 8f1005d07f..83e9524046 100644
--- a/drivers/vulkan/vulkan_context.h
+++ b/drivers/vulkan/vulkan_context.h
@@ -124,6 +124,7 @@ private:
uint32_t current_buffer = 0;
int width = 0;
int height = 0;
+ DisplayServer::VSyncMode vsync_mode = DisplayServer::VSYNC_ENABLED;
VkCommandPool present_cmd_pool = VK_NULL_HANDLE; // For separate present queue.
VkRenderPass render_pass = VK_NULL_HANDLE;
};
@@ -222,7 +223,7 @@ private:
protected:
virtual const char *_get_platform_surface_extension() const = 0;
- virtual Error _window_create(DisplayServer::WindowID p_window_id, VkSurfaceKHR p_surface, int p_width, int p_height);
+ virtual Error _window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, VkSurfaceKHR p_surface, int p_width, int p_height);
virtual bool _use_validation_layers();
@@ -276,6 +277,9 @@ public:
String get_device_name() const;
String get_device_pipeline_cache_uuid() const;
+ void set_vsync_mode(DisplayServer::WindowID p_window, DisplayServer::VSyncMode p_mode);
+ DisplayServer::VSyncMode get_vsync_mode(DisplayServer::WindowID p_window = 0) const;
+
VulkanContext();
virtual ~VulkanContext();
};
diff --git a/main/main.cpp b/main/main.cpp
index 9e3b5c9ba2..2b5f8d9315 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -151,9 +151,9 @@ static bool auto_build_solutions = false;
static DisplayServer::WindowMode window_mode = DisplayServer::WINDOW_MODE_WINDOWED;
static DisplayServer::ScreenOrientation window_orientation = DisplayServer::SCREEN_LANDSCAPE;
+static DisplayServer::VSyncMode window_vsync_mode = DisplayServer::VSYNC_ENABLED;
static uint32_t window_flags = 0;
static Size2i window_size = Size2i(1024, 600);
-static bool window_vsync_via_compositor = false;
static int init_screen = -1;
static bool init_fullscreen = false;
@@ -338,8 +338,6 @@ void Main::print_help(const char *p_binary) {
OS::get_singleton()->print(" --position <X>,<Y> Request window position.\n");
OS::get_singleton()->print(" --low-dpi Force low-DPI mode (macOS and Windows only).\n");
OS::get_singleton()->print(" --no-window Disable window creation (Windows only). Useful together with --script.\n");
- OS::get_singleton()->print(" --enable-vsync-via-compositor When vsync is enabled, vsync via the OS' window compositor (Windows only).\n");
- OS::get_singleton()->print(" --disable-vsync-via-compositor Disable vsync via the OS' window compositor (Windows only).\n");
OS::get_singleton()->print(" --single-window Use a single window (no separate subwindows).\n");
OS::get_singleton()->print(" --tablet-driver Pen tablet input driver.\n");
OS::get_singleton()->print("\n");
@@ -599,11 +597,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
Vector<String> breakpoints;
bool use_custom_res = true;
bool force_res = false;
- bool saw_vsync_via_compositor_override = false;
#ifdef TOOLS_ENABLED
bool found_project = false;
#endif
- bool use_vsync = false;
packed_data = PackedData::get_singleton();
if (!packed_data) {
@@ -825,12 +821,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "--no-window") { // disable window creation (Windows only)
OS::get_singleton()->set_no_window_mode(true);
- } else if (I->get() == "--enable-vsync-via-compositor") {
- window_vsync_via_compositor = true;
- saw_vsync_via_compositor_override = true;
- } else if (I->get() == "--disable-vsync-via-compositor") {
- window_vsync_via_compositor = false;
- saw_vsync_via_compositor_override = true;
#endif
} else if (I->get() == "--profiling") { // enable profiling
@@ -1287,19 +1277,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
OS::get_singleton()->_allow_hidpi = GLOBAL_DEF("display/window/dpi/allow_hidpi", false);
}
- use_vsync = GLOBAL_DEF_RST("display/window/vsync/use_vsync", true);
- OS::get_singleton()->_use_vsync = use_vsync;
-
- if (!saw_vsync_via_compositor_override) {
- // If one of the command line options to enable/disable vsync via the
- // window compositor ("--enable-vsync-via-compositor" or
- // "--disable-vsync-via-compositor") was present then it overrides the
- // project setting.
- window_vsync_via_compositor = GLOBAL_DEF("display/window/vsync/vsync_via_compositor", false);
- }
-
- OS::get_singleton()->_vsync_via_compositor = window_vsync_via_compositor;
-
/* todo restore
OS::get_singleton()->_allow_layered = GLOBAL_DEF("display/window/per_pixel_transparency/allowed", false);
video_mode.layered = GLOBAL_DEF("display/window/per_pixel_transparency/enabled", false);
@@ -1357,7 +1334,22 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
{
window_orientation = DisplayServer::ScreenOrientation(int(GLOBAL_DEF_BASIC("display/window/handheld/orientation", DisplayServer::ScreenOrientation::SCREEN_LANDSCAPE)));
}
-
+ {
+ String vsync_mode = GLOBAL_DEF("display/window/vsync/vsync_mode", "Enabled");
+
+ if (vsync_mode == "Disabled") {
+ window_vsync_mode = DisplayServer::VSYNC_DISABLED;
+ } else if (vsync_mode == "Enabled") {
+ window_vsync_mode = DisplayServer::VSYNC_ENABLED;
+ } else if (vsync_mode == "Adaptive") {
+ window_vsync_mode = DisplayServer::VSYNC_ADAPTIVE;
+ } else if (vsync_mode == "Mailbox") {
+ window_vsync_mode = DisplayServer::VSYNC_MAILBOX;
+ } else {
+ WARN_PRINT("VSync mode unknown.");
+ window_vsync_mode = DisplayServer::VSYNC_ENABLED;
+ }
+ }
Engine::get_singleton()->set_iterations_per_second(GLOBAL_DEF_BASIC("physics/common/physics_fps", 60));
ProjectSettings::get_singleton()->set_custom_property_info("physics/common/physics_fps",
PropertyInfo(Variant::INT, "physics/common/physics_fps",
@@ -1550,14 +1542,14 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
String rendering_driver; // temp broken
Error err;
- display_server = DisplayServer::create(display_driver_idx, rendering_driver, window_mode, window_flags, window_size, err);
+ display_server = DisplayServer::create(display_driver_idx, rendering_driver, window_mode, window_vsync_mode, window_flags, window_size, err);
if (err != OK || display_server == nullptr) {
//ok i guess we can't use this display server, try other ones
for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
if (i == display_driver_idx) {
continue; //don't try the same twice
}
- display_server = DisplayServer::create(i, rendering_driver, window_mode, window_flags, window_size, err);
+ display_server = DisplayServer::create(i, rendering_driver, window_mode, window_vsync_mode, window_flags, window_size, err);
if (err == OK && display_server != nullptr) {
break;
}
diff --git a/misc/dist/linux/godot.6 b/misc/dist/linux/godot.6
index 4140094813..3e5bdefdce 100644
--- a/misc/dist/linux/godot.6
+++ b/misc/dist/linux/godot.6
@@ -85,12 +85,6 @@ Force low\-DPI mode (macOS and Windows only).
.TP
\fB\-\-no\-window\fR
Disable window creation (Windows only). Useful together with \fB\-\-script\fR.
-.TP
-\fB\-\-enable\-vsync\-via\-compositor\fR
-When vsync is enabled, vsync via the OS' window compositor (Windows only).
-.TP
-\fB\-\-disable\-vsync\-via\-compositor\fR
-Disable vsync via the OS' window compositor (Windows only).
.SS "Debug options:"
.TP
\fB\-d\fR, \fB\-\-debug\fR
diff --git a/misc/dist/shell/_godot.zsh-completion b/misc/dist/shell/_godot.zsh-completion
index 8e14240b53..b29746bfc4 100644
--- a/misc/dist/shell/_godot.zsh-completion
+++ b/misc/dist/shell/_godot.zsh-completion
@@ -51,8 +51,6 @@ _arguments \
'--position[request window position]:position in X,Y format' \
'--low-dpi[force low-DPI mode (macOS and Windows only)]' \
'--no-window[disable window creation (Windows only), useful together with --script]' \
- "--enable-vsync-via-compositor[when Vsync is enabled, Vsync via the OS' window compositor (Windows only)]" \
- "--disable-vsync-via-compositor[disable Vsync via the OS' window compositor (Windows only)]" \
'(-d --debug)'{-d,--debug}'[debug (local stdout debugger)]' \
'(-b --breakpoints)'{-b,--breakpoints}'[specify the breakpoint list as source::line comma-separated pairs, no spaces (use %20 instead)]:breakpoint list' \
'--profiling[enable profiling in the script debugger]' \
diff --git a/misc/dist/shell/godot.bash-completion b/misc/dist/shell/godot.bash-completion
index 14f2be37b1..03861e43f8 100644
--- a/misc/dist/shell/godot.bash-completion
+++ b/misc/dist/shell/godot.bash-completion
@@ -54,8 +54,6 @@ _complete_godot_options() {
--position
--low-dpi
--no-window
---enable-vsync-via-compositor
---disable-vsync-via-compositor
--debug
--breakpoints
--profiling
diff --git a/misc/dist/shell/godot.fish b/misc/dist/shell/godot.fish
index a485a1dcdb..1367665bbc 100644
--- a/misc/dist/shell/godot.fish
+++ b/misc/dist/shell/godot.fish
@@ -61,8 +61,6 @@ complete -c godot -l resolution -d "Request window resolution" -x
complete -c godot -l position -d "Request window position" -x
complete -c godot -l low-dpi -d "Force low-DPI mode (macOS and Windows only)"
complete -c godot -l no-window -d "Disable window creation (Windows only), useful together with --script"
-complete -c godot -l enable-vsync-via-compositor -d "When Vsync is enabled, Vsync via the OS' window compositor (Windows only)"
-complete -c godot -l disable-vsync-via-compositor -d "Disable Vsync via the OS' window compositor (Windows only)"
# Debug options:
complete -c godot -s d -l debug -d "Debug (local stdout debugger)"
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index 66a2013c4e..1fcc3d4a5c 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -358,8 +358,8 @@ Vector<String> DisplayServerAndroid::get_rendering_drivers_func() {
return drivers;
}
-DisplayServer *DisplayServerAndroid::create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
- DisplayServer *ds = memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_flags, p_resolution, r_error));
+DisplayServer *DisplayServerAndroid::create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
if (r_error != OK) {
ds->alert("Your video card driver does not support any of the supported Vulkan versions.", "Unable to initialize Video driver");
}
@@ -377,10 +377,11 @@ void DisplayServerAndroid::reset_window() {
ERR_FAIL_COND(!native_window);
ERR_FAIL_COND(!context_vulkan);
+ VSyncMode last_vsync_mode = context_vulkan->get_vsync_mode(MAIN_WINDOW_ID);
context_vulkan->window_destroy(MAIN_WINDOW_ID);
Size2i display_size = OS_Android::get_singleton()->get_display_size();
- if (context_vulkan->window_create(native_window, display_size.width, display_size.height) == -1) {
+ if (context_vulkan->window_create(native_window, last_vsync_mode, display_size.width, display_size.height) == -1) {
memdelete(context_vulkan);
context_vulkan = nullptr;
ERR_FAIL_MSG("Failed to reset Vulkan window.");
@@ -402,7 +403,7 @@ void DisplayServerAndroid::notify_surface_changed(int p_width, int p_height) {
rect_changed_callback.call(reinterpret_cast<const Variant **>(&sizep), 1, ret, ce);
}
-DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
rendering_driver = p_rendering_driver;
// TODO: rendering_driver is broken, change when different drivers are supported again
@@ -446,7 +447,7 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis
}
Size2i display_size = OS_Android::get_singleton()->get_display_size();
- if (context_vulkan->window_create(native_window, display_size.width, display_size.height) == -1) {
+ if (context_vulkan->window_create(native_window, p_vsync_mode, display_size.width, display_size.height) == -1) {
memdelete(context_vulkan);
context_vulkan = nullptr;
ERR_FAIL_MSG("Failed to create Vulkan window.");
@@ -901,3 +902,17 @@ void DisplayServerAndroid::cursor_set_shape(DisplayServer::CursorShape p_shape)
DisplayServer::CursorShape DisplayServerAndroid::cursor_get_shape() const {
return cursor_shape;
}
+
+void DisplayServerAndroid::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
+#if defined(VULKAN_ENABLED)
+ context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
+#endif
+}
+
+DisplayServer::VSyncMode DisplayServerAndroid::window_get_vsync_mode(WindowID p_window) const {
+#if defined(VULKAN_ENABLED)
+ return context_vulkan->get_vsync_mode(p_window);
+#else
+ return DisplayServer::VSYNC_ENABLED;
+#endif
+}
diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h
index 8c626d28d5..bd5bed31cd 100644
--- a/platform/android/display_server_android.h
+++ b/platform/android/display_server_android.h
@@ -188,6 +188,8 @@ public:
virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID);
virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const;
virtual bool can_any_window_draw() const;
+ virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID);
+ virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const;
virtual void alert(const String &p_alert, const String &p_title);
@@ -211,7 +213,7 @@ public:
void mouse_set_mode(MouseMode p_mode);
MouseMode mouse_get_mode() const;
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
static Vector<String> get_rendering_drivers_func();
static void register_android_driver();
@@ -221,7 +223,7 @@ public:
virtual Point2i mouse_get_position() const;
virtual MouseButton mouse_get_button_state() const;
- DisplayServerAndroid(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerAndroid(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
~DisplayServerAndroid();
};
diff --git a/platform/android/vulkan/vulkan_context_android.cpp b/platform/android/vulkan/vulkan_context_android.cpp
index 63f2026fae..a031f3beee 100644
--- a/platform/android/vulkan/vulkan_context_android.cpp
+++ b/platform/android/vulkan/vulkan_context_android.cpp
@@ -36,7 +36,7 @@ const char *VulkanContextAndroid::_get_platform_surface_extension() const {
return VK_KHR_ANDROID_SURFACE_EXTENSION_NAME;
}
-int VulkanContextAndroid::window_create(ANativeWindow *p_window, int p_width, int p_height) {
+int VulkanContextAndroid::window_create(ANativeWindow *p_window, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height) {
VkAndroidSurfaceCreateInfoKHR createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = nullptr;
@@ -49,7 +49,7 @@ int VulkanContextAndroid::window_create(ANativeWindow *p_window, int p_width, in
ERR_FAIL_V_MSG(-1, "vkCreateAndroidSurfaceKHR failed with error " + itos(err));
}
- return _window_create(DisplayServer::MAIN_WINDOW_ID, surface, p_width, p_height);
+ return _window_create(DisplayServer::MAIN_WINDOW_ID, p_vsync_mode, surface, p_width, p_height);
}
bool VulkanContextAndroid::_use_validation_layers() {
diff --git a/platform/android/vulkan/vulkan_context_android.h b/platform/android/vulkan/vulkan_context_android.h
index 5a84eaf8f3..182ce33c97 100644
--- a/platform/android/vulkan/vulkan_context_android.h
+++ b/platform/android/vulkan/vulkan_context_android.h
@@ -39,7 +39,7 @@ class VulkanContextAndroid : public VulkanContext {
virtual const char *_get_platform_surface_extension() const override;
public:
- int window_create(ANativeWindow *p_window, int p_width, int p_height);
+ int window_create(ANativeWindow *p_window, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height);
VulkanContextAndroid() = default;
~VulkanContextAndroid() override = default;
diff --git a/platform/iphone/display_server_iphone.h b/platform/iphone/display_server_iphone.h
index 34c56382a4..6f64130b23 100644
--- a/platform/iphone/display_server_iphone.h
+++ b/platform/iphone/display_server_iphone.h
@@ -67,7 +67,7 @@ class DisplayServerIPhone : public DisplayServer {
void perform_event(const Ref<InputEvent> &p_event);
- DisplayServerIPhone(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerIPhone(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
~DisplayServerIPhone();
public:
@@ -76,7 +76,7 @@ public:
static DisplayServerIPhone *get_singleton();
static void register_iphone_driver();
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
static Vector<String> get_rendering_drivers_func();
// MARK: - Events
@@ -176,6 +176,9 @@ public:
virtual bool can_any_window_draw() const override;
+ virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;
+
virtual bool screen_is_touchscreen(int p_screen) const override;
virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_length, int p_cursor_start, int p_cursor_end) override;
diff --git a/platform/iphone/display_server_iphone.mm b/platform/iphone/display_server_iphone.mm
index 74d7419715..bd95e2c703 100644
--- a/platform/iphone/display_server_iphone.mm
+++ b/platform/iphone/display_server_iphone.mm
@@ -48,7 +48,7 @@ DisplayServerIPhone *DisplayServerIPhone::get_singleton() {
return (DisplayServerIPhone *)DisplayServer::get_singleton();
}
-DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
rendering_driver = p_rendering_driver;
#if defined(OPENGL_ENABLED)
@@ -108,7 +108,7 @@ DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, Displ
}
Size2i size = Size2i(layer.bounds.size.width, layer.bounds.size.height) * screen_get_max_scale();
- if (context_vulkan->window_create(MAIN_WINDOW_ID, layer, size.width, size.height) != OK) {
+ if (context_vulkan->window_create(MAIN_WINDOW_ID, p_vsync_mode, layer, size.width, size.height) != OK) {
memdelete(context_vulkan);
context_vulkan = nullptr;
ERR_FAIL_MSG("Failed to create Vulkan window.");
@@ -147,8 +147,8 @@ DisplayServerIPhone::~DisplayServerIPhone() {
#endif
}
-DisplayServer *DisplayServerIPhone::create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
- return memnew(DisplayServerIPhone(p_rendering_driver, p_mode, p_flags, p_resolution, r_error));
+DisplayServer *DisplayServerIPhone::create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ return memnew(DisplayServerIPhone(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
}
Vector<String> DisplayServerIPhone::get_rendering_drivers_func() {
@@ -581,3 +581,19 @@ void DisplayServerIPhone::resize_window(CGSize viewSize) {
Variant resize_rect = Rect2i(Point2i(), size);
_window_callback(window_resize_callback, resize_rect);
}
+
+void DisplayServerIPhone::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
+ _THREAD_SAFE_METHOD_
+#if defined(VULKAN_ENABLED)
+ context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
+#endif
+}
+
+DisplayServer::VSyncMode DisplayServerIPhone::window_get_vsync_mode(WindowID p_window) const {
+ _THREAD_SAFE_METHOD_
+#if defined(VULKAN_ENABLED)
+ return context_vulkan->get_vsync_mode(p_window);
+#else
+ return DisplayServer::VSYNC_ENABLED;
+#endif
+}
diff --git a/platform/iphone/vulkan_context_iphone.h b/platform/iphone/vulkan_context_iphone.h
index 88764e270e..ec6aaf46e8 100644
--- a/platform/iphone/vulkan_context_iphone.h
+++ b/platform/iphone/vulkan_context_iphone.h
@@ -39,7 +39,7 @@ class VulkanContextIPhone : public VulkanContext {
virtual const char *_get_platform_surface_extension() const;
public:
- Error window_create(DisplayServer::WindowID p_window_id, CALayer *p_metal_layer, int p_width, int p_height);
+ Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, CALayer *p_metal_layer, int p_width, int p_height);
VulkanContextIPhone();
~VulkanContextIPhone();
diff --git a/platform/iphone/vulkan_context_iphone.mm b/platform/iphone/vulkan_context_iphone.mm
index 08c9007fbb..17f2b167b3 100644
--- a/platform/iphone/vulkan_context_iphone.mm
+++ b/platform/iphone/vulkan_context_iphone.mm
@@ -35,7 +35,7 @@ const char *VulkanContextIPhone::_get_platform_surface_extension() const {
return VK_MVK_IOS_SURFACE_EXTENSION_NAME;
}
-Error VulkanContextIPhone::window_create(DisplayServer::WindowID p_window_id, CALayer *p_metal_layer, int p_width, int p_height) {
+Error VulkanContextIPhone::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, CALayer *p_metal_layer, int p_width, int p_height) {
VkIOSSurfaceCreateInfoMVK createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
createInfo.pNext = nullptr;
@@ -47,7 +47,7 @@ Error VulkanContextIPhone::window_create(DisplayServer::WindowID p_window_id, CA
vkCreateIOSSurfaceMVK(_get_instance(), &createInfo, nullptr, &surface);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
- return _window_create(p_window_id, surface, p_width, p_height);
+ return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height);
}
VulkanContextIPhone::VulkanContextIPhone() {}
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index fd652c0af2..8f0742041c 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -855,10 +855,10 @@ Vector<DisplayServer::WindowID> DisplayServerX11::get_window_list() const {
return ret;
}
-DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) {
+DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
_THREAD_SAFE_METHOD_
- WindowID id = _create_window(p_mode, p_flags, p_rect);
+ WindowID id = _create_window(p_mode, p_vsync_mode, p_flags, p_rect);
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
window_set_flag(WindowFlags(i), true, id);
@@ -3641,6 +3641,22 @@ void DisplayServerX11::set_icon(const Ref<Image> &p_icon) {
XSetErrorHandler(oldHandler);
}
+void DisplayServerX11::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
+ _THREAD_SAFE_METHOD_
+#if defined(VULKAN_ENABLED)
+ context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
+#endif
+}
+
+DisplayServer::VSyncMode DisplayServerX11::window_get_vsync_mode(WindowID p_window) const {
+ _THREAD_SAFE_METHOD_
+#if defined(VULKAN_ENABLED)
+ return context_vulkan->get_vsync_mode(p_window);
+#else
+ return DisplayServer::VSYNC_ENABLED;
+#endif
+}
+
Vector<String> DisplayServerX11::get_rendering_drivers_func() {
Vector<String> drivers;
@@ -3654,8 +3670,8 @@ Vector<String> DisplayServerX11::get_rendering_drivers_func() {
return drivers;
}
-DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
- DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_flags, p_resolution, r_error));
+DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
if (r_error != OK) {
ds->alert("Your video card driver does not support any of the supported Vulkan versions.\n"
"Please update your drivers or if you have a very old or integrated GPU upgrade it.",
@@ -3664,7 +3680,7 @@ DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, W
return ds;
}
-DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) {
+DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
//Create window
long visualMask = VisualScreenMask;
@@ -3828,7 +3844,7 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, u
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
- Error err = context_vulkan->window_create(id, wd.x11_window, x11_display, p_rect.size.width, p_rect.size.height);
+ Error err = context_vulkan->window_create(id, p_vsync_mode, wd.x11_window, x11_display, p_rect.size.width, p_rect.size.height);
ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create a Vulkan window");
}
#endif
@@ -3865,7 +3881,7 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, u
return id;
}
-DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
r_error = OK;
@@ -4101,7 +4117,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
Point2i window_position(
(screen_get_size(0).width - p_resolution.width) / 2,
(screen_get_size(0).height - p_resolution.height) / 2);
- WindowID main_window = _create_window(p_mode, p_flags, Rect2i(window_position, p_resolution));
+ WindowID main_window = _create_window(p_mode, p_vsync_mode, p_flags, Rect2i(window_position, p_resolution));
if (main_window == INVALID_WINDOW_ID) {
r_error = ERR_CANT_CREATE;
return;
diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h
index 707775a1da..c5cf5ee4cb 100644
--- a/platform/linuxbsd/display_server_x11.h
+++ b/platform/linuxbsd/display_server_x11.h
@@ -152,7 +152,7 @@ class DisplayServerX11 : public DisplayServer {
Map<WindowID, WindowData> windows;
WindowID window_id_counter = MAIN_WINDOW_ID;
- WindowID _create_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect);
+ WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect);
String internal_clipboard;
Window xdnd_source_window;
@@ -307,7 +307,7 @@ public:
virtual Vector<DisplayServer::WindowID> get_window_list() const;
- virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
+ virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
virtual void show_window(WindowID p_id);
virtual void delete_sub_window(WindowID p_id);
@@ -362,6 +362,9 @@ public:
virtual void window_set_ime_active(const bool p_active, WindowID p_window = MAIN_WINDOW_ID);
virtual void window_set_ime_position(const Point2i &p_pos, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;
+
virtual void cursor_set_shape(CursorShape p_shape);
virtual CursorShape cursor_get_shape() const;
virtual void cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
@@ -383,12 +386,12 @@ public:
virtual void set_native_icon(const String &p_filename);
virtual void set_icon(const Ref<Image> &p_icon);
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
static Vector<String> get_rendering_drivers_func();
static void register_x11_driver();
- DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
~DisplayServerX11();
};
diff --git a/platform/linuxbsd/vulkan_context_x11.cpp b/platform/linuxbsd/vulkan_context_x11.cpp
index 021db630e0..88cb00a8a1 100644
--- a/platform/linuxbsd/vulkan_context_x11.cpp
+++ b/platform/linuxbsd/vulkan_context_x11.cpp
@@ -35,7 +35,7 @@ const char *VulkanContextX11::_get_platform_surface_extension() const {
return VK_KHR_XLIB_SURFACE_EXTENSION_NAME;
}
-Error VulkanContextX11::window_create(DisplayServer::WindowID p_window_id, ::Window p_window, Display *p_display, int p_width, int p_height) {
+Error VulkanContextX11::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, ::Window p_window, Display *p_display, int p_width, int p_height) {
VkXlibSurfaceCreateInfoKHR createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = nullptr;
@@ -46,7 +46,7 @@ Error VulkanContextX11::window_create(DisplayServer::WindowID p_window_id, ::Win
VkSurfaceKHR surface;
VkResult err = vkCreateXlibSurfaceKHR(_get_instance(), &createInfo, nullptr, &surface);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
- return _window_create(p_window_id, surface, p_width, p_height);
+ return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height);
}
VulkanContextX11::VulkanContextX11() {
diff --git a/platform/linuxbsd/vulkan_context_x11.h b/platform/linuxbsd/vulkan_context_x11.h
index 26472444ad..de4a9c7b90 100644
--- a/platform/linuxbsd/vulkan_context_x11.h
+++ b/platform/linuxbsd/vulkan_context_x11.h
@@ -38,7 +38,7 @@ class VulkanContextX11 : public VulkanContext {
virtual const char *_get_platform_surface_extension() const;
public:
- Error window_create(DisplayServer::WindowID p_window_id, ::Window p_window, Display *p_display, int p_width, int p_height);
+ Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, ::Window p_window, Display *p_display, int p_width, int p_height);
VulkanContextX11();
~VulkanContextX11();
diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h
index 5f7f5f84a2..c7b9e411b8 100644
--- a/platform/osx/display_server_osx.h
+++ b/platform/osx/display_server_osx.h
@@ -145,7 +145,7 @@ public:
WindowID window_id_counter = MAIN_WINDOW_ID;
- WindowID _create_window(WindowMode p_mode, const Rect2i &p_rect);
+ WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect);
void _update_window(WindowData p_wd);
void _send_window_event(const WindowData &wd, WindowEvent p_event);
static void _dispatch_input_events(const Ref<InputEvent> &p_event);
@@ -232,7 +232,7 @@ public:
virtual Vector<int> get_window_list() const override;
- virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override;
+ virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override;
virtual void show_window(WindowID p_id) override;
virtual void delete_sub_window(WindowID p_id) override;
@@ -286,6 +286,9 @@ public:
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override;
+ virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;
+
virtual Point2i ime_get_selection() const override;
virtual String ime_get_text() const override;
@@ -314,12 +317,12 @@ public:
virtual void console_set_visible(bool p_enabled) override;
virtual bool is_console_visible() const override;
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
static Vector<String> get_rendering_drivers_func();
static void register_osx_driver();
- DisplayServerOSX(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerOSX(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
~DisplayServerOSX();
};
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index 4a672a4b17..dec6da42fe 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -2388,10 +2388,10 @@ Vector<DisplayServer::WindowID> DisplayServerOSX::get_window_list() const {
return ret;
}
-DisplayServer::WindowID DisplayServerOSX::create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) {
+DisplayServer::WindowID DisplayServerOSX::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
_THREAD_SAFE_METHOD_
- WindowID id = _create_window(p_mode, p_rect);
+ WindowID id = _create_window(p_mode, p_vsync_mode, p_rect);
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
window_set_flag(WindowFlags(i), true, id);
@@ -3546,6 +3546,22 @@ void DisplayServerOSX::set_icon(const Ref<Image> &p_icon) {
[nsimg release];
}
+void DisplayServerOSX::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
+ _THREAD_SAFE_METHOD_
+#if defined(VULKAN_ENABLED)
+ context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
+#endif
+}
+
+DisplayServer::VSyncMode DisplayServerOSX::window_get_vsync_mode(WindowID p_window) const {
+ _THREAD_SAFE_METHOD_
+#if defined(VULKAN_ENABLED)
+ return context_vulkan->get_vsync_mode(p_window);
+#else
+ return DisplayServer::VSYNC_ENABLED;
+#endif
+}
+
Vector<String> DisplayServerOSX::get_rendering_drivers_func() {
Vector<String> drivers;
@@ -3596,15 +3612,15 @@ ObjectID DisplayServerOSX::window_get_attached_instance_id(WindowID p_window) co
return windows[p_window].instance_id;
}
-DisplayServer *DisplayServerOSX::create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
- DisplayServer *ds = memnew(DisplayServerOSX(p_rendering_driver, p_mode, p_flags, p_resolution, r_error));
+DisplayServer *DisplayServerOSX::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerOSX(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
if (r_error != OK) {
ds->alert("Your video card driver does not support any of the supported Metal versions.", "Unable to initialize Video driver");
}
return ds;
}
-DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, const Rect2i &p_rect) {
+DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect) {
WindowID id;
const float scale = screen_get_max_scale();
{
@@ -3651,7 +3667,7 @@ DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, c
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
if (context_vulkan) {
- Error err = context_vulkan->window_create(window_id_counter, wd.window_view, p_rect.size.width, p_rect.size.height);
+ Error err = context_vulkan->window_create(window_id_counter, p_vsync_mode, wd.window_view, p_rect.size.width, p_rect.size.height);
ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create a Vulkan context");
}
}
@@ -3750,7 +3766,7 @@ bool DisplayServerOSX::is_console_visible() const {
return isatty(STDIN_FILENO);
}
-DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
r_error = OK;
@@ -3886,7 +3902,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
Point2i window_position(
screen_get_position(0).x + (screen_get_size(0).width - p_resolution.width) / 2,
screen_get_position(0).y + (screen_get_size(0).height - p_resolution.height) / 2);
- WindowID main_window = _create_window(p_mode, Rect2i(window_position, p_resolution));
+ WindowID main_window = _create_window(p_mode, p_vsync_mode, Rect2i(window_position, p_resolution));
ERR_FAIL_COND(main_window == INVALID_WINDOW_ID);
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
diff --git a/platform/osx/vulkan_context_osx.h b/platform/osx/vulkan_context_osx.h
index 8b6a75adfb..22d43688a3 100644
--- a/platform/osx/vulkan_context_osx.h
+++ b/platform/osx/vulkan_context_osx.h
@@ -38,7 +38,7 @@ class VulkanContextOSX : public VulkanContext {
virtual const char *_get_platform_surface_extension() const;
public:
- Error window_create(DisplayServer::WindowID p_window_id, id p_window, int p_width, int p_height);
+ Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, id p_window, int p_width, int p_height);
VulkanContextOSX();
~VulkanContextOSX();
diff --git a/platform/osx/vulkan_context_osx.mm b/platform/osx/vulkan_context_osx.mm
index 6b87fbd489..7e18e177c1 100644
--- a/platform/osx/vulkan_context_osx.mm
+++ b/platform/osx/vulkan_context_osx.mm
@@ -35,7 +35,7 @@ const char *VulkanContextOSX::_get_platform_surface_extension() const {
return VK_MVK_MACOS_SURFACE_EXTENSION_NAME;
}
-Error VulkanContextOSX::window_create(DisplayServer::WindowID p_window_id, id p_window, int p_width, int p_height) {
+Error VulkanContextOSX::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, id p_window, int p_width, int p_height) {
VkMacOSSurfaceCreateInfoMVK createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
createInfo.pNext = nullptr;
@@ -45,7 +45,7 @@ Error VulkanContextOSX::window_create(DisplayServer::WindowID p_window_id, id p_
VkSurfaceKHR surface;
VkResult err = vkCreateMacOSSurfaceMVK(_get_instance(), &createInfo, nullptr, &surface);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
- return _window_create(p_window_id, surface, p_width, p_height);
+ return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height);
}
VulkanContextOSX::VulkanContextOSX() {
diff --git a/platform/windows/context_gl_windows.cpp b/platform/windows/context_gl_windows.cpp
index 7cf9738f13..74b12cbb3b 100644
--- a/platform/windows/context_gl_windows.cpp
+++ b/platform/windows/context_gl_windows.cpp
@@ -66,46 +66,13 @@ int ContextGL_Windows::get_window_height() {
return OS::get_singleton()->get_video_mode().height;
}
-bool ContextGL_Windows::should_vsync_via_compositor() {
- if (OS::get_singleton()->is_window_fullscreen() || !OS::get_singleton()->is_vsync_via_compositor_enabled()) {
- return false;
- }
-
- // Note: All Windows versions supported by Godot have a compositor.
- // It can be disabled on earlier Windows versions.
- BOOL dwm_enabled;
-
- if (SUCCEEDED(DwmIsCompositionEnabled(&dwm_enabled))) {
- return dwm_enabled;
- }
-
- return false;
-}
-
void ContextGL_Windows::swap_buffers() {
SwapBuffers(hDC);
-
- if (use_vsync) {
- bool vsync_via_compositor_now = should_vsync_via_compositor();
-
- if (vsync_via_compositor_now && wglGetSwapIntervalEXT() == 0) {
- DwmFlush();
- }
-
- if (vsync_via_compositor_now != vsync_via_compositor) {
- // The previous frame had a different operating mode than this
- // frame. Set the 'vsync_via_compositor' member variable and the
- // OpenGL swap interval to their proper values.
- set_use_vsync(true);
- }
- }
}
void ContextGL_Windows::set_use_vsync(bool p_use) {
- vsync_via_compositor = p_use && should_vsync_via_compositor();
-
if (wglSwapIntervalEXT) {
- int swap_interval = (p_use && !vsync_via_compositor) ? 1 : 0;
+ int swap_interval = p_use ? 1 : 0;
wglSwapIntervalEXT(swap_interval);
}
@@ -210,7 +177,6 @@ ContextGL_Windows::ContextGL_Windows(HWND hwnd, bool p_opengl_3_context) {
opengl_3_context = p_opengl_3_context;
hWnd = hwnd;
use_vsync = false;
- vsync_via_compositor = false;
pixel_format = 0;
}
diff --git a/platform/windows/context_gl_windows.h b/platform/windows/context_gl_windows.h
index e44e2945ca..c8e8a0891d 100644
--- a/platform/windows/context_gl_windows.h
+++ b/platform/windows/context_gl_windows.h
@@ -50,13 +50,10 @@ class ContextGL_Windows {
HWND hWnd;
bool opengl_3_context;
bool use_vsync;
- bool vsync_via_compositor;
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT;
- static bool should_vsync_via_compositor();
-
public:
void release_current();
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index f7172598ec..4f64809abc 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -477,10 +477,10 @@ DisplayServer::WindowID DisplayServerWindows::get_window_at_screen_position(cons
return INVALID_WINDOW_ID;
}
-DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) {
+DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
_THREAD_SAFE_METHOD_
- WindowID window_id = _create_window(p_mode, p_flags, p_rect);
+ WindowID window_id = _create_window(p_mode, p_vsync_mode, p_flags, p_rect);
ERR_FAIL_COND_V_MSG(window_id == INVALID_WINDOW_ID, INVALID_WINDOW_ID, "Failed to create sub window.");
WindowData &wd = windows[window_id];
@@ -1697,11 +1697,20 @@ void DisplayServerWindows::set_icon(const Ref<Image> &p_icon) {
SendMessage(windows[MAIN_WINDOW_ID].hWnd, WM_SETICON, ICON_BIG, (LPARAM)hicon);
}
-void DisplayServerWindows::vsync_set_use_via_compositor(bool p_enable) {
+void DisplayServerWindows::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
+ _THREAD_SAFE_METHOD_
+#if defined(VULKAN_ENABLED)
+ context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
+#endif
}
-bool DisplayServerWindows::vsync_is_using_via_compositor() const {
- return false;
+DisplayServer::VSyncMode DisplayServerWindows::window_get_vsync_mode(WindowID p_window) const {
+ _THREAD_SAFE_METHOD_
+#if defined(VULKAN_ENABLED)
+ return context_vulkan->get_vsync_mode(p_window);
+#else
+ return DisplayServer::VSYNC_ENABLED;
+#endif
}
void DisplayServerWindows::set_context(Context p_context) {
@@ -2968,7 +2977,7 @@ void DisplayServerWindows::_update_tablet_ctx(const String &p_old_driver, const
}
}
-DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) {
+DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
DWORD dwExStyle;
DWORD dwStyle;
@@ -3030,7 +3039,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
#ifdef VULKAN_ENABLED
if (rendering_driver == "vulkan") {
- if (context_vulkan->window_create(id, wd.hWnd, hInstance, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top) == -1) {
+ if (context_vulkan->window_create(id, p_vsync_mode, wd.hWnd, hInstance, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top) == -1) {
memdelete(context_vulkan);
context_vulkan = nullptr;
windows.erase(id);
@@ -3151,7 +3160,7 @@ void DisplayServerWindows::tablet_set_current_driver(const String &p_driver) {
}
}
-DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
drop_events = false;
key_event_pos = 0;
@@ -3270,7 +3279,6 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
}
context_gles2->set_use_vsync(video_mode.use_vsync);
- set_vsync_via_compositor(video_mode.vsync_via_compositor);
if (RasterizerGLES2::is_viable() == OK) {
RasterizerGLES2::register_config();
@@ -3286,7 +3294,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
(screen_get_size(0).width - p_resolution.width) / 2,
(screen_get_size(0).height - p_resolution.height) / 2);
- WindowID main_window = _create_window(p_mode, 0, Rect2i(window_position, p_resolution));
+ WindowID main_window = _create_window(p_mode, p_vsync_mode, 0, Rect2i(window_position, p_resolution));
ERR_FAIL_COND_MSG(main_window == INVALID_WINDOW_ID, "Failed to create main window.");
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
@@ -3347,8 +3355,8 @@ Vector<String> DisplayServerWindows::get_rendering_drivers_func() {
return drivers;
}
-DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
- DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_flags, p_resolution, r_error));
+DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
if (r_error != OK) {
ds->alert("Your video card driver does not support any of the supported Vulkan versions.\n"
"Please update your drivers or if you have a very old or integrated GPU upgrade it.",
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index d71e579c67..394bed79b0 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -389,7 +389,7 @@ class DisplayServerWindows : public DisplayServer {
JoypadWindows *joypad;
- WindowID _create_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect);
+ WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect);
WindowID window_id_counter = MAIN_WINDOW_ID;
Map<WindowID, WindowData> windows;
@@ -469,7 +469,7 @@ public:
virtual Vector<DisplayServer::WindowID> get_window_list() const;
- virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
+ virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
virtual void show_window(WindowID p_window);
virtual void delete_sub_window(WindowID p_window);
@@ -525,6 +525,9 @@ public:
virtual void window_set_ime_active(const bool p_active, WindowID p_window = MAIN_WINDOW_ID);
virtual void window_set_ime_position(const Point2i &p_pos, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;
+
virtual void console_set_visible(bool p_enabled);
virtual bool is_console_visible() const;
@@ -558,16 +561,13 @@ public:
virtual void set_native_icon(const String &p_filename);
virtual void set_icon(const Ref<Image> &p_icon);
- virtual void vsync_set_use_via_compositor(bool p_enable);
- virtual bool vsync_is_using_via_compositor() const;
-
virtual void set_context(Context p_context);
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
static Vector<String> get_rendering_drivers_func();
static void register_windows_driver();
- DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
~DisplayServerWindows();
};
diff --git a/platform/windows/vulkan_context_win.cpp b/platform/windows/vulkan_context_win.cpp
index e5e176ab93..191792b329 100644
--- a/platform/windows/vulkan_context_win.cpp
+++ b/platform/windows/vulkan_context_win.cpp
@@ -35,18 +35,17 @@ const char *VulkanContextWindows::_get_platform_surface_extension() const {
return VK_KHR_WIN32_SURFACE_EXTENSION_NAME;
}
-int VulkanContextWindows::window_create(DisplayServer::WindowID p_window_id, HWND p_window, HINSTANCE p_instance, int p_width, int p_height) {
+int VulkanContextWindows::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, HWND p_window, HINSTANCE p_instance, int p_width, int p_height) {
VkWin32SurfaceCreateInfoKHR createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.hinstance = p_instance;
createInfo.hwnd = p_window;
-
VkSurfaceKHR surface;
VkResult err = vkCreateWin32SurfaceKHR(_get_instance(), &createInfo, nullptr, &surface);
ERR_FAIL_COND_V(err, -1);
- return _window_create(p_window_id, surface, p_width, p_height);
+ return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height);
}
VulkanContextWindows::VulkanContextWindows() {
diff --git a/platform/windows/vulkan_context_win.h b/platform/windows/vulkan_context_win.h
index 4fe987218d..39dd2641fd 100644
--- a/platform/windows/vulkan_context_win.h
+++ b/platform/windows/vulkan_context_win.h
@@ -38,7 +38,7 @@ class VulkanContextWindows : public VulkanContext {
virtual const char *_get_platform_surface_extension() const;
public:
- int window_create(DisplayServer::WindowID p_window_id, HWND p_window, HINSTANCE p_instance, int p_width, int p_height);
+ int window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, HWND p_window, HINSTANCE p_instance, int p_width, int p_height);
VulkanContextWindows();
~VulkanContextWindows();
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index cf2a6b2adf..9299f8d6be 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -227,7 +227,8 @@ void Window::_make_window() {
}
}
- window_id = DisplayServer::get_singleton()->create_sub_window(DisplayServer::WindowMode(mode), f, Rect2i(position, size));
+ DisplayServer::VSyncMode vsync_mode = DisplayServer::get_singleton()->window_get_vsync_mode(DisplayServer::MAIN_WINDOW_ID);
+ window_id = DisplayServer::get_singleton()->create_sub_window(DisplayServer::WindowMode(mode), vsync_mode, f, Rect2i(position, size));
ERR_FAIL_COND(window_id == DisplayServer::INVALID_WINDOW_ID);
DisplayServer::get_singleton()->window_set_current_screen(current_screen, window_id);
DisplayServer::get_singleton()->window_set_max_size(max_size, window_id);
diff --git a/servers/display_server.cpp b/servers/display_server.cpp
index d746117884..be2a813fd1 100644
--- a/servers/display_server.cpp
+++ b/servers/display_server.cpp
@@ -35,7 +35,6 @@
#include "servers/display_server_headless.h"
DisplayServer *DisplayServer::singleton = nullptr;
-DisplayServer::SwitchVSyncCallbackInThread DisplayServer::switch_vsync_function = nullptr;
bool DisplayServer::hidpi_allowed = false;
@@ -185,7 +184,7 @@ bool DisplayServer::screen_is_kept_on() const {
return false;
}
-DisplayServer::WindowID DisplayServer::create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) {
+DisplayServer::WindowID DisplayServer::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Sub-windows not supported by this display server.");
}
@@ -309,29 +308,13 @@ void DisplayServer::set_icon(const Ref<Image> &p_icon) {
WARN_PRINT("Icon not supported by this display server.");
}
-void DisplayServer::_set_use_vsync(bool p_enable) {
- WARN_PRINT("VSync not supported by this display server.");
+void DisplayServer::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
+ WARN_PRINT("Changing the VSync mode is not supported by this display server.");
}
-void DisplayServer::vsync_set_enabled(bool p_enable) {
- vsync_enabled = p_enable;
- if (switch_vsync_function) { //if a function was set, use function
- switch_vsync_function(p_enable);
- } else { //otherwise just call here
- _set_use_vsync(p_enable);
- }
-}
-
-bool DisplayServer::vsync_is_enabled() const {
- return vsync_enabled;
-}
-
-void DisplayServer::vsync_set_use_via_compositor(bool p_enable) {
- WARN_PRINT("VSync via compositor not supported by this display server.");
-}
-
-bool DisplayServer::vsync_is_using_via_compositor() const {
- return false;
+DisplayServer::VSyncMode DisplayServer::window_get_vsync_mode(WindowID p_window) const {
+ WARN_PRINT("Changing the VSync mode is not supported by this display server.");
+ return VSyncMode::VSYNC_ENABLED;
}
void DisplayServer::set_context(Context p_context) {
@@ -394,7 +377,7 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_window_list"), &DisplayServer::get_window_list);
ClassDB::bind_method(D_METHOD("get_window_at_screen_position", "position"), &DisplayServer::get_window_at_screen_position);
- ClassDB::bind_method(D_METHOD("create_sub_window", "mode", "flags", "rect"), &DisplayServer::create_sub_window, DEFVAL(Rect2i()));
+ ClassDB::bind_method(D_METHOD("create_sub_window", "mode", "vsync_mode", "flags", "rect"), &DisplayServer::create_sub_window, DEFVAL(Rect2i()));
ClassDB::bind_method(D_METHOD("delete_sub_window", "window_id"), &DisplayServer::delete_sub_window);
ClassDB::bind_method(D_METHOD("window_set_title", "title", "window_id"), &DisplayServer::window_set_title, DEFVAL(MAIN_WINDOW_ID));
@@ -441,6 +424,9 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("window_set_ime_active", "active", "window_id"), &DisplayServer::window_set_ime_active, DEFVAL(MAIN_WINDOW_ID));
ClassDB::bind_method(D_METHOD("window_set_ime_position", "position", "window_id"), &DisplayServer::window_set_ime_position, DEFVAL(MAIN_WINDOW_ID));
+ ClassDB::bind_method(D_METHOD("window_set_vsync_mode", "vsync_mode", "window_id"), &DisplayServer::window_set_vsync_mode, DEFVAL(MAIN_WINDOW_ID));
+ ClassDB::bind_method(D_METHOD("window_get_vsync_mode", "window_id"), &DisplayServer::window_get_vsync_mode, DEFVAL(MAIN_WINDOW_ID));
+
ClassDB::bind_method(D_METHOD("ime_get_selection"), &DisplayServer::ime_get_selection);
ClassDB::bind_method(D_METHOD("ime_get_text"), &DisplayServer::ime_get_text);
@@ -472,12 +458,6 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("process_events"), &DisplayServer::process_events);
ClassDB::bind_method(D_METHOD("force_process_and_drop_events"), &DisplayServer::force_process_and_drop_events);
- ClassDB::bind_method(D_METHOD("vsync_set_enabled", "enabled"), &DisplayServer::vsync_set_enabled);
- ClassDB::bind_method(D_METHOD("vsync_is_enabled"), &DisplayServer::vsync_is_enabled);
-
- ClassDB::bind_method(D_METHOD("vsync_set_use_via_compositor", "enabled"), &DisplayServer::vsync_set_use_via_compositor);
- ClassDB::bind_method(D_METHOD("vsync_is_using_via_compositor"), &DisplayServer::vsync_is_using_via_compositor);
-
ClassDB::bind_method(D_METHOD("set_native_icon", "filename"), &DisplayServer::set_native_icon);
ClassDB::bind_method(D_METHOD("set_icon", "image"), &DisplayServer::set_icon);
@@ -561,6 +541,11 @@ void DisplayServer::_bind_methods() {
BIND_ENUM_CONSTANT(WINDOW_EVENT_CLOSE_REQUEST);
BIND_ENUM_CONSTANT(WINDOW_EVENT_GO_BACK_REQUEST);
BIND_ENUM_CONSTANT(WINDOW_EVENT_DPI_CHANGE);
+
+ BIND_ENUM_CONSTANT(VSYNC_DISABLED);
+ BIND_ENUM_CONSTANT(VSYNC_ENABLED);
+ BIND_ENUM_CONSTANT(VSYNC_ADAPTIVE);
+ BIND_ENUM_CONSTANT(VSYNC_MAILBOX);
}
void DisplayServer::register_create_function(const char *p_name, CreateFunction p_function, GetRenderingDriversFunction p_get_drivers) {
@@ -587,9 +572,9 @@ Vector<String> DisplayServer::get_create_function_rendering_drivers(int p_index)
return server_create_functions[p_index].get_rendering_drivers_function();
}
-DisplayServer *DisplayServer::create(int p_index, const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+DisplayServer *DisplayServer::create(int p_index, const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
ERR_FAIL_INDEX_V(p_index, server_create_count, nullptr);
- return server_create_functions[p_index].create_function(p_rendering_driver, p_mode, p_flags, p_resolution, r_error);
+ return server_create_functions[p_index].create_function(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error);
}
void DisplayServer::_input_set_mouse_mode(Input::MouseMode p_mode) {
diff --git a/servers/display_server.h b/servers/display_server.h
index 7dab7b7481..caffdc941d 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -42,7 +42,6 @@ class DisplayServer : public Object {
GDCLASS(DisplayServer, Object)
static DisplayServer *singleton;
- bool vsync_enabled = true;
static bool hidpi_allowed;
public:
@@ -57,7 +56,14 @@ public:
WINDOW_MODE_FULLSCREEN
};
- typedef DisplayServer *(*CreateFunction)(const String &, WindowMode, uint32_t, const Size2i &, Error &r_error);
+ enum VSyncMode {
+ VSYNC_DISABLED,
+ VSYNC_ENABLED,
+ VSYNC_ADAPTIVE,
+ VSYNC_MAILBOX
+ };
+
+ typedef DisplayServer *(*CreateFunction)(const String &, WindowMode, VSyncMode, uint32_t, const Size2i &, Error &r_error);
typedef Vector<String> (*GetRenderingDriversFunction)();
private:
@@ -84,7 +90,6 @@ protected:
static int server_create_count;
friend class RendererViewport;
- virtual void _set_use_vsync(bool p_enable);
public:
enum Feature {
@@ -221,7 +226,7 @@ public:
WINDOW_FLAG_NO_FOCUS_BIT = (1 << WINDOW_FLAG_NO_FOCUS)
};
- virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
+ virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
virtual void show_window(WindowID p_id);
virtual void delete_sub_window(WindowID p_id);
@@ -272,6 +277,9 @@ public:
virtual void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID) = 0;
virtual WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const = 0;
+ virtual void window_set_vsync_mode(VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID);
+ virtual VSyncMode window_get_vsync_mode(WindowID p_window) const;
+
virtual bool window_is_maximize_allowed(WindowID p_window = MAIN_WINDOW_ID) const = 0;
virtual void window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window = MAIN_WINDOW_ID) = 0;
@@ -352,18 +360,6 @@ public:
virtual void set_native_icon(const String &p_filename);
virtual void set_icon(const Ref<Image> &p_icon);
- typedef void (*SwitchVSyncCallbackInThread)(bool);
-
- static SwitchVSyncCallbackInThread switch_vsync_function;
-
- void vsync_set_enabled(bool p_enable);
- bool vsync_is_enabled() const;
-
- virtual void vsync_set_use_via_compositor(bool p_enable);
- virtual bool vsync_is_using_via_compositor() const;
-
- //real, actual overridable function to switch vsync, which needs to be called from graphics thread if needed
-
enum Context {
CONTEXT_EDITOR,
CONTEXT_PROJECTMAN,
@@ -376,7 +372,7 @@ public:
static int get_create_function_count();
static const char *get_create_function_name(int p_index);
static Vector<String> get_create_function_rendering_drivers(int p_index);
- static DisplayServer *create(int p_index, const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create(int p_index, const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
DisplayServer();
~DisplayServer();
@@ -389,5 +385,6 @@ VARIANT_ENUM_CAST(DisplayServer::ScreenOrientation)
VARIANT_ENUM_CAST(DisplayServer::WindowMode)
VARIANT_ENUM_CAST(DisplayServer::WindowFlags)
VARIANT_ENUM_CAST(DisplayServer::CursorShape)
+VARIANT_ENUM_CAST(DisplayServer::VSyncMode)
#endif // DISPLAY_SERVER_H
diff --git a/servers/display_server_headless.h b/servers/display_server_headless.h
index 8b386c8d9c..870401b180 100644
--- a/servers/display_server_headless.h
+++ b/servers/display_server_headless.h
@@ -45,7 +45,7 @@ private:
return drivers;
}
- static DisplayServer *create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ static DisplayServer *create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
r_error = OK;
RasterizerDummy::make_current();
return memnew(DisplayServerHeadless());
diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index 46e340c0ac..f651fbfa75 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -1116,9 +1116,9 @@ void RendererViewport::set_default_clear_color(const Color &p_color) {
RSG::storage->set_default_clear_color(p_color);
}
-//workaround for setting this on thread
-void RendererViewport::call_set_use_vsync(bool p_enable) {
- DisplayServer::get_singleton()->_set_use_vsync(p_enable);
+// Workaround for setting this on thread.
+void RendererViewport::call_set_vsync_mode(DisplayServer::VSyncMode p_mode, DisplayServer::WindowID p_window) {
+ DisplayServer::get_singleton()->window_set_vsync_mode(p_mode, p_window);
}
int RendererViewport::get_total_objects_drawn() const {
diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h
index b449a9fa1a..ac7a35f97d 100644
--- a/servers/rendering/renderer_viewport.h
+++ b/servers/rendering/renderer_viewport.h
@@ -271,8 +271,8 @@ public:
int get_total_vertices_drawn() const;
int get_total_draw_calls_used() const;
- //workaround for setting this on thread
- void call_set_use_vsync(bool p_enable);
+ // Workaround for setting this on thread.
+ void call_set_vsync_mode(DisplayServer::VSyncMode p_mode, DisplayServer::WindowID p_window);
RendererViewport();
virtual ~RendererViewport() {}
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index 48c96cb02a..79665dcdd2 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -577,7 +577,7 @@ public:
FUNC1RC(float, viewport_get_measured_render_time_cpu, RID)
FUNC1RC(float, viewport_get_measured_render_time_gpu, RID)
- FUNC1(call_set_use_vsync, bool)
+ FUNC2(call_set_vsync_mode, DisplayServer::VSyncMode, DisplayServer::WindowID)
/* ENVIRONMENT API */
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index e260ff99a1..0d01d4a2bd 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -1454,7 +1454,7 @@ public:
virtual void set_debug_generate_wireframes(bool p_generate) = 0;
- virtual void call_set_use_vsync(bool p_enable) = 0;
+ virtual void call_set_vsync_mode(DisplayServer::VSyncMode p_mode, DisplayServer::WindowID p_window) = 0;
virtual bool is_low_end() const = 0;