Make Node::orphan_node_count thread-safe

This commit is contained in:
Ryan 2025-08-22 23:02:51 -04:00
parent 1ce3101fbc
commit 6ebef31b3c
5 changed files with 25 additions and 9 deletions

View file

@ -154,6 +154,7 @@
</constant>
<constant name="OBJECT_ORPHAN_NODE_COUNT" value="10" enum="Monitor">
Number of orphan nodes, i.e. nodes which are not parented to a node of the scene tree. [i]Lower is better.[/i]
[b]Note:[/b] This is only available in debug mode and will always return [code]0[/code] when used in a project exported in release mode.
</constant>
<constant name="RENDER_TOTAL_OBJECTS_IN_FRAME" value="11" enum="Monitor">
The total number of objects in the last rendered frame. This metric doesn't include culled objects (either via hiding nodes, frustum culling or occlusion culling). [i]Lower is better.[/i]

View file

@ -141,6 +141,16 @@ int Performance::_get_node_count() const {
return sml->get_node_count();
}
int Performance::_get_orphan_node_count() const {
#ifdef DEBUG_ENABLED
const int total_node_count = Node::total_node_count.get();
const int orphan_node_count = total_node_count - _get_node_count();
return orphan_node_count;
#else
return 0;
#endif
}
String Performance::get_monitor_name(Monitor p_monitor) const {
ERR_FAIL_INDEX_V(p_monitor, MONITOR_MAX, String());
static const char *names[MONITOR_MAX] = {
@ -240,7 +250,7 @@ double Performance::get_monitor(Monitor p_monitor) const {
case OBJECT_NODE_COUNT:
return _get_node_count();
case OBJECT_ORPHAN_NODE_COUNT:
return Node::orphan_node_count;
return _get_orphan_node_count();
case RENDER_TOTAL_OBJECTS_IN_FRAME:
return RS::get_singleton()->get_rendering_info(RS::RENDERING_INFO_TOTAL_OBJECTS_IN_FRAME);
case RENDER_TOTAL_PRIMITIVES_IN_FRAME:

View file

@ -46,6 +46,7 @@ class Performance : public Object {
static void _bind_methods();
int _get_node_count() const;
int _get_orphan_node_count() const;
double _process_time;
double _physics_process_time;

View file

@ -44,7 +44,9 @@
#include "scene/resources/packed_scene.h"
#include "viewport.h"
int Node::orphan_node_count = 0;
#ifdef DEBUG_ENABLED
SafeNumeric<uint64_t> Node::total_node_count{ 0 };
#endif
thread_local Node *Node::current_process_thread_group = nullptr;
@ -165,7 +167,6 @@ void Node::_notification(int p_notification) {
}
data.tree->nodes_in_tree_count++;
orphan_node_count--;
} break;
@ -193,7 +194,6 @@ void Node::_notification(int p_notification) {
}
data.tree->nodes_in_tree_count--;
orphan_node_count++;
if (data.input) {
remove_from_group("_vp_input" + itos(get_viewport()->get_instance_id()));
@ -4058,9 +4058,9 @@ String Node::_get_name_num_separator() {
Node::Node() {
_define_ancestry(AncestralClass::NODE);
orphan_node_count++;
#ifdef DEBUG_ENABLED
total_node_count.increment();
#endif
// Default member initializer for bitfield is a C++20 extension, so:
data.process_mode = PROCESS_MODE_INHERIT;
@ -4107,7 +4107,9 @@ Node::~Node() {
ERR_FAIL_COND(data.parent);
ERR_FAIL_COND(data.children_cache.size());
orphan_node_count--;
#ifdef DEBUG_ENABLED
total_node_count.decrement();
#endif
}
////////////////////////////////

View file

@ -130,7 +130,9 @@ public:
bool operator()(const Node *p_a, const Node *p_b) const { return p_b->is_greater_than(p_a); }
};
static int orphan_node_count;
#ifdef DEBUG_ENABLED
static SafeNumeric<uint64_t> total_node_count;
#endif
void _update_process(bool p_enable, bool p_for_children);