Nodes: Slightly improve editor drawing performance with large node trees

Avoid retrieving context data for every single node which can be
expensive when there are thousands of nodes. In the "Mouse House"
test file I observed a 13% improvement in drawing timings.

Pull Request: https://projects.blender.org/blender/blender/pulls/130239
This commit is contained in:
Hans Goudey
2024-11-14 16:04:33 +01:00
committed by Hans Goudey
parent 9ad9984611
commit 6c3ac28eb3
4 changed files with 119 additions and 23 deletions

View File

@@ -877,7 +877,21 @@ uiBlock *UI_block_begin(const bContext *C,
ARegion *region,
std::string name,
eUIEmbossType emboss);
void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_xy[2]);
uiBlock *UI_block_begin(const bContext *C,
Scene *scene,
wmWindow *window,
ARegion *region,
std::string name,
eUIEmbossType emboss);
void UI_block_end_ex(const bContext *C,
Main *bmain,
wmWindow *window,
Scene *scene,
ARegion *region,
Depsgraph *depsgraph,
uiBlock *block,
const int xy[2] = nullptr,
int r_xy[2] = nullptr);
void UI_block_end(const bContext *C, uiBlock *block);
/**
* Uses local copy of style, to scale things down, and allow widgets to change stuff.

View File

@@ -1919,13 +1919,16 @@ bool ui_but_context_poll_operator(bContext *C, wmOperatorType *ot, const uiBut *
return ui_but_context_poll_operator_ex(C, but, &params);
}
void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_xy[2])
void UI_block_end_ex(const bContext *C,
Main *bmain,
wmWindow *window,
Scene *scene,
ARegion *region,
Depsgraph *depsgraph,
uiBlock *block,
const int xy[2],
int r_xy[2])
{
wmWindow *window = CTX_wm_window(C);
Scene *scene = CTX_data_scene(C);
ARegion *region = CTX_wm_region(C);
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
BLI_assert(block->active);
/* Extend button data. This needs to be done before the block updating. */
@@ -1958,7 +1961,7 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
depsgraph, (scene) ? scene->r.cfra : 0.0f);
ui_but_anim_flag(but, &anim_eval_context);
ui_but_override_flag(CTX_data_main(C), but);
ui_but_override_flag(bmain, but);
if (UI_but_is_decorator(but)) {
ui_but_anim_decorate_update_from_flag((uiButDecorator *)but);
}
@@ -1972,7 +1975,7 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x
if (block->layouts.first) {
UI_block_layout_resolve(block, nullptr, nullptr);
}
ui_block_align_calc(block, CTX_wm_region(C));
ui_block_align_calc(block, region);
if ((block->flag & UI_BLOCK_LOOP) && (block->flag & UI_BLOCK_NUMSELECT) &&
(block->flag & UI_BLOCK_NO_ACCELERATOR_KEYS) == 0)
{
@@ -2029,7 +2032,15 @@ void UI_block_end(const bContext *C, uiBlock *block)
{
wmWindow *window = CTX_wm_window(C);
UI_block_end_ex(C, block, window->eventstate->xy, nullptr);
UI_block_end_ex(C,
CTX_data_main(C),
window,
CTX_data_scene(C),
CTX_wm_region(C),
CTX_data_depsgraph_pointer(C),
block,
window->eventstate->xy,
nullptr);
}
/* ************** BLOCK DRAWING FUNCTION ************* */
@@ -3786,11 +3797,13 @@ void UI_block_region_set(uiBlock *block, ARegion *region)
block->oldblock = oldblock;
}
uiBlock *UI_block_begin(const bContext *C, ARegion *region, std::string name, eUIEmbossType emboss)
uiBlock *UI_block_begin(const bContext *C,
Scene *scene,
wmWindow *window,
ARegion *region,
std::string name,
eUIEmbossType emboss)
{
wmWindow *window = CTX_wm_window(C);
Scene *scene = CTX_data_scene(C);
uiBlock *block = MEM_new<uiBlock>(__func__);
block->active = true;
block->emboss = emboss;
@@ -3831,6 +3844,11 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, std::string name, eU
return block;
}
uiBlock *UI_block_begin(const bContext *C, ARegion *region, std::string name, eUIEmbossType emboss)
{
return UI_block_begin(C, CTX_data_scene(C), CTX_wm_window(C), region, std::move(name), emboss);
}
void ui_block_add_dynamic_listener(uiBlock *block,
void (*listener_func)(const wmRegionListenerParams *params))
{

View File

@@ -706,8 +706,15 @@ uiBlock *ui_popup_block_refresh(bContext *C,
block->oldblock = nullptr;
if (!block->endblock) {
UI_block_end_ex(
C, block, handle->popup_create_vars.event_xy, handle->popup_create_vars.event_xy);
UI_block_end_ex(C,
CTX_data_main(C),
window,
CTX_data_scene(C),
region,
CTX_data_depsgraph_pointer(C),
block,
handle->popup_create_vars.event_xy,
handle->popup_create_vars.event_xy);
}
/* if this is being created from a button */

View File

@@ -111,6 +111,12 @@ using blender::nodes::NodeExtraInfoRow;
* This is passed to many functions which draw the node editor.
*/
struct TreeDrawContext {
Main *bmain;
wmWindow *window;
Scene *scene;
ARegion *region;
Depsgraph *depsgraph;
/**
* Whether a viewer node is active in geometry nodes can not be determined by a flag on the node
* alone. That's because if the node group with the viewer is used multiple times, it's only
@@ -339,7 +345,11 @@ Array<bNode *> tree_draw_order_calc_nodes_reversed(bNodeTree &ntree)
static Array<uiBlock *> node_uiblocks_init(const bContext &C, const Span<bNode *> nodes)
{
Array<uiBlock *> blocks(nodes.size());
/* Add node uiBlocks in drawing order - prevents events going to overlapping nodes. */
Scene *scene = CTX_data_scene(&C);
wmWindow *window = CTX_wm_window(&C);
ARegion *region = CTX_wm_region(&C);
for (const int i : nodes.index_range()) {
const bNode &node = *nodes[i];
std::string block_name = "node_" + std::string(node.name);
@@ -3486,7 +3496,13 @@ static void node_draw_basis(const bContext &C,
rect_with_preview.ymax += NODE_WIDTH(node);
}
if (BLI_rctf_isect(&rect_with_preview, &v2d.cur, nullptr) == false) {
UI_block_end(&C, &block);
UI_block_end_ex(&C,
tree_draw_ctx.bmain,
tree_draw_ctx.window,
tree_draw_ctx.scene,
tree_draw_ctx.region,
tree_draw_ctx.depsgraph,
&block);
return;
}
@@ -3826,7 +3842,13 @@ static void node_draw_basis(const bContext &C,
node_draw_panels(ntree, node, block);
}
UI_block_end(&C, &block);
UI_block_end_ex(&C,
tree_draw_ctx.bmain,
tree_draw_ctx.window,
tree_draw_ctx.scene,
tree_draw_ctx.region,
tree_draw_ctx.depsgraph,
&block);
UI_block_draw(&C, &block);
}
@@ -4011,7 +4033,13 @@ static void node_draw_hidden(const bContext &C,
node_draw_sockets(v2d, C, ntree, node, block, true, false);
UI_block_end(&C, &block);
UI_block_end_ex(&C,
tree_draw_ctx.bmain,
tree_draw_ctx.window,
tree_draw_ctx.scene,
tree_draw_ctx.region,
tree_draw_ctx.depsgraph,
&block);
UI_block_draw(&C, &block);
}
@@ -4337,7 +4365,13 @@ static void frame_node_draw_overlay(const bContext &C,
{
/* Skip if out of view. */
if (BLI_rctf_isect(&node.runtime->totr, &region.v2d.cur, nullptr) == false) {
UI_block_end(&C, &block);
UI_block_end_ex(&C,
tree_draw_ctx.bmain,
tree_draw_ctx.window,
tree_draw_ctx.scene,
tree_draw_ctx.region,
tree_draw_ctx.depsgraph,
&block);
return;
}
@@ -4346,7 +4380,13 @@ static void frame_node_draw_overlay(const bContext &C,
node_draw_extra_info_panel(C, tree_draw_ctx, snode, node, nullptr, block);
UI_block_end(&C, &block);
UI_block_end_ex(&C,
tree_draw_ctx.bmain,
tree_draw_ctx.window,
tree_draw_ctx.scene,
tree_draw_ctx.region,
tree_draw_ctx.depsgraph,
&block);
UI_block_draw(&C, &block);
}
@@ -4516,7 +4556,13 @@ static void reroute_node_draw(const bContext &C,
if (rct.xmax < region.v2d.cur.xmin || rct.xmin > region.v2d.cur.xmax ||
rct.ymax < region.v2d.cur.ymin || node.runtime->totr.ymin > region.v2d.cur.ymax)
{
UI_block_end(&C, &block);
UI_block_end_ex(&C,
tree_draw_ctx.bmain,
tree_draw_ctx.window,
tree_draw_ctx.scene,
tree_draw_ctx.region,
tree_draw_ctx.depsgraph,
&block);
return;
}
@@ -4526,7 +4572,13 @@ static void reroute_node_draw(const bContext &C,
* if node itself is selected, since we don't display the node body separately. */
node_draw_sockets(region.v2d, C, ntree, node, block, false, node.flag & SELECT);
UI_block_end(&C, &block);
UI_block_end_ex(&C,
tree_draw_ctx.bmain,
tree_draw_ctx.window,
tree_draw_ctx.scene,
tree_draw_ctx.region,
tree_draw_ctx.depsgraph,
&block);
UI_block_draw(&C, &block);
}
@@ -4936,6 +4988,11 @@ static void draw_nodetree(const bContext &C,
Array<uiBlock *> blocks = node_uiblocks_init(C, nodes);
TreeDrawContext tree_draw_ctx;
tree_draw_ctx.bmain = CTX_data_main(&C);
tree_draw_ctx.window = CTX_wm_window(&C);
tree_draw_ctx.scene = CTX_data_scene(&C);
tree_draw_ctx.region = CTX_wm_region(&C);
tree_draw_ctx.depsgraph = CTX_data_depsgraph_pointer(&C);
BLI_SCOPED_DEFER([&]() { ntree.runtime->sockets_on_active_gizmo_paths.clear(); });
if (ntree.type == NTREE_GEOMETRY) {