From 44d5f7bf22c882073b526f751492d4144047d365 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 6 Feb 2024 10:19:44 +0100 Subject: [PATCH 1/5] Compositor: Implement per-node execution time report Visually it is the same as the execution time implemented for the geometry nodes, and it is to be enabled in the overlay popover. The implementation is separate from the geometry nodes, as it is not easy or practical to re-use the geometry nodes implementation. The execution time is stored in a run-time hash, indexed by a node instance key. This is similar to the storage of the mode preview images. The time is only implemented for full-frame compositor, as for the tiled compositor it could be tricky to calculate reliable time for pixel processing nodes which process one pixel at a time. --- scripts/startup/bl_ui/space_node.py | 3 + source/blender/blenkernel/BKE_node_runtime.hh | 10 ++ source/blender/compositor/CMakeLists.txt | 2 + source/blender/compositor/COM_profile.hh | 42 ++++++ .../intern/COM_FullFrameExecutionModel.cc | 8 + .../intern/COM_FullFrameExecutionModel.h | 3 + .../compositor/intern/COM_NodeOperation.h | 12 ++ .../intern/COM_NodeOperationBuilder.cc | 1 + .../blender/compositor/intern/COM_profile.cc | 81 ++++++++++ .../blender/editors/space_node/node_draw.cc | 140 ++++++++++++++++-- .../blender/editors/space_node/node_edit.cc | 6 + source/blender/makesdna/DNA_node_types.h | 16 ++ 12 files changed, 309 insertions(+), 15 deletions(-) create mode 100644 source/blender/compositor/COM_profile.hh create mode 100644 source/blender/compositor/intern/COM_profile.cc diff --git a/scripts/startup/bl_ui/space_node.py b/scripts/startup/bl_ui/space_node.py index b69e5de6d5b..6a7a0f2e177 100644 --- a/scripts/startup/bl_ui/space_node.py +++ b/scripts/startup/bl_ui/space_node.py @@ -867,6 +867,9 @@ class NODE_PT_overlay(Panel): col.prop(overlay, "show_timing", text="Timings") col.prop(overlay, "show_named_attributes", text="Named Attributes") + if snode.tree_type == 'CompositorNodeTree': + col.prop(overlay, "show_timing", text="Timings") + class NODE_MT_node_tree_interface_context_menu(Menu): bl_label = "Node Tree Interface Specials" diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index 08f4ced5ab1..f5ea32348ef 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -11,6 +11,7 @@ #include "BLI_math_vector_types.hh" #include "BLI_multi_value_map.hh" #include "BLI_resource_scope.hh" +#include "BLI_timeit.hh" #include "BLI_utility_mixins.hh" #include "BLI_vector.hh" #include "BLI_vector_set.hh" @@ -75,6 +76,13 @@ namespace blender::bke { using NodeIDVectorSet = VectorSet; +/* Runtime data specific to the compositing trees. */ +struct bCompositorNodeTreeRuntime { + /* Per-node instance total execution time for the corresponding node, during the last tree + * evaluation. */ + Map per_node_execution_time; +}; + class bNodeTreeRuntime : NonCopyable, NonMovable { public: /** @@ -171,6 +179,8 @@ class bNodeTreeRuntime : NonCopyable, NonMovable { bool has_undefined_nodes_or_sockets = false; bNode *group_output_node = nullptr; Vector root_frames; + + bCompositorNodeTreeRuntime compositor; }; /** diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index 57e0e71ab60..e681152175e 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -35,6 +35,7 @@ if(WITH_COMPOSITOR_CPU) set(SRC COM_compositor.hh COM_defines.h + COM_profile.hh intern/COM_BufferArea.h intern/COM_BufferOperation.cc @@ -100,6 +101,7 @@ if(WITH_COMPOSITOR_CPU) intern/COM_WorkScheduler.cc intern/COM_WorkScheduler.h intern/COM_compositor.cc + intern/COM_profile.cc operations/COM_QualityStepHelper.cc operations/COM_QualityStepHelper.h diff --git a/source/blender/compositor/COM_profile.hh b/source/blender/compositor/COM_profile.hh new file mode 100644 index 00000000000..5a60fcb59a7 --- /dev/null +++ b/source/blender/compositor/COM_profile.hh @@ -0,0 +1,42 @@ +/* SPDX-FileCopyrightText: 2024 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include "BLI_map.hh" +#include "BLI_timeit.hh" + +#include "DNA_node_types.h" + +struct bNodeTree; + +namespace blender::compositor { + +class NodeOperation; + +class Profiler { + /* Per-node accumulated execution time. Includes execution time of all operations the node was + * break down into. */ + Map per_node_execution_time_; + + public: + void add_operation_execution_time(const NodeOperation &operation, + const timeit::TimePoint &start, + const timeit::TimePoint &end); + + void finalize(const bNodeTree &node_tree); + + private: + /* Add execution time to the node denoted by its key. */ + void add_execution_time(const bNodeInstanceKey parent_key, + const timeit::Nanoseconds &execution_time); + + /* Accumulate execution time of the group node instances, and store their execution time in the + * per_node_execution_time_. + * Returns total execution time of the given node tree. */ + timeit::Nanoseconds accumulate_node_group_times( + const bNodeTree &node_tree, const bNodeInstanceKey parent_key = NODE_INSTANCE_KEY_BASE); +}; + +} // namespace blender::compositor \ No newline at end of file diff --git a/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc b/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc index 1ac1d2d4be7..8aa3c486008 100644 --- a/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc +++ b/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc @@ -12,6 +12,8 @@ #include "COM_ViewerOperation.h" #include "COM_WorkScheduler.h" +#include "BLI_timeit.hh" + #ifdef WITH_CXX_GUARDEDALLOC # include "MEM_guardedalloc.h" #endif @@ -42,6 +44,8 @@ void FullFrameExecutionModel::execute(ExecutionSystem &exec_system) determine_areas_to_render_and_reads(); render_operations(); + + profiler_.finalize(*node_tree); } void FullFrameExecutionModel::determine_areas_to_render_and_reads() @@ -101,6 +105,8 @@ void FullFrameExecutionModel::render_operation(NodeOperation *op) constexpr int output_x = 0; constexpr int output_y = 0; + const timeit::TimePoint time_start = timeit::Clock::now(); + const bool has_outputs = op->get_number_of_output_sockets() > 0; MemoryBuffer *op_buf = has_outputs ? create_operation_buffer(op, output_x, output_y) : nullptr; if (op->get_width() > 0 && op->get_height() > 0) { @@ -120,6 +126,8 @@ void FullFrameExecutionModel::render_operation(NodeOperation *op) active_buffers_.set_rendered_buffer(op, std::unique_ptr(op_buf)); operation_finished(op); + + profiler_.add_operation_execution_time(*op, time_start, timeit::Clock::now()); } void FullFrameExecutionModel::render_operations() diff --git a/source/blender/compositor/intern/COM_FullFrameExecutionModel.h b/source/blender/compositor/intern/COM_FullFrameExecutionModel.h index 30f0a2a55bf..e7874f5f472 100644 --- a/source/blender/compositor/intern/COM_FullFrameExecutionModel.h +++ b/source/blender/compositor/intern/COM_FullFrameExecutionModel.h @@ -8,6 +8,7 @@ #include "COM_Enums.h" #include "COM_ExecutionModel.h" +#include "COM_profile.hh" #ifdef WITH_CXX_GUARDEDALLOC # include "MEM_guardedalloc.h" @@ -43,6 +44,8 @@ class FullFrameExecutionModel : public ExecutionModel { */ Vector priorities_; + Profiler profiler_; + public: FullFrameExecutionModel(CompositorContext &context, SharedOperationBuffers &shared_buffers, diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h index 82c002e1852..e76ea23b487 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.h +++ b/source/blender/compositor/intern/COM_NodeOperation.h @@ -19,6 +19,7 @@ #include "COM_MemoryBuffer.h" #include "COM_MetaData.h" +#include "BKE_node.h" #include "BKE_node_runtime.hh" #include "clew.h" @@ -310,6 +311,8 @@ class NodeOperation { private: int id_; std::string name_; + bNodeInstanceKey node_instance_key_{NODE_INSTANCE_KEY_NONE}; + Vector inputs_; Vector outputs_; @@ -377,6 +380,15 @@ class NodeOperation { return id_; } + const void set_node_instance_key(const bNodeInstanceKey &node_instance_key) + { + node_instance_key_ = node_instance_key; + } + const bNodeInstanceKey get_node_instance_key() const + { + return node_instance_key_; + } + /** Get constant value when operation is constant, otherwise return default_value. */ float get_constant_value_default(float default_value); /** Get constant elem when operation is constant, otherwise return default_elem. */ diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc index 70a2fbbe12f..c3174c351eb 100644 --- a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc +++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc @@ -124,6 +124,7 @@ void NodeOperationBuilder::add_operation(NodeOperation *operation) operations_.append(operation); if (current_node_) { operation->set_name(current_node_->get_bnode()->name); + operation->set_node_instance_key(current_node_->get_instance_key()); } operation->set_execution_model(context_->get_execution_model()); operation->set_execution_system(exec_system_); diff --git a/source/blender/compositor/intern/COM_profile.cc b/source/blender/compositor/intern/COM_profile.cc new file mode 100644 index 00000000000..63ccd348419 --- /dev/null +++ b/source/blender/compositor/intern/COM_profile.cc @@ -0,0 +1,81 @@ +/* SPDX-FileCopyrightText: 2024 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "COM_profile.hh" + +#include "BKE_node_runtime.hh" + +#include "COM_NodeOperation.h" + +#include "DNA_node_types.h" + +namespace blender::compositor { + +void Profiler::add_operation_execution_time(const NodeOperation &operation, + const timeit::TimePoint &start, + const timeit::TimePoint &end) +{ + const timeit::Nanoseconds execution_time = end - start; + + const bNodeInstanceKey key = operation.get_node_instance_key(); + if (key.value == NODE_INSTANCE_KEY_NONE.value) { + /* The operation does not come from any node. It was, for example, added to convert data type. + * Do not accumulate time from its execution. */ + return; + } + + add_execution_time(key, execution_time); +} + +void Profiler::add_execution_time(const bNodeInstanceKey key, + const timeit::Nanoseconds &execution_time) +{ + per_node_execution_time_.add_or_modify( + key, + [&](timeit::Nanoseconds *total_execution_time) { *total_execution_time = execution_time; }, + [&](timeit::Nanoseconds *total_execution_time) { *total_execution_time += execution_time; }); +} + +void Profiler::finalize(const bNodeTree &node_tree) +{ + accumulate_node_group_times(node_tree); + + bke::bCompositorNodeTreeRuntime &compositor_runtime = node_tree.runtime->compositor; + compositor_runtime.per_node_execution_time = std::move(per_node_execution_time_); +} + +timeit::Nanoseconds Profiler::accumulate_node_group_times(const bNodeTree &node_tree, + const bNodeInstanceKey parent_key) +{ + timeit::Nanoseconds tree_execution_time(0); + + for (const bNode *node : node_tree.all_nodes()) { + const bNodeInstanceKey key = BKE_node_instance_key(parent_key, &node_tree, node); + + if (node->type != NODE_GROUP) { + /* Non-group node, no need to recurs into. Simply accumulate the node's execution time to the + * current tree's execution time. */ + tree_execution_time += per_node_execution_time_.lookup_default(key, timeit::Nanoseconds(0)); + continue; + } + + if (node->id == nullptr) { + /* Node group has lost link to its node tree. For example, due to missing linked file. */ + continue; + } + + const timeit::Nanoseconds group_execution_time = accumulate_node_group_times( + *reinterpret_cast(node->id), key); + + /* Store execution time of the group node. */ + add_execution_time(key, group_execution_time); + + /* Add group execution time to the overall tree execution time. */ + tree_execution_time += group_execution_time; + } + + return tree_execution_time; +} + +} // namespace blender::compositor \ No newline at end of file diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 53ef7219c7b..a579937ab21 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -92,6 +92,8 @@ #include "GEO_fillet_curves.hh" +#include "COM_profile.hh" + #include "node_intern.hh" /* own include */ #include @@ -2408,9 +2410,11 @@ static void node_add_error_message_button(const TreeDrawContext &tree_draw_ctx, UI_block_emboss_set(&block, UI_EMBOSS); } -static std::optional node_get_execution_time( - const TreeDrawContext &tree_draw_ctx, const bNodeTree &ntree, const bNode &node) +static std::optional geo_node_get_execution_time( + const TreeDrawContext &tree_draw_ctx, const SpaceNode &snode, const bNode &node) { + const bNodeTree &ntree = *snode.edittree; + geo_log::GeoTreeLog *tree_log = [&]() -> geo_log::GeoTreeLog * { const bNodeTreeZones *zones = ntree.zones(); if (!zones) { @@ -2433,8 +2437,8 @@ static std::optional node_get_execution_time( for (const bNode *tnode : node.direct_children_in_frame()) { if (tnode->is_frame()) { - std::optional sub_frame_run_time = node_get_execution_time( - tree_draw_ctx, ntree, *tnode); + std::optional sub_frame_run_time = geo_node_get_execution_time( + tree_draw_ctx, snode, *tnode); if (sub_frame_run_time.has_value()) { run_time += *sub_frame_run_time; found_node = true; @@ -2459,12 +2463,89 @@ static std::optional node_get_execution_time( return std::nullopt; } +/* Cerate node key instance, assuming the node comes from the currently editing node tree. */ +static bNodeInstanceKey current_node_instance_key(const SpaceNode &snode, const bNode &node) +{ + /* Assume that the currently editing tree is the last in the path. */ + BLI_assert(snode.edittree == snode.treepath.last); + + const bNodeTreePath *path = static_cast(snode.treepath.last); + /* Some code in this file checks for the non-null elements of the tree path. However, if we did + * iterate into a node it is expected that there is a tree, and it should be in the path. + * Otherwise something else went wrong. */ + BLI_assert(path); + + return BKE_node_instance_key(path->parent_key, snode.edittree, &node); +} + +static std::optional compositor_accumulate_frame_node_execution_time( + const SpaceNode &snode, const bNode &node) +{ + const bNodeTree &compositor_tree = *snode.nodetree; + const bke::bCompositorNodeTreeRuntime &compositor_runtime = compositor_tree.runtime->compositor; + + timeit::Nanoseconds frame_execution_time(0); + bool has_any_execution_time = false; + + for (const bNode *current_node : node.direct_children_in_frame()) { + const bNodeInstanceKey key = current_node_instance_key(snode, *current_node); + if (const timeit::Nanoseconds *node_execution_time = + compositor_runtime.per_node_execution_time.lookup_ptr(key)) + { + frame_execution_time += *node_execution_time; + has_any_execution_time = true; + } + } + + if (!has_any_execution_time) { + return std::nullopt; + } + + return frame_execution_time; +} + +static std::optional compositor_node_get_execution_time( + const TreeDrawContext & /*tree_draw_ctx*/, const SpaceNode &snode, const bNode &node) +{ + + const bNodeTree &compositor_tree = *snode.nodetree; + const bke::bCompositorNodeTreeRuntime &compositor_runtime = compositor_tree.runtime->compositor; + + /* For the frame nodes accumulate execution time of its children. */ + if (node.is_frame()) { + return compositor_accumulate_frame_node_execution_time(snode, node); + } + + /* For other nodes simply lookup execution time. + * The group node instances have their own entries in the execution times map. */ + const bNodeInstanceKey key = current_node_instance_key(snode, node); + if (const timeit::Nanoseconds *execution_time = + compositor_runtime.per_node_execution_time.lookup_ptr(key)) + { + return *execution_time; + } + + return std::nullopt; +} + +static std::optional node_get_execution_time( + const TreeDrawContext &tree_draw_ctx, const SpaceNode &snode, const bNode &node) +{ + switch (snode.edittree->type) { + case NTREE_GEOMETRY: + return geo_node_get_execution_time(tree_draw_ctx, snode, node); + case NTREE_COMPOSIT: + return compositor_node_get_execution_time(tree_draw_ctx, snode, node); + } + return std::nullopt; +} + static std::string node_get_execution_time_label(TreeDrawContext &tree_draw_ctx, const SpaceNode &snode, const bNode &node) { const std::optional exec_time = node_get_execution_time( - tree_draw_ctx, *snode.edittree, node); + tree_draw_ctx, snode, node); if (!exec_time.has_value()) { return std::string(""); @@ -2603,6 +2684,35 @@ static std::optional node_get_accessed_attributes_row( return row_from_used_named_attribute(node_log->used_named_attributes); } +static std::optional node_get_execution_time_label_row( + TreeDrawContext &tree_draw_ctx, const SpaceNode &snode, const bNode &node) +{ + NodeExtraInfoRow row; + row.text = node_get_execution_time_label(tree_draw_ctx, snode, node); + if (row.text.empty()) { + return std::nullopt; + } + row.tooltip = TIP_( + "The execution time from the node tree's latest evaluation. For frame and group " + "nodes, the time for all sub-nodes"); + row.icon = ICON_PREVIEW_RANGE; + return row; +} + +static void node_get_compositor_extra_info(TreeDrawContext &tree_draw_ctx, + const SpaceNode &snode, + const bNode &node, + Vector &rows) +{ + if (snode.overlay.flag & SN_OVERLAY_SHOW_TIMINGS) { + std::optional row = node_get_execution_time_label_row( + tree_draw_ctx, snode, node); + if (row.has_value()) { + rows.append(std::move(*row)); + } + } +} + static Vector node_get_extra_info(const bContext &C, TreeDrawContext &tree_draw_ctx, const SpaceNode &snode, @@ -2615,8 +2725,13 @@ static Vector node_get_extra_info(const bContext &C, node.typeinfo->get_extra_info(params); } + if (snode.edittree->type == NTREE_COMPOSIT) { + node_get_compositor_extra_info(tree_draw_ctx, snode, node, rows); + return rows; + } + if (!(snode.edittree->type == NTREE_GEOMETRY)) { - /* Currently geometry nodes are the only nodes to have extra infos per nodes. */ + /* Currently geometry and compositor nodes are the only nodes to have extra infos per nodes. */ return rows; } @@ -2632,15 +2747,10 @@ static Vector node_get_extra_info(const bContext &C, (ELEM(node.typeinfo->nclass, NODE_CLASS_GEOMETRY, NODE_CLASS_GROUP, NODE_CLASS_ATTRIBUTE) || ELEM(node.type, NODE_FRAME, NODE_GROUP_OUTPUT))) { - NodeExtraInfoRow row; - row.text = node_get_execution_time_label(tree_draw_ctx, snode, node); - if (!row.text.empty()) { - row.tooltip = TIP_( - "The execution time from the node tree's latest evaluation. For frame and group " - "nodes, " - "the time for all sub-nodes"); - row.icon = ICON_PREVIEW_RANGE; - rows.append(std::move(row)); + std::optional row = node_get_execution_time_label_row( + tree_draw_ctx, snode, node); + if (row.has_value()) { + rows.append(std::move(*row)); } } diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index 2bd944f7d01..27d51ec0434 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -320,6 +320,9 @@ static void compo_canceljob(void *cjv) Scene *scene = cj->scene; BKE_callback_exec_id(bmain, &scene->id, BKE_CB_EVT_COMPOSITE_CANCEL); cj->cancelled = true; + + cj->ntree->runtime->compositor.per_node_execution_time = + cj->localtree->runtime->compositor.per_node_execution_time; } static void compo_completejob(void *cjv) @@ -328,6 +331,9 @@ static void compo_completejob(void *cjv) Main *bmain = cj->bmain; Scene *scene = cj->scene; BKE_callback_exec_id(bmain, &scene->id, BKE_CB_EVT_COMPOSITE_POST); + + cj->ntree->runtime->compositor.per_node_execution_time = + cj->localtree->runtime->compositor.per_node_execution_time; } /** \} */ diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 05852be43f1..367130f7de7 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -539,6 +539,22 @@ enum { */ typedef struct bNodeInstanceKey { unsigned int value; + +#ifdef __cplusplus + inline bool operator==(const bNodeInstanceKey &other) const + { + return value == other.value; + } + inline bool operator!=(const bNodeInstanceKey &other) const + { + return !(*this == other); + } + + inline uint64_t hash() const + { + return value; + } +#endif } bNodeInstanceKey; /** -- 2.30.2 From 6b1e565283a3079509feaca1e3192d715fb45ab3 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 7 Feb 2024 17:36:37 +0100 Subject: [PATCH 2/5] Fix spelling --- source/blender/compositor/COM_profile.hh | 2 +- source/blender/editors/space_node/node_draw.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/compositor/COM_profile.hh b/source/blender/compositor/COM_profile.hh index 5a60fcb59a7..f82f99c5b65 100644 --- a/source/blender/compositor/COM_profile.hh +++ b/source/blender/compositor/COM_profile.hh @@ -17,7 +17,7 @@ class NodeOperation; class Profiler { /* Per-node accumulated execution time. Includes execution time of all operations the node was - * break down into. */ + * broken down into. */ Map per_node_execution_time_; public: diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index a5552826611..d0dc3a2dc70 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -2463,7 +2463,7 @@ static std::optional geo_node_get_execution_time( return std::nullopt; } -/* Cerate node key instance, assuming the node comes from the currently editing node tree. */ +/* Create node key instance, assuming the node comes from the currently editing node tree. */ static bNodeInstanceKey current_node_instance_key(const SpaceNode &snode, const bNode &node) { /* Assume that the currently editing tree is the last in the path. */ @@ -2739,7 +2739,7 @@ static Vector node_get_extra_info(const bContext &C, } if (!(snode.edittree->type == NTREE_GEOMETRY)) { - /* Currently geometry and compositor nodes are the only nodes to have extra infos per nodes. */ + /* Currently geometry and compositor nodes are the only nodes to have extra info per nodes. */ return rows; } -- 2.30.2 From 9089e21f5c12fbaffa47e8dac42c33df83b1f594 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 7 Feb 2024 17:57:45 +0100 Subject: [PATCH 3/5] Fix assert --- source/blender/editors/space_node/node_draw.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index d0dc3a2dc70..52f06e124e0 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -2466,15 +2466,16 @@ static std::optional geo_node_get_execution_time( /* Create node key instance, assuming the node comes from the currently editing node tree. */ static bNodeInstanceKey current_node_instance_key(const SpaceNode &snode, const bNode &node) { - /* Assume that the currently editing tree is the last in the path. */ - BLI_assert(snode.edittree == snode.treepath.last); - const bNodeTreePath *path = static_cast(snode.treepath.last); + /* Some code in this file checks for the non-null elements of the tree path. However, if we did * iterate into a node it is expected that there is a tree, and it should be in the path. * Otherwise something else went wrong. */ BLI_assert(path); + /* Assume that the currently editing tree is the last in the path. */ + BLI_assert(snode.edittree == path->nodetree); + return BKE_node_instance_key(path->parent_key, snode.edittree, &node); } -- 2.30.2 From 27053d0f46ccf638961357cc433ea659bbd94e18 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 8 Feb 2024 15:13:18 +0100 Subject: [PATCH 4/5] Move timing information storage to scene runtime --- source/blender/blenkernel/BKE_node_runtime.hh | 10 ------- .../blender/blenkernel/BKE_scene_runtime.hh | 10 +++++++ source/blender/compositor/COM_compositor.hh | 8 +++-- source/blender/compositor/COM_profile.hh | 18 +++++++++-- .../compositor/intern/COM_ExecutionModel.h | 10 +++++++ .../compositor/intern/COM_ExecutionSystem.cc | 6 +++- .../compositor/intern/COM_ExecutionSystem.h | 7 ++++- .../intern/COM_FullFrameExecutionModel.h | 3 -- .../compositor/intern/COM_compositor.cc | 15 +++++++--- .../blender/compositor/intern/COM_profile.cc | 8 ++--- .../blender/editors/space_node/node_draw.cc | 24 ++++++++------- .../blender/editors/space_node/node_edit.cc | 30 +++++++++++++------ source/blender/nodes/NOD_composite.hh | 6 +++- .../nodes/composite/node_composite_tree.cc | 7 +++-- source/blender/render/CMakeLists.txt | 2 ++ source/blender/render/intern/pipeline.cc | 5 +++- 16 files changed, 117 insertions(+), 52 deletions(-) diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index f5ea32348ef..08f4ced5ab1 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -11,7 +11,6 @@ #include "BLI_math_vector_types.hh" #include "BLI_multi_value_map.hh" #include "BLI_resource_scope.hh" -#include "BLI_timeit.hh" #include "BLI_utility_mixins.hh" #include "BLI_vector.hh" #include "BLI_vector_set.hh" @@ -76,13 +75,6 @@ namespace blender::bke { using NodeIDVectorSet = VectorSet; -/* Runtime data specific to the compositing trees. */ -struct bCompositorNodeTreeRuntime { - /* Per-node instance total execution time for the corresponding node, during the last tree - * evaluation. */ - Map per_node_execution_time; -}; - class bNodeTreeRuntime : NonCopyable, NonMovable { public: /** @@ -179,8 +171,6 @@ class bNodeTreeRuntime : NonCopyable, NonMovable { bool has_undefined_nodes_or_sockets = false; bNode *group_output_node = nullptr; Vector root_frames; - - bCompositorNodeTreeRuntime compositor; }; /** diff --git a/source/blender/blenkernel/BKE_scene_runtime.hh b/source/blender/blenkernel/BKE_scene_runtime.hh index 65d474caba3..87b2faf7552 100644 --- a/source/blender/blenkernel/BKE_scene_runtime.hh +++ b/source/blender/blenkernel/BKE_scene_runtime.hh @@ -4,12 +4,22 @@ #pragma once +#include "BLI_map.hh" +#include "BLI_timeit.hh" #include "BLI_utility_mixins.hh" namespace blender::bke { +/* Runtime data specific to the compositing trees. */ +struct CompositorRuntime { + /* Per-node instance total execution time for the corresponding node, during the last tree + * evaluation. */ + Map per_node_execution_time; +}; + class SceneRuntime : NonCopyable, NonMovable { public: + CompositorRuntime compositor; }; } // namespace blender::bke diff --git a/source/blender/compositor/COM_compositor.hh b/source/blender/compositor/COM_compositor.hh index 896da42a0c7..a70edbb5d02 100644 --- a/source/blender/compositor/COM_compositor.hh +++ b/source/blender/compositor/COM_compositor.hh @@ -10,6 +10,9 @@ namespace blender::realtime_compositor { class RenderContext; } +namespace blender::compositor { +class ProfilerData; +} struct Render; @@ -325,7 +328,7 @@ struct Render; * should be checked further, probably it'll be also needed for preview * generation in display space */ -/* clang-format off */ +/* clang-format on */ void COM_execute(Render *render, RenderData *render_data, @@ -333,7 +336,8 @@ void COM_execute(Render *render, bNodeTree *node_tree, bool rendering, const char *view_name, - blender::realtime_compositor::RenderContext *render_context); + blender::realtime_compositor::RenderContext *render_context, + blender::compositor::ProfilerData &profiler_data); /** * \brief Deinitialize the compositor caches and allocated memory. diff --git a/source/blender/compositor/COM_profile.hh b/source/blender/compositor/COM_profile.hh index f82f99c5b65..be9f22b5fd6 100644 --- a/source/blender/compositor/COM_profile.hh +++ b/source/blender/compositor/COM_profile.hh @@ -15,10 +15,19 @@ namespace blender::compositor { class NodeOperation; -class Profiler { +/* Profiling ddata gathered during execution of a compositing node tree. */ +class ProfilerData { + public: /* Per-node accumulated execution time. Includes execution time of all operations the node was * broken down into. */ - Map per_node_execution_time_; + Map per_node_execution_time; +}; + +/* Profiler implementation which is used by the node execution system. */ +class Profiler { + /* Local copy of the profiling data, which is known to not cause threading conflicts with the + * interface thread while the compositing tree is evaluated in background. */ + ProfilerData data_; public: void add_operation_execution_time(const NodeOperation &operation, @@ -27,6 +36,11 @@ class Profiler { void finalize(const bNodeTree &node_tree); + const ProfilerData &get_data() const + { + return data_; + } + private: /* Add execution time to the node denoted by its key. */ void add_execution_time(const bNodeInstanceKey parent_key, diff --git a/source/blender/compositor/intern/COM_ExecutionModel.h b/source/blender/compositor/intern/COM_ExecutionModel.h index 2ce24e5e06b..d08699da5cd 100644 --- a/source/blender/compositor/intern/COM_ExecutionModel.h +++ b/source/blender/compositor/intern/COM_ExecutionModel.h @@ -12,11 +12,14 @@ # include "MEM_guardedalloc.h" #endif +#include "COM_profile.hh" + namespace blender::compositor { class CompositorContext; class ExecutionSystem; class NodeOperation; +class ProfilerData; /** * Base class for execution models. Contains shared implementation. @@ -43,6 +46,8 @@ class ExecutionModel { */ Span operations_; + Profiler profiler_; + public: ExecutionModel(CompositorContext &context, Span operations); @@ -50,6 +55,11 @@ class ExecutionModel { virtual void execute(ExecutionSystem &exec_system) = 0; + const ProfilerData &get_profiler_data() const + { + return profiler_.get_data(); + } + #ifdef WITH_CXX_GUARDEDALLOC MEM_CXX_CLASS_ALLOC_FUNCS("COM:BaseExecutionModel") #endif diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cc b/source/blender/compositor/intern/COM_ExecutionSystem.cc index 5740ec26333..1fbe26185f6 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cc +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cc @@ -25,7 +25,9 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, bool rendering, bool fastcalculation, const char *view_name, - realtime_compositor::RenderContext *render_context) + realtime_compositor::RenderContext *render_context, + ProfilerData &profiler_data) + : profiler_data_(profiler_data) { num_work_threads_ = WorkScheduler::get_num_cpu_threads(); context_.set_render_context(render_context); @@ -100,6 +102,8 @@ void ExecutionSystem::execute() op->init_data(); } execution_model_->execute(*this); + + profiler_data_ = execution_model_->get_profiler_data(); } void ExecutionSystem::execute_work(const rcti &work_rect, diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.h b/source/blender/compositor/intern/COM_ExecutionSystem.h index 4e367a73248..5f6832b42cf 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.h +++ b/source/blender/compositor/intern/COM_ExecutionSystem.h @@ -26,6 +26,8 @@ class RenderContext; namespace blender::compositor { +class ProfilerData; + /** * \page execution Execution model * In order to get to an efficient model for execution, several steps are being done. these steps @@ -152,6 +154,8 @@ class ExecutionSystem { ThreadMutex work_mutex_; ThreadCondition work_finished_cond_; + ProfilerData &profiler_data_; + public: /** * \brief Create a new ExecutionSystem and initialize it with the @@ -166,7 +170,8 @@ class ExecutionSystem { bool rendering, bool fastcalculation, const char *view_name, - realtime_compositor::RenderContext *render_context); + realtime_compositor::RenderContext *render_context, + ProfilerData &profiler_data); /** * Destructor diff --git a/source/blender/compositor/intern/COM_FullFrameExecutionModel.h b/source/blender/compositor/intern/COM_FullFrameExecutionModel.h index e7874f5f472..30f0a2a55bf 100644 --- a/source/blender/compositor/intern/COM_FullFrameExecutionModel.h +++ b/source/blender/compositor/intern/COM_FullFrameExecutionModel.h @@ -8,7 +8,6 @@ #include "COM_Enums.h" #include "COM_ExecutionModel.h" -#include "COM_profile.hh" #ifdef WITH_CXX_GUARDEDALLOC # include "MEM_guardedalloc.h" @@ -44,8 +43,6 @@ class FullFrameExecutionModel : public ExecutionModel { */ Vector priorities_; - Profiler profiler_; - public: FullFrameExecutionModel(CompositorContext &context, SharedOperationBuffers &shared_buffers, diff --git a/source/blender/compositor/intern/COM_compositor.cc b/source/blender/compositor/intern/COM_compositor.cc index ea73f8c87d2..37ea61f87a1 100644 --- a/source/blender/compositor/intern/COM_compositor.cc +++ b/source/blender/compositor/intern/COM_compositor.cc @@ -55,7 +55,8 @@ void COM_execute(Render *render, bNodeTree *node_tree, bool rendering, const char *view_name, - blender::realtime_compositor::RenderContext *render_context) + blender::realtime_compositor::RenderContext *render_context, + blender::compositor::ProfilerData &profiler_data) { /* Initialize mutex, TODO: this mutex init is actually not thread safe and * should be done somewhere as part of blender startup, all the other @@ -95,8 +96,14 @@ void COM_execute(Render *render, /* Execute. */ const bool twopass = (node_tree->flag & NTREE_TWO_PASS) && !rendering; if (twopass) { - blender::compositor::ExecutionSystem fast_pass( - render_data, scene, node_tree, rendering, true, view_name, render_context); + blender::compositor::ExecutionSystem fast_pass(render_data, + scene, + node_tree, + rendering, + true, + view_name, + render_context, + profiler_data); fast_pass.execute(); if (node_tree->runtime->test_break(node_tree->runtime->tbh)) { @@ -106,7 +113,7 @@ void COM_execute(Render *render, } blender::compositor::ExecutionSystem system( - render_data, scene, node_tree, rendering, false, view_name, render_context); + render_data, scene, node_tree, rendering, false, view_name, render_context, profiler_data); system.execute(); } diff --git a/source/blender/compositor/intern/COM_profile.cc b/source/blender/compositor/intern/COM_profile.cc index 63ccd348419..4aab52960af 100644 --- a/source/blender/compositor/intern/COM_profile.cc +++ b/source/blender/compositor/intern/COM_profile.cc @@ -31,7 +31,7 @@ void Profiler::add_operation_execution_time(const NodeOperation &operation, void Profiler::add_execution_time(const bNodeInstanceKey key, const timeit::Nanoseconds &execution_time) { - per_node_execution_time_.add_or_modify( + data_.per_node_execution_time.add_or_modify( key, [&](timeit::Nanoseconds *total_execution_time) { *total_execution_time = execution_time; }, [&](timeit::Nanoseconds *total_execution_time) { *total_execution_time += execution_time; }); @@ -40,9 +40,6 @@ void Profiler::add_execution_time(const bNodeInstanceKey key, void Profiler::finalize(const bNodeTree &node_tree) { accumulate_node_group_times(node_tree); - - bke::bCompositorNodeTreeRuntime &compositor_runtime = node_tree.runtime->compositor; - compositor_runtime.per_node_execution_time = std::move(per_node_execution_time_); } timeit::Nanoseconds Profiler::accumulate_node_group_times(const bNodeTree &node_tree, @@ -56,7 +53,8 @@ timeit::Nanoseconds Profiler::accumulate_node_group_times(const bNodeTree &node_ if (node->type != NODE_GROUP) { /* Non-group node, no need to recurs into. Simply accumulate the node's execution time to the * current tree's execution time. */ - tree_execution_time += per_node_execution_time_.lookup_default(key, timeit::Nanoseconds(0)); + tree_execution_time += data_.per_node_execution_time.lookup_default(key, + timeit::Nanoseconds(0)); continue; } diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 52f06e124e0..d5931d16710 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -47,6 +47,7 @@ #include "BKE_node_tree_zones.hh" #include "BKE_object.hh" #include "BKE_scene.h" +#include "BKE_scene_runtime.hh" #include "BKE_type_conversions.hh" #include "IMB_imbuf.hh" @@ -128,6 +129,9 @@ struct TreeDrawContext { * True if there is an active realtime compositor using the node tree, false otherwise. */ bool used_by_realtime_compositor = false; + + blender::Map + *compositor_per_node_execution_time = nullptr; }; float ED_node_grid_size() @@ -2480,10 +2484,9 @@ static bNodeInstanceKey current_node_instance_key(const SpaceNode &snode, const } static std::optional compositor_accumulate_frame_node_execution_time( - const SpaceNode &snode, const bNode &node) + const TreeDrawContext &tree_draw_ctx, const SpaceNode &snode, const bNode &node) { - const bNodeTree &compositor_tree = *snode.nodetree; - const bke::bCompositorNodeTreeRuntime &compositor_runtime = compositor_tree.runtime->compositor; + BLI_assert(tree_draw_ctx.compositor_per_node_execution_time); timeit::Nanoseconds frame_execution_time(0); bool has_any_execution_time = false; @@ -2491,7 +2494,7 @@ static std::optional compositor_accumulate_frame_node_ for (const bNode *current_node : node.direct_children_in_frame()) { const bNodeInstanceKey key = current_node_instance_key(snode, *current_node); if (const timeit::Nanoseconds *node_execution_time = - compositor_runtime.per_node_execution_time.lookup_ptr(key)) + tree_draw_ctx.compositor_per_node_execution_time->lookup_ptr(key)) { frame_execution_time += *node_execution_time; has_any_execution_time = true; @@ -2506,22 +2509,20 @@ static std::optional compositor_accumulate_frame_node_ } static std::optional compositor_node_get_execution_time( - const TreeDrawContext & /*tree_draw_ctx*/, const SpaceNode &snode, const bNode &node) + const TreeDrawContext &tree_draw_ctx, const SpaceNode &snode, const bNode &node) { - - const bNodeTree &compositor_tree = *snode.nodetree; - const bke::bCompositorNodeTreeRuntime &compositor_runtime = compositor_tree.runtime->compositor; + BLI_assert(tree_draw_ctx.compositor_per_node_execution_time); /* For the frame nodes accumulate execution time of its children. */ if (node.is_frame()) { - return compositor_accumulate_frame_node_execution_time(snode, node); + return compositor_accumulate_frame_node_execution_time(tree_draw_ctx, snode, node); } /* For other nodes simply lookup execution time. * The group node instances have their own entries in the execution times map. */ const bNodeInstanceKey key = current_node_instance_key(snode, node); if (const timeit::Nanoseconds *execution_time = - compositor_runtime.per_node_execution_time.lookup_ptr(key)) + tree_draw_ctx.compositor_per_node_execution_time->lookup_ptr(key)) { return *execution_time; } @@ -4251,7 +4252,10 @@ static void draw_nodetree(const bContext &C, workspace->viewer_path, *snode); } else if (ntree.type == NTREE_COMPOSIT) { + const Scene *scene = CTX_data_scene(&C); tree_draw_ctx.used_by_realtime_compositor = realtime_compositor_is_in_use(C); + tree_draw_ctx.compositor_per_node_execution_time = + &scene->runtime->compositor.per_node_execution_time; } else if (ntree.type == NTREE_SHADER && U.experimental.use_shader_node_previews && BKE_scene_uses_shader_previews(CTX_data_scene(&C)) && diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index 27d51ec0434..59b0e6d9624 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -29,6 +29,7 @@ #include "BKE_node_tree_update.hh" #include "BKE_report.h" #include "BKE_scene.h" +#include "BKE_scene_runtime.hh" #include "BKE_workspace.h" #include "BLI_set.hh" @@ -74,6 +75,8 @@ #include "NOD_texture.h" #include "node_intern.hh" /* own include */ +#include "COM_profile.hh" + namespace blender::ed::space_node { #define USE_ESC_COMPO @@ -104,6 +107,8 @@ struct CompoJob { bool *do_update; float *progress; bool cancelled; + + blender::compositor::ProfilerData profiler_data; }; float node_socket_calculate_height(const bNodeSocket &socket) @@ -223,7 +228,8 @@ static void compo_freejob(void *cjv) if (cj->compositor_depsgraph != nullptr) { DEG_graph_free(cj->compositor_depsgraph); } - MEM_freeN(cj); + + MEM_delete(cj); } /* Only now we copy the nodetree, so adding many jobs while @@ -296,15 +302,23 @@ static void compo_startjob(void *cjv, wmJobWorkerStatus *worker_status) BKE_callback_exec_id(cj->bmain, &scene->id, BKE_CB_EVT_COMPOSITE_PRE); if ((cj->scene->r.scemode & R_MULTIVIEW) == 0) { - ntreeCompositExecTree(cj->re, cj->scene, ntree, &cj->scene->r, false, true, "", nullptr); + ntreeCompositExecTree( + cj->re, cj->scene, ntree, &cj->scene->r, false, true, "", nullptr, cj->profiler_data); } else { LISTBASE_FOREACH (SceneRenderView *, srv, &scene->r.views) { if (BKE_scene_multiview_is_render_view_active(&scene->r, srv) == false) { continue; } - ntreeCompositExecTree( - cj->re, cj->scene, ntree, &cj->scene->r, false, true, srv->name, nullptr); + ntreeCompositExecTree(cj->re, + cj->scene, + ntree, + &cj->scene->r, + false, + true, + srv->name, + nullptr, + cj->profiler_data); } } @@ -321,8 +335,7 @@ static void compo_canceljob(void *cjv) BKE_callback_exec_id(bmain, &scene->id, BKE_CB_EVT_COMPOSITE_CANCEL); cj->cancelled = true; - cj->ntree->runtime->compositor.per_node_execution_time = - cj->localtree->runtime->compositor.per_node_execution_time; + scene->runtime->compositor.per_node_execution_time = cj->profiler_data.per_node_execution_time; } static void compo_completejob(void *cjv) @@ -332,8 +345,7 @@ static void compo_completejob(void *cjv) Scene *scene = cj->scene; BKE_callback_exec_id(bmain, &scene->id, BKE_CB_EVT_COMPOSITE_POST); - cj->ntree->runtime->compositor.per_node_execution_time = - cj->localtree->runtime->compositor.per_node_execution_time; + scene->runtime->compositor.per_node_execution_time = cj->profiler_data.per_node_execution_time; } /** \} */ @@ -401,7 +413,7 @@ void ED_node_composite_job(const bContext *C, bNodeTree *nodetree, Scene *scene_ "Compositing", WM_JOB_EXCL_RENDER | WM_JOB_PROGRESS, WM_JOB_TYPE_COMPOSITE); - CompoJob *cj = MEM_cnew("compo job"); + CompoJob *cj = MEM_new("compo job"); /* Custom data for preview thread. */ cj->bmain = bmain; diff --git a/source/blender/nodes/NOD_composite.hh b/source/blender/nodes/NOD_composite.hh index 4544c3a4fd0..144505447ec 100644 --- a/source/blender/nodes/NOD_composite.hh +++ b/source/blender/nodes/NOD_composite.hh @@ -13,6 +13,9 @@ namespace blender::realtime_compositor { class RenderContext; } +namespace blender::compositor { +class ProfilerData; +} struct bNodeTreeType; struct CryptomatteSession; @@ -41,7 +44,8 @@ void ntreeCompositExecTree(Render *render, bool rendering, int do_previews, const char *view_name, - blender::realtime_compositor::RenderContext *render_context); + blender::realtime_compositor::RenderContext *render_context, + blender::compositor::ProfilerData &profiler_data); /** * Called from render pipeline, to tag render input and output. diff --git a/source/blender/nodes/composite/node_composite_tree.cc b/source/blender/nodes/composite/node_composite_tree.cc index 022eafd75e3..c095039a1ed 100644 --- a/source/blender/nodes/composite/node_composite_tree.cc +++ b/source/blender/nodes/composite/node_composite_tree.cc @@ -180,12 +180,13 @@ void ntreeCompositExecTree(Render *render, bool rendering, int do_preview, const char *view_name, - blender::realtime_compositor::RenderContext *render_context) + blender::realtime_compositor::RenderContext *render_context, + blender::compositor::ProfilerData &profiler_data) { #ifdef WITH_COMPOSITOR_CPU - COM_execute(render, rd, scene, ntree, rendering, view_name, render_context); + COM_execute(render, rd, scene, ntree, rendering, view_name, render_context, profiler_data); #else - UNUSED_VARS(render, scene, ntree, rd, rendering, view_name, render_context); + UNUSED_VARS(render, scene, ntree, rd, rendering, view_name, render_context, profiler_data); #endif UNUSED_VARS(do_preview); diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt index f7b39a0a9f6..e49a6141172 100644 --- a/source/blender/render/CMakeLists.txt +++ b/source/blender/render/CMakeLists.txt @@ -8,6 +8,7 @@ set(INC intern ../blenkernel ../blentranslation + ../compositor ../compositor/realtime_compositor ../compositor/realtime_compositor/cached_resources ../draw @@ -64,6 +65,7 @@ set(LIB PRIVATE bf::depsgraph PRIVATE bf::dna PRIVATE bf::intern::guardedalloc + bf_compositor bf_realtime_compositor PRIVATE bf::intern::atomic ) diff --git a/source/blender/render/intern/pipeline.cc b/source/blender/render/intern/pipeline.cc index ebe4a65c13d..bc1a677f5f9 100644 --- a/source/blender/render/intern/pipeline.cc +++ b/source/blender/render/intern/pipeline.cc @@ -67,6 +67,7 @@ #include "NOD_composite.hh" +#include "COM_profile.hh" #include "COM_render_context.hh" #include "DEG_depsgraph.hh" @@ -1301,6 +1302,7 @@ static void do_render_compositor(Render *re) } blender::realtime_compositor::RenderContext compositor_render_context; + blender::compositor::ProfilerData profiler_data; LISTBASE_FOREACH (RenderView *, rv, &re->result->views) { ntreeCompositExecTree(re, re->pipeline_scene_eval, @@ -1309,7 +1311,8 @@ static void do_render_compositor(Render *re) true, G.background == 0, rv->name, - &compositor_render_context); + &compositor_render_context, + profiler_data); } compositor_render_context.save_file_outputs(re->pipeline_scene_eval); -- 2.30.2 From aa841a7a84e0ae347f282a826d08a3759b486dad Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 8 Feb 2024 17:10:41 +0100 Subject: [PATCH 5/5] Address review points from Hans --- source/blender/compositor/COM_profile.hh | 2 +- source/blender/compositor/intern/COM_profile.cc | 12 ++++++------ source/blender/editors/space_node/node_draw.cc | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/blender/compositor/COM_profile.hh b/source/blender/compositor/COM_profile.hh index be9f22b5fd6..2dee5bccf74 100644 --- a/source/blender/compositor/COM_profile.hh +++ b/source/blender/compositor/COM_profile.hh @@ -26,7 +26,7 @@ class ProfilerData { /* Profiler implementation which is used by the node execution system. */ class Profiler { /* Local copy of the profiling data, which is known to not cause threading conflicts with the - * interface thread while the compositing tree is evaluated in background. */ + * interface thread while the compositing tree is evaluated in the background. */ ProfilerData data_; public: diff --git a/source/blender/compositor/intern/COM_profile.cc b/source/blender/compositor/intern/COM_profile.cc index 4aab52960af..bce0963168c 100644 --- a/source/blender/compositor/intern/COM_profile.cc +++ b/source/blender/compositor/intern/COM_profile.cc @@ -25,7 +25,7 @@ void Profiler::add_operation_execution_time(const NodeOperation &operation, return; } - add_execution_time(key, execution_time); + this->add_execution_time(key, execution_time); } void Profiler::add_execution_time(const bNodeInstanceKey key, @@ -39,7 +39,7 @@ void Profiler::add_execution_time(const bNodeInstanceKey key, void Profiler::finalize(const bNodeTree &node_tree) { - accumulate_node_group_times(node_tree); + this->accumulate_node_group_times(node_tree); } timeit::Nanoseconds Profiler::accumulate_node_group_times(const bNodeTree &node_tree, @@ -51,8 +51,8 @@ timeit::Nanoseconds Profiler::accumulate_node_group_times(const bNodeTree &node_ const bNodeInstanceKey key = BKE_node_instance_key(parent_key, &node_tree, node); if (node->type != NODE_GROUP) { - /* Non-group node, no need to recurs into. Simply accumulate the node's execution time to the - * current tree's execution time. */ + /* Non-group node, no need to recurse into. Simply accumulate the node's execution time to + * the current tree's execution time. */ tree_execution_time += data_.per_node_execution_time.lookup_default(key, timeit::Nanoseconds(0)); continue; @@ -63,11 +63,11 @@ timeit::Nanoseconds Profiler::accumulate_node_group_times(const bNodeTree &node_ continue; } - const timeit::Nanoseconds group_execution_time = accumulate_node_group_times( + const timeit::Nanoseconds group_execution_time = this->accumulate_node_group_times( *reinterpret_cast(node->id), key); /* Store execution time of the group node. */ - add_execution_time(key, group_execution_time); + this->add_execution_time(key, group_execution_time); /* Add group execution time to the overall tree execution time. */ tree_execution_time += group_execution_time; diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index d5931d16710..989d0fbdba9 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -2467,7 +2467,7 @@ static std::optional geo_node_get_execution_time( return std::nullopt; } -/* Create node key instance, assuming the node comes from the currently editing node tree. */ +/* Create node key instance, assuming the node comes from the currently edited node tree. */ static bNodeInstanceKey current_node_instance_key(const SpaceNode &snode, const bNode &node) { const bNodeTreePath *path = static_cast(snode.treepath.last); -- 2.30.2