Fix T76970: Unneccessary update calls viewport

Due to recent changes clicks in the node editor would trigger a
depsgraph update resulting in too many redraws. This patch limits
the updates to when workbench shown in texture mode in any visible
screen.

There are still cases where too many updates are created. For example when
there are a Cycles render viewport and a Workbench texture viewport on the
same screen.

This fix is meant as a workaround. The actual fix should add a mechanism
to the depsgraph and the viewports should check if they need to be redrawn.

Reviewed By: Brecht van Lommel

Differential Revision: https://developer.blender.org/D7830
This commit is contained in:
Jeroen Bakker 2020-05-25 10:43:44 +02:00
parent 39aa122a0e
commit 77fdd189e4
Notes: blender-bot 2023-02-14 06:17:14 +01:00
Referenced by issue #78520, EEVEE viewport isn't updating when adding or connecting new nodes to a material.
Referenced by issue #78358, Crash while modifying shader nodes
Referenced by issue #76970, Cycles viewport unneccessary update calls
7 changed files with 86 additions and 8 deletions

View File

@ -101,7 +101,10 @@ void ED_node_texture_default(const struct bContext *C, struct Tex *tex);
bool ED_node_select_check(ListBase *lb);
void ED_node_select_all(ListBase *lb, int action);
void ED_node_post_apply_transform(struct bContext *C, struct bNodeTree *ntree);
void ED_node_set_active(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node);
void ED_node_set_active(struct Main *bmain,
struct bNodeTree *ntree,
struct bNode *node,
bool *r_active_texture_changed);
void ED_node_composite_job(const struct bContext *C,
struct bNodeTree *nodetree,

View File

@ -129,6 +129,9 @@ enum eV3DCursorOrient {
void ED_view3d_background_color_get(const struct Scene *scene,
const struct View3D *v3d,
float r_color[3]);
bool ED_view3d_has_workbench_in_texture_color(const struct Scene *scene,
const struct Object *ob,
const struct View3D *v3d);
void ED_view3d_cursor3d_position(struct bContext *C,
const int mval[2],
const bool use_depth,

View File

@ -373,7 +373,7 @@ static void template_texture_select(bContext *C, void *user_p, void *UNUSED(arg)
/* set user as active */
if (user->node) {
ED_node_set_active(CTX_data_main(C), user->ntree, user->node);
ED_node_set_active(CTX_data_main(C), user->ntree, user->node, NULL);
ct->texture = NULL;
}
else {

View File

@ -82,7 +82,7 @@ bNode *node_add_node(const bContext *C, const char *idname, int type, float locx
nodeSetSelected(node, true);
ntreeUpdateTree(bmain, snode->edittree);
ED_node_set_active(bmain, snode->edittree, node);
ED_node_set_active(bmain, snode->edittree, node, NULL);
snode_update(snode, node);

View File

@ -642,9 +642,12 @@ void snode_update(SpaceNode *snode, bNode *node)
}
}
void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node, bool *r_active_texture_changed)
{
const bool was_active_texture = (node->flag & NODE_ACTIVE_TEXTURE) != 0;
if (r_active_texture_changed) {
*r_active_texture_changed = false;
}
nodeSetActive(ntree, node);
@ -713,6 +716,9 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
}
}
if (r_active_texture_changed) {
*r_active_texture_changed = true;
}
ED_node_tag_update_nodetree(bmain, ntree, node);
WM_main_add_notifier(NC_IMAGE, NULL);
}
@ -1284,7 +1290,7 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
newnode = node->new_node;
nodeSetSelected(node, false);
node->flag &= ~NODE_ACTIVE;
node->flag &= ~(NODE_ACTIVE | NODE_ACTIVE_TEXTURE);
nodeSetSelected(newnode, true);
do_tag_update |= (do_tag_update || node_connected_to_output(bmain, ntree, newnode));

View File

@ -24,6 +24,7 @@
#include <stdlib.h>
#include "DNA_node_types.h"
#include "DNA_windowmanager_types.h"
#include "BLI_lasso_2d.h"
#include "BLI_listbase.h"
@ -36,10 +37,12 @@
#include "BKE_context.h"
#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_workspace.h"
#include "ED_node.h" /* own include */
#include "ED_screen.h"
#include "ED_select_utils.h"
#include "ED_view3d.h"
#include "RNA_access.h"
#include "RNA_define.h"
@ -57,6 +60,36 @@
#include "node_intern.h" /* own include */
/* Function to detect if there is a visible view3d that uses workbench in texture mode.
* This function is for fixing T76970 for Blender 2.83. The actual fix should add a mechanism in
* the depsgraph that can be used by the draw engines to check if they need to be redrawn.
*
* We don't want to add these risky changes this close before releasing 2.83 without good testing
* hence this workaround. There are still cases were too many updates happen. For example when you
* have both a Cycles and workbench with textures viewport.
* */
static bool has_workbench_in_texture_color(const wmWindowManager *wm,
const Scene *scene,
const Object *ob)
{
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
if (win->scene != scene) {
continue;
}
const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
if (area->spacetype == SPACE_VIEW3D) {
const View3D *v3d = area->spacedata.first;
if (ED_view3d_has_workbench_in_texture_color(scene, ob, v3d)) {
return true;
}
}
}
}
return false;
}
/* -------------------------------------------------------------------- */
/** \name Public Node Selection API
* \{ */
@ -415,6 +448,10 @@ void node_select_single(bContext *C, bNode *node)
{
Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
const Object *ob = CTX_data_active_object(C);
const Scene *scene = CTX_data_scene(C);
const wmWindowManager *wm = CTX_wm_manager(C);
bool active_texture_changed = false;
bNode *tnode;
for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) {
@ -424,10 +461,13 @@ void node_select_single(bContext *C, bNode *node)
}
nodeSetSelected(node, true);
ED_node_set_active(bmain, snode->edittree, node);
ED_node_set_active(bmain, snode->edittree, node, &active_texture_changed);
ED_node_set_active_viewer_key(snode);
ED_node_sort(snode->edittree);
if (active_texture_changed && has_workbench_in_texture_color(wm, scene, ob)) {
DEG_id_tag_update(&snode->edittree->id, ID_RECALC_COPY_ON_WRITE);
}
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
}
@ -440,6 +480,9 @@ static int node_mouse_select(bContext *C,
Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *region = CTX_wm_region(C);
const Object *ob = CTX_data_active_object(C);
const Scene *scene = CTX_data_scene(C);
const wmWindowManager *wm = CTX_wm_manager(C);
bNode *node, *tnode;
bNodeSocket *sock = NULL;
bNodeSocket *tsock;
@ -546,12 +589,15 @@ static int node_mouse_select(bContext *C,
/* update node order */
if (ret_value != OPERATOR_CANCELLED) {
bool active_texture_changed = false;
if (node != NULL && ret_value != OPERATOR_RUNNING_MODAL) {
ED_node_set_active(bmain, snode->edittree, node);
ED_node_set_active(bmain, snode->edittree, node, &active_texture_changed);
}
ED_node_set_active_viewer_key(snode);
ED_node_sort(snode->edittree);
DEG_id_tag_update(&snode->edittree->id, ID_RECALC_COPY_ON_WRITE);
if (active_texture_changed && has_workbench_in_texture_color(wm, scene, ob)) {
DEG_id_tag_update(&snode->edittree->id, ID_RECALC_COPY_ON_WRITE);
}
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
}

View File

@ -86,6 +86,26 @@ void ED_view3d_background_color_get(const Scene *scene, const View3D *v3d, float
UI_GetThemeColor3fv(TH_BACK, r_color);
}
bool ED_view3d_has_workbench_in_texture_color(const Scene *scene,
const Object *ob,
const View3D *v3d)
{
if (v3d->shading.type == OB_SOLID) {
if (v3d->shading.color_type == V3D_SHADING_TEXTURE_COLOR) {
return true;
}
if (ob->mode == OB_MODE_TEXTURE_PAINT) {
return true;
}
}
else if (v3d->shading.type == OB_RENDER) {
if (STREQ(scene->r.engine, RE_engine_id_BLENDER_WORKBENCH)) {
return scene->display.shading.color_type == V3D_SHADING_TEXTURE_COLOR;
}
}
return false;
}
Camera *ED_view3d_camera_data_get(View3D *v3d, RegionView3D *rv3d)
{
/* establish the camera object,