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:
@@ -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.
|
||||
|
||||
@@ -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, ¶ms);
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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, ®ion.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) {
|
||||
|
||||
Reference in New Issue
Block a user