WM: reduce CPU use while idle in ED_view3d_datamask

When idle, each 3D view made two calls CTX_data_mode_enum(C) from the
WM_main loop. While not causing problems it complicated troubleshooting
high CPU use while idle in other areas.

Access the object via the view layer, giving approx 40x speedup.
This commit is contained in:
Campbell Barton 2023-01-13 17:48:54 +11:00
parent 0c2a3054ba
commit c158dd560e
Notes: blender-bot 2023-02-14 11:35:46 +01:00
Referenced by commit fc9c818531, Fix missing view layer sync in recent change to ED_view3d_datamask
Referenced by issue #103866, Assert when running tests in debug build
4 changed files with 31 additions and 19 deletions

View File

@ -1104,15 +1104,13 @@ char ED_view3d_lock_view_from_index(int index);
char ED_view3d_axis_view_opposite(char view);
bool ED_view3d_lock(struct RegionView3D *rv3d);
void ED_view3d_datamask(const struct bContext *C,
const struct Scene *scene,
void ED_view3d_datamask(const struct ViewLayer *view_layer,
const struct View3D *v3d,
struct CustomData_MeshMasks *r_cddata_masks);
/**
* Goes over all modes and view3d settings.
*/
void ED_view3d_screen_datamask(const struct bContext *C,
const struct Scene *scene,
void ED_view3d_screen_datamask(const struct ViewLayer *view_layer,
const struct bScreen *screen,
struct CustomData_MeshMasks *r_cddata_masks);

View File

@ -809,7 +809,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
0,
sizeof(oglrender->scene->customdata_mask_modal));
ED_view3d_datamask(
C, oglrender->scene, oglrender->v3d, &oglrender->scene->customdata_mask_modal);
oglrender->view_layer, oglrender->v3d, &oglrender->scene->customdata_mask_modal);
/* apply immediately in case we're rendering from a script,
* running notifiers again will overwrite */

View File

@ -2407,11 +2407,13 @@ void ED_view3d_depths_free(ViewDepths *depths)
/** \name Custom-data Utilities
* \{ */
void ED_view3d_datamask(const bContext *C,
const Scene * /*scene*/,
void ED_view3d_datamask(const ViewLayer *view_layer,
const View3D *v3d,
CustomData_MeshMasks *r_cddata_masks)
{
/* NOTE(@campbellbarton): as this function runs continuously while idle
* (from #wm_event_do_depsgraph) take care to avoid expensive lookups.
* While they won't hurt performance noticeably, they will increase CPU usage while idle. */
if (ELEM(v3d->shading.type, OB_TEXTURE, OB_MATERIAL, OB_RENDER)) {
r_cddata_masks->lmask |= CD_MASK_PROP_FLOAT2 | CD_MASK_PROP_BYTE_COLOR;
r_cddata_masks->vmask |= CD_MASK_ORCO | CD_MASK_PROP_COLOR;
@ -2426,26 +2428,38 @@ void ED_view3d_datamask(const bContext *C,
}
}
if ((CTX_data_mode_enum(C) == CTX_MODE_EDIT_MESH) &&
(v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_WEIGHT)) {
r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
}
if (CTX_data_mode_enum(C) == CTX_MODE_SCULPT) {
r_cddata_masks->vmask |= CD_MASK_PAINT_MASK;
Object *obact = BKE_view_layer_active_object_get(view_layer);
if (obact) {
switch (obact->type) {
case OB_MESH: {
switch (obact->mode) {
case OB_MODE_EDIT: {
if (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_WEIGHT) {
r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
}
break;
}
case OB_MODE_SCULPT: {
r_cddata_masks->vmask |= CD_MASK_PAINT_MASK;
break;
}
}
break;
}
}
}
}
void ED_view3d_screen_datamask(const bContext *C,
const Scene *scene,
void ED_view3d_screen_datamask(const ViewLayer *view_layer,
const bScreen *screen,
CustomData_MeshMasks *r_cddata_masks)
{
CustomData_MeshMasks_update(r_cddata_masks, &CD_MASK_BAREMESH);
/* Check if we need tfaces & mcols due to view mode. */
/* Check if we need UV or color data due to the view mode. */
LISTBASE_FOREACH (const ScrArea *, area, &screen->areabase) {
if (area->spacetype == SPACE_VIEW3D) {
ED_view3d_datamask(C, scene, static_cast<View3D *>(area->spacedata.first), r_cddata_masks);
ED_view3d_datamask(view_layer, static_cast<View3D *>(area->spacedata.first), r_cddata_masks);
}
}
}

View File

@ -423,10 +423,10 @@ void wm_event_do_depsgraph(bContext *C, bool is_after_open_file)
/* Combine data-masks so one window doesn't disable UVs in another T26448. */
CustomData_MeshMasks win_combine_v3d_datamask = {0};
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
const Scene *scene = WM_window_get_active_scene(win);
const ViewLayer *view_layer = WM_window_get_active_view_layer(win);
const bScreen *screen = WM_window_get_active_screen(win);
ED_view3d_screen_datamask(C, scene, screen, &win_combine_v3d_datamask);
ED_view3d_screen_datamask(view_layer, screen, &win_combine_v3d_datamask);
}
/* Update all the dependency graphs of visible view layers. */
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {