We now cache the Node*<>TreeItem* mapping in the SceneTreeEditor. This
allows us to make targeted updates to the Tree used to display the scene
tree in the editor.
Previously on almost all changes to the scene tree the editor would
rebuild the entire widget, causing a large number of deallocations an
allocations. We now carefully manipulate the Tree widget in-situ saving
a large number of these allocations.
In order to know what Nodes need to be updated we add a
editor_state_changed signal to Node, this is a TOOLS_ENABLED,
editor-only signal fired when changes to Node happen that are relevant
to editor state.
We also now make sure that when nodes are moved/renamed we don't check
expensive properties that cannot contain NodePaths. This saves a lot of
time when SceneTreeDock renames a node in a scene with a lot of
MeshInstances. This makes renaming nodes go from ~27 seconds to ~2
seconds on large scenes.
SceneTreeEditor instances will now also not do all of the potentially
expensive update work if they are invisible. This behavior is turned off
by default so it won't affect existing users. This change allows the
editor to only update SceneTreeEditors that actually in view. In
practice this means that for most changes instead of updating 6
SceneTreeEditors we only update 1 instantly, and the others only when
they become visible.
There is definitely more that could be done, but this is already a
massive improvement. In complex scenes we see an improvement of 10x,
things that used to take ~30 seconds now only take 2.
This fixes#83460
I want to thank KoBeWi, TokisanGames, a-johnston, aniel080400 for
their tireless testing. And AeioMuch for their testing and providing a
fix for the hover issue.
This new method allow you to get the line offset of the current
selection (returns -1 if nothing is selected.)
This is useful if you want to pop up a control or menu above the
currently selected text. Previously there was no accurate way to get
this information.
The logic is moved from the implementation of `scroll_to_selection`
verbatim, and that method has been adjusted to avoid repetition.
The work was performed by collaboration of TheForge and Google. I am
merely splitting it up into smaller PRs and cleaning it up.
This is the most "risky" PR so far because the previous ones have been
miscellaneous stuff aimed at either [improve
debugging](https://github.com/godotengine/godot/pull/90993) (e.g. device
lost), [improve Android
experience](https://github.com/godotengine/godot/pull/96439) (add Swappy
for better Frame Pacing + Pre-Transformed Swapchains for slightly better
performance), or harmless [ASTC
improvements](https://github.com/godotengine/godot/pull/96045) (better
performance by simply toggling a feature when available).
However this PR contains larger modifications aimed at improving
performance or reducing memory fragmentation. With greater
modifications, come greater risks of bugs or breakage.
Changes introduced by this PR:
TBDR GPUs (e.g. most of Android + iOS + M1 Apple) support rendering to
Render Targets that are not backed by actual GPU memory (everything
stays in cache). This works as long as load action isn't `LOAD`, and
store action must be `DONT_CARE`. This saves VRAM (it also makes
painfully obvious when a mistake introduces a performance regression).
Of particular usefulness is when doing MSAA and keeping the raw MSAA
content is not necessary.
Some GPUs get faster when the sampler settings are hard-coded into the
GLSL shaders (instead of being dynamically bound at runtime). This
required changes to the GLSL shaders, PSO creation routines, Descriptor
creation routines, and Descriptor binding routines.
- `bool immutable_samplers_enabled = true`
Setting it to false enforces the old behavior. Useful for debugging bugs
and regressions.
Immutable samplers requires that the samplers stay... immutable, hence
this boolean is useful if the promise gets broken. We might want to turn
this into a `GLOBAL_DEF` setting.
Instead of creating dozen/hundreds/thousands of `VkDescriptorSet` every
frame that need to be freed individually when they are no longer needed,
they all get freed at once by resetting the whole pool. Once the whole
pool is no longer in use by the GPU, it gets reset and its memory
recycled. Descriptor sets that are created to be kept around for longer
or forever (i.e. not created and freed within the same frame) **must
not** use linear pools. There may be more than one pool per frame. How
many pools per frame Godot ends up with depends on its capacity, and
that is controlled by
`rendering/rendering_device/vulkan/max_descriptors_per_pool`.
- **Possible improvement for later:** It should be possible for Godot
to adapt to how many descriptors per pool are needed on a per-key basis
(i.e. grow their capacity like `std::vector` does) after rendering a few
frames; which would be better than the current solution of having a
single global value for all pools (`max_descriptors_per_pool`) that the
user needs to tweak.
- `bool linear_descriptor_pools_enabled = true`
Setting it to false enforces the old behavior. Useful for debugging bugs
and regressions.
Setting it to false is required when workarounding driver bugs (e.g.
Adreno 730).
A ridiculous optimization. Ridiculous because the original code
should've done this in the first place. Previously Godot was doing the
following:
1. Create a command buffer **pool**. One per frame.
2. Create multiple command buffers from the pool in point 1.
3. Call `vkBeginCommandBuffer` on the cmd buffer in point 2. This
resets the cmd buffer because Godot requests the
`VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT` flag.
4. Add commands to the cmd buffers from point 2.
5. Submit those commands.
6. On frame N + 2, recycle the buffer pool and cmd buffers from pt 1 &
2, and repeat from step 3.
The problem here is that step 3 resets each command buffer individually.
Initially Godot used to have 1 cmd buffer per pool, thus the impact is
very low.
But not anymore (specially with Adreno workarounds to force splitting
compute dispatches into a new cmd buffer, more on this later). However
Godot keeps around a very low amount of command buffers per frame.
The recommended method is to reset the whole pool, to reset all cmd
buffers at once. Hence the new steps would be:
1. Create a command buffer **pool**. One per frame.
2. Create multiple command buffers from the pool in point 1.
3. Call `vkBeginCommandBuffer` on the cmd buffer in point 2, which is
already reset/empty (see step 6).
4. Add commands to the cmd buffers from point 2.
5. Submit those commands.
6. On frame N + 2, recycle the buffer pool and cmd buffers from pt 1 &
2, call `vkResetCommandPool` and repeat from step 3.
**Possible issues:** @dariosamo added `transfer_worker` which creates a
command buffer pool:
```cpp
transfer_worker->command_pool =
driver->command_pool_create(transfer_queue_family,
RDD::COMMAND_BUFFER_TYPE_PRIMARY);
```
As expected, validation was complaining that command buffers were being
reused without being reset (that's good, we now know Validation Layers
will warn us of wrong use).
I fixed it by adding:
```cpp
void RenderingDevice::_wait_for_transfer_worker(TransferWorker
*p_transfer_worker) {
driver->fence_wait(p_transfer_worker->command_fence);
driver->command_pool_reset(p_transfer_worker->command_pool); //
! New line !
```
**Secondary cmd buffers are subject to the same issue but I didn't alter
them. I talked this with Dario and he is aware of this.**
Secondary cmd buffers are currently disabled due to other issues (it's
disabled on master).
- `bool RenderingDeviceCommons::command_pool_reset_enabled`
Setting it to false enforces the old behavior. Useful for debugging bugs
and regressions.
There's no other reason for this boolean. Possibly once it becomes well
tested, the boolean could be removed entirely.
Adds `command_bind_render_uniform_sets` and
`add_draw_list_bind_uniform_sets` (+ compute variants).
It performs the same as `add_draw_list_bind_uniform_set` (notice
singular vs plural), but on multiple consecutive uniform sets, thus
reducing graph and draw call overhead.
- `bool descriptor_set_batching = true;`
Setting it to false enforces the old behavior. Useful for debugging bugs
and regressions.
There's no other reason for this boolean. Possibly once it becomes well
tested, the boolean could be removed entirely.
Godot currently does the following:
1. Fill the entire cmd buffer with commands.
2. `submit()`
- Wait with a semaphore for the swapchain.
- Trigger a semaphore to indicate when we're done (so the swapchain
can submit).
3. `present()`
The optimization opportunity here is that 95% of Godot's rendering is
done offscreen.
Then a fullscreen pass copies everything to the swapchain. Godot doesn't
practically render directly to the swapchain.
The problem with this is that the GPU has to wait for the swapchain to
be released **to start anything**, when we could start *much earlier*.
Only the final blit pass must wait for the swapchain.
TheForge changed it to the following (more complicated, I'm simplifying
the idea):
1. Fill the entire cmd buffer with commands.
2. In `screen_prepare_for_drawing` do `submit()`
- There are no semaphore waits for the swapchain.
- Trigger a semaphore to indicate when we're done.
3. Fill a new cmd buffer that only does the final blit to the
swapchain.
4. `submit()`
- Wait with a semaphore for the submit() from step 2.
- Wait with a semaphore for the swapchain (so the swapchain can
submit).
- Trigger a semaphore to indicate when we're done (so the swapchain
can submit).
5. `present()`
Dario discovered this problem independently while working on a different
platform.
**However TheForge's solution had to be rewritten from scratch:** The
complexity to achieve the solution was high and quite difficult to
maintain with the way Godot works now (after Übershaders PR).
But on the other hand, re-implementing the solution became much simpler
because Dario already had to do something similar: To fix an Adreno 730
driver bug, he had to implement splitting command buffers. **This is
exactly what we need!**. Thus it was re-written using this existing
functionality for a new purpose.
To achieve this, I added a new argument, `bool p_split_cmd_buffer`, to
`RenderingDeviceGraph::add_draw_list_begin`, which is only set to true
by `RenderingDevice::draw_list_begin_for_screen`.
The graph will split the draw list into its own command buffer.
- `bool split_swapchain_into_its_own_cmd_buffer = true;`
Setting it to false enforces the old behavior. This might be necessary
for consoles which follow an alternate solution to the same problem.
If not, then we should consider removing it.
PR #90993 added `shader_destroy_modules()` but it was not actually in
use.
This PR adds several places where `shader_destroy_modules()` is called
after initialization to free up memory of SPIR-V structures that are no
longer needed.
Changed the incorrect verb "have" into its correct form, "has."
Fixes#99972
Co-authored-by: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
This commit adds a new navigation preset called `Tablet/Trackpad` which enables "Emulate 3 Button Mouse" to more quickly set up good default keys for tablet users.
It also adds support for mouse buttons 4 and 5 in the navigation settings which will be helpful if users want to customize 3D navigation further for specific pens/mice.
This prevents the antialiasing feather from becoming too wide
at viewport sizes higher than the default, which can lead to blurry visuals.
This is adjusted to account for the 2D scale factor returned on the root
Window, so it takes both the `canvas_items` scaling and
`content_scale_factor` into account.
Tested with various ZIP files found on the web, with a single root
folder or multiple files at its root.
Co-authored-by: Raul Santos <raulsntos@gmail.com>
This allows changing the display colour of a CollisionShape3D node on a per-shape basis.
It also adds the ability to display a solid coloured preview of a CollisionShape3D.
Closes https://github.com/godotengine/godot-proposals/issues/906
The functionality of the parameter is not limited to drag-and-drop
operations, but it has also other uses.
So its name should not be tied to drag-and-drop.
The API was created in the not yet released Godot 4.4-dev6, so this
change should not be considered compatibility breaking.
Document fact that themes only propagate to control children
(not Node2D, etc). Wording is copied from Theme docs.
Also clarifies line somewhat.
Co-Authored-By: Allyson Chan <allysonn.chann@gmail.com>
I was playing around with C# code snippet but I kept hearing a clipping sound. I think this is because the phase variable is being set to 0 in the wrong spot.
The phase at the end of the FillBuffer() method is some non zero number. When FillBuffer is called again, the phase is suddenly changed back to zero. This causes the end of one sin wave segment to be out of sync with the next sin wave segment. The sin wave needs to be continuous between FillBuffer calls so no clipping sound occurs.
Moving the phase variable out of FillBuffer and putting it in a scope above makes it retain its value between FillBuffer calls, making the sin wave continuous, and the clipping sound is gone.
For further proof, the demo project "Audio Generator Demo" has the phase variable be one scope above FillBuffer and it does not set phase=0 inside of FillBuffer. If anything, I'm fixing this documentation to match the working demo
Move buttons related to the file view on the container above so that they take less horizontal space and make search bar similar to the one in FileDialog
All Packed classes that have the same paragraph will compare the currently viewed Packed array type with the equivalent typed Array but here the comparison was with the Int32 version instead of the Int64 version
Comparing locales can have surprising outcomes since it standardizes
locales with defaults. For example, zh and zh_CN result in an exact
match since the defaults change them both to zh_Hans_CN. Expose the
add_default parameter publicly with a default of false so the fully
standardized locale can be inspected.
`Viewport.get_stretch_transform()` returns the automatically computed
2D stretch transform. Combined with `Transform2D.get_scale()`, this is
useful when using the `canvas_items` stretch mode in a project.
There are many situations where knowing this factor is useful:
- Divide Camera2D zoom to keep the size of the 2D game world identical
regardless of the 2D scale factor (so that UI elements can still be scaled).
- Make certain controls always drawn at 1:1 scale
(e.g. for the crosshair in a FPS). This is done by dividing the Control
node's scale by the scale factor.
With the drag-and-drop rewrite, `SubViewportContainer` nodes were no
longer available as drop-locations.
This PR introduces a configuration option, that allows
`SubViewportContainer` to be considered as drop-location, but disables the
`Control` nodes inside its `SubViewport` children as drop-location.
Some notes are ported from FileAccess (for example file_exist)
Other notes were added when needed (for example when included on the non static version but not on the static version)
Other entirely new notes were added as well when required for example when getting a list of directories or if a directory exist or not
Clarified note at the top and made it more in line with the one found in file access
Co-Authored-By: Micky <66727710+Mickeon@users.noreply.github.com>
Closesgodotengine/godot-proposals#5983
Adds put/get methods to `StreamPeer` that handles half precision
floating point values.
Adds endode/decode half precision floating point to `marshalls`.
Adds `get_half` and `store_half` to `FileAccess`
Co-Authored-By: "Alfonso J. Ramos" <theraot@gmail.com>
Apply suggestions from code review
Co-authored-by: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
Co-authored-by: Micky <66727710+Mickeon@users.noreply.github.com>
Updated wording in comments to be more concise
`LightmapGI`'s documentation currently doesn't mention the fact it only bakes nodes under its parent.
This can make the user think there is something wrong with their scene setup or 3D models, as it refuses to bake when the user's models / world isn't under the same parent as the `LightmapGI`.
Ensures all resource types support UIDs in a project.
This is required to fix:
* Scripts and many other resource types can't be referenced by UID and when refactored the references are lost.
* Path export properties can't use UID for unsupported types.
* Refactoring problems when files are moved outside the editor (this PR effectively fixes it).
* Editor properly refreshing paths if they changed externally while opened (as example, git update).
This needs to be addressed in a subsequent PR, but this one effectively sets the prerequisites.
Resource types that do not support UID will get a .uid file appended to them (this includes .gd, .gdshader, .gdextension, etc. files).
Add examples for sending packets and listening for packets.
Fix documentation indentation.
Change tabs to spaced for codeblocks.
Fix typos
Remove typing in documentation code
Add a blank line to comply with style guidelines
Fix blank line to contain tabs
Remove tabs from empty code lines
Commit suggested changes by Mickeon
Use correct syntax for >
in editor>editor settings>Text Editor>Theme, if you hover hover over "Engine Type Color", it has "Vector2", "Vector3"and "Color" as example but these are not Engine types. and their color is controlled by the "Base Type Color" setting. I discovered this while trying to customize my editor a bit more.
This fixes a bug in the analyzer where it did not push the SHADOWED_VARIABLE_BASE_CLASS
warning for members shadowed by variable in subclass. It does this by comparing the class
which contains the shadowed member with the class containing the variable, and pushing
SHADOWED_VARIABLE only if the classes are the same. Additionally, SHADOWED_VARIABLE_BASE_CLASS
can take an extra symbol which helps to specify the line for non native base class.
- Adds Swappy for Android for stable frame pacing
- Implements pre-transformed Swapchain so that Godot's compositor is in
charge of rotating the screen instead of Android's compositor
(performance optimization for phones that don't have HW rotator)
============================
The work was performed by collaboration of TheForge and Google. I am
merely splitting it up into smaller PRs and cleaning it up.
Changes from original PR:
- Removed "display/window/frame_pacing/android/target_frame_rate" option
to use Engine::get_max_fps instead.
- Target framerate can be changed at runtime using Engine::set_max_fps.
- Swappy is enabled by default.
- Added documentation.
- enable_auto_swap setting is replaced with swappy_mode.
"Raycast Normals" was introduced in 4.4 dev and defaulted to "false".
The limited testing results at the time suggested that raycasting
generally reduces normal quality compared to native simplifier results,
at the same time increasing vertex memory and import time.
To play it safe, we introduced a setting that defaulted to false, with
the goal of removing it later in 4.4 development cycle if no regressions
are noticed. Since we already had three dev snapshots and no reports,
this change removes the setting and associated code.
"Normal Split Angle" was only used when raycast normals were enabled;
this change removes it from the settings, but keeps it in the script
binding for compatibility.
Existing meshes import exactly the same after this change (unless they
chose to override raycasting which would be surprising).
split_normals helper was only used in this code path and is also removed
for simplicity; it is unlikely that this code will be useful as is, as
it can only regenerate normals without fixing tangents or updating
positions.