Refactor Node Processing
* Node processing works on the concept of process groups. * A node group can be inherited, run on main thread, or a sub-thread. * Groups can be ordered. * Process priority is now present for physics. This is the first steps towards implementing https://github.com/godotengine/godot-proposals/issues/6424. No threading or thread guards exist yet in most of the scene code other than Node. That will have to be added later.
This commit is contained in:
@ -33,6 +33,7 @@
|
||||
|
||||
#include "core/os/main_loop.h"
|
||||
#include "core/os/thread_safe.h"
|
||||
#include "core/templates/paged_allocator.h"
|
||||
#include "core/templates/self_list.h"
|
||||
#include "scene/resources/mesh.h"
|
||||
|
||||
@ -86,6 +87,34 @@ public:
|
||||
typedef void (*IdleCallback)();
|
||||
|
||||
private:
|
||||
CallQueue::Allocator *process_group_call_queue_allocator = nullptr;
|
||||
|
||||
struct ProcessGroup {
|
||||
CallQueue call_queue;
|
||||
Vector<Node *> nodes;
|
||||
Vector<Node *> physics_nodes;
|
||||
bool node_order_dirty = true;
|
||||
bool physics_node_order_dirty = true;
|
||||
bool removed = false;
|
||||
Node *owner = nullptr;
|
||||
uint64_t last_pass = 0;
|
||||
};
|
||||
|
||||
struct ProcessGroupSort {
|
||||
_FORCE_INLINE_ bool operator()(const ProcessGroup *p_left, const ProcessGroup *p_right) const;
|
||||
};
|
||||
|
||||
PagedAllocator<ProcessGroup, true> group_allocator; // Allocate groups on pages, to enhance cache usage.
|
||||
|
||||
LocalVector<ProcessGroup *> process_groups;
|
||||
bool process_groups_dirty = true;
|
||||
LocalVector<ProcessGroup *> local_process_group_cache; // Used when processing to group what needs to
|
||||
uint64_t process_last_pass = 1;
|
||||
|
||||
ProcessGroup default_process_group;
|
||||
|
||||
bool node_threading_disabled = false;
|
||||
|
||||
struct Group {
|
||||
Vector<Node *> nodes;
|
||||
bool changed = false;
|
||||
@ -117,7 +146,7 @@ private:
|
||||
StringName node_renamed_name = "node_renamed";
|
||||
|
||||
int64_t current_frame = 0;
|
||||
int node_count = 0;
|
||||
int nodes_in_tree_count = 0;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
Node *edited_scene_root = nullptr;
|
||||
@ -134,8 +163,10 @@ private:
|
||||
};
|
||||
|
||||
// Safety for when a node is deleted while a group is being called.
|
||||
int call_lock = 0;
|
||||
HashSet<Node *> call_skip; // Skip erased nodes.
|
||||
|
||||
bool processing = false;
|
||||
int nodes_removed_on_group_call_lock = 0;
|
||||
HashSet<Node *> nodes_removed_on_group_call; // Skip erased nodes.
|
||||
|
||||
List<ObjectID> delete_queue;
|
||||
|
||||
@ -143,7 +174,7 @@ private:
|
||||
bool ugc_locked = false;
|
||||
void _flush_ugc();
|
||||
|
||||
_FORCE_INLINE_ void _update_group_order(Group &g, bool p_use_priority = false);
|
||||
_FORCE_INLINE_ void _update_group_order(Group &g);
|
||||
|
||||
TypedArray<Node> _get_nodes_in_group(const StringName &p_group);
|
||||
|
||||
@ -187,7 +218,15 @@ private:
|
||||
void remove_from_group(const StringName &p_group, Node *p_node);
|
||||
void make_group_changed(const StringName &p_group);
|
||||
|
||||
void _notify_group_pause(const StringName &p_group, int p_notification);
|
||||
void _process_group(ProcessGroup *p_group, bool p_physics);
|
||||
void _process_groups_thread(uint32_t p_index, bool p_physics);
|
||||
void _process(bool p_physics);
|
||||
|
||||
void _remove_process_group(Node *p_node);
|
||||
void _add_process_group(Node *p_node);
|
||||
void _remove_node_from_process_group(Node *p_node, Node *p_owner);
|
||||
void _add_node_to_process_group(Node *p_node, Node *p_owner);
|
||||
|
||||
void _call_group_flags(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
|
||||
void _call_group(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
|
||||
|
||||
@ -383,6 +422,7 @@ public:
|
||||
|
||||
static void add_idle_callback(IdleCallback p_callback);
|
||||
|
||||
void set_disable_node_threading(bool p_disable);
|
||||
//default texture settings
|
||||
|
||||
SceneTree();
|
||||
|
||||
Reference in New Issue
Block a user