1
0
Fork 0

Compare commits

...

20 Commits

Author SHA1 Message Date
Pāvels Nadtočajevs 189d18be58 Use list properties for display drivers. 2025-02-28 08:03:07 +02:00
Pāvels Nadtočajevs 9cc6e4a1be Add support for "ordered" list properties.
Add support for "ordered" list properties.
2025-02-28 08:00:32 +02:00
Rémi Verschelde 15ff450680
Merge pull request #103371 from m4gr3d/add_checks_for_game_menu_utils_jni
Add checks to prevent crashes when accessing the GameMenu api
2025-02-28 01:12:11 +01:00
Fredia Huya-Kouadio 7fb37a088b Add checks to prevent crashes when accessing the GameMenu api
This should address crashes reported on the Play store. Note that those crashes lack debug symbols which reduces our ability to narrow down the exact cause of the crash. We aim to resolve that in Godot 4.5.
2025-02-27 13:20:23 -08:00
Rémi Verschelde 33a15a12b1
Merge pull request #103370 from m4gr3d/inform_android_sensors_mobile_vr
Inform that Android sensors must be enabled for MobileVR support
2025-02-27 22:17:07 +01:00
Rémi Verschelde c01b9de703
Merge pull request #103364 from akien-mga/input-deadzone-ui-0.5
Input: Change default deadzone back to 0.5 for `ui_*` actions and axis `pressed` state
2025-02-27 22:17:01 +01:00
Fredia Huya-Kouadio 33a235beb8 Inform that Android sensors must be enabled for MobileVR support 2025-02-27 12:53:57 -08:00
Rémi Verschelde a9c5c4db71
Merge pull request #103201 from beicause/shaders-only-convert-source-color-linear
Shaders: Only convert default value to linear color if type hint is `source_color`
2025-02-27 19:34:12 +01:00
Rémi Verschelde 1af42620fa
Merge pull request #103362 from bruvzg/gds_get_set_bchk
Add bound checks to `Array`/`Packed*Array` variant call `get` and `set` methods.
2025-02-27 18:50:57 +01:00
Rémi Verschelde 672fe2487f
Input: Change default deadzone back to 0.5 for `ui_*` actions and axis `pressed` state
Fixes #103360.
Partial revert of changes in #97281 and #99135.
2025-02-27 17:30:48 +01:00
Pāvels Nadtočajevs f9c7d348c3 Add bound checks to `Array`/`Packed*Array` variant call `get` and `set` methods. 2025-02-27 17:54:40 +02:00
Rémi Verschelde 53faed5351
Merge pull request #103339 from Hilderin/adjustment-error-message-embedded-game
Replace error to info messages for embedded game
2025-02-27 12:40:39 +01:00
Rémi Verschelde dd43d401ec
Merge pull request #103338 from dsnopek/openxr-passthrough-emulation-wins
OpenXR: Emulated alpha blend mode should override the real blend mode
2025-02-27 12:40:36 +01:00
Rémi Verschelde 9014202366
Merge pull request #103337 from stuartcarnie/fix_ios_options
Metal: Fix SPIR-V → MSL compilation on iOS targets
2025-02-27 12:40:33 +01:00
Rémi Verschelde bb88938596
Merge pull request #103354 from bruvzg/gproc
Add `(void *)` cast directly to `GetProcAddress` calls.
2025-02-27 12:40:27 +01:00
Pāvels Nadtočajevs ddd807ff7d Add `(void *)` cast directly to `GetProcAddress` calls. 2025-02-27 12:30:04 +02:00
Hilderin 0c384e7217 Replace error to info messages for embedded game 2025-02-26 19:32:25 -05:00
David Snopek fd622afb1d OpenXR: Emulated alpha blend mode should override the real blend mode 2025-02-26 17:35:03 -06:00
Stuart Carnie 5312811c4d Metal: Fix SPIR-V → MSL compilation on iOS targets 2025-02-27 10:22:39 +11:00
LuoZhihao 5ca3862636 Shaders: Only convert default value to linear color if type is `source_color` 2025-02-23 12:35:53 +08:00
41 changed files with 1472 additions and 957 deletions

View File

@ -1439,7 +1439,7 @@ void ProjectSettings::_add_builtin_input_map() {
}
Dictionary action;
action["deadzone"] = Variant(InputMap::DEFAULT_DEADZONE);
action["deadzone"] = Variant(InputMap::DEFAULT_TOGGLE_DEADZONE);
action["events"] = events;
String action_name = "input/" + E.key;

View File

@ -678,6 +678,7 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_PASSWORD);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_TOOL_BUTTON);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ONESHOT);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ORDERED_LIST);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_MAX);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NONE);

View File

@ -1104,7 +1104,7 @@ JoyAxis InputEventJoypadMotion::get_axis() const {
void InputEventJoypadMotion::set_axis_value(float p_value) {
axis_value = p_value;
pressed = Math::abs(axis_value) >= InputMap::DEFAULT_DEADZONE;
pressed = Math::abs(axis_value) >= InputMap::DEFAULT_TOGGLE_DEADZONE;
emit_changed();
}

View File

@ -55,6 +55,8 @@ public:
};
static constexpr float DEFAULT_DEADZONE = 0.2f;
// Keep bigger deadzone for toggle actions (default `ui_*` actions, axis `pressed`) (GH-103360).
static constexpr float DEFAULT_TOGGLE_DEADZONE = 0.5f;
private:
static InputMap *singleton;

View File

@ -90,6 +90,7 @@ enum PropertyHint {
PROPERTY_HINT_TOOL_BUTTON,
PROPERTY_HINT_ONESHOT, ///< the property will be changed by self after setting, such as AudioStreamPlayer.playing, Particles.emitting.
PROPERTY_HINT_NO_NODEPATH, /// < this property will not contain a NodePath, regardless of type (Array, Dictionary, List, etc.). Needed for SceneTreeDock.
PROPERTY_HINT_ORDERED_LIST,
PROPERTY_HINT_MAX,
};

View File

@ -657,22 +657,28 @@ static _FORCE_INLINE_ void vc_ptrcall(void (*method)(T *, P...), void *p_base, c
} \
};
#define VARCALL_PACKED_GETTER(m_packed_type, m_return_type) \
static m_return_type func_##m_packed_type##_get(m_packed_type *p_instance, int64_t p_index) { \
return p_instance->get(p_index); \
#define VARCALL_ARRAY_GETTER_SETTER(m_packed_type, m_type) \
static m_type func_##m_packed_type##_get(m_packed_type *p_instance, int64_t p_index) { \
ERR_FAIL_INDEX_V(p_index, p_instance->size(), m_type()); \
return p_instance->get(p_index); \
} \
static void func_##m_packed_type##_set(m_packed_type *p_instance, int64_t p_index, const m_type &p_value) { \
ERR_FAIL_INDEX(p_index, p_instance->size()); \
p_instance->set(p_index, p_value); \
}
struct _VariantCall {
VARCALL_PACKED_GETTER(PackedByteArray, uint8_t)
VARCALL_PACKED_GETTER(PackedColorArray, Color)
VARCALL_PACKED_GETTER(PackedFloat32Array, float)
VARCALL_PACKED_GETTER(PackedFloat64Array, double)
VARCALL_PACKED_GETTER(PackedInt32Array, int32_t)
VARCALL_PACKED_GETTER(PackedInt64Array, int64_t)
VARCALL_PACKED_GETTER(PackedStringArray, String)
VARCALL_PACKED_GETTER(PackedVector2Array, Vector2)
VARCALL_PACKED_GETTER(PackedVector3Array, Vector3)
VARCALL_PACKED_GETTER(PackedVector4Array, Vector4)
VARCALL_ARRAY_GETTER_SETTER(PackedByteArray, uint8_t)
VARCALL_ARRAY_GETTER_SETTER(PackedColorArray, Color)
VARCALL_ARRAY_GETTER_SETTER(PackedFloat32Array, float)
VARCALL_ARRAY_GETTER_SETTER(PackedFloat64Array, double)
VARCALL_ARRAY_GETTER_SETTER(PackedInt32Array, int32_t)
VARCALL_ARRAY_GETTER_SETTER(PackedInt64Array, int64_t)
VARCALL_ARRAY_GETTER_SETTER(PackedStringArray, String)
VARCALL_ARRAY_GETTER_SETTER(PackedVector2Array, Vector2)
VARCALL_ARRAY_GETTER_SETTER(PackedVector3Array, Vector3)
VARCALL_ARRAY_GETTER_SETTER(PackedVector4Array, Vector4)
VARCALL_ARRAY_GETTER_SETTER(Array, Variant)
static String func_PackedByteArray_get_string_from_ascii(PackedByteArray *p_instance) {
String s;
@ -2354,8 +2360,8 @@ static void _register_variant_builtin_methods_array() {
bind_method(Array, clear, sarray(), varray());
bind_method(Array, hash, sarray(), varray());
bind_method(Array, assign, sarray("array"), varray());
bind_method(Array, get, sarray("index"), varray());
bind_method(Array, set, sarray("index", "value"), varray());
bind_function(Array, get, _VariantCall::func_Array_get, sarray("index"), varray());
bind_functionnc(Array, set, _VariantCall::func_Array_set, sarray("index", "value"), varray());
bind_method(Array, push_back, sarray("value"), varray());
bind_method(Array, push_front, sarray("value"), varray());
bind_method(Array, append, sarray("value"), varray());
@ -2400,7 +2406,7 @@ static void _register_variant_builtin_methods_array() {
bind_method(Array, make_read_only, sarray(), varray());
bind_method(Array, is_read_only, sarray(), varray());
/* Packed*Array get (see VARCALL_PACKED_GETTER macro) */
/* Packed*Array get/set (see VARCALL_ARRAY_GETTER_SETTER macro) */
bind_function(PackedByteArray, get, _VariantCall::func_PackedByteArray_get, sarray("index"), varray());
bind_function(PackedColorArray, get, _VariantCall::func_PackedColorArray_get, sarray("index"), varray());
bind_function(PackedFloat32Array, get, _VariantCall::func_PackedFloat32Array_get, sarray("index"), varray());
@ -2412,10 +2418,20 @@ static void _register_variant_builtin_methods_array() {
bind_function(PackedVector3Array, get, _VariantCall::func_PackedVector3Array_get, sarray("index"), varray());
bind_function(PackedVector4Array, get, _VariantCall::func_PackedVector4Array_get, sarray("index"), varray());
bind_functionnc(PackedByteArray, set, _VariantCall::func_PackedByteArray_set, sarray("index", "value"), varray());
bind_functionnc(PackedColorArray, set, _VariantCall::func_PackedColorArray_set, sarray("index", "value"), varray());
bind_functionnc(PackedFloat32Array, set, _VariantCall::func_PackedFloat32Array_set, sarray("index", "value"), varray());
bind_functionnc(PackedFloat64Array, set, _VariantCall::func_PackedFloat64Array_set, sarray("index", "value"), varray());
bind_functionnc(PackedInt32Array, set, _VariantCall::func_PackedInt32Array_set, sarray("index", "value"), varray());
bind_functionnc(PackedInt64Array, set, _VariantCall::func_PackedInt64Array_set, sarray("index", "value"), varray());
bind_functionnc(PackedStringArray, set, _VariantCall::func_PackedStringArray_set, sarray("index", "value"), varray());
bind_functionnc(PackedVector2Array, set, _VariantCall::func_PackedVector2Array_set, sarray("index", "value"), varray());
bind_functionnc(PackedVector3Array, set, _VariantCall::func_PackedVector3Array_set, sarray("index", "value"), varray());
bind_functionnc(PackedVector4Array, set, _VariantCall::func_PackedVector4Array_set, sarray("index", "value"), varray());
/* Byte Array */
bind_method(PackedByteArray, size, sarray(), varray());
bind_method(PackedByteArray, is_empty, sarray(), varray());
bind_method(PackedByteArray, set, sarray("index", "value"), varray());
bind_method(PackedByteArray, push_back, sarray("value"), varray());
bind_method(PackedByteArray, append, sarray("value"), varray());
bind_method(PackedByteArray, append_array, sarray("array"), varray());
@ -2481,7 +2497,6 @@ static void _register_variant_builtin_methods_array() {
bind_method(PackedInt32Array, size, sarray(), varray());
bind_method(PackedInt32Array, is_empty, sarray(), varray());
bind_method(PackedInt32Array, set, sarray("index", "value"), varray());
bind_method(PackedInt32Array, push_back, sarray("value"), varray());
bind_method(PackedInt32Array, append, sarray("value"), varray());
bind_method(PackedInt32Array, append_array, sarray("array"), varray());
@ -2505,7 +2520,6 @@ static void _register_variant_builtin_methods_array() {
bind_method(PackedInt64Array, size, sarray(), varray());
bind_method(PackedInt64Array, is_empty, sarray(), varray());
bind_method(PackedInt64Array, set, sarray("index", "value"), varray());
bind_method(PackedInt64Array, push_back, sarray("value"), varray());
bind_method(PackedInt64Array, append, sarray("value"), varray());
bind_method(PackedInt64Array, append_array, sarray("array"), varray());
@ -2529,7 +2543,6 @@ static void _register_variant_builtin_methods_array() {
bind_method(PackedFloat32Array, size, sarray(), varray());
bind_method(PackedFloat32Array, is_empty, sarray(), varray());
bind_method(PackedFloat32Array, set, sarray("index", "value"), varray());
bind_method(PackedFloat32Array, push_back, sarray("value"), varray());
bind_method(PackedFloat32Array, append, sarray("value"), varray());
bind_method(PackedFloat32Array, append_array, sarray("array"), varray());
@ -2553,7 +2566,6 @@ static void _register_variant_builtin_methods_array() {
bind_method(PackedFloat64Array, size, sarray(), varray());
bind_method(PackedFloat64Array, is_empty, sarray(), varray());
bind_method(PackedFloat64Array, set, sarray("index", "value"), varray());
bind_method(PackedFloat64Array, push_back, sarray("value"), varray());
bind_method(PackedFloat64Array, append, sarray("value"), varray());
bind_method(PackedFloat64Array, append_array, sarray("array"), varray());
@ -2577,7 +2589,6 @@ static void _register_variant_builtin_methods_array() {
bind_method(PackedStringArray, size, sarray(), varray());
bind_method(PackedStringArray, is_empty, sarray(), varray());
bind_method(PackedStringArray, set, sarray("index", "value"), varray());
bind_method(PackedStringArray, push_back, sarray("value"), varray());
bind_method(PackedStringArray, append, sarray("value"), varray());
bind_method(PackedStringArray, append_array, sarray("array"), varray());
@ -2601,7 +2612,6 @@ static void _register_variant_builtin_methods_array() {
bind_method(PackedVector2Array, size, sarray(), varray());
bind_method(PackedVector2Array, is_empty, sarray(), varray());
bind_method(PackedVector2Array, set, sarray("index", "value"), varray());
bind_method(PackedVector2Array, push_back, sarray("value"), varray());
bind_method(PackedVector2Array, append, sarray("value"), varray());
bind_method(PackedVector2Array, append_array, sarray("array"), varray());
@ -2625,7 +2635,6 @@ static void _register_variant_builtin_methods_array() {
bind_method(PackedVector3Array, size, sarray(), varray());
bind_method(PackedVector3Array, is_empty, sarray(), varray());
bind_method(PackedVector3Array, set, sarray("index", "value"), varray());
bind_method(PackedVector3Array, push_back, sarray("value"), varray());
bind_method(PackedVector3Array, append, sarray("value"), varray());
bind_method(PackedVector3Array, append_array, sarray("array"), varray());
@ -2649,7 +2658,6 @@ static void _register_variant_builtin_methods_array() {
bind_method(PackedColorArray, size, sarray(), varray());
bind_method(PackedColorArray, is_empty, sarray(), varray());
bind_method(PackedColorArray, set, sarray("index", "value"), varray());
bind_method(PackedColorArray, push_back, sarray("value"), varray());
bind_method(PackedColorArray, append, sarray("value"), varray());
bind_method(PackedColorArray, append_array, sarray("array"), varray());
@ -2673,7 +2681,6 @@ static void _register_variant_builtin_methods_array() {
bind_method(PackedVector4Array, size, sarray(), varray());
bind_method(PackedVector4Array, is_empty, sarray(), varray());
bind_method(PackedVector4Array, set, sarray("index", "value"), varray());
bind_method(PackedVector4Array, push_back, sarray("value"), varray());
bind_method(PackedVector4Array, append, sarray("value"), varray());
bind_method(PackedVector4Array, append_array, sarray("array"), varray());

View File

@ -2954,7 +2954,11 @@
<constant name="PROPERTY_HINT_ONESHOT" value="40" enum="PropertyHint">
Hints that a property will be changed on its own after setting, such as [member AudioStreamPlayer.playing] or [member GPUParticles3D.emitting].
</constant>
<constant name="PROPERTY_HINT_MAX" value="42" enum="PropertyHint">
<constant name="PROPERTY_HINT_ORDERED_LIST" value="42" enum="PropertyHint">
Hints that a property is ordered list of values.
The hint string is a comma separated list of display name/value pairs separated by [code]:[/code] such as [code]"Hello:hello,Something Else:else"[/code].
</constant>
<constant name="PROPERTY_HINT_MAX" value="43" enum="PropertyHint">
Represents the size of the [enum PropertyHint] enum.
</constant>
<constant name="PROPERTY_USAGE_NONE" value="0" enum="PropertyUsageFlags" is_bitfield="true">

View File

@ -2684,59 +2684,25 @@
Base size used to determine size of froxel buffer in the camera X-axis and Y-axis. The final size is scaled by the aspect ratio of the screen, so actual values may differ from what is set. Set a larger size for more detailed fog, set a smaller size for better performance.
</member>
<member name="rendering/gl_compatibility/driver" type="String" setter="" getter="" default="&quot;opengl3&quot;">
Sets the driver to be used by the renderer when using the Compatibility renderer. Editing this property has no effect in the default configuration, as first-party platforms each have platform-specific overrides. Use those overrides to configure the driver for each platform.
This can be overridden using the [code]--rendering-driver &lt;driver&gt;[/code] command line argument.
Supported values are:
- [code]opengl3[/code], OpenGL 3.3 on desktop platforms, OpenGL ES 3.0 on mobile platforms, WebGL 2.0 on web.
- [code]opengl3_angle[/code], OpenGL ES 3.0 using the ANGLE compatibility layer, supported on macOS (over native OpenGL) and Windows (over Direct3D 11).
- [code]opengl3_es[/code], OpenGL ES 3.0 on Linux/BSD.
[b]Note:[/b] The availability of these options depends on whether the engine was compiled with support for them (determined by SCons options [code]opengl3[/code] and [code]angle_libs[/code]).
[b]Note:[/b] The actual rendering driver may be automatically changed by the engine as a result of a fallback, or a user-specified command line argument. To get the actual rendering driver that is used at runtime, use [method RenderingServer.get_current_rendering_driver_name] instead of reading this project setting's value.
TODO
</member>
<member name="rendering/gl_compatibility/driver.android" type="String" setter="" getter="" default="&quot;opengl3&quot;">
Android override for [member rendering/gl_compatibility/driver].
Only one option is supported:
- [code]opengl3[/code], OpenGL ES 3.0 from native drivers.
</member>
<member name="rendering/gl_compatibility/driver.ios" type="String" setter="" getter="" default="&quot;opengl3&quot;">
iOS override for [member rendering/gl_compatibility/driver].
Only one option is supported:
- [code]opengl3[/code], OpenGL ES 3.0 from native drivers.
</member>
<member name="rendering/gl_compatibility/driver.linuxbsd" type="String" setter="" getter="" default="&quot;opengl3&quot;">
<member name="rendering/gl_compatibility/driver.linuxbsd" type="String" setter="" getter="" default="&quot;opengl3,opengl3_es&quot;">
LinuxBSD override for [member rendering/gl_compatibility/driver].
Two options are supported:
- [code]opengl3[/code] (default), OpenGL 3.3 from native drivers.
- [code]opengl3_es[/code], OpenGL ES 3.0 from native drivers. If [member rendering/gl_compatibility/fallback_to_gles] is enabled, this is used as a fallback if OpenGL 3.3 is not supported.
</member>
<member name="rendering/gl_compatibility/driver.macos" type="String" setter="" getter="" default="&quot;opengl3&quot;">
<member name="rendering/gl_compatibility/driver.macos" type="String" setter="" getter="" default="&quot;opengl3,opengl3_angle&quot;">
macOS override for [member rendering/gl_compatibility/driver].
Two options are supported:
- [code]opengl3[/code] (default), OpenGL 3.3 from native drivers. If [member rendering/gl_compatibility/fallback_to_native] is enabled, this is used as a fallback if ANGLE is configured as the preferred driver but not supported.
- [code]opengl3_angle[/code], OpenGL ES 3.0 using the ANGLE compatibility layer over native OpenGL drivers. If [member rendering/gl_compatibility/fallback_to_angle] is enabled, this is used as a fallback if OpenGL 3.3 is not supported.
</member>
<member name="rendering/gl_compatibility/driver.web" type="String" setter="" getter="" default="&quot;opengl3&quot;">
Web override for [member rendering/gl_compatibility/driver].
Only one option is supported:
- [code]opengl3[/code], WebGL 2.0. The underlying native API depends on the target OS, browser, and browser configuration.
</member>
<member name="rendering/gl_compatibility/driver.windows" type="String" setter="" getter="" default="&quot;opengl3&quot;">
<member name="rendering/gl_compatibility/driver.windows" type="String" setter="" getter="" default="&quot;opengl3,opengl3_angle&quot;">
Windows override for [member rendering/gl_compatibility/driver].
Two options are supported:
- [code]opengl3[/code] (default), OpenGL 3.3 from native drivers. If [member rendering/gl_compatibility/fallback_to_native] is enabled, this is used as a fallback if ANGLE is configured as the preferred driver but not supported.
- [code]opengl3_angle[/code], OpenGL ES 3.0 using the ANGLE compatibility layer over native Direct3D 11 drivers. If [member rendering/gl_compatibility/fallback_to_angle] is enabled, this is used as a fallback if OpenGL 3.3 is not supported. By default, ANGLE is used as the default driver for some devices listed in [member rendering/gl_compatibility/force_angle_on_devices].
</member>
<member name="rendering/gl_compatibility/fallback_to_angle" type="bool" setter="" getter="" default="true">
If [code]true[/code], the compatibility renderer will fall back to ANGLE if native OpenGL is not supported or the device is listed in [member rendering/gl_compatibility/force_angle_on_devices].
[b]Note:[/b] This setting is implemented only on Windows.
</member>
<member name="rendering/gl_compatibility/fallback_to_gles" type="bool" setter="" getter="" default="true">
If [code]true[/code], the compatibility renderer will fall back to OpenGLES if desktop OpenGL is not supported.
[b]Note:[/b] This setting is implemented only on Linux/X11.
</member>
<member name="rendering/gl_compatibility/fallback_to_native" type="bool" setter="" getter="" default="true">
If [code]true[/code], the compatibility renderer will fall back to native OpenGL if ANGLE is not supported, or ANGLE dynamic libraries aren't found.
[b]Note:[/b] This setting is implemented on macOS and Windows.
</member>
<member name="rendering/gl_compatibility/force_angle_on_devices" type="Array" setter="" getter="">
An [Array] of devices which should always use the ANGLE renderer.
@ -2961,6 +2927,10 @@
<member name="rendering/reflections/sky_reflections/texture_array_reflections.mobile" type="bool" setter="" getter="" default="false">
Lower-end override for [member rendering/reflections/sky_reflections/texture_array_reflections] on mobile devices, due to performance concerns or driver support.
</member>
<member name="rendering/renderer/fallback_to_dummy" type="bool" setter="" getter="" default="false">
</member>
<member name="rendering/renderer/fallback_to_opengl3" type="bool" setter="" getter="" default="true">
</member>
<member name="rendering/renderer/rendering_method" type="String" setter="" getter="" default="&quot;forward_plus&quot;">
Sets the renderer that will be used by the project. Options are:
[b]forward_plus[/b] (Forward+): High-end renderer designed for desktop devices. Has a higher base overhead, but scales well with complex scenes. Not suitable for older devices or mobile.
@ -2991,57 +2961,22 @@
Depending on the complexity of scenes, this value may be lowered or may need to be raised.
</member>
<member name="rendering/rendering_device/driver" type="String" setter="" getter="" default="&quot;vulkan&quot;">
Sets the driver to be used by the renderer when using a RenderingDevice-based renderer like the Forward+ or Mobile renderers. Editing this property has no effect in the default configuration, as first-party platforms each have platform-specific overrides. Use those overrides to configure the driver for each platform.
This can be overridden using the [code]--rendering-driver &lt;driver&gt;[/code] command line argument.
Supported values are:
- [code]metal[/code], Metal (supported on Apple Silicon Macs and iOS).
- [code]vulkan[/code], Vulkan (supported on all desktop and mobile platforms).
- [code]d3d12[/code], Direct3D 12 (supported on Windows).
[b]Note:[/b] The availability of these options depends on whether the engine was compiled with support for them (determined by SCons options [code]vulkan[/code], [code]metal[/code], and [code]d3d12[/code]).
[b]Note:[/b] If a given platform has no registered drivers, it can fall back to the Compatibility renderer (OpenGL 3) if [member rendering/rendering_device/fallback_to_opengl3] is enabled. This fallback happens automatically for the Web platform regardless of that property.
[b]Note:[/b] The actual rendering driver may be automatically changed by the engine as a result of a fallback, or a user-specified command line argument. To get the actual rendering driver that is used at runtime, use [method RenderingServer.get_current_rendering_driver_name] instead of reading this project setting's value.
TODO
</member>
<member name="rendering/rendering_device/driver.android" type="String" setter="" getter="" default="&quot;vulkan&quot;">
Android override for [member rendering/rendering_device/driver].
Only one option is supported:
- [code]vulkan[/code], Vulkan from native drivers.
[b]Note:[/b] If Vulkan was disabled at compile time, there is no alternative RenderingDevice driver.
</member>
<member name="rendering/rendering_device/driver.ios" type="String" setter="" getter="" default="&quot;metal&quot;">
<member name="rendering/rendering_device/driver.ios" type="String" setter="" getter="" default="&quot;metal,vulkan&quot;">
iOS override for [member rendering/rendering_device/driver].
Two options are supported:
- [code]metal[/code] (default), Metal from native drivers.
- [code]vulkan[/code], Vulkan over Metal via MoltenVK.
</member>
<member name="rendering/rendering_device/driver.linuxbsd" type="String" setter="" getter="" default="&quot;vulkan&quot;">
LinuxBSD override for [member rendering/rendering_device/driver].
Only one option is supported:
- [code]vulkan[/code], Vulkan from native drivers.
[b]Note:[/b] If Vulkan was disabled at compile time, there is no alternative RenderingDevice driver.
</member>
<member name="rendering/rendering_device/driver.macos" type="String" setter="" getter="" default="&quot;metal&quot;">
<member name="rendering/rendering_device/driver.macos" type="String" setter="" getter="" default="&quot;metal,vulkan&quot;">
macOS override for [member rendering/rendering_device/driver].
Two options are supported:
- [code]metal[/code] (default), Metal from native drivers, only supported on Apple Silicon Macs. On Intel Macs, it will automatically fall back to [code]vulkan[/code] as Metal support is not implemented.
- [code]vulkan[/code], Vulkan over Metal via MoltenVK, supported on both Apple Silicon and Intel Macs.
</member>
<member name="rendering/rendering_device/driver.windows" type="String" setter="" getter="" default="&quot;vulkan&quot;">
<member name="rendering/rendering_device/driver.windows" type="String" setter="" getter="" default="&quot;vulkan,d3d12&quot;">
Windows override for [member rendering/rendering_device/driver].
Two options are supported:
- [code]vulkan[/code] (default), Vulkan from native drivers. If [member rendering/rendering_device/fallback_to_vulkan] is enabled, this is used as a fallback if Direct3D 12 is not supported.
- [code]d3d12[/code], Direct3D 12 from native drivers. If [member rendering/rendering_device/fallback_to_d3d12] is enabled, this is used as a fallback if Vulkan is not supported.
</member>
<member name="rendering/rendering_device/fallback_to_d3d12" type="bool" setter="" getter="" default="true">
If [code]true[/code], the forward renderer will fall back to Direct3D 12 if Vulkan is not supported. The fallback is always attempted regardless of this setting if Vulkan driver support was disabled at compile time.
[b]Note:[/b] This setting is implemented only on Windows.
</member>
<member name="rendering/rendering_device/fallback_to_opengl3" type="bool" setter="" getter="" default="true">
If [code]true[/code], the forward renderer will fall back to OpenGL 3 if Direct3D 12, Metal, and Vulkan are not supported.
[b]Note:[/b] This setting is implemented only on Windows, Android, macOS, iOS, and Linux/X11.
</member>
<member name="rendering/rendering_device/fallback_to_vulkan" type="bool" setter="" getter="" default="true">
If [code]true[/code], the forward renderer will fall back to Vulkan if Direct3D 12 (on Windows) or Metal (on macOS x86_64) are not supported. The fallback is always attempted regardless of this setting if Direct3D 12 (Windows) or Metal (macOS) driver support was disabled at compile time.
[b]Note:[/b] This setting is implemented only on Windows and macOS.
</member>
<member name="rendering/rendering_device/pipeline_cache/enable" type="bool" setter="" getter="" default="true">
Enable the pipeline cache that is saved to disk if the graphics API supports it.

View File

@ -2045,6 +2045,7 @@ Vector<uint8_t> RenderingDeviceDriverMetal::shader_compile_binary_from_spirv(Vec
#if TARGET_OS_IPHONE
msl_options.ios_use_simdgroup_functions = (*device_properties).features.simdPermute;
msl_options.ios_support_base_vertex_instance = true;
#endif
bool disable_argument_buffers = false;

View File

@ -52,6 +52,7 @@
#include "scene/3d/gpu_particles_3d.h"
#include "scene/gui/color_picker.h"
#include "scene/gui/grid_container.h"
#include "scene/gui/tree.h"
#include "scene/main/window.h"
#include "scene/resources/font.h"
#include "scene/resources/mesh.h"
@ -249,6 +250,225 @@ EditorPropertyMultilineText::EditorPropertyMultilineText(bool p_expression) {
}
}
///////////////////// ORDERED LIST /////////////////////////
void EditorPropertyOrderedList::_set_read_only(bool p_read_only) {
read_only = p_read_only;
_update_tree();
}
void EditorPropertyOrderedList::_update_tree() {
tree->clear();
TreeItem *root = tree->create_item(nullptr);
// Add missing keys to the value.
for (const KeyValue<String, String> &E : names) {
if (!values.has(E.key)) {
values.push_back(E.key);
}
}
// Update tree.
for (int i = 0; i < values.size(); i++) {
if (!names.has(values[i])) {
WARN_PRINT(vformat("Invalid list item %s for property %s.", values[i], get_edited_property()));
continue;
}
TreeItem *it = tree->create_item(root);
it->set_text(0, names[values[i]]);
it->set_metadata(0, values[i]);
if (!read_only) {
it->add_button(0, get_editor_theme_icon(SNAME("ArrowUp")), BUTTON_UP, (i == 0), TTR("Move Up"));
it->add_button(0, get_editor_theme_icon(SNAME("ArrowDown")), BUTTON_DOWN, (i == values.size() - 1), TTR("Move Down"));
}
}
// Update size.
Ref<Font> font = get_theme_font(SceneStringName(font), SNAME("TextEdit"));
int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("TextEdit"));
tree->set_custom_minimum_size(tree->get_background_size() + Size2i(0, MIN(tree->get_internal_min_size().height, 6 * font->get_height(font_size))));
}
Variant EditorPropertyOrderedList::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
if (read_only) {
return Variant();
}
if (tree->get_button_id_at_position(p_point) != -1) {
return Variant();
}
TreeItem *item = tree->get_next_selected(nullptr);
if (!item) {
return Variant();
}
String value = item->get_metadata(0);
if (!names.has(value)) {
return Variant();
}
String name = names[value];
// Preview.
HBoxContainer *hb = memnew(HBoxContainer);
Label *label_prev = memnew(Label(vformat("%s (%s)", name, value)));
label_prev->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
hb->add_child(label_prev);
set_drag_preview(hb);
// Drag data.
Dictionary drag_data;
drag_data["type"] = "list_reorder";
drag_data["id"] = get_instance_id();
drag_data["value"] = value;
tree->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN);
return drag_data;
}
bool EditorPropertyOrderedList::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
if (read_only) {
return false;
}
Dictionary d = p_data;
if (!d.has("type") || !d.has("id") || !d.has("value")) {
return false;
}
if (d["type"] != "list_reorder" || d["id"] != get_instance_id()) {
return false;
}
TreeItem *item = tree->get_item_at_position(p_point);
if (!item) {
return false;
}
int section = tree->get_drop_section_at_position(p_point);
if (section == -100) {
return false;
}
return true;
}
void EditorPropertyOrderedList::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
if (!can_drop_data_fw(p_point, p_data, p_from)) {
return;
}
Dictionary d = p_data;
String drop_value = d["value"];
TreeItem *item = tree->get_item_at_position(p_point);
ERR_FAIL_COND(!item);
String target_value = item->get_metadata(0);
int section = tree->get_drop_section_at_position(p_point);
ERR_FAIL_COND(section == -100);
tree->set_drop_mode_flags(Tree::DROP_MODE_DISABLED);
Vector<String> new_values = values;
new_values.erase(drop_value);
if (section == 1) {
int pos = new_values.find(target_value);
if (pos == -1) {
return;
}
new_values.insert(pos + 1, drop_value);
} else {
int pos = new_values.find(target_value);
if (pos == -1) {
return;
}
new_values.insert(pos, drop_value);
}
values = new_values;
_update_tree();
emit_changed(get_edited_property(), String(",").join(values));
}
void EditorPropertyOrderedList::_tree_button_pressed(TreeItem *p_item, int p_column, int p_id, MouseButton p_button) {
ERR_FAIL_COND(!p_item);
if (p_button != MouseButton::LEFT) {
return;
}
String drop_value = p_item->get_metadata(0);
Vector<String> new_values = values;
if (p_id == BUTTON_DOWN) {
int pos = new_values.find(drop_value);
if (pos == -1) {
return;
}
new_values.erase(drop_value);
new_values.insert(pos + 1, drop_value);
} else {
int pos = new_values.find(drop_value);
if (pos == -1) {
return;
}
new_values.erase(drop_value);
new_values.insert(pos - 1, drop_value);
}
values = new_values;
_update_tree();
emit_changed(get_edited_property(), String(",").join(values));
}
void EditorPropertyOrderedList::update_property() {
String current_value = get_edited_property_value();
values = current_value.split(",");
print_line(values);
_update_tree();
}
void EditorPropertyOrderedList::setup(const Vector<String> &p_options) {
values.clear();
names.clear();
for (const String &option : p_options) {
Vector<String> text_split = option.split(":");
if (text_split.size() != 1) {
names[text_split[1]] = text_split[0];
} else {
names[text_split[0]] = text_split[0];
}
}
_update_tree();
}
void EditorPropertyOrderedList::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
tree->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("normal"), SNAME("Button")));
tree->add_theme_style_override(SNAME("focus"), get_theme_stylebox(SNAME("focus"), SNAME("Button")));
_update_tree();
} break;
}
}
EditorPropertyOrderedList::EditorPropertyOrderedList() {
HBoxContainer *hb = memnew(HBoxContainer);
add_child(hb);
default_layout = memnew(HBoxContainer);
default_layout->set_h_size_flags(SIZE_EXPAND_FILL);
hb->add_child(default_layout);
tree = memnew(Tree);
tree->set_h_size_flags(SIZE_EXPAND_FILL);
tree->set_hide_root(true);
tree->connect("button_clicked", callable_mp(this, &EditorPropertyOrderedList::_tree_button_pressed));
default_layout->add_child(tree);
SET_DRAG_FORWARDING_GCD(tree, EditorPropertyOrderedList);
add_focusable(tree);
}
///////////////////// TEXT ENUM /////////////////////////
void EditorPropertyTextEnum::_set_read_only(bool p_read_only) {
@ -3615,7 +3835,12 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_
}
} break;
case Variant::STRING: {
if (p_hint == PROPERTY_HINT_ENUM || p_hint == PROPERTY_HINT_ENUM_SUGGESTION) {
if (p_hint == PROPERTY_HINT_ORDERED_LIST) {
EditorPropertyOrderedList *editor = memnew(EditorPropertyOrderedList);
Vector<String> options = p_hint_text.split(",", false);
editor->setup(options);
return editor;
} else if (p_hint == PROPERTY_HINT_ENUM || p_hint == PROPERTY_HINT_ENUM_SUGGESTION) {
EditorPropertyTextEnum *editor = memnew(EditorPropertyTextEnum);
Vector<String> options = p_hint_text.split(",", false);
editor->setup(options, false, (p_hint == PROPERTY_HINT_ENUM_SUGGESTION));

View File

@ -45,6 +45,8 @@ class PropertySelector;
class SceneTreeDialog;
class TextEdit;
class TextureButton;
class Tree;
class TreeItem;
class EditorPropertyNil : public EditorProperty {
GDCLASS(EditorPropertyNil, EditorProperty);
@ -132,6 +134,39 @@ public:
EditorPropertyTextEnum();
};
class EditorPropertyOrderedList : public EditorProperty {
GDCLASS(EditorPropertyOrderedList, EditorProperty);
enum EditorPropertyOrderedListButtonID {
BUTTON_UP,
BUTTON_DOWN,
};
HBoxContainer *default_layout = nullptr;
bool read_only = false;
Tree *tree = nullptr;
HashMap<String, String> names;
Vector<String> values;
void _update_tree();
void _tree_button_pressed(TreeItem *p_item, int p_column, int p_id, MouseButton p_button);
protected:
virtual void _set_read_only(bool p_read_only) override;
void _notification(int p_what);
Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
public:
void setup(const Vector<String> &p_options);
virtual void update_property() override;
EditorPropertyOrderedList();
};
class EditorPropertyPath : public EditorProperty {
GDCLASS(EditorPropertyPath, EditorProperty);
Vector<String> extensions;

View File

@ -1017,7 +1017,7 @@ void ProjectManager::_perform_full_project_conversion() {
args.push_back(path);
args.push_back("--convert-3to4");
args.push_back("--rendering-driver");
args.push_back(Main::get_rendering_driver_name());
args.push_back(OS::get_singleton()->get_current_rendering_driver_name());
Error err = OS::get_singleton()->create_instance(args);
ERR_FAIL_COND(err);

View File

@ -2072,32 +2072,25 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
{
// RenderingDevice driver overrides per platform.
GLOBAL_DEF_RST("rendering/rendering_device/driver", "vulkan");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.windows", PROPERTY_HINT_ENUM, "vulkan,d3d12"), "vulkan");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.linuxbsd", PROPERTY_HINT_ENUM, "vulkan"), "vulkan");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.android", PROPERTY_HINT_ENUM, "vulkan"), "vulkan");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.ios", PROPERTY_HINT_ENUM, "metal,vulkan"), "metal");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.macos", PROPERTY_HINT_ENUM, "metal,vulkan"), "metal");
GLOBAL_DEF_RST("rendering/rendering_device/fallback_to_vulkan", true);
GLOBAL_DEF_RST("rendering/rendering_device/fallback_to_d3d12", true);
GLOBAL_DEF_RST("rendering/rendering_device/fallback_to_opengl3", true);
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "vulkan");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.windows", PROPERTY_HINT_ORDERED_LIST, "Vulkan:vulkan,Direct3D 12:d3d12"), "vulkan,d3d12");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.linuxbsd", PROPERTY_HINT_ORDERED_LIST, "Vulkan:vulkan"), "vulkan");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.android", PROPERTY_HINT_ORDERED_LIST, "Vulkan:vulkan"), "vulkan");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.ios", PROPERTY_HINT_ORDERED_LIST, "Metal:metal,Vulkan (using MoltenVK):vulkan"), "metal,vulkan");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.macos", PROPERTY_HINT_ORDERED_LIST, "Metal (supported on Apple Silicon only):metal,Vulkan (using MoltenVK):vulkan"), "metal,vulkan");
}
{
// GL Compatibility driver overrides per platform.
GLOBAL_DEF_RST("rendering/gl_compatibility/driver", "opengl3");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.windows", PROPERTY_HINT_ENUM, "opengl3,opengl3_angle"), "opengl3");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.linuxbsd", PROPERTY_HINT_ENUM, "opengl3,opengl3_es"), "opengl3");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.web", PROPERTY_HINT_ENUM, "opengl3"), "opengl3");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.android", PROPERTY_HINT_ENUM, "opengl3"), "opengl3");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.ios", PROPERTY_HINT_ENUM, "opengl3"), "opengl3");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.macos", PROPERTY_HINT_ENUM, "opengl3,opengl3_angle"), "opengl3");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "opengl3");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.windows", PROPERTY_HINT_ORDERED_LIST, "OpenGL 3.3:opengl3,OpenGLES 3.0 (using ANGLE):opengl3_angle"), "opengl3,opengl3_angle");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.linuxbsd", PROPERTY_HINT_ORDERED_LIST, "OpenGL 3.3:opengl3,OpenGLES 3.0:opengl3_es"), "opengl3,opengl3_es");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.web", PROPERTY_HINT_ORDERED_LIST, "WebGL 2.0:opengl3"), "opengl3");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.android", PROPERTY_HINT_ORDERED_LIST, "OpenGLES 3.0:opengl3"), "opengl3");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.ios", PROPERTY_HINT_ORDERED_LIST, "OpenGLES 3.0:opengl3"), "opengl3");
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.macos", PROPERTY_HINT_ORDERED_LIST, "OpenGL 3.2:opengl3,OpenGLES 3.0 (using ANGLE):opengl3_angle"), "opengl3,opengl3_angle");
GLOBAL_DEF_RST("rendering/gl_compatibility/nvidia_disable_threaded_optimization", true);
GLOBAL_DEF_RST("rendering/gl_compatibility/fallback_to_angle", true);
GLOBAL_DEF_RST("rendering/gl_compatibility/fallback_to_native", true);
GLOBAL_DEF_RST("rendering/gl_compatibility/fallback_to_gles", true);
Array device_blocklist;
@ -2272,7 +2265,13 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
// Default to Compatibility when using the project manager.
if (rendering_driver.is_empty() && rendering_method.is_empty() && project_manager) {
#if defined(WINDOWS_ENABLED)
rendering_driver = "opengl3,opengl3_angle";
#elif defined(LINUXBSD_ENABLED)
rendering_driver = "opengl3,opengl3_es";
#else
rendering_driver = "opengl3";
#endif
rendering_method = "gl_compatibility";
default_renderer_mobile = "gl_compatibility";
}
@ -2304,105 +2303,64 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
if (!rendering_driver.is_empty()) {
// As the rendering drivers available may depend on the display driver and renderer
// selected, we can't do an exhaustive check here, but we can look through all
// the options in all the display drivers for a match.
rendering_driver = rendering_driver.to_lower();
bool found = false;
Vector<String> unique_rendering_drivers_modern;
Vector<String> unique_rendering_drivers_compat;
for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
Vector<String> r_drivers = DisplayServer::get_create_function_rendering_drivers(i);
for (int d = 0; d < r_drivers.size(); d++) {
if (rendering_driver == r_drivers[d]) {
found = true;
break;
for (const String &ds_driver : r_drivers) {
if (ds_driver == "opengl3" || ds_driver == "opengl3_angle" || ds_driver == "opengl3_es") {
if (!unique_rendering_drivers_modern.has(ds_driver)) {
unique_rendering_drivers_modern.append(ds_driver);
}
} else {
if (!unique_rendering_drivers_compat.has(ds_driver)) {
unique_rendering_drivers_compat.append(ds_driver);
}
}
}
}
Vector<String> pending_drivers = rendering_driver.split(",");
bool has_compat = pending_drivers.has("opengl3") || pending_drivers.has("opengl3_angle") || pending_drivers.has("opengl3_es");
bool has_modern = pending_drivers.has("metal") || pending_drivers.has("vulkan") || pending_drivers.has("d3d12");
bool found = false;
for (const String &cmd_driver : pending_drivers) {
if (unique_rendering_drivers_compat.has(cmd_driver) || unique_rendering_drivers_modern.has(cmd_driver)) {
found = true;
break;
}
}
if (!found) {
OS::get_singleton()->print("Unknown rendering driver '%s', aborting.\nValid options are ",
rendering_driver.utf8().get_data());
OS::get_singleton()->print("Rendering driver argument '%s' has no valid drivers, aborting. Valid options are:\n", rendering_driver.utf8().get_data());
// Deduplicate driver entries, as a rendering driver may be supported by several display servers.
Vector<String> unique_rendering_drivers;
for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
Vector<String> r_drivers = DisplayServer::get_create_function_rendering_drivers(i);
OS::get_singleton()->print(" for 'compatibility' rendering method: '%s'.\n", String("', '").join(unique_rendering_drivers_compat).utf8().get_data());
OS::get_singleton()->print(" for 'forward_plus' and 'mobile' rendering methods: '%s'.\n", String("', '").join(unique_rendering_drivers_modern).utf8().get_data());
for (int d = 0; d < r_drivers.size(); d++) {
if (!unique_rendering_drivers.has(r_drivers[d])) {
unique_rendering_drivers.append(r_drivers[d]);
}
}
}
for (int i = 0; i < unique_rendering_drivers.size(); i++) {
if (i == unique_rendering_drivers.size() - 1) {
OS::get_singleton()->print(" and ");
} else if (i != 0) {
OS::get_singleton()->print(", ");
}
OS::get_singleton()->print("'%s'", unique_rendering_drivers[i].utf8().get_data());
}
OS::get_singleton()->print(".\n");
goto error;
}
// Now validate whether the selected driver matches with the renderer.
if (has_compat && (rendering_method == "forward_plus" || rendering_method == "mobile")) {
OS::get_singleton()->print("Invalid rendering method/driver combination '%s' and '%s', aborting. Valid options are: '%s'.\n", rendering_method.utf8().get_data(), rendering_driver.utf8().get_data(), String("', '").join(unique_rendering_drivers_modern).utf8().get_data());
goto error;
}
if (has_modern && (rendering_method == "gl_compatibility")) {
OS::get_singleton()->print("Invalid rendering method/driver combination '%s' and '%s', aborting. Valid options are: '%s'.\n", rendering_method.utf8().get_data(), rendering_driver.utf8().get_data(), String("', '").join(unique_rendering_drivers_compat).utf8().get_data());
goto error;
}
// Set a default renderer if none selected. Try to choose one that matches the driver.
if (rendering_method.is_empty()) {
if (rendering_driver == "opengl3" || rendering_driver == "opengl3_angle" || rendering_driver == "opengl3_es") {
rendering_method = "gl_compatibility";
} else {
if (has_modern) {
rendering_method = "forward_plus";
} else {
rendering_method = "gl_compatibility";
}
}
// Now validate whether the selected driver matches with the renderer.
bool valid_combination = false;
Vector<String> available_drivers;
if (rendering_method == "forward_plus" || rendering_method == "mobile") {
#ifdef VULKAN_ENABLED
available_drivers.push_back("vulkan");
#endif
#ifdef D3D12_ENABLED
available_drivers.push_back("d3d12");
#endif
#ifdef METAL_ENABLED
available_drivers.push_back("metal");
#endif
}
#ifdef GLES3_ENABLED
if (rendering_method == "gl_compatibility") {
available_drivers.push_back("opengl3");
available_drivers.push_back("opengl3_angle");
available_drivers.push_back("opengl3_es");
}
#endif
if (available_drivers.is_empty()) {
OS::get_singleton()->print("Unknown renderer name '%s', aborting.\n", rendering_method.utf8().get_data());
goto error;
}
for (int i = 0; i < available_drivers.size(); i++) {
if (rendering_driver == available_drivers[i]) {
valid_combination = true;
break;
}
}
if (!valid_combination) {
OS::get_singleton()->print("Invalid renderer/driver combination '%s' and '%s', aborting. %s only supports the following drivers ", rendering_method.utf8().get_data(), rendering_driver.utf8().get_data(), rendering_method.utf8().get_data());
for (int d = 0; d < available_drivers.size(); d++) {
OS::get_singleton()->print("'%s', ", available_drivers[d].utf8().get_data());
}
OS::get_singleton()->print(".\n");
goto error;
}
}
default_renderer = renderer_hints.get_slice(",", 0);
@ -2410,6 +2368,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
GLOBAL_DEF_RST_BASIC("rendering/renderer/rendering_method.mobile", default_renderer_mobile);
GLOBAL_DEF_RST_BASIC("rendering/renderer/rendering_method.web", "gl_compatibility"); // This is a bit of a hack until we have WebGPU support.
GLOBAL_DEF_RST("rendering/renderer/fallback_to_opengl3", true);
GLOBAL_DEF_RST("rendering/renderer/fallback_to_dummy", false);
// Default to ProjectSettings default if nothing set on the command line.
if (rendering_method.is_empty()) {
rendering_method = GLOBAL_GET("rendering/renderer/rendering_method");
@ -2423,10 +2384,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
}
// always convert to lower case for consistency in the code
rendering_driver = rendering_driver.to_lower();
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver.get_slice(",", 0));
OS::get_singleton()->set_current_rendering_method(rendering_method);
#ifdef TOOLS_ENABLED
@ -3584,10 +3542,6 @@ void Main::setup_boot_logo() {
GLOBAL_GET("rendering/environment/defaults/default_clear_color"));
}
String Main::get_rendering_driver_name() {
return rendering_driver;
}
// everything the main loop needs to know about frame timings
static MainTimerSync main_timer_sync;

View File

@ -72,7 +72,6 @@ public:
static int test_entrypoint(int argc, char *argv[], bool &tests_need_run);
static Error setup(const char *execpath, int argc, char *argv[], bool p_second_phase = true);
static Error setup2(bool p_show_boot_logo = true); // The thread calling setup2() will effectively become the main thread.
static String get_rendering_driver_name();
static void setup_boot_logo();
#ifdef TESTS_ENABLED
static Error test_setup();

View File

@ -12,6 +12,7 @@
if interface and interface.initialize():
get_viewport().use_xr = true
[/codeblock]
[b]Note:[/b] For Android, [member ProjectSettings.input_devices/sensors/enable_accelerometer], [member ProjectSettings.input_devices/sensors/enable_gravity], [member ProjectSettings.input_devices/sensors/enable_gyroscope] and [member ProjectSettings.input_devices/sensors/enable_magnetometer] must be enabled.
</description>
<tutorials>
</tutorials>

View File

@ -135,7 +135,7 @@ typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS)(HANDLE, PBOOL);
BOOL is_wow64() {
BOOL wow64 = FALSE;
LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)(void *)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
if (fnIsWow64Process) {
if (!fnIsWow64Process(GetCurrentProcess(), &wow64)) {

View File

@ -3641,10 +3641,10 @@ void OpenXRAPI::set_emulate_environment_blend_mode_alpha_blend(bool p_enabled) {
}
OpenXRAPI::OpenXRAlphaBlendModeSupport OpenXRAPI::is_environment_blend_mode_alpha_blend_supported() {
if (is_environment_blend_mode_supported(XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND)) {
return OPENXR_ALPHA_BLEND_MODE_SUPPORT_REAL;
} else if (emulate_environment_blend_mode_alpha_blend) {
if (emulate_environment_blend_mode_alpha_blend) {
return OPENXR_ALPHA_BLEND_MODE_SUPPORT_EMULATING;
} else if (is_environment_blend_mode_supported(XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND)) {
return OPENXR_ALPHA_BLEND_MODE_SUPPORT_REAL;
}
return OPENXR_ALPHA_BLEND_MODE_SUPPORT_NONE;
}

View File

@ -163,7 +163,7 @@ void initialize_openxr_module(ModuleInitializationLevel p_level) {
openxr_api = memnew(OpenXRAPI);
ERR_FAIL_NULL(openxr_api);
if (!openxr_api->initialize(Main::get_rendering_driver_name())) {
if (!openxr_api->initialize(OS::get_singleton()->get_current_rendering_driver_name())) {
const char *init_error_message =
"OpenXR was requested but failed to start.\n"
"Please check if your HMD is connected.\n"

View File

@ -52,6 +52,8 @@
#include <EGL/egl.h>
#endif
#include "servers/rendering/dummy/rasterizer_dummy.h"
DisplayServerAndroid *DisplayServerAndroid::get_singleton() {
return static_cast<DisplayServerAndroid *>(DisplayServer::get_singleton());
}
@ -578,22 +580,42 @@ Vector<String> DisplayServerAndroid::get_rendering_drivers_func() {
#ifdef VULKAN_ENABLED
drivers.push_back("vulkan");
#endif
drivers.push_back("dummy");
return drivers;
}
String DisplayServerAndroid::get_readable_driver_name(const String &p_driver) const {
if (p_driver == "vulkan") {
return "Vulkan";
} else if (p_driver == "opengl3") {
return "OpenGLES 3.0";
} else if (p_driver == "dummy") {
return "Dummy";
} else {
return p_driver;
}
}
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_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error) {
DisplayServer *ds = memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, p_parent_window, r_error));
DisplayServerAndroid *ds = memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, p_parent_window, r_error));
if (r_error != OK) {
if (p_rendering_driver == "vulkan") {
Vector<String> names;
for (const String &driver : ds->tested_drivers) {
names.push_back(ds->get_readable_driver_name(driver));
}
if (!ds->tested_drivers.has("opengl3")) {
OS::get_singleton()->alert(
"Your device seems not to support the required Vulkan version.\n\n"
"Please try exporting your game using the 'gl_compatibility' renderer.",
"Unable to initialize Vulkan video driver");
vformat("Your device seem not to support the required version of the following drivers:\n%s.\n\n"
"Please try exporting your game using the 'gl_compatibility' renderer.",
String(", ").join(names)),
"Unable to initialize video driver");
} else {
OS::get_singleton()->alert(
"Your device seems not to support the required OpenGL ES 3.0 version.",
"Unable to initialize OpenGL video driver");
vformat("Your device seem not to support the required version of the following drivers:\n%s.\n\n",
String(", ").join(names)),
"Unable to initialize video driver");
}
}
return ds;
@ -657,37 +679,71 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis
native_menu = memnew(NativeMenu);
#if defined(RD_ENABLED)
rendering_context = nullptr;
rendering_device = nullptr;
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
rendering_context = memnew(RenderingContextDriverVulkanAndroid);
Vector<String> driver_list;
for (const String &drv : p_rendering_driver.split(",")) {
if (!driver_list.has(drv)) {
driver_list.push_back(drv);
}
}
#endif
if (rendering_context) {
if (rendering_context->initialize() != OK) {
memdelete(rendering_context);
rendering_context = nullptr;
#if defined(GLES3_ENABLED)
bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3");
if (fallback_to_opengl3 && rendering_driver != "opengl3") {
WARN_PRINT("Your device seem not to support Vulkan, switching to OpenGL 3.");
rendering_driver = "opengl3";
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
} else
#endif
{
ERR_PRINT(vformat("Failed to initialize %s context", rendering_driver));
r_error = ERR_UNAVAILABLE;
return;
if (GLOBAL_GET("rendering/renderer/fallback_to_opengl3").operator bool()) {
for (const String &drv : GLOBAL_GET("rendering/gl_compatibility/driver").operator String().split(",")) {
if (!driver_list.has(drv)) {
driver_list.push_back(drv);
}
}
}
if (GLOBAL_GET("rendering/renderer/fallback_to_dummy").operator bool()) {
if (!driver_list.has("dummy")) {
driver_list.push_back("dummy");
}
}
bool driver_found = false;
for (const String &driver : driver_list) {
print_line(vformat("Trying to initialize \"%s\" rendering driver.", get_readable_driver_name(driver)));
tested_drivers.push_back(driver);
#if defined(RD_ENABLED)
#if defined(VULKAN_ENABLED)
if (driver == "vulkan") {
rendering_context = memnew(RenderingContextDriverVulkanAndroid);
if (rendering_context->initialize() == OK) {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
memdelete(rendering_context);
rendering_context = nullptr;
}
#endif // VULKAN_ENABLED
#endif // RD_ENABLED
#if defined(GLES3_ENABLED)
if (driver == "opengl3") {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
#endif // GLES3_ENABLED
if (driver == "dummy") {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
print_line(vformat(" \"%s\" rendering driver initialization failed.", get_readable_driver_name(driver)));
}
if (driver_found) {
print_line(vformat(" \"%s\" rendering driver initialized successfully.", get_readable_driver_name(rendering_driver)));
} else {
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Could not initialize any of the rendering drivers.");
}
#if defined(RD_ENABLED)
if (rendering_context) {
union {
#ifdef VULKAN_ENABLED
@ -733,6 +789,9 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis
RasterizerGLES3::make_current(false);
}
#endif
if (rendering_driver == "dummy") {
RasterizerDummy::make_current();
}
Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events);

View File

@ -42,6 +42,7 @@ class DisplayServerAndroid : public DisplayServer {
// No need to register with GDCLASS, it's platform-specific and nothing is added.
String rendering_driver;
Vector<String> tested_drivers;
// https://developer.android.com/reference/android/view/PointerIcon
// mapping between Godot's cursor shape to Android's'
@ -254,6 +255,8 @@ public:
virtual void set_native_icon(const String &p_filename) override;
virtual void set_icon(const Ref<Image> &p_icon) override;
String get_readable_driver_name(const String &p_driver) const override;
DisplayServerAndroid(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error);
~DisplayServerAndroid();
};

View File

@ -34,13 +34,20 @@
#include "editor/editor_interface.h"
#include "editor/editor_node.h"
#include "editor/plugins/game_view_plugin.h"
static GameViewPlugin *_get_game_view_plugin() {
ERR_FAIL_NULL_V(EditorNode::get_singleton(), nullptr);
ERR_FAIL_NULL_V(EditorNode::get_singleton()->get_editor_main_screen(), nullptr);
return Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
}
#endif
extern "C" {
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setSuspend(JNIEnv *env, jclass clazz, jboolean enabled) {
#ifdef TOOLS_ENABLED
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
game_view_plugin->get_debugger()->set_suspend(enabled);
}
@ -49,7 +56,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setSuspend
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_nextFrame(JNIEnv *env, jclass clazz) {
#ifdef TOOLS_ENABLED
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
game_view_plugin->get_debugger()->next_frame();
}
@ -58,7 +65,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_nextFrame(
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setNodeType(JNIEnv *env, jclass clazz, jint type) {
#ifdef TOOLS_ENABLED
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
game_view_plugin->get_debugger()->set_node_type(type);
}
@ -67,7 +74,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setNodeTyp
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setSelectMode(JNIEnv *env, jclass clazz, jint mode) {
#ifdef TOOLS_ENABLED
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
game_view_plugin->get_debugger()->set_select_mode(mode);
}
@ -76,7 +83,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setSelectM
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setSelectionVisible(JNIEnv *env, jclass clazz, jboolean visible) {
#ifdef TOOLS_ENABLED
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
game_view_plugin->get_debugger()->set_selection_visible(visible);
}
@ -85,7 +92,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setSelecti
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setCameraOverride(JNIEnv *env, jclass clazz, jboolean enabled) {
#ifdef TOOLS_ENABLED
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
game_view_plugin->get_debugger()->set_camera_override(enabled);
}
@ -94,7 +101,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setCameraO
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setCameraManipulateMode(JNIEnv *env, jclass clazz, jint mode) {
#ifdef TOOLS_ENABLED
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
game_view_plugin->get_debugger()->set_camera_manipulate_mode(static_cast<EditorDebuggerNode::CameraOverride>(mode));
}
@ -103,7 +110,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setCameraM
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_resetCamera2DPosition(JNIEnv *env, jclass clazz) {
#ifdef TOOLS_ENABLED
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
game_view_plugin->get_debugger()->reset_camera_2d_position();
}
@ -112,7 +119,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_resetCamer
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_resetCamera3DPosition(JNIEnv *env, jclass clazz) {
#ifdef TOOLS_ENABLED
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
game_view_plugin->get_debugger()->reset_camera_3d_position();
}
@ -121,7 +128,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_resetCamer
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_playMainScene(JNIEnv *env, jclass clazz) {
#ifdef TOOLS_ENABLED
EditorInterface::get_singleton()->play_main_scene();
if (EditorInterface::get_singleton()) {
EditorInterface::get_singleton()->play_main_scene();
}
#endif
}
}

View File

@ -89,6 +89,9 @@ class DisplayServerIOS : public DisplayServer {
public:
String rendering_driver;
Vector<String> tested_drivers;
String get_readable_driver_name(const String &p_driver) const override;
static DisplayServerIOS *get_singleton();

View File

@ -43,6 +43,8 @@
#include "core/config/project_settings.h"
#include "core/io/file_access_pack.h"
#include "servers/rendering/dummy/rasterizer_dummy.h"
#import <sys/utsname.h>
#import <GameController/GameController.h>
@ -56,7 +58,7 @@ DisplayServerIOS *DisplayServerIOS::get_singleton() {
DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error) {
KeyMappingIOS::initialize();
rendering_driver = p_rendering_driver;
CALayer *layer = nullptr;
// Init TTS
bool tts_enabled = GLOBAL_GET("audio/general/text_to_speech");
@ -65,12 +67,93 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode
}
native_menu = memnew(NativeMenu);
Vector<String> driver_list;
for (const String &drv : p_rendering_driver.split(",")) {
if (!driver_list.has(drv)) {
driver_list.push_back(drv);
}
}
if (GLOBAL_GET("rendering/renderer/fallback_to_opengl3").operator bool()) {
for (const String &drv : GLOBAL_GET("rendering/gl_compatibility/driver").operator String().split(",")) {
if (!driver_list.has(drv)) {
driver_list.push_back(drv);
}
}
}
if (GLOBAL_GET("rendering/renderer/fallback_to_dummy").operator bool()) {
if (!driver_list.has("dummy")) {
driver_list.push_back("dummy");
}
}
bool driver_found = false;
for (const String &driver : driver_list) {
print_line(vformat("Trying to initialize \"%s\" rendering driver.", get_readable_driver_name(driver)));
tested_drivers.push_back(driver);
#if defined(RD_ENABLED)
rendering_context = nullptr;
rendering_device = nullptr;
#if defined(METAL_ENABLED)
if (driver == "metal") {
if (@available(iOS 14.0, *)) {
layer = [AppDelegate.viewController.godotView initializeRenderingForDriver:@"metal"];
rendering_context = memnew(RenderingContextDriverMetal);
if (rendering_context->initialize() == OK && layer) {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
memdelete(rendering_context);
rendering_context = nullptr;
layer = nullptr;
}
}
#endif // METAL_ENABLED
#if defined(VULKAN_ENABLED)
if (driver == "vulkan") {
layer = [AppDelegate.viewController.godotView initializeRenderingForDriver:@"vulkan"];
rendering_context = memnew(RenderingContextDriverVulkanIOS);
if (rendering_context->initialize() == OK && layer) {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
memdelete(rendering_context);
rendering_context = nullptr;
layer = nullptr;
}
#endif // VULKAN_ENABLED
#endif // RD_ENABLED
#if defined(GLES3_ENABLED)
if (driver == "opengl3") {
layer = [AppDelegate.viewController.godotView initializeRenderingForDriver:@"opengl3"];
if (layer) {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
}
#endif // GLES3_ENABLED
if (driver == "dummy") {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
print_line(vformat(" \"%s\" rendering driver initialization failed.", get_readable_driver_name(driver)));
}
CALayer *layer = nullptr;
if (driver_found) {
print_line(vformat(" \"%s\" rendering driver initialized successfully.", get_readable_driver_name(rendering_driver)));
} else {
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Could not initialize any of the rendering drivers.");
}
#if defined(RD_ENABLED)
union {
#ifdef VULKAN_ENABLED
RenderingContextDriverVulkanIOS::WindowPlatformData vulkan;
@ -86,47 +169,16 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
layer = [AppDelegate.viewController.godotView initializeRenderingForDriver:@"vulkan"];
if (!layer) {
ERR_FAIL_MSG("Failed to create iOS Vulkan rendering layer.");
}
wpd.vulkan.layer_ptr = (CAMetalLayer *const *)&layer;
rendering_context = memnew(RenderingContextDriverVulkanIOS);
}
#endif
#ifdef METAL_ENABLED
if (rendering_driver == "metal") {
if (@available(iOS 14.0, *)) {
layer = [AppDelegate.viewController.godotView initializeRenderingForDriver:@"metal"];
wpd.metal.layer = (CAMetalLayer *)layer;
rendering_context = memnew(RenderingContextDriverMetal);
} else {
OS::get_singleton()->alert("Metal is only supported on iOS 14.0 and later.");
r_error = ERR_UNAVAILABLE;
return;
}
}
#endif
if (rendering_context) {
if (rendering_context->initialize() != OK) {
memdelete(rendering_context);
rendering_context = nullptr;
#if defined(GLES3_ENABLED)
bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3");
if (fallback_to_opengl3 && rendering_driver != "opengl3") {
WARN_PRINT("Your device seem not to support MoltenVK or Metal, switching to OpenGL 3.");
rendering_driver = "opengl3";
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
} else
#endif
{
ERR_PRINT(vformat("Failed to initialize %s context", rendering_driver));
r_error = ERR_UNAVAILABLE;
return;
}
}
}
if (rendering_context) {
if (rendering_context->window_create(MAIN_WINDOW_ID, &wpd) != OK) {
@ -157,15 +209,12 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode
#if defined(GLES3_ENABLED)
if (rendering_driver == "opengl3") {
CALayer *layer = [AppDelegate.viewController.godotView initializeRenderingForDriver:@"opengl3"];
if (!layer) {
ERR_FAIL_MSG("Failed to create iOS OpenGLES rendering layer.");
}
RasterizerGLES3::make_current(false);
}
#endif
if (rendering_driver == "dummy") {
RasterizerDummy::make_current();
}
bool keep_screen_on = bool(GLOBAL_GET("display/window/energy_saving/keep_screen_on"));
screen_set_keep_on(keep_screen_on);
@ -196,8 +245,44 @@ DisplayServerIOS::~DisplayServerIOS() {
#endif
}
String DisplayServerIOS::get_readable_driver_name(const String &p_driver) const {
if (p_driver == "metal") {
return "Metal";
} else if (p_driver == "vulkan") {
return "Vulkan (MoltenVK)";
} else if (p_driver == "opengl3") {
return "OpenGLES 3.0";
} else if (p_driver == "opengl3_angle") {
return "OpenGLES 3.0 (ANGLE)";
} else if (p_driver == "dummy") {
return "Dummy";
} else {
return p_driver;
}
}
DisplayServer *DisplayServerIOS::create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error) {
return memnew(DisplayServerIOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, p_parent_window, r_error));
DisplayServerIOS *ds = memnew(DisplayServerIOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, p_parent_window, r_error));
if (r_error != OK) {
Vector<String> names;
for (const String &driver : ds->tested_drivers) {
names.push_back(ds->get_readable_driver_name(driver));
}
if (!ds->tested_drivers.has("opengl3")) {
OS::get_singleton()->alert(
vformat("Your device seem not to support the required version of the following drivers:\n%s.\n\n"
"Please try exporting your game using the 'gl_compatibility' renderer.",
String(", ").join(names)),
"Unable to initialize video driver");
} else {
OS::get_singleton()->alert(
vformat("Your device seem not to support the required version of the following drivers:\n%s.\n\n",
String(", ").join(names)),
"Unable to initialize video driver");
}
}
return ds;
}
Vector<String> DisplayServerIOS::get_rendering_drivers_func() {
@ -214,6 +299,7 @@ Vector<String> DisplayServerIOS::get_rendering_drivers_func() {
#if defined(GLES3_ENABLED)
drivers.push_back("opengl3");
#endif
drivers.push_back("dummy");
return drivers;
}

View File

@ -50,6 +50,8 @@
#include "wayland/egl_manager_wayland_gles.h"
#endif
#include "servers/rendering/dummy/rasterizer_dummy.h"
String DisplayServerWayland::_get_app_id_from_context(Context p_context) {
String app_id;
@ -1381,17 +1383,53 @@ Vector<String> DisplayServerWayland::get_rendering_drivers_func() {
drivers.push_back("opengl3");
drivers.push_back("opengl3_es");
#endif
drivers.push_back("dummy");
return drivers;
}
DisplayServer *DisplayServerWayland::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error) {
DisplayServer *ds = memnew(DisplayServerWayland(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, p_context, p_parent_window, r_error));
if (r_error != OK) {
ERR_PRINT("Can't create the Wayland display server.");
memdelete(ds);
String DisplayServerWayland::get_readable_driver_name(const String &p_driver) const {
if (p_driver == "vulkan") {
return "Vulkan";
} else if (p_driver == "opengl3") {
return "OpenGL 3.2";
} else if (p_driver == "opengl3_es") {
return "OpenGLES 3.0";
} else if (p_driver == "dummy") {
return "Dummy";
} else {
return p_driver;
}
}
return nullptr;
DisplayServer *DisplayServerWayland::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error) {
DisplayServerWayland *ds = memnew(DisplayServerWayland(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, p_context, p_parent_window, r_error));
if (r_error != OK) {
Vector<String> names;
for (const String &driver : ds->tested_drivers) {
names.push_back(ds->get_readable_driver_name(driver));
}
if (!ds->tested_drivers.has("opengl3") && !ds->tested_drivers.has("opengl3_es")) {
String executable_command = vformat("\"%s\" --rendering-driver opengl3", OS::get_singleton()->get_executable_path());
OS::get_singleton()->alert(
vformat("Your video card drivers seem not to support the required version of the following drivers:\n%s.\n\n"
"If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n"
"If you have recently updated your video card drivers, try rebooting.\n\n"
"You can enable the OpenGL 3 driver by starting the engine from the\n"
"command line with the command:\n\n %s",
String(", ").join(names),
executable_command),
"Unable to initialize video driver");
} else {
OS::get_singleton()->alert(
vformat("Your video card drivers seem not to support the required version of the following drivers:\n%s.\n\n"
"If possible, consider updating your video card drivers\n"
"If you have recently updated your video card drivers, try rebooting.",
String(", ").join(names)),
"Unable to initialize video driver");
}
}
return ds;
}
@ -1427,165 +1465,152 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win
tts = memnew(TTS_Linux);
#endif
rendering_driver = p_rendering_driver;
bool driver_found = false;
String executable_name = OS::get_singleton()->get_executable_path().get_file();
#ifdef RD_ENABLED
#ifdef VULKAN_ENABLED
if (rendering_driver == "vulkan") {
rendering_context = memnew(RenderingContextDriverVulkanWayland);
Vector<String> driver_list;
for (const String &drv : p_rendering_driver.split(",")) {
if (!driver_list.has(drv)) {
driver_list.push_back(drv);
}
}
if (GLOBAL_GET("rendering/renderer/fallback_to_opengl3").operator bool()) {
for (const String &drv : GLOBAL_GET("rendering/gl_compatibility/driver").operator String().split(",")) {
if (!driver_list.has(drv)) {
driver_list.push_back(drv);
}
}
}
if (GLOBAL_GET("rendering/renderer/fallback_to_dummy").operator bool()) {
if (!driver_list.has("dummy")) {
driver_list.push_back("dummy");
}
}
#endif // VULKAN_ENABLED
if (rendering_context) {
if (rendering_context->initialize() != OK) {
bool egl_dri_checked = false;
bool egl_found = true;
bool driver_found = false;
for (const String &driver : driver_list) {
print_line(vformat("Trying to initialize \"%s\" rendering driver.", get_readable_driver_name(driver)));
tested_drivers.push_back(driver);
#if defined(RD_ENABLED)
#if defined(VULKAN_ENABLED)
if (driver == "vulkan") {
rendering_context = memnew(RenderingContextDriverVulkanWayland);
if (rendering_context->initialize() == OK) {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
memdelete(rendering_context);
rendering_context = nullptr;
#if defined(GLES3_ENABLED)
bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3");
if (fallback_to_opengl3 && rendering_driver != "opengl3") {
WARN_PRINT("Your video card drivers seem not to support the required Vulkan version, switching to OpenGL 3.");
rendering_driver = "opengl3";
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
} else
#endif // GLES3_ENABLED
{
r_error = ERR_CANT_CREATE;
if (p_rendering_driver == "vulkan") {
OS::get_singleton()->alert(
vformat("Your video card drivers seem not to support the required Vulkan version.\n\n"
"If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n"
"You can enable the OpenGL 3 driver by starting the engine from the\n"
"command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n"
"If you recently updated your video card drivers, try rebooting.",
executable_name),
"Unable to initialize Vulkan video driver");
}
ERR_FAIL_MSG(vformat("Could not initialize %s", rendering_driver));
}
}
driver_found = true;
}
#endif // VULKAN_ENABLED
#endif // RD_ENABLED
#ifdef GLES3_ENABLED
if (rendering_driver == "opengl3" || rendering_driver == "opengl3_es") {
#if defined(GLES3_ENABLED)
if (driver == "opengl3" || driver == "opengl3_es") {
if (!egl_dri_checked) {
egl_dri_checked = true;
#ifdef SOWRAP_ENABLED
if (initialize_wayland_egl(dylibloader_verbose) != 0) {
WARN_PRINT("Can't load the Wayland EGL library.");
return;
}
if (initialize_wayland_egl(dylibloader_verbose) != 0) {
egl_found = false;
WARN_PRINT("Can't load the Wayland EGL library.");
continue;
}
#endif // SOWRAP_ENABLED
if (getenv("DRI_PRIME") == nullptr) {
int prime_idx = -1;
if (getenv("DRI_PRIME") == nullptr) {
int prime_idx = -1;
if (getenv("PRIMUS_DISPLAY") ||
getenv("PRIMUS_libGLd") ||
getenv("PRIMUS_libGLa") ||
getenv("PRIMUS_libGL") ||
getenv("PRIMUS_LOAD_GLOBAL") ||
getenv("BUMBLEBEE_SOCKET") ||
getenv("__NV_PRIME_RENDER_OFFLOAD")) {
print_verbose("Optirun/primusrun detected. Skipping GPU detection");
prime_idx = 0;
}
// Some tools use fake libGL libraries and have them override the real one using
// LD_LIBRARY_PATH, so we skip them. *But* Steam also sets LD_LIBRARY_PATH for its
// runtime and includes system `/lib` and `/lib64`... so ignore Steam.
if (prime_idx == -1 && getenv("LD_LIBRARY_PATH") && !getenv("STEAM_RUNTIME_LIBRARY_PATH")) {
String ld_library_path(getenv("LD_LIBRARY_PATH"));
Vector<String> libraries = ld_library_path.split(":");
for (int i = 0; i < libraries.size(); ++i) {
if (FileAccess::exists(libraries[i] + "/libGL.so.1") ||
FileAccess::exists(libraries[i] + "/libGL.so")) {
print_verbose("Custom libGL override detected. Skipping GPU detection");
if (getenv("PRIMUS_DISPLAY") ||
getenv("PRIMUS_libGLd") ||
getenv("PRIMUS_libGLa") ||
getenv("PRIMUS_libGL") ||
getenv("PRIMUS_LOAD_GLOBAL") ||
getenv("BUMBLEBEE_SOCKET") ||
getenv("__NV_PRIME_RENDER_OFFLOAD")) {
print_verbose("Optirun/primusrun detected. Skipping GPU detection");
prime_idx = 0;
}
// Some tools use fake libGL libraries and have them override the real one using
// LD_LIBRARY_PATH, so we skip them. *But* Steam also sets LD_LIBRARY_PATH for its
// runtime and includes system `/lib` and `/lib64`... so ignore Steam.
if (prime_idx == -1 && getenv("LD_LIBRARY_PATH") && !getenv("STEAM_RUNTIME_LIBRARY_PATH")) {
String ld_library_path(getenv("LD_LIBRARY_PATH"));
Vector<String> libraries = ld_library_path.split(":");
for (int i = 0; i < libraries.size(); ++i) {
if (FileAccess::exists(libraries[i] + "/libGL.so.1") ||
FileAccess::exists(libraries[i] + "/libGL.so")) {
print_verbose("Custom libGL override detected. Skipping GPU detection");
prime_idx = 0;
}
}
}
if (prime_idx == -1) {
print_verbose("Detecting GPUs, set DRI_PRIME in the environment to override GPU detection logic.");
prime_idx = DetectPrimeEGL::detect_prime(EGL_PLATFORM_WAYLAND_KHR);
}
if (prime_idx) {
print_line(vformat("Found discrete GPU, setting DRI_PRIME=%d to use it.", prime_idx));
print_line("Note: Set DRI_PRIME=0 in the environment to disable Godot from using the discrete GPU.");
setenv("DRI_PRIME", itos(prime_idx).utf8().ptr(), 1);
}
}
}
if (prime_idx == -1) {
print_verbose("Detecting GPUs, set DRI_PRIME in the environment to override GPU detection logic.");
prime_idx = DetectPrimeEGL::detect_prime(EGL_PLATFORM_WAYLAND_KHR);
}
if (prime_idx) {
print_line(vformat("Found discrete GPU, setting DRI_PRIME=%d to use it.", prime_idx));
print_line("Note: Set DRI_PRIME=0 in the environment to disable Godot from using the discrete GPU.");
setenv("DRI_PRIME", itos(prime_idx).utf8().ptr(), 1);
}
}
if (rendering_driver == "opengl3") {
if (egl_found && driver == "opengl3") {
egl_manager = memnew(EGLManagerWayland);
if (egl_manager->initialize(wayland_thread.get_wl_display()) != OK || egl_manager->open_display(wayland_thread.get_wl_display()) != OK) {
memdelete(egl_manager);
egl_manager = nullptr;
bool fallback = GLOBAL_GET("rendering/gl_compatibility/fallback_to_gles");
if (fallback) {
WARN_PRINT("Your video card drivers seem not to support the required OpenGL version, switching to OpenGLES.");
rendering_driver = "opengl3_es";
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
} else {
r_error = ERR_UNAVAILABLE;
OS::get_singleton()->alert(
vformat("Your video card drivers seem not to support the required OpenGL 3.3 version.\n\n"
"If possible, consider updating your video card drivers or using the Vulkan driver.\n\n"
"You can enable the Vulkan driver by starting the engine from the\n"
"command line with the command:\n\n \"%s\" --rendering-driver vulkan\n\n"
"If you recently updated your video card drivers, try rebooting.",
executable_name),
"Unable to initialize OpenGL video driver");
ERR_FAIL_MSG("Could not initialize OpenGL.");
}
} else {
RasterizerGLES3::make_current(true);
if (egl_manager->initialize(wayland_thread.get_wl_display()) == OK && egl_manager->open_display(wayland_thread.get_wl_display()) == OK) {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
memdelete(egl_manager);
egl_manager = nullptr;
}
if (rendering_driver == "opengl3_es") {
if (egl_found && driver == "opengl3_es") {
egl_manager = memnew(EGLManagerWaylandGLES);
if (egl_manager->initialize(wayland_thread.get_wl_display()) != OK || egl_manager->open_display(wayland_thread.get_wl_display()) != OK) {
memdelete(egl_manager);
egl_manager = nullptr;
r_error = ERR_CANT_CREATE;
OS::get_singleton()->alert(
vformat("Your video card drivers seem not to support the required OpenGL ES 3.0 version.\n\n"
"If possible, consider updating your video card drivers or using the Vulkan driver.\n\n"
"You can enable the Vulkan driver by starting the engine from the\n"
"command line with the command:\n\n \"%s\" --rendering-driver vulkan\n\n"
"If you recently updated your video card drivers, try rebooting.",
executable_name),
"Unable to initialize OpenGL ES video driver");
ERR_FAIL_MSG("Could not initialize OpenGL ES.");
if (egl_manager->initialize(wayland_thread.get_wl_display()) == OK && egl_manager->open_display(wayland_thread.get_wl_display()) == OK) {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
RasterizerGLES3::make_current(false);
driver_found = true;
memdelete(egl_manager);
egl_manager = nullptr;
}
#endif // GLES3_ENABLED
if (driver == "dummy") {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
print_line(vformat(" \"%s\" rendering driver initialization failed.", get_readable_driver_name(driver)));
}
if (driver_found) {
print_line(vformat(" \"%s\" rendering driver initialized successfully.", get_readable_driver_name(rendering_driver)));
} else {
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Could not initialize any of the rendering drivers.");
}
#ifdef GLES3_ENABLED
if (rendering_driver == "opengl3") {
RasterizerGLES3::make_current(true);
}
if (rendering_driver == "opengl3_es") {
RasterizerGLES3::make_current(false);
}
#endif // GLES3_ENABLED
if (!driver_found) {
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Video driver not found.");
if (rendering_driver == "dummy") {
RasterizerDummy::make_current();
}
cursor_set_shape(CURSOR_BUSY);

View File

@ -132,6 +132,7 @@ class DisplayServerWayland : public DisplayServer {
bool emulate_vsync = false;
String rendering_driver;
Vector<String> tested_drivers;
#ifdef RD_ENABLED
RenderingContextDriver *rendering_context = nullptr;
@ -314,6 +315,8 @@ public:
static void register_wayland_driver();
String get_readable_driver_name(const String &p_driver) const override;
DisplayServerWayland(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Context p_context, int64_t p_parent_window, Error &r_error);
~DisplayServerWayland();
};

View File

@ -50,6 +50,8 @@
#include "drivers/gles3/rasterizer_gles3.h"
#endif
#include "servers/rendering/dummy/rasterizer_dummy.h"
#include <dlfcn.h>
#include <limits.h>
#include <stdio.h>
@ -2171,7 +2173,10 @@ void DisplayServerX11::window_set_current_screen(int p_screen, WindowID p_window
return;
}
ERR_FAIL_COND_MSG(wd.embed_parent, "Embedded window can't be moved to another screen.");
if (wd.embed_parent) {
print_line("Embedded window can't be moved to another screen.");
return;
}
if (window_get_mode(p_window) == WINDOW_MODE_FULLSCREEN || window_get_mode(p_window) == WINDOW_MODE_MAXIMIZED) {
Point2i position = screen_get_position(p_screen);
@ -2330,7 +2335,10 @@ void DisplayServerX11::window_set_position(const Point2i &p_position, WindowID p
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
ERR_FAIL_COND_MSG(wd.embed_parent, "Embedded window can't be moved.");
if (wd.embed_parent) {
print_line("Embedded window can't be moved.");
return;
}
int x = 0;
int y = 0;
@ -2364,7 +2372,10 @@ void DisplayServerX11::window_set_max_size(const Size2i p_size, WindowID p_windo
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
ERR_FAIL_COND_MSG(wd.embed_parent, "Embedded windows can't have a maximum size.");
if (wd.embed_parent) {
print_line("Embedded windows can't have a maximum size.");
return;
}
if ((p_size != Size2i()) && ((p_size.x < wd.min_size.x) || (p_size.y < wd.min_size.y))) {
ERR_PRINT("Maximum window size can't be smaller than minimum window size!");
@ -2391,7 +2402,10 @@ void DisplayServerX11::window_set_min_size(const Size2i p_size, WindowID p_windo
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
ERR_FAIL_COND_MSG(wd.embed_parent, "Embedded windows can't have a minimum size.");
if (wd.embed_parent) {
print_line("Embedded windows can't have a minimum size.");
return;
}
if ((p_size != Size2i()) && (wd.max_size != Size2i()) && ((p_size.x > wd.max_size.x) || (p_size.y > wd.max_size.y))) {
ERR_PRINT("Minimum window size can't be larger than maximum window size!");
@ -2422,7 +2436,10 @@ void DisplayServerX11::window_set_size(const Size2i p_size, WindowID p_window) {
WindowData &wd = windows[p_window];
ERR_FAIL_COND_MSG(wd.embed_parent, "Embedded window can't be resized.");
if (wd.embed_parent) {
print_line("Embedded window can't be resized.");
return;
}
if (wd.size.width == size.width && wd.size.height == size.height) {
return;
@ -2842,7 +2859,10 @@ void DisplayServerX11::window_set_mode(WindowMode p_mode, WindowID p_window) {
return; // do nothing
}
ERR_FAIL_COND_MSG(p_mode != WINDOW_MODE_WINDOWED && wd.embed_parent, "Embedded window only supports Windowed mode.");
if (p_mode != WINDOW_MODE_WINDOWED && wd.embed_parent) {
print_line("Embedded window only supports Windowed mode.");
return;
}
// Remove all "extra" modes.
switch (old_mode) {
@ -2944,7 +2964,10 @@ void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo
switch (p_flag) {
case WINDOW_FLAG_RESIZE_DISABLED: {
ERR_FAIL_COND_MSG(p_enabled && wd.embed_parent, "Embedded window resize can't be disabled.");
if (p_enabled && wd.embed_parent) {
print_line("Embedded window resize can't be disabled.");
return;
}
wd.resize_disabled = p_enabled;
_update_size_hints(p_window);
@ -2971,7 +2994,10 @@ void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo
} break;
case WINDOW_FLAG_ALWAYS_ON_TOP: {
ERR_FAIL_COND_MSG(wd.transient_parent != INVALID_WINDOW_ID, "Can't make a window transient if the 'on top' flag is active.");
ERR_FAIL_COND_MSG(p_enabled && wd.embed_parent, "Embedded window can't become on top.");
if (p_enabled && wd.embed_parent) {
print_line("Embedded window can't become on top.");
return;
}
if (p_enabled && wd.fullscreen) {
_set_wm_maximized(p_window, true);
}
@ -3013,7 +3039,10 @@ void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo
ERR_FAIL_COND_MSG(p_window == MAIN_WINDOW_ID, "Main window can't be popup.");
ERR_FAIL_COND_MSG((xwa.map_state == IsViewable) && (wd.is_popup != p_enabled), "Popup flag can't changed while window is opened.");
ERR_FAIL_COND_MSG(p_enabled && wd.embed_parent, "Embedded window can't be popup.");
if (p_enabled && wd.embed_parent) {
print_line("Embedded window can't be popup.");
return;
}
wd.is_popup = p_enabled;
} break;
default: {
@ -6003,12 +6032,54 @@ Vector<String> DisplayServerX11::get_rendering_drivers_func() {
drivers.push_back("opengl3");
drivers.push_back("opengl3_es");
#endif
drivers.push_back("dummy");
return drivers;
}
String DisplayServerX11::get_readable_driver_name(const String &p_driver) const {
if (p_driver == "vulkan") {
return "Vulkan";
} else if (p_driver == "opengl3") {
return "OpenGL 3.2";
} else if (p_driver == "opengl3_es") {
return "OpenGLES 3.0";
} else if (p_driver == "dummy") {
return "Dummy";
} else {
return p_driver;
}
}
DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error) {
DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, p_parent_window, r_error));
DisplayServerX11 *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, p_parent_window, r_error));
if (r_error != OK) {
Vector<String> names;
for (const String &driver : ds->tested_drivers) {
names.push_back(ds->get_readable_driver_name(driver));
}
if (!ds->tested_drivers.has("opengl3") && !ds->tested_drivers.has("opengl3_es")) {
String executable_command = vformat("\"%s\" --rendering-driver opengl3", OS::get_singleton()->get_executable_path());
OS::get_singleton()->alert(
vformat("Your video card drivers seem not to support the required version of the following drivers:\n%s.\n\n"
"If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n"
"If you have recently updated your video card drivers, try rebooting.\n\n"
"You can enable the OpenGL 3 driver by starting the engine from the\n"
"command line with the command:\n\n %s",
String(", ").join(names),
executable_command),
"Unable to initialize video driver");
} else {
OS::get_singleton()->alert(
vformat("Your video card drivers seem not to support the required version of the following drivers:\n%s.\n\n"
"If possible, consider updating your video card drivers\n"
"If you have recently updated your video card drivers, try rebooting.",
String(", ").join(names)),
"Unable to initialize video driver");
}
}
return ds;
}
@ -6734,150 +6805,147 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
}
#endif
//!!!!!!!!!!!!!!!!!!!!!!!!!!
//TODO - do Vulkan and OpenGL support checks, driver selection and fallback
rendering_driver = p_rendering_driver;
bool driver_found = false;
String executable_name = OS::get_singleton()->get_executable_path().get_file();
// Initialize context and rendering device.
#if defined(RD_ENABLED)
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
rendering_context = memnew(RenderingContextDriverVulkanX11);
Vector<String> driver_list;
for (const String &drv : p_rendering_driver.split(",")) {
if (!driver_list.has(drv)) {
driver_list.push_back(drv);
}
}
#endif // VULKAN_ENABLED
if (rendering_context) {
if (rendering_context->initialize() != OK) {
memdelete(rendering_context);
rendering_context = nullptr;
#if defined(GLES3_ENABLED)
bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3");
if (fallback_to_opengl3 && rendering_driver != "opengl3") {
WARN_PRINT("Your video card drivers seem not to support the required Vulkan version, switching to OpenGL 3.");
rendering_driver = "opengl3";
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
} else
#endif // GLES3_ENABLED
{
r_error = ERR_CANT_CREATE;
if (p_rendering_driver == "vulkan") {
OS::get_singleton()->alert(
vformat("Your video card drivers seem not to support the required Vulkan version.\n\n"
"If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n"
"You can enable the OpenGL 3 driver by starting the engine from the\n"
"command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n"
"If you recently updated your video card drivers, try rebooting.",
executable_name),
"Unable to initialize Vulkan video driver");
}
ERR_FAIL_MSG(vformat("Could not initialize %s", rendering_driver));
if (GLOBAL_GET("rendering/renderer/fallback_to_opengl3").operator bool()) {
for (const String &drv : GLOBAL_GET("rendering/gl_compatibility/driver").operator String().split(",")) {
if (!driver_list.has(drv)) {
driver_list.push_back(drv);
}
}
driver_found = true;
}
#endif // RD_ENABLED
if (GLOBAL_GET("rendering/renderer/fallback_to_dummy").operator bool()) {
if (!driver_list.has("dummy")) {
driver_list.push_back("dummy");
}
}
#if defined(GLES3_ENABLED)
if (rendering_driver == "opengl3" || rendering_driver == "opengl3_es") {
if (getenv("DRI_PRIME") == nullptr) {
int use_prime = -1;
if (getenv("PRIMUS_DISPLAY") ||
getenv("PRIMUS_libGLd") ||
getenv("PRIMUS_libGLa") ||
getenv("PRIMUS_libGL") ||
getenv("PRIMUS_LOAD_GLOBAL") ||
getenv("BUMBLEBEE_SOCKET")) {
print_verbose("Optirun/primusrun detected. Skipping GPU detection");
use_prime = 0;
bool egl_dri_checked = false;
bool driver_found = false;
for (const String &driver : driver_list) {
print_line(vformat("Trying to initialize \"%s\" rendering driver.", get_readable_driver_name(driver)));
tested_drivers.push_back(driver);
#if defined(RD_ENABLED)
#if defined(VULKAN_ENABLED)
if (driver == "vulkan") {
rendering_context = memnew(RenderingContextDriverVulkanX11);
if (rendering_context->initialize() == OK) {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
memdelete(rendering_context);
rendering_context = nullptr;
}
#endif // VULKAN_ENABLED
#endif // RD_ENABLED
#if defined(GLES3_ENABLED)
if (driver == "opengl3" || driver == "opengl3_es") {
if (!egl_dri_checked) {
egl_dri_checked = true;
if (getenv("DRI_PRIME") == nullptr) {
int use_prime = -1;
// Some tools use fake libGL libraries and have them override the real one using
// LD_LIBRARY_PATH, so we skip them. *But* Steam also sets LD_LIBRARY_PATH for its
// runtime and includes system `/lib` and `/lib64`... so ignore Steam.
if (use_prime == -1 && getenv("LD_LIBRARY_PATH") && !getenv("STEAM_RUNTIME_LIBRARY_PATH")) {
String ld_library_path(getenv("LD_LIBRARY_PATH"));
Vector<String> libraries = ld_library_path.split(":");
for (int i = 0; i < libraries.size(); ++i) {
if (FileAccess::exists(libraries[i] + "/libGL.so.1") ||
FileAccess::exists(libraries[i] + "/libGL.so")) {
print_verbose("Custom libGL override detected. Skipping GPU detection");
if (getenv("PRIMUS_DISPLAY") ||
getenv("PRIMUS_libGLd") ||
getenv("PRIMUS_libGLa") ||
getenv("PRIMUS_libGL") ||
getenv("PRIMUS_LOAD_GLOBAL") ||
getenv("BUMBLEBEE_SOCKET")) {
print_verbose("Optirun/primusrun detected. Skipping GPU detection");
use_prime = 0;
}
// Some tools use fake libGL libraries and have them override the real one using
// LD_LIBRARY_PATH, so we skip them. *But* Steam also sets LD_LIBRARY_PATH for its
// runtime and includes system `/lib` and `/lib64`... so ignore Steam.
if (use_prime == -1 && getenv("LD_LIBRARY_PATH") && !getenv("STEAM_RUNTIME_LIBRARY_PATH")) {
String ld_library_path(getenv("LD_LIBRARY_PATH"));
Vector<String> libraries = ld_library_path.split(":");
for (int i = 0; i < libraries.size(); ++i) {
if (FileAccess::exists(libraries[i] + "/libGL.so.1") ||
FileAccess::exists(libraries[i] + "/libGL.so")) {
print_verbose("Custom libGL override detected. Skipping GPU detection");
use_prime = 0;
}
}
}
if (use_prime == -1) {
print_verbose("Detecting GPUs, set DRI_PRIME in the environment to override GPU detection logic.");
use_prime = detect_prime();
}
if (use_prime) {
print_line("Found discrete GPU, setting DRI_PRIME=1 to use it.");
print_line("Note: Set DRI_PRIME=0 in the environment to disable Godot from using the discrete GPU.");
setenv("DRI_PRIME", "1", 1);
}
}
}
if (use_prime == -1) {
print_verbose("Detecting GPUs, set DRI_PRIME in the environment to override GPU detection logic.");
use_prime = detect_prime();
}
if (use_prime) {
print_line("Found discrete GPU, setting DRI_PRIME=1 to use it.");
print_line("Note: Set DRI_PRIME=0 in the environment to disable Godot from using the discrete GPU.");
setenv("DRI_PRIME", "1", 1);
}
}
}
if (rendering_driver == "opengl3") {
gl_manager = memnew(GLManager_X11(p_resolution, GLManager_X11::GLES_3_0_COMPATIBLE));
if (gl_manager->initialize(x11_display) != OK || gl_manager->open_display(x11_display) != OK) {
if (driver == "opengl3") {
gl_manager = memnew(GLManager_X11(p_resolution, GLManager_X11::GLES_3_0_COMPATIBLE));
if (gl_manager->initialize(x11_display) == OK && gl_manager->open_display(x11_display) == OK) {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
memdelete(gl_manager);
gl_manager = nullptr;
bool fallback = GLOBAL_GET("rendering/gl_compatibility/fallback_to_gles");
if (fallback) {
WARN_PRINT("Your video card drivers seem not to support the required OpenGL version, switching to OpenGLES.");
rendering_driver = "opengl3_es";
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
} else {
r_error = ERR_UNAVAILABLE;
OS::get_singleton()->alert(
vformat("Your video card drivers seem not to support the required OpenGL 3.3 version.\n\n"
"If possible, consider updating your video card drivers or using the Vulkan driver.\n\n"
"You can enable the Vulkan driver by starting the engine from the\n"
"command line with the command:\n\n \"%s\" --rendering-driver vulkan\n\n"
"If you recently updated your video card drivers, try rebooting.",
executable_name),
"Unable to initialize OpenGL video driver");
ERR_FAIL_MSG("Could not initialize OpenGL.");
}
} else {
driver_found = true;
RasterizerGLES3::make_current(true);
}
if (driver == "opengl3_es") {
gl_manager_egl = memnew(GLManagerEGL_X11);
if (gl_manager_egl->initialize() == OK && gl_manager_egl->open_display(x11_display) == OK) {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
memdelete(gl_manager);
gl_manager = nullptr;
}
#endif // GLES3_ENABLED
if (driver == "dummy") {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
print_line(vformat(" \"%s\" rendering driver initialization failed.", get_readable_driver_name(driver)));
}
if (driver_found) {
print_line(vformat(" \"%s\" rendering driver initialized successfully.", get_readable_driver_name(rendering_driver)));
} else {
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Could not initialize any of the rendering drivers.");
}
#if defined(GLES3_ENABLED)
if (rendering_driver == "opengl3") {
RasterizerGLES3::make_current(true);
}
if (rendering_driver == "opengl3_es") {
gl_manager_egl = memnew(GLManagerEGL_X11);
if (gl_manager_egl->initialize() != OK || gl_manager_egl->open_display(x11_display) != OK) {
memdelete(gl_manager_egl);
gl_manager_egl = nullptr;
r_error = ERR_UNAVAILABLE;
OS::get_singleton()->alert(
"Your video card drivers seem not to support the required OpenGL ES 3.0 version.\n\n"
"If possible, consider updating your video card drivers.\n\n"
"If you recently updated your video card drivers, try rebooting.",
"Unable to initialize OpenGL ES video driver");
ERR_FAIL_MSG("Could not initialize OpenGL ES.");
}
driver_found = true;
RasterizerGLES3::make_current(false);
}
#endif // GLES3_ENABLED
if (rendering_driver == "dummy") {
RasterizerDummy::make_current();
}
if (!driver_found) {
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Video driver not found.");

View File

@ -326,6 +326,8 @@ class DisplayServerX11 : public DisplayServer {
HashMap<CursorShape, Vector<Variant>> cursors_cache;
String rendering_driver;
Vector<String> tested_drivers;
void set_wm_fullscreen(bool p_enabled);
void set_wm_above(bool p_enabled);
@ -573,6 +575,8 @@ public:
static void register_x11_driver();
String get_readable_driver_name(const String &p_driver) const override;
DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error);
~DisplayServerX11();
};

View File

@ -148,6 +148,7 @@ private:
RenderingDevice *rendering_device = nullptr;
#endif
String rendering_driver;
Vector<String> tested_drivers;
struct WarpEvent {
NSTimeInterval timestamp;
@ -464,6 +465,8 @@ public:
static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error);
static Vector<String> get_rendering_drivers_func();
String get_readable_driver_name(const String &p_driver) const override;
static void register_macos_driver();
DisplayServerMacOS(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error);

View File

@ -60,6 +60,8 @@
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#endif
#include "servers/rendering/dummy/rasterizer_dummy.h"
#import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
#import <IOKit/IOCFPlugIn.h>
@ -3462,10 +3464,31 @@ bool DisplayServerMacOS::is_window_transparency_available() const {
return OS::get_singleton()->is_layered_allowed();
}
String DisplayServerMacOS::get_readable_driver_name(const String &p_driver) const {
if (p_driver == "metal") {
return "Metal";
} else if (p_driver == "vulkan") {
return "Vulkan (MoltenVK)";
} else if (p_driver == "opengl3") {
return "OpenGL 3.2";
} else if (p_driver == "opengl3_angle") {
return "OpenGLES 3.0 (ANGLE)";
} else if (p_driver == "dummy") {
return "Dummy";
} else {
return p_driver;
}
}
DisplayServer *DisplayServerMacOS::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error) {
DisplayServer *ds = memnew(DisplayServerMacOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, p_parent_window, r_error));
DisplayServerMacOS *ds = memnew(DisplayServerMacOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, p_parent_window, r_error));
if (r_error != OK) {
if (p_rendering_driver == "vulkan") {
Vector<String> names;
for (const String &driver : ds->tested_drivers) {
names.push_back(ds->get_readable_driver_name(driver));
}
if (!ds->tested_drivers.has("opengl3") && !ds->tested_drivers.has("opengl3_angle")) {
String executable_command;
if (OS::get_singleton()->get_bundle_resource_dir() == OS::get_singleton()->get_executable_path().get_base_dir()) {
executable_command = vformat("\"%s\" --rendering-driver opengl3", OS::get_singleton()->get_executable_path());
@ -3473,17 +3496,19 @@ DisplayServer *DisplayServerMacOS::create_func(const String &p_rendering_driver,
executable_command = vformat("open \"%s\" --args --rendering-driver opengl3", OS::get_singleton()->get_bundle_resource_dir().path_join("../..").simplify_path());
}
OS::get_singleton()->alert(
vformat("Your video card drivers seem not to support the required Vulkan version.\n\n"
vformat("Your video card drivers seem not to support the required version of the following drivers:\n%s.\n\n"
"If possible, consider updating your macOS version or using the OpenGL 3 driver.\n\n"
"You can enable the OpenGL 3 driver by starting the engine from the\n"
"command line with the command:\n\n %s",
String(", ").join(names),
executable_command),
"Unable to initialize Vulkan video driver");
"Unable to initialize video driver");
} else {
OS::get_singleton()->alert(
"Your video card drivers seem not to support the required OpenGL 3.3 version.\n\n"
"If possible, consider updating your macOS version.",
"Unable to initialize OpenGL video driver");
vformat("Your video card drivers seem not to support the required version of the following drivers:\n%s.\n\n"
"If possible, consider updating your macOS version.",
String(", ").join(names)),
"Unable to initialize video driver");
}
}
return ds;
@ -3502,6 +3527,7 @@ Vector<String> DisplayServerMacOS::get_rendering_drivers_func() {
drivers.push_back("opengl3");
drivers.push_back("opengl3_angle");
#endif
drivers.push_back("dummy");
return drivers;
}
@ -3783,86 +3809,99 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM
native_menu->_register_system_menus(main_menu, application_menu, window_menu, help_menu, dock_menu);
//!!!!!!!!!!!!!!!!!!!!!!!!!!
//TODO - do Vulkan and OpenGL support checks, driver selection and fallback
rendering_driver = p_rendering_driver;
Vector<String> driver_list;
for (const String &drv : p_rendering_driver.split(",")) {
if (!driver_list.has(drv)) {
driver_list.push_back(drv);
}
}
if (GLOBAL_GET("rendering/renderer/fallback_to_opengl3").operator bool()) {
for (const String &drv : GLOBAL_GET("rendering/gl_compatibility/driver").operator String().split(",")) {
if (!driver_list.has(drv)) {
driver_list.push_back(drv);
}
}
}
if (GLOBAL_GET("rendering/renderer/fallback_to_dummy").operator bool()) {
if (!driver_list.has("dummy")) {
driver_list.push_back("dummy");
}
}
bool driver_found = false;
for (const String &driver : driver_list) {
print_line(vformat("Trying to initialize \"%s\" rendering driver.", get_readable_driver_name(driver)));
tested_drivers.push_back(driver);
#if defined(RD_ENABLED)
#if defined(VULKAN_ENABLED)
#if defined(__x86_64__)
bool fallback_to_vulkan = GLOBAL_GET("rendering/rendering_device/fallback_to_vulkan");
if (!fallback_to_vulkan) {
WARN_PRINT("Metal is not supported on Intel Macs, switching to Vulkan.");
}
// Metal rendering driver not available on Intel.
if (rendering_driver == "metal") {
rendering_driver = "vulkan";
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
}
#endif
if (rendering_driver == "vulkan") {
rendering_context = memnew(RenderingContextDriverVulkanMacOS);
}
#endif
#if defined(METAL_ENABLED)
if (rendering_driver == "metal") {
rendering_context = memnew(RenderingContextDriverMetal);
}
#endif
if (rendering_context) {
if (rendering_context->initialize() != OK) {
if (driver == "metal") {
rendering_context = memnew(RenderingContextDriverMetal);
if (rendering_context->initialize() == OK) {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
memdelete(rendering_context);
rendering_context = nullptr;
}
#endif // METAL_ENABLED
#if defined(VULKAN_ENABLED)
if (driver == "vulkan") {
rendering_context = memnew(RenderingContextDriverVulkanMacOS);
if (rendering_context->initialize() == OK) {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
memdelete(rendering_context);
rendering_context = nullptr;
}
#endif // VULKAN_ENABLED
#endif // RD_ENABLED
#if defined(GLES3_ENABLED)
bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3");
if (fallback_to_opengl3 && rendering_driver != "opengl3") {
WARN_PRINT("Your device seem not to support MoltenVK or Metal, switching to OpenGL 3.");
rendering_driver = "opengl3";
if (driver == "opengl3") {
gl_manager_legacy = memnew(GLManagerLegacy_MacOS);
if (gl_manager_legacy->initialize() == OK) {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
} else
#endif
{
r_error = ERR_CANT_CREATE;
ERR_FAIL_MSG("Could not initialize " + rendering_driver);
driver_found = true;
break;
}
}
}
#endif
#if defined(GLES3_ENABLED)
if (rendering_driver == "opengl3_angle") {
gl_manager_angle = memnew(GLManagerANGLE_MacOS);
if (gl_manager_angle->initialize() != OK || gl_manager_angle->open_display(nullptr) != OK) {
memdelete(gl_manager_angle);
gl_manager_angle = nullptr;
bool fallback = GLOBAL_GET("rendering/gl_compatibility/fallback_to_native");
if (fallback) {
#ifdef EGL_STATIC
WARN_PRINT("Your video card drivers seem not to support GLES3 / ANGLE, switching to native OpenGL.");
#else
WARN_PRINT("Your video card drivers seem not to support GLES3 / ANGLE or ANGLE dynamic libraries (libEGL.dylib and libGLESv2.dylib) are missing, switching to native OpenGL.");
#endif
rendering_driver = "opengl3";
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
} else {
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Could not initialize ANGLE OpenGL.");
}
}
}
if (rendering_driver == "opengl3") {
gl_manager_legacy = memnew(GLManagerLegacy_MacOS);
if (gl_manager_legacy->initialize() != OK) {
memdelete(gl_manager_legacy);
gl_manager_legacy = nullptr;
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Could not initialize native OpenGL.");
}
if (driver == "opengl3_angle") {
gl_manager_angle = memnew(GLManagerANGLE_MacOS);
if (gl_manager_angle->initialize() == OK && gl_manager_angle->open_display(nullptr) == OK) {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
memdelete(gl_manager_angle);
gl_manager_angle = nullptr;
}
#endif // GLES3_ENABLED
if (driver == "dummy") {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
print_line(vformat(" \"%s\" rendering driver initialization failed.", get_readable_driver_name(driver)));
}
if (driver_found) {
print_line(vformat(" \"%s\" rendering driver initialized successfully.", get_readable_driver_name(rendering_driver)));
} else {
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Could not initialize any of the rendering drivers.");
}
#endif
Point2i window_position;
if (p_position != nullptr) {
@ -3902,6 +3941,9 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM
RendererCompositorRD::make_current();
}
#endif
if (rendering_driver == "dummy") {
RasterizerDummy::make_current();
}
screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on"));
}

View File

@ -975,6 +975,8 @@ Vector<String> DisplayServerWeb::get_rendering_drivers_func() {
#ifdef GLES3_ENABLED
drivers.push_back("opengl3");
#endif
drivers.push_back("dummy");
return drivers;
}
@ -1079,8 +1081,32 @@ void DisplayServerWeb::_dispatch_input_event(const Ref<InputEvent> &p_event) {
}
}
String DisplayServerWeb::get_readable_driver_name(const String &p_driver) const {
if (p_driver == "opengl3") {
return "WebGL 2.0";
} else if (p_driver == "dummy") {
return "Dummy";
} else {
return p_driver;
}
}
DisplayServer *DisplayServerWeb::create_func(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error) {
return memnew(DisplayServerWeb(p_rendering_driver, p_window_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, p_parent_window, r_error));
DisplayServerWeb *ds = memnew(DisplayServerWeb(p_rendering_driver, p_window_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, p_parent_window, r_error));
if (r_error != OK) {
Vector<String> names;
for (const String &driver : ds->tested_drivers) {
names.push_back(ds->get_readable_driver_name(driver));
}
OS::get_singleton()->alert(
vformat("Your browser seem not to support the required version of the following drivers:\n%s.\n\n"
"If possible, consider updating your browser version and video card drivers.\n"
"If you have recently updated your video card drivers, try rebooting.",
String(", ").join(names)),
"Unable to initialize video driver");
}
return ds;
}
DisplayServerWeb::DisplayServerWeb(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error) {
@ -1101,35 +1127,77 @@ DisplayServerWeb::DisplayServerWeb(const String &p_rendering_driver, WindowMode
// Expose method for requesting quit.
godot_js_os_request_quit_cb(request_quit_callback);
#ifdef GLES3_ENABLED
bool webgl2_inited = false;
if (godot_js_display_has_webgl(2)) {
EmscriptenWebGLContextAttributes attributes;
emscripten_webgl_init_context_attributes(&attributes);
attributes.alpha = OS::get_singleton()->is_layered_allowed();
attributes.antialias = false;
attributes.majorVersion = 2;
attributes.explicitSwapControl = true;
webgl_ctx = emscripten_webgl_create_context(canvas_id, &attributes);
webgl2_inited = webgl_ctx && emscripten_webgl_make_context_current(webgl_ctx) == EMSCRIPTEN_RESULT_SUCCESS;
}
if (webgl2_inited) {
if (!emscripten_webgl_enable_extension(webgl_ctx, "OVR_multiview2")) {
print_verbose("Failed to enable WebXR extension.");
Vector<String> driver_list;
for (const String &drv : p_rendering_driver.split(",")) {
if (!driver_list.has(drv)) {
driver_list.push_back(drv);
}
RasterizerGLES3::make_current(false);
}
if (GLOBAL_GET("rendering/renderer/fallback_to_opengl3").operator bool()) {
for (const String &drv : GLOBAL_GET("rendering/gl_compatibility/driver").operator String().split(",")) {
if (!driver_list.has(drv)) {
driver_list.push_back(drv);
}
}
}
if (GLOBAL_GET("rendering/renderer/fallback_to_dummy").operator bool()) {
if (!driver_list.has("dummy")) {
driver_list.push_back("dummy");
}
}
bool driver_found = false;
for (const String &driver : driver_list) {
print_line(vformat("Trying to initialize \"%s\" rendering driver.", get_readable_driver_name(driver)));
tested_drivers.push_back(driver);
#if defined(GLES3_ENABLED)
if (driver == "opengl3") {
bool webgl2_inited = false;
if (godot_js_display_has_webgl(2)) {
EmscriptenWebGLContextAttributes attributes;
emscripten_webgl_init_context_attributes(&attributes);
attributes.alpha = OS::get_singleton()->is_layered_allowed();
attributes.antialias = false;
attributes.majorVersion = 2;
attributes.explicitSwapControl = true;
webgl_ctx = emscripten_webgl_create_context(canvas_id, &attributes);
webgl2_inited = webgl_ctx && emscripten_webgl_make_context_current(webgl_ctx) == EMSCRIPTEN_RESULT_SUCCESS;
}
if (webgl2_inited) {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
}
#endif // GLES3_ENABLED
if (driver == "dummy") {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
print_line(vformat(" \"%s\" rendering driver initialization failed.", get_readable_driver_name(driver)));
}
if (driver_found) {
print_line(vformat(" \"%s\" rendering driver initialized successfully.", get_readable_driver_name(rendering_driver)));
} else {
OS::get_singleton()->alert(
"Your browser seems not to support WebGL 2.\n\n"
"If possible, consider updating your browser version and video card drivers.",
"Unable to initialize WebGL 2 video driver");
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Could not initialize any of the rendering drivers.");
}
#ifdef GLES3_ENABLED
if (rendering_driver == "opengl3") {
RasterizerGLES3::make_current(false);
}
#endif
if (rendering_driver == "dummy") {
RasterizerDummy::make_current();
}
#else
RasterizerDummy::make_current();
#endif
// JS Input interface (js/libs/library_godot_input.js)
godot_js_input_mouse_button_cb(&DisplayServerWeb::mouse_button_callback);

View File

@ -152,6 +152,9 @@ private:
void process_joypads();
void process_keys();
String rendering_driver;
Vector<String> tested_drivers;
static Vector<String> get_rendering_drivers_func();
static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error);
@ -289,6 +292,8 @@ public:
virtual bool get_swap_cancel_ok() override;
virtual void swap_buffers() override;
String get_readable_driver_name(const String &p_driver) const override;
static void register_web_driver();
DisplayServerWeb(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Point2i *p_position, const Size2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error);
~DisplayServerWeb();

View File

@ -51,6 +51,7 @@
#if defined(GLES3_ENABLED)
#include "drivers/gles3/rasterizer_gles3.h"
#endif
#include "servers/rendering/dummy/rasterizer_dummy.h"
#include <avrt.h>
#include <dwmapi.h>
@ -83,11 +84,6 @@
#define WM_INDICATOR_CALLBACK_MESSAGE (WM_USER + 1)
#if defined(__GNUC__)
// Workaround GCC warning from -Wcast-function-type.
#define GetProcAddress (void *)GetProcAddress
#endif
static String format_error_message(DWORD id) {
LPWSTR messageBuffer = nullptr;
size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
@ -1294,7 +1290,7 @@ static int QueryDpiForMonitor(HMONITOR hmon, _MonitorDpiType dpiType = MDT_Defau
if (Shcore == nullptr) {
Shcore = LoadLibraryW(L"Shcore.dll");
getDPIForMonitor = Shcore ? (GetDPIForMonitor_t)GetProcAddress(Shcore, "GetDpiForMonitor") : nullptr;
getDPIForMonitor = Shcore ? (GetDPIForMonitor_t)(void *)GetProcAddress(Shcore, "GetDpiForMonitor") : nullptr;
if ((Shcore == nullptr) || (getDPIForMonitor == nullptr)) {
if (Shcore) {
@ -1974,7 +1970,10 @@ void DisplayServerWindows::window_set_current_screen(int p_screen, WindowID p_wi
return;
}
const WindowData &wd = windows[p_window];
ERR_FAIL_COND_MSG(wd.parent_hwnd, "Embedded window can't be moved to another screen.");
if (wd.parent_hwnd) {
print_line("Embedded window can't be moved to another screen.");
return;
}
if (wd.fullscreen) {
Point2 pos = screen_get_position(p_screen) + _get_screens_origin();
Size2 size = screen_get_size(p_screen);
@ -2055,7 +2054,10 @@ void DisplayServerWindows::window_set_position(const Point2i &p_position, Window
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
ERR_FAIL_COND_MSG(wd.parent_hwnd, "Embedded window can't be moved.");
if (wd.parent_hwnd) {
print_line("Embedded window can't be moved.");
return;
}
if (wd.fullscreen || wd.maximized) {
return;
@ -2141,7 +2143,10 @@ void DisplayServerWindows::window_set_max_size(const Size2i p_size, WindowID p_w
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
ERR_FAIL_COND_MSG(wd.parent_hwnd, "Embedded windows can't have a maximum size.");
if (wd.parent_hwnd) {
print_line("Embedded windows can't have a maximum size.");
return;
}
if ((p_size != Size2()) && ((p_size.x < wd.min_size.x) || (p_size.y < wd.min_size.y))) {
ERR_PRINT("Maximum window size can't be smaller than minimum window size!");
@ -2164,7 +2169,10 @@ void DisplayServerWindows::window_set_min_size(const Size2i p_size, WindowID p_w
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
ERR_FAIL_COND_MSG(wd.parent_hwnd, "Embedded windows can't have a minimum size.");
if (wd.parent_hwnd) {
print_line("Embedded windows can't have a minimum size.");
return;
}
if ((p_size != Size2()) && (wd.max_size != Size2()) && ((p_size.x > wd.max_size.x) || (p_size.y > wd.max_size.y))) {
ERR_PRINT("Minimum window size can't be larger than maximum window size!");
@ -2187,7 +2195,10 @@ void DisplayServerWindows::window_set_size(const Size2i p_size, WindowID p_windo
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
ERR_FAIL_COND_MSG(wd.parent_hwnd, "Embedded window can't be resized.");
if (wd.parent_hwnd) {
print_line("Embedded window can't be resized.");
return;
}
if (wd.fullscreen || wd.maximized) {
return;
@ -2345,7 +2356,10 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window)
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
ERR_FAIL_COND_MSG(p_mode != WINDOW_MODE_WINDOWED && wd.parent_hwnd, "Embedded window only supports Windowed mode.");
if (p_mode != WINDOW_MODE_WINDOWED && wd.parent_hwnd) {
print_line("Embedded window only supports Windowed mode.");
return;
}
bool was_fullscreen = wd.fullscreen;
wd.was_fullscreen_pre_min = false;
@ -2480,7 +2494,10 @@ void DisplayServerWindows::window_set_flag(WindowFlags p_flag, bool p_enabled, W
WindowData &wd = windows[p_window];
switch (p_flag) {
case WINDOW_FLAG_RESIZE_DISABLED: {
ERR_FAIL_COND_MSG(p_enabled && wd.parent_hwnd, "Embedded window resize can't be disabled.");
if (p_enabled && wd.parent_hwnd) {
print_line("Embedded window resize can't be disabled.");
return;
}
wd.resizable = !p_enabled;
_update_window_style(p_window);
} break;
@ -2492,7 +2509,10 @@ void DisplayServerWindows::window_set_flag(WindowFlags p_flag, bool p_enabled, W
} break;
case WINDOW_FLAG_ALWAYS_ON_TOP: {
ERR_FAIL_COND_MSG(wd.transient_parent != INVALID_WINDOW_ID && p_enabled, "Transient windows can't become on top.");
ERR_FAIL_COND_MSG(p_enabled && wd.parent_hwnd, "Embedded window can't become on top.");
if (p_enabled && wd.parent_hwnd) {
print_line("Embedded window can't become on top.");
return;
}
wd.always_on_top = p_enabled;
_update_window_style(p_window);
} break;
@ -2552,7 +2572,10 @@ void DisplayServerWindows::window_set_flag(WindowFlags p_flag, bool p_enabled, W
case WINDOW_FLAG_POPUP: {
ERR_FAIL_COND_MSG(p_window == MAIN_WINDOW_ID, "Main window can't be popup.");
ERR_FAIL_COND_MSG(IsWindowVisible(wd.hWnd) && (wd.is_popup != p_enabled), "Popup flag can't changed while window is opened.");
ERR_FAIL_COND_MSG(p_enabled && wd.parent_hwnd, "Embedded window can't be popup.");
if (p_enabled && wd.parent_hwnd) {
print_line("Embedded window can't be popup.");
return;
}
wd.is_popup = p_enabled;
} break;
default:
@ -3137,7 +3160,7 @@ Error DisplayServerWindows::dialog_show(String p_title, String p_description, Ve
if (comctl) {
typedef HRESULT(WINAPI * TaskDialogIndirectPtr)(const TASKDIALOGCONFIG *pTaskConfig, int *pnButton, int *pnRadioButton, BOOL *pfVerificationFlagChecked);
TaskDialogIndirectPtr task_dialog_indirect = (TaskDialogIndirectPtr)GetProcAddress(comctl, "TaskDialogIndirect");
TaskDialogIndirectPtr task_dialog_indirect = (TaskDialogIndirectPtr)(void *)GetProcAddress(comctl, "TaskDialogIndirect");
int button_pressed;
if (task_dialog_indirect && SUCCEEDED(task_dialog_indirect(&config, &button_pressed, nullptr, nullptr))) {
@ -6393,8 +6416,6 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
return id;
}
BitField<DisplayServerWindows::DriverID> DisplayServerWindows::tested_drivers = 0;
// WinTab API.
bool DisplayServerWindows::wintab_available = false;
WTOpenPtr DisplayServerWindows::wintab_WTOpen = nullptr;
@ -6592,9 +6613,9 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
HMODULE nt_lib = LoadLibraryW(L"ntdll.dll");
if (nt_lib) {
WineGetVersionPtr wine_get_version = (WineGetVersionPtr)GetProcAddress(nt_lib, "wine_get_version"); // Do not read Windows build number under Wine, it can be set to arbitrary value.
WineGetVersionPtr wine_get_version = (WineGetVersionPtr)(void *)GetProcAddress(nt_lib, "wine_get_version"); // Do not read Windows build number under Wine, it can be set to arbitrary value.
if (!wine_get_version) {
RtlGetVersionPtr RtlGetVersion = (RtlGetVersionPtr)GetProcAddress(nt_lib, "RtlGetVersion");
RtlGetVersionPtr RtlGetVersion = (RtlGetVersionPtr)(void *)GetProcAddress(nt_lib, "RtlGetVersion");
if (RtlGetVersion) {
RtlGetVersion(&os_ver);
}
@ -6605,28 +6626,28 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
// Load Shell API.
HMODULE shellapi_lib = LoadLibraryW(L"shlwapi.dll");
if (shellapi_lib) {
load_indirect_string = (SHLoadIndirectStringPtr)GetProcAddress(shellapi_lib, "SHLoadIndirectString");
load_indirect_string = (SHLoadIndirectStringPtr)(void *)GetProcAddress(shellapi_lib, "SHLoadIndirectString");
}
// Load UXTheme, available on Windows 10+ only.
if (os_ver.dwBuildNumber >= 10240) {
HMODULE ux_theme_lib = LoadLibraryW(L"uxtheme.dll");
if (ux_theme_lib) {
ShouldAppsUseDarkMode = (ShouldAppsUseDarkModePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(132));
GetImmersiveColorFromColorSetEx = (GetImmersiveColorFromColorSetExPtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(95));
GetImmersiveColorTypeFromName = (GetImmersiveColorTypeFromNamePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(96));
GetImmersiveUserColorSetPreference = (GetImmersiveUserColorSetPreferencePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(98));
ShouldAppsUseDarkMode = (ShouldAppsUseDarkModePtr)(void *)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(132));
GetImmersiveColorFromColorSetEx = (GetImmersiveColorFromColorSetExPtr)(void *)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(95));
GetImmersiveColorTypeFromName = (GetImmersiveColorTypeFromNamePtr)(void *)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(96));
GetImmersiveUserColorSetPreference = (GetImmersiveUserColorSetPreferencePtr)(void *)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(98));
if (os_ver.dwBuildNumber >= 17763) { // Windows 10 Redstone 5 (1809)+ only.
AllowDarkModeForAppPtr AllowDarkModeForApp = nullptr;
SetPreferredAppModePtr SetPreferredAppMode = nullptr;
FlushMenuThemesPtr FlushMenuThemes = nullptr;
if (os_ver.dwBuildNumber < 18362) { // Windows 10 Redstone 5 (1809) and 19H1 (1903) only.
AllowDarkModeForApp = (AllowDarkModeForAppPtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(135));
AllowDarkModeForApp = (AllowDarkModeForAppPtr)(void *)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(135));
} else { // Windows 10 19H2 (1909)+ only.
SetPreferredAppMode = (SetPreferredAppModePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(135));
FlushMenuThemes = (FlushMenuThemesPtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(136));
SetPreferredAppMode = (SetPreferredAppModePtr)(void *)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(135));
FlushMenuThemes = (FlushMenuThemesPtr)(void *)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(136));
}
RefreshImmersiveColorPolicyStatePtr RefreshImmersiveColorPolicyState = (RefreshImmersiveColorPolicyStatePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(104));
RefreshImmersiveColorPolicyStatePtr RefreshImmersiveColorPolicyState = (RefreshImmersiveColorPolicyStatePtr)(void *)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(104));
if (ShouldAppsUseDarkMode) {
bool dark_mode = ShouldAppsUseDarkMode();
if (SetPreferredAppMode) {
@ -6659,10 +6680,10 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
// Note: DPI conversion API, available on Windows 8.1+ only.
HMODULE user32_lib = LoadLibraryW(L"user32.dll");
if (user32_lib) {
win8p_GetPointerType = (GetPointerTypePtr)GetProcAddress(user32_lib, "GetPointerType");
win8p_GetPointerPenInfo = (GetPointerPenInfoPtr)GetProcAddress(user32_lib, "GetPointerPenInfo");
win81p_LogicalToPhysicalPointForPerMonitorDPI = (LogicalToPhysicalPointForPerMonitorDPIPtr)GetProcAddress(user32_lib, "LogicalToPhysicalPointForPerMonitorDPI");
win81p_PhysicalToLogicalPointForPerMonitorDPI = (PhysicalToLogicalPointForPerMonitorDPIPtr)GetProcAddress(user32_lib, "PhysicalToLogicalPointForPerMonitorDPI");
win8p_GetPointerType = (GetPointerTypePtr)(void *)GetProcAddress(user32_lib, "GetPointerType");
win8p_GetPointerPenInfo = (GetPointerPenInfoPtr)(void *)GetProcAddress(user32_lib, "GetPointerPenInfo");
win81p_LogicalToPhysicalPointForPerMonitorDPI = (LogicalToPhysicalPointForPerMonitorDPIPtr)(void *)GetProcAddress(user32_lib, "LogicalToPhysicalPointForPerMonitorDPI");
win81p_PhysicalToLogicalPointForPerMonitorDPI = (PhysicalToLogicalPointForPerMonitorDPIPtr)(void *)GetProcAddress(user32_lib, "PhysicalToLogicalPointForPerMonitorDPI");
winink_available = win8p_GetPointerType && win8p_GetPointerPenInfo;
}
@ -6674,11 +6695,11 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
// Note: Wacom WinTab driver API for pen input, for devices incompatible with Windows Ink.
HMODULE wintab_lib = LoadLibraryW(L"wintab32.dll");
if (wintab_lib) {
wintab_WTOpen = (WTOpenPtr)GetProcAddress(wintab_lib, "WTOpenW");
wintab_WTClose = (WTClosePtr)GetProcAddress(wintab_lib, "WTClose");
wintab_WTInfo = (WTInfoPtr)GetProcAddress(wintab_lib, "WTInfoW");
wintab_WTPacket = (WTPacketPtr)GetProcAddress(wintab_lib, "WTPacket");
wintab_WTEnable = (WTEnablePtr)GetProcAddress(wintab_lib, "WTEnable");
wintab_WTOpen = (WTOpenPtr)(void *)GetProcAddress(wintab_lib, "WTOpenW");
wintab_WTClose = (WTClosePtr)(void *)GetProcAddress(wintab_lib, "WTClose");
wintab_WTInfo = (WTInfoPtr)(void *)GetProcAddress(wintab_lib, "WTInfoW");
wintab_WTPacket = (WTPacketPtr)(void *)GetProcAddress(wintab_lib, "WTPacket");
wintab_WTEnable = (WTEnablePtr)(void *)GetProcAddress(wintab_lib, "WTEnable");
wintab_available = wintab_WTOpen && wintab_WTClose && wintab_WTInfo && wintab_WTPacket && wintab_WTEnable;
}
@ -6716,7 +6737,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
if (Shcore != nullptr) {
typedef HRESULT(WINAPI * SetProcessDpiAwareness_t)(SHC_PROCESS_DPI_AWARENESS);
SetProcessDpiAwareness_t SetProcessDpiAwareness = (SetProcessDpiAwareness_t)GetProcAddress(Shcore, "SetProcessDpiAwareness");
SetProcessDpiAwareness_t SetProcessDpiAwareness = (SetProcessDpiAwareness_t)(void *)GetProcAddress(Shcore, "SetProcessDpiAwareness");
if (SetProcessDpiAwareness) {
SetProcessDpiAwareness(SHC_PROCESS_SYSTEM_DPI_AWARE);
@ -6727,7 +6748,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
HMODULE comctl32 = LoadLibraryW(L"comctl32.dll");
if (comctl32) {
typedef BOOL(WINAPI * InitCommonControlsExPtr)(_In_ const INITCOMMONCONTROLSEX *picce);
InitCommonControlsExPtr init_common_controls_ex = (InitCommonControlsExPtr)GetProcAddress(comctl32, "InitCommonControlsEx");
InitCommonControlsExPtr init_common_controls_ex = (InitCommonControlsExPtr)(void *)GetProcAddress(comctl32, "InitCommonControlsEx");
// Fails if the incorrect version was loaded. Probably not a big enough deal to print an error about.
if (init_common_controls_ex) {
@ -6763,180 +6784,132 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
_register_raw_input_devices(INVALID_WINDOW_ID);
Vector<String> driver_list;
for (const String &drv : p_rendering_driver.split(",")) {
if (!driver_list.has(drv)) {
driver_list.push_back(drv);
}
}
if (GLOBAL_GET("rendering/renderer/fallback_to_opengl3").operator bool()) {
for (const String &drv : GLOBAL_GET("rendering/gl_compatibility/driver").operator String().split(",")) {
if (!driver_list.has(drv)) {
driver_list.push_back(drv);
}
}
}
if (GLOBAL_GET("rendering/renderer/fallback_to_dummy").operator bool()) {
if (!driver_list.has("dummy")) {
driver_list.push_back("dummy");
}
}
bool gl_support_checked = false;
bool force_angle = false;
bool driver_found = false;
for (const String &driver : driver_list) {
print_line(vformat("Trying to initialize \"%s\" rendering driver.", get_readable_driver_name(driver)));
tested_drivers.push_back(driver);
#if defined(RD_ENABLED)
[[maybe_unused]] bool fallback_to_vulkan = GLOBAL_GET("rendering/rendering_device/fallback_to_vulkan");
[[maybe_unused]] bool fallback_to_d3d12 = GLOBAL_GET("rendering/rendering_device/fallback_to_d3d12");
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
rendering_context = memnew(RenderingContextDriverVulkanWindows);
tested_drivers.set_flag(DRIVER_ID_RD_VULKAN);
}
#else
fallback_to_d3d12 = true; // Always enable fallback if engine was built w/o other driver support.
#endif
#if defined(D3D12_ENABLED)
if (rendering_driver == "d3d12") {
rendering_context = memnew(RenderingContextDriverD3D12);
tested_drivers.set_flag(DRIVER_ID_RD_D3D12);
}
#else
fallback_to_vulkan = true; // Always enable fallback if engine was built w/o other driver support.
#endif
if (rendering_context) {
if (rendering_context->initialize() != OK) {
bool failed = true;
if (driver == "d3d12") {
rendering_context = memnew(RenderingContextDriverD3D12);
if (rendering_context->initialize() == OK) {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
memdelete(rendering_context);
rendering_context = nullptr;
}
#endif // METAL_ENABLED
#if defined(VULKAN_ENABLED)
if (failed && fallback_to_vulkan && rendering_driver != "vulkan") {
memdelete(rendering_context);
rendering_context = memnew(RenderingContextDriverVulkanWindows);
tested_drivers.set_flag(DRIVER_ID_RD_VULKAN);
if (rendering_context->initialize() == OK) {
WARN_PRINT("Your video card drivers seem not to support Direct3D 12, switching to Vulkan.");
rendering_driver = "vulkan";
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
failed = false;
}
if (driver == "vulkan") {
rendering_context = memnew(RenderingContextDriverVulkanWindows);
if (rendering_context->initialize() == OK) {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
#endif
#if defined(D3D12_ENABLED)
if (failed && fallback_to_d3d12 && rendering_driver != "d3d12") {
memdelete(rendering_context);
rendering_context = memnew(RenderingContextDriverD3D12);
tested_drivers.set_flag(DRIVER_ID_RD_D3D12);
if (rendering_context->initialize() == OK) {
WARN_PRINT("Your video card drivers seem not to support Vulkan, switching to Direct3D 12.");
rendering_driver = "d3d12";
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
failed = false;
}
}
#endif
memdelete(rendering_context);
rendering_context = nullptr;
}
#endif // VULKAN_ENABLED
#endif // RD_ENABLED
#if defined(GLES3_ENABLED)
bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3");
if (failed && fallback_to_opengl3 && rendering_driver != "opengl3") {
memdelete(rendering_context);
rendering_context = nullptr;
tested_drivers.set_flag(DRIVER_ID_COMPAT_OPENGL3);
WARN_PRINT("Your video card drivers seem not to support Direct3D 12 or Vulkan, switching to OpenGL 3.");
rendering_driver = "opengl3";
if (driver == "opengl3" || driver == "opengl3_angle") {
if (!gl_support_checked) {
gl_support_checked = true;
Dictionary gl_info = detect_wgl();
if (gl_info["version"].operator int() >= 30003) {
Vector2i device_id = _get_device_ids(gl_info["name"]);
Array device_list = GLOBAL_GET("rendering/gl_compatibility/force_angle_on_devices");
for (int i = 0; i < device_list.size(); i++) {
const Dictionary &device = device_list[i];
if (device.has("vendor") && device.has("name")) {
const String &vendor = device["vendor"];
const String &name = device["name"];
if (device_id != Vector2i() && vendor.begins_with("0x") && name.begins_with("0x") && device_id.x == vendor.lstrip("0x").hex_to_int() && device_id.y == name.lstrip("0x").hex_to_int()) {
// Check vendor/device IDs.
force_angle = true;
break;
} else if (gl_info["vendor"].operator String().to_upper().contains(vendor.to_upper()) && (name == "*" || gl_info["name"].operator String().to_upper().contains(name.to_upper()))) {
// Check vendor/device names.
force_angle = true;
break;
}
}
}
} else {
force_angle = true;
}
}
}
if (!force_angle && driver == "opengl3") {
gl_manager_native = memnew(GLManagerNative_Windows);
if (gl_manager_native->initialize() == OK) {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
failed = false;
driver_found = true;
break;
}
#endif
if (failed) {
memdelete(rendering_context);
rendering_context = nullptr;
r_error = ERR_UNAVAILABLE;
return;
}
}
}
#endif
// Init context and rendering device
#if defined(GLES3_ENABLED)
bool fallback = GLOBAL_GET("rendering/gl_compatibility/fallback_to_angle");
bool show_warning = true;
if (rendering_driver == "opengl3") {
// There's no native OpenGL drivers on Windows for ARM, always enable fallback.
#if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) || defined(_M_ARM64)
fallback = true;
show_warning = false;
#else
typedef BOOL(WINAPI * IsWow64Process2Ptr)(HANDLE, USHORT *, USHORT *);
IsWow64Process2Ptr IsWow64Process2 = (IsWow64Process2Ptr)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process2");
if (IsWow64Process2) {
USHORT process_arch = 0;
USHORT machine_arch = 0;
if (!IsWow64Process2(GetCurrentProcess(), &process_arch, &machine_arch)) {
machine_arch = 0;
}
if (machine_arch == 0xAA64) {
fallback = true;
show_warning = false;
}
}
#endif
}
bool gl_supported = true;
if (fallback && (rendering_driver == "opengl3")) {
Dictionary gl_info = detect_wgl();
bool force_angle = false;
gl_supported = gl_info["version"].operator int() >= 30003;
Vector2i device_id = _get_device_ids(gl_info["name"]);
Array device_list = GLOBAL_GET("rendering/gl_compatibility/force_angle_on_devices");
for (int i = 0; i < device_list.size(); i++) {
const Dictionary &device = device_list[i];
if (device.has("vendor") && device.has("name")) {
const String &vendor = device["vendor"];
const String &name = device["name"];
if (device_id != Vector2i() && vendor.begins_with("0x") && name.begins_with("0x") && device_id.x == vendor.lstrip("0x").hex_to_int() && device_id.y == name.lstrip("0x").hex_to_int()) {
// Check vendor/device IDs.
force_angle = true;
break;
} else if (gl_info["vendor"].operator String().to_upper().contains(vendor.to_upper()) && (name == "*" || gl_info["name"].operator String().to_upper().contains(name.to_upper()))) {
// Check vendor/device names.
force_angle = true;
break;
}
}
}
if (force_angle || (gl_info["version"].operator int() < 30003)) {
tested_drivers.set_flag(DRIVER_ID_COMPAT_OPENGL3);
if (show_warning) {
if (gl_info["version"].operator int() < 30003) {
WARN_PRINT("Your video card drivers seem not to support the required OpenGL 3.3 version, switching to ANGLE.");
} else {
WARN_PRINT("Your video card drivers are known to have low quality OpenGL 3.3 support, switching to ANGLE.");
}
}
rendering_driver = "opengl3_angle";
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
}
}
if (rendering_driver == "opengl3_angle") {
gl_manager_angle = memnew(GLManagerANGLE_Windows);
tested_drivers.set_flag(DRIVER_ID_COMPAT_ANGLE_D3D11);
if (gl_manager_angle->initialize() != OK) {
memdelete(gl_manager_angle);
gl_manager_angle = nullptr;
bool fallback_to_native = GLOBAL_GET("rendering/gl_compatibility/fallback_to_native");
if (fallback_to_native && gl_supported) {
#ifdef EGL_STATIC
WARN_PRINT("Your video card drivers seem not to support GLES3 / ANGLE, switching to native OpenGL.");
#else
WARN_PRINT("Your video card drivers seem not to support GLES3 / ANGLE or ANGLE dynamic libraries (libEGL.dll and libGLESv2.dll) are missing, switching to native OpenGL.");
#endif
rendering_driver = "opengl3";
} else {
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Could not initialize ANGLE OpenGL.");
}
}
}
if (rendering_driver == "opengl3") {
gl_manager_native = memnew(GLManagerNative_Windows);
tested_drivers.set_flag(DRIVER_ID_COMPAT_OPENGL3);
if (gl_manager_native->initialize() != OK) {
memdelete(gl_manager_native);
gl_manager_native = nullptr;
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Could not initialize native OpenGL.");
}
if (force_angle || driver == "opengl3_angle") {
gl_manager_angle = memnew(GLManagerANGLE_Windows);
if (gl_manager_angle->initialize() == OK) {
rendering_driver = "opengl3_angle";
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
memdelete(gl_manager_angle);
gl_manager_angle = nullptr;
}
#endif // GLES3_ENABLED
if (driver == "dummy") {
rendering_driver = driver;
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
driver_found = true;
break;
}
print_line(vformat(" \"%s\" rendering driver initialization failed.", get_readable_driver_name(driver)));
}
if (driver_found) {
print_line(vformat(" \"%s\" rendering driver initialized successfully.", get_readable_driver_name(rendering_driver)));
} else {
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Could not initialize any of the rendering drivers.");
}
#if defined(GLES3_ENABLED)
if (rendering_driver == "opengl3") {
RasterizerGLES3::make_current(true);
}
@ -6944,6 +6917,10 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
RasterizerGLES3::make_current(false);
}
#endif
if (rendering_driver == "dummy") {
RasterizerDummy::make_current();
}
String appname;
if (Engine::get_singleton()->is_editor_hint()) {
appname = "Godot.GodotEditor." + String(VERSION_FULL_CONFIG);
@ -7067,47 +7044,53 @@ Vector<String> DisplayServerWindows::get_rendering_drivers_func() {
drivers.push_back("opengl3");
drivers.push_back("opengl3_angle");
#endif
drivers.push_back("dummy");
return drivers;
}
String DisplayServerWindows::get_readable_driver_name(const String &p_driver) const {
if (p_driver == "d3d12") {
return "Direct3D 12";
} else if (p_driver == "vulkan") {
return "Vulkan";
} else if (p_driver == "opengl3") {
return "OpenGL 3.2";
} else if (p_driver == "opengl3_angle") {
return "OpenGLES 3.0 (ANGLE)";
} else if (p_driver == "dummy") {
return "Dummy";
} else {
return p_driver;
}
}
DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error) {
DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, p_parent_window, r_error));
DisplayServerWindows *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, p_parent_window, r_error));
if (r_error != OK) {
if (tested_drivers == 0) {
OS::get_singleton()->alert("Failed to register the window class.", "Unable to initialize DisplayServer");
} else if (tested_drivers.has_flag(DRIVER_ID_RD_VULKAN) || tested_drivers.has_flag(DRIVER_ID_RD_D3D12)) {
Vector<String> drivers;
if (tested_drivers.has_flag(DRIVER_ID_RD_VULKAN)) {
drivers.push_back("Vulkan");
}
if (tested_drivers.has_flag(DRIVER_ID_RD_D3D12)) {
drivers.push_back("Direct3D 12");
}
String executable_name = OS::get_singleton()->get_executable_path().get_file();
Vector<String> names;
for (const String &driver : ds->tested_drivers) {
names.push_back(ds->get_readable_driver_name(driver));
}
if (!ds->tested_drivers.has("opengl3") && !ds->tested_drivers.has("opengl3_angle")) {
String executable_command = vformat("\"%s\" --rendering-driver opengl3", OS::get_singleton()->get_executable_path());
OS::get_singleton()->alert(
vformat("Your video card drivers seem not to support the required %s version.\n\n"
"If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n"
vformat("Your video card drivers seem not to support the required version of the following drivers:\n%s.\n\n"
"If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n"
"If you have recently updated your video card drivers, try rebooting.\n\n"
"You can enable the OpenGL 3 driver by starting the engine from the\n"
"command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n"
"If you have recently updated your video card drivers, try rebooting.",
String(" or ").join(drivers),
executable_name),
"command line with the command:\n\n %s",
String(", ").join(names),
executable_command),
"Unable to initialize video driver");
} else {
Vector<String> drivers;
if (tested_drivers.has_flag(DRIVER_ID_COMPAT_OPENGL3)) {
drivers.push_back("OpenGL 3.3");
}
if (tested_drivers.has_flag(DRIVER_ID_COMPAT_ANGLE_D3D11)) {
drivers.push_back("Direct3D 11");
}
OS::get_singleton()->alert(
vformat(
"Your video card drivers seem not to support the required %s version.\n\n"
"If possible, consider updating your video card drivers.\n\n"
vformat("Your video card drivers seem not to support the required version of the following drivers:\n%s.\n\n"
"If possible, consider updating your video card drivers\n"
"If you have recently updated your video card drivers, try rebooting.",
String(" or ").join(drivers)),
String(", ").join(names)),
"Unable to initialize video driver");
}
}

View File

@ -407,14 +407,6 @@ class DisplayServerWindows : public DisplayServer {
Vector<String> tablet_drivers;
bool winink_disabled = false;
enum DriverID {
DRIVER_ID_COMPAT_OPENGL3 = 1 << 0,
DRIVER_ID_COMPAT_ANGLE_D3D11 = 1 << 1,
DRIVER_ID_RD_VULKAN = 1 << 2,
DRIVER_ID_RD_D3D12 = 1 << 3,
};
static BitField<DriverID> tested_drivers;
enum TimerID {
TIMER_ID_MOVE_REDRAW = 1,
TIMER_ID_WINDOW_ACTIVATION = 2,
@ -458,6 +450,8 @@ class DisplayServerWindows : public DisplayServer {
int pressrc;
HINSTANCE hInstance; // Holds The Instance Of The Application
String rendering_driver;
Vector<String> tested_drivers;
bool app_focused = false;
bool keep_screen_on = false;
HANDLE power_request;
@ -885,6 +879,8 @@ public:
static Vector<String> get_rendering_drivers_func();
static void register_windows_driver();
String get_readable_driver_name(const String &p_driver) const override;
DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error);
~DisplayServerWindows();
};

View File

@ -50,11 +50,6 @@
#define _WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
#if defined(__GNUC__)
// Workaround GCC warning from -Wcast-function-type.
#define GetProcAddress (void *)GetProcAddress
#endif
typedef HGLRC(APIENTRY *PFNWGLCREATECONTEXT)(HDC);
typedef BOOL(APIENTRY *PFNWGLDELETECONTEXT)(HGLRC);
typedef BOOL(APIENTRY *PFNWGLMAKECURRENT)(HDC, HGLRC);
@ -364,10 +359,10 @@ Error GLManagerNative_Windows::_create_context(GLWindow &win, GLDisplay &gl_disp
if (!module) {
return ERR_CANT_CREATE;
}
gd_wglCreateContext = (PFNWGLCREATECONTEXT)GetProcAddress(module, "wglCreateContext");
gd_wglMakeCurrent = (PFNWGLMAKECURRENT)GetProcAddress(module, "wglMakeCurrent");
gd_wglDeleteContext = (PFNWGLDELETECONTEXT)GetProcAddress(module, "wglDeleteContext");
gd_wglGetProcAddress = (PFNWGLGETPROCADDRESS)GetProcAddress(module, "wglGetProcAddress");
gd_wglCreateContext = (PFNWGLCREATECONTEXT)(void *)GetProcAddress(module, "wglCreateContext");
gd_wglMakeCurrent = (PFNWGLMAKECURRENT)(void *)GetProcAddress(module, "wglMakeCurrent");
gd_wglDeleteContext = (PFNWGLDELETECONTEXT)(void *)GetProcAddress(module, "wglDeleteContext");
gd_wglGetProcAddress = (PFNWGLGETPROCADDRESS)(void *)GetProcAddress(module, "wglGetProcAddress");
if (!gd_wglCreateContext || !gd_wglMakeCurrent || !gd_wglDeleteContext || !gd_wglGetProcAddress) {
return ERR_CANT_CREATE;
}

View File

@ -33,11 +33,6 @@
#include <oleauto.h>
#include <wbemidl.h>
#if defined(__GNUC__)
// Workaround GCC warning from -Wcast-function-type.
#define GetProcAddress (void *)GetProcAddress
#endif
DWORD WINAPI _xinput_get_state(DWORD dwUserIndex, XINPUT_STATE *pState) {
return ERROR_DEVICE_NOT_CONNECTED;
}
@ -597,8 +592,8 @@ void JoypadWindows::load_xinput() {
// (LPCSTR)100 is the magic number to get XInputGetStateEx, which also provides the state for the guide button
LPCSTR get_state_func_name = legacy_xinput ? "XInputGetState" : (LPCSTR)100;
XInputGetState_t func = (XInputGetState_t)GetProcAddress((HMODULE)xinput_dll, get_state_func_name);
XInputSetState_t set_func = (XInputSetState_t)GetProcAddress((HMODULE)xinput_dll, "XInputSetState");
XInputGetState_t func = (XInputGetState_t)(void *)GetProcAddress((HMODULE)xinput_dll, get_state_func_name);
XInputSetState_t set_func = (XInputSetState_t)(void *)GetProcAddress((HMODULE)xinput_dll, "XInputSetState");
if (!func || !set_func) {
unload_xinput();
return;
@ -608,7 +603,7 @@ void JoypadWindows::load_xinput() {
winmm_dll = LoadLibrary("Winmm.dll");
if (winmm_dll) {
joyGetDevCaps_t caps_func = (joyGetDevCaps_t)GetProcAddress((HMODULE)winmm_dll, "joyGetDevCapsW");
joyGetDevCaps_t caps_func = (joyGetDevCaps_t)(void *)GetProcAddress((HMODULE)winmm_dll, "joyGetDevCapsW");
if (caps_func) {
winmm_get_joycaps = caps_func;
} else {

View File

@ -106,11 +106,6 @@ __declspec(dllexport) void NoHotPatch() {} // Disable Nahimic code injection.
#define DWRITE_FONT_WEIGHT_SEMI_LIGHT (DWRITE_FONT_WEIGHT)350
#endif
#if defined(__GNUC__)
// Workaround GCC warning from -Wcast-function-type.
#define GetProcAddress (void *)GetProcAddress
#endif
static String fix_path(const String &p_path) {
String path = p_path;
if (p_path.is_relative_path()) {
@ -503,8 +498,8 @@ Error OS_Windows::open_dynamic_library(const String &p_path, void *&p_library_ha
typedef DLL_DIRECTORY_COOKIE(WINAPI * PAddDllDirectory)(PCWSTR);
typedef BOOL(WINAPI * PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE);
PAddDllDirectory add_dll_directory = (PAddDllDirectory)GetProcAddress(GetModuleHandle("kernel32.dll"), "AddDllDirectory");
PRemoveDllDirectory remove_dll_directory = (PRemoveDllDirectory)GetProcAddress(GetModuleHandle("kernel32.dll"), "RemoveDllDirectory");
PAddDllDirectory add_dll_directory = (PAddDllDirectory)(void *)GetProcAddress(GetModuleHandle("kernel32.dll"), "AddDllDirectory");
PRemoveDllDirectory remove_dll_directory = (PRemoveDllDirectory)(void *)GetProcAddress(GetModuleHandle("kernel32.dll"), "RemoveDllDirectory");
bool has_dll_directory_api = ((add_dll_directory != nullptr) && (remove_dll_directory != nullptr));
DLL_DIRECTORY_COOKIE cookie = nullptr;
@ -603,7 +598,7 @@ String OS_Windows::get_distribution_name() const {
}
String OS_Windows::get_version() const {
RtlGetVersionPtr version_ptr = (RtlGetVersionPtr)GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlGetVersion");
RtlGetVersionPtr version_ptr = (RtlGetVersionPtr)(void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlGetVersion");
if (version_ptr != nullptr) {
RTL_OSVERSIONINFOEXW fow;
ZeroMemory(&fow, sizeof(fow));
@ -616,7 +611,7 @@ String OS_Windows::get_version() const {
}
String OS_Windows::get_version_alias() const {
RtlGetVersionPtr version_ptr = (RtlGetVersionPtr)GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlGetVersion");
RtlGetVersionPtr version_ptr = (RtlGetVersionPtr)(void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlGetVersion");
if (version_ptr != nullptr) {
RTL_OSVERSIONINFOEXW fow;
ZeroMemory(&fow, sizeof(fow));
@ -789,7 +784,7 @@ bool OS_Windows::get_user_prefers_integrated_gpu() const {
HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll");
if (kernel32) {
using GetCurrentApplicationUserModelIdPtr = LONG(WINAPI *)(UINT32 * length, PWSTR id);
GetCurrentApplicationUserModelIdPtr GetCurrentApplicationUserModelId = (GetCurrentApplicationUserModelIdPtr)GetProcAddress(kernel32, "GetCurrentApplicationUserModelId");
GetCurrentApplicationUserModelIdPtr GetCurrentApplicationUserModelId = (GetCurrentApplicationUserModelIdPtr)(void *)GetProcAddress(kernel32, "GetCurrentApplicationUserModelId");
if (GetCurrentApplicationUserModelId) {
UINT32 length = sizeof(value_name) / sizeof(value_name[0]);
@ -991,7 +986,7 @@ Dictionary OS_Windows::get_memory_info() const {
GetPerformanceInfo(&pref_info, sizeof(pref_info));
typedef void(WINAPI * PGetCurrentThreadStackLimits)(PULONG_PTR, PULONG_PTR);
PGetCurrentThreadStackLimits GetCurrentThreadStackLimits = (PGetCurrentThreadStackLimits)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetCurrentThreadStackLimits");
PGetCurrentThreadStackLimits GetCurrentThreadStackLimits = (PGetCurrentThreadStackLimits)(void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetCurrentThreadStackLimits");
ULONG_PTR LowLimit = 0;
ULONG_PTR HighLimit = 0;

View File

@ -53,11 +53,6 @@
#define WGL_RENDERER 0x1F01
#define WGL_VERSION 0x1F02
#if defined(__GNUC__)
// Workaround GCC warning from -Wcast-function-type.
#define GetProcAddress (void *)GetProcAddress
#endif
typedef HGLRC(APIENTRY *PFNWGLCREATECONTEXT)(HDC);
typedef BOOL(APIENTRY *PFNWGLDELETECONTEXT)(HGLRC);
typedef BOOL(APIENTRY *PFNWGLMAKECURRENT)(HDC, HGLRC);
@ -80,10 +75,10 @@ Dictionary detect_wgl() {
if (!module) {
return gl_info;
}
gd_wglCreateContext = (PFNWGLCREATECONTEXT)GetProcAddress(module, "wglCreateContext");
gd_wglMakeCurrent = (PFNWGLMAKECURRENT)GetProcAddress(module, "wglMakeCurrent");
gd_wglDeleteContext = (PFNWGLDELETECONTEXT)GetProcAddress(module, "wglDeleteContext");
gd_wglGetProcAddress = (PFNWGLGETPROCADDRESS)GetProcAddress(module, "wglGetProcAddress");
gd_wglCreateContext = (PFNWGLCREATECONTEXT)(void *)GetProcAddress(module, "wglCreateContext");
gd_wglMakeCurrent = (PFNWGLMAKECURRENT)(void *)GetProcAddress(module, "wglMakeCurrent");
gd_wglDeleteContext = (PFNWGLDELETECONTEXT)(void *)GetProcAddress(module, "wglDeleteContext");
gd_wglGetProcAddress = (PFNWGLGETPROCADDRESS)(void *)GetProcAddress(module, "wglGetProcAddress");
if (!gd_wglCreateContext || !gd_wglMakeCurrent || !gd_wglDeleteContext || !gd_wglGetProcAddress) {
return gl_info;
}
@ -143,7 +138,7 @@ Dictionary detect_wgl() {
HGLRC new_hRC = gd_wglCreateContextAttribsARB(hDC, nullptr, attribs);
if (new_hRC) {
if (gd_wglMakeCurrent(hDC, new_hRC)) {
PFNWGLGETSTRINGPROC gd_wglGetString = (PFNWGLGETSTRINGPROC)GetProcAddress(module, "glGetString");
PFNWGLGETSTRINGPROC gd_wglGetString = (PFNWGLGETSTRINGPROC)(void *)GetProcAddress(module, "glGetString");
if (gd_wglGetString) {
const char *prefixes[] = {
"OpenGL ES-CM ",

View File

@ -4196,10 +4196,20 @@ void Tree::set_editor_selection(int p_from_line, int p_to_line, int p_from_colum
}
}
Size2 Tree::get_background_size() const {
const Ref<StyleBox> background = theme_cache.panel_style;
// This is the background stylebox's content rect.
const real_t width = background->get_margin(SIDE_LEFT) + background->get_margin(SIDE_RIGHT);
const real_t height = background->get_margin(SIDE_TOP) + background->get_margin(SIDE_BOTTOM);
return Size2(width, height);
}
Size2 Tree::get_internal_min_size() const {
Size2i size;
if (root) {
size.height += get_item_height(root);
size.height -= theme_cache.v_separation;
}
for (int i = 0; i < columns.size(); i++) {
size.width += get_column_minimum_width(i);

View File

@ -657,7 +657,6 @@ private:
bool h_scroll_enabled = true;
bool v_scroll_enabled = true;
Size2 get_internal_min_size() const;
void update_scrollbars();
Rect2 search_item_rect(TreeItem *p_from, TreeItem *p_item);
@ -798,6 +797,8 @@ public:
void ensure_cursor_is_visible();
Rect2 get_custom_popup_rect() const;
Size2 get_background_size() const;
Size2 get_internal_min_size() const;
int get_item_offset(TreeItem *p_item) const;
Rect2 get_item_rect(TreeItem *p_item, int p_column = -1, int p_button = -1) const;

View File

@ -637,6 +637,8 @@ public:
void unregister_additional_output(Object *p_output);
bool has_additional_outputs() const { return additional_outputs.size() > 0; }
virtual String get_readable_driver_name(const String &p_driver) const { return p_driver; }
static void register_create_function(const char *p_name, CreateFunction p_function, GetRenderingDriversFunction p_get_drivers);
static int get_create_function_count();
static const char *get_create_function_name(int p_index);

View File

@ -799,7 +799,7 @@ void MaterialStorage::MaterialData::update_uniform_buffer(const HashMap<StringNa
} else if (E.value.default_value.size()) {
//default value
_fill_std140_ubo_value(E.value.type, E.value.default_value, data, p_use_linear_color);
_fill_std140_ubo_value(E.value.type, E.value.default_value, data, E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR && p_use_linear_color);
//value=E.value.default_value;
} else {
//zero because it was not provided