UI: (Performance) Avoid drawing buttons out of view

The UI was always drawing all buttons in a layout, no matter if they
were scrolled out of view (as in, outside of the visible part of the
region) or not. This means it's doing quite some work that can be
avoided.
UI drawing generally isn't a big bottleneck in Blender, so I don't
expect huge speedups from this. But while playing back animation, we do
redraw a fair bit of the UI, so in cases where there are many buttons
out of view, it may bring a little FPS boost. E.g. say in complex node
trees (the node editor is redrawn on animation playback in case there
are animated values that need updated UI feedback). This also mitigates
the issue in T92922 significantly.

Differential Revision: https://developer.blender.org/T92922

Reviewed by: Brecht Van Lommel
This commit is contained in:
Julian Eisel 2021-11-12 18:16:18 +01:00
parent 896d3f1ce5
commit 2b394e1108
1 changed files with 20 additions and 7 deletions

View File

@ -2022,6 +2022,13 @@ static void ui_but_to_pixelrect(rcti *rect, const ARegion *region, uiBlock *bloc
BLI_rcti_translate(rect, -region->winrct.xmin, -region->winrct.ymin);
}
static bool ui_but_pixelrect_in_view(const ARegion *region, const rcti *rect)
{
rcti rect_winspace = *rect;
BLI_rcti_translate(&rect_winspace, region->winrct.xmin, region->winrct.ymin);
return BLI_rcti_isect(&region->winrct, &rect_winspace, NULL);
}
/* uses local copy of style, to scale things down, and allow widgets to change stuff */
void UI_block_draw(const bContext *C, uiBlock *block)
{
@ -2095,14 +2102,20 @@ void UI_block_draw(const bContext *C, uiBlock *block)
/* widgets */
LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (!(but->flag & (UI_HIDDEN | UI_SCROLLED))) {
ui_but_to_pixelrect(&rect, region, block, but);
if (but->flag & (UI_HIDDEN | UI_SCROLLED)) {
continue;
}
/* XXX: figure out why invalid coordinates happen when closing render window */
/* and material preview is redrawn in main window (temp fix for bug T23848) */
if (rect.xmin < rect.xmax && rect.ymin < rect.ymax) {
ui_draw_but(C, region, &style, but, &rect);
}
ui_but_to_pixelrect(&rect, region, block, but);
/* Optimization: Don't draw buttons that are not visible (outside view bounds). */
if (!ui_but_pixelrect_in_view(region, &rect)) {
continue;
}
/* XXX: figure out why invalid coordinates happen when closing render window */
/* and material preview is redrawn in main window (temp fix for bug T23848) */
if (rect.xmin < rect.xmax && rect.ymin < rect.ymax) {
ui_draw_but(C, region, &style, but, &rect);
}
}