Merge pull request #48622 from Geometror/reimplement-disableable-vsync
This commit is contained in:
commit
a2d5f191d8
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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=""Enabled"">
|
||||
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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]' \
|
||||
|
|
|
@ -54,8 +54,6 @@ _complete_godot_options() {
|
|||
--position
|
||||
--low-dpi
|
||||
--no-window
|
||||
--enable-vsync-via-compositor
|
||||
--disable-vsync-via-compositor
|
||||
--debug
|
||||
--breakpoints
|
||||
--profiling
|
||||
|
|
|
@ -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)"
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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.",
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue