[Bf-blender-cvs] [65779b022dc] blender2.8: Fix T58280: Blender 2.8 hangs when the LookDev mode is enabled

Clément Foucault noreply at git.blender.org
Mon Dec 3 17:19:34 CET 2018


Commit: 65779b022dc14e4dff107e925817968fc93570f1
Author: Clément Foucault
Date:   Mon Dec 3 17:19:04 2018 +0100
Branches: blender2.8
https://developer.blender.org/rB65779b022dc14e4dff107e925817968fc93570f1

Fix T58280: Blender 2.8 hangs when the LookDev mode is enabled

The hang was due to the nodes being "evaluated" for every incomming link.

Solution: only evaluate once per nodetree.

Also merge the tagging of SSS and SSR into one traversal only.

===================================================================

M	source/blender/makesdna/DNA_node_types.h
M	source/blender/nodes/shader/node_shader_tree.c

===================================================================

diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index a776fbbc3a6..fe921cf96ac 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -221,7 +221,7 @@ typedef struct bNode {
 	 * and replacing all uses with per-instance data.
 	 */
 	short preview_xsize, preview_ysize;	/* reserved size of the preview rect */
-	short pad2[2];
+	short tmp_flag, pad2;   /* Used at runtime when going through the tree. Initialize before use. */
 	struct uiBlock *block;	/* runtime during drawing */
 
 	float ssr_id; /* XXX: eevee only, id of screen space reflection layer, needs to be a float to feed GPU_uniform. */
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c
index 7fe5b7df37d..6a8fce76fa7 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.c
@@ -66,8 +66,11 @@
 #include "node_shader_util.h"
 
 
-static void ntree_shader_tag_ssr_node(bNodeTree *ntree, bNode *output_node);
-static void ntree_shader_tag_sss_node(bNodeTree *ntree, bNode *output_node);
+typedef struct nTreeTags {
+	float ssr_id, sss_id;
+} nTreeTags;
+
+static void ntree_shader_tag_nodes(bNodeTree *ntree, bNode *output_node, nTreeTags *tags);
 
 static bool shader_tree_poll(const bContext *C, bNodeTreeType *UNUSED(treetype))
 {
@@ -633,27 +636,42 @@ static void ntree_shader_relink_displacement(bNodeTree *ntree, bNode *output_nod
 	ntreeUpdateTree(G.main, ntree);
 }
 
-static bool ntree_tag_ssr_bsdf_cb(bNode *fromnode, bNode *UNUSED(tonode), void *userdata, const bool UNUSED(reversed))
+static bool ntree_tag_bsdf_cb(bNode *fromnode, bNode *UNUSED(tonode), void *userdata, const bool UNUSED(reversed))
 {
+	/* Don't evaluate nodes more than once. */
+	if (fromnode->tmp_flag) {
+		return true;
+	}
+	fromnode->tmp_flag = 1;
+
 	switch (fromnode->type) {
 		case NODE_GROUP:
 			/* Recursive */
 			if (fromnode->id != NULL) {
 				bNodeTree *ntree = (bNodeTree *)fromnode->id;
 				bNode *group_output = ntree_group_output_node(ntree);
-				ntree_shader_tag_ssr_node(ntree, group_output);
+				ntree_shader_tag_nodes(ntree, group_output, (nTreeTags *)userdata);
 			}
 			break;
 		case SH_NODE_BSDF_ANISOTROPIC:
 		case SH_NODE_EEVEE_SPECULAR:
-		case SH_NODE_BSDF_PRINCIPLED:
 		case SH_NODE_BSDF_GLOSSY:
 		case SH_NODE_BSDF_GLASS:
-			fromnode->ssr_id = (*(float *)userdata);
-			(*(float *)userdata) += 1;
+			fromnode->ssr_id = ((nTreeTags *)userdata)->ssr_id;
+			((nTreeTags *)userdata)->ssr_id += 1;
+			break;
+		case SH_NODE_SUBSURFACE_SCATTERING:
+			fromnode->sss_id = ((nTreeTags *)userdata)->sss_id;
+			((nTreeTags *)userdata)->sss_id += 1;
+			break;
+		case SH_NODE_BSDF_PRINCIPLED:
+			fromnode->ssr_id = ((nTreeTags *)userdata)->ssr_id;
+			fromnode->sss_id = ((nTreeTags *)userdata)->sss_id;
+			((nTreeTags *)userdata)->sss_id += 1;
+			((nTreeTags *)userdata)->ssr_id += 1;
 			break;
 		default:
-			/* We could return false here but since we (will)
+			/* We could return false here but since we
 			 * allow the use of Closure as RGBA, we can have
 			 * Bsdf nodes linked to other Bsdf nodes. */
 			break;
@@ -663,9 +681,9 @@ static bool ntree_tag_ssr_bsdf_cb(bNode *fromnode, bNode *UNUSED(tonode), void *
 }
 
 /* EEVEE: Scan the ntree to set the Screen Space Reflection
- * layer id of every specular node.
+ * layer id of every specular node AND the Subsurface Scattering id of every SSS node.
  */
-void ntree_shader_tag_ssr_node(bNodeTree *ntree, bNode *output_node)
+void ntree_shader_tag_nodes(bNodeTree *ntree, bNode *output_node, nTreeTags *tags)
 {
 	if (output_node == NULL) {
 		return;
@@ -673,45 +691,12 @@ void ntree_shader_tag_ssr_node(bNodeTree *ntree, bNode *output_node)
 	/* Make sure sockets links pointers are correct. */
 	ntreeUpdateTree(G.main, ntree);
 
-	float lobe_id = 1;
-	nodeChainIter(ntree, output_node, ntree_tag_ssr_bsdf_cb, &lobe_id, true);
-}
-
-static bool ntree_tag_sss_bsdf_cb(bNode *fromnode, bNode *UNUSED(tonode), void *userdata, const bool UNUSED(reversed))
-{
-	switch (fromnode->type) {
-		case NODE_GROUP:
-			/* Recursive */
-			if (fromnode->id != NULL) {
-				bNodeTree *ntree = (bNodeTree *)fromnode->id;
-				bNode *group_output = ntree_group_output_node(ntree);
-				ntree_shader_tag_sss_node(ntree, group_output);
-			}
-			break;
-		case SH_NODE_BSDF_PRINCIPLED:
-		case SH_NODE_SUBSURFACE_SCATTERING:
-			fromnode->sss_id = (*(float *)userdata);
-			(*(float *)userdata) += 1;
-			break;
-		default:
-			break;
-	}
-
-	return true;
-}
-
-/* EEVEE: Scan the ntree to set the Subsurface Scattering id of every SSS node.
- */
-void ntree_shader_tag_sss_node(bNodeTree *ntree, bNode *output_node)
-{
-	if (output_node == NULL) {
-		return;
+	/* Reset visit flag. */
+	for (bNode *node = ntree->nodes.first; node; node = node->next) {
+		node->tmp_flag = 0;
 	}
-	/* Make sure sockets links pointers are correct. */
-	ntreeUpdateTree(G.main, ntree);
 
-	float sss_id = 1;
-	nodeChainIter(ntree, output_node, ntree_tag_sss_bsdf_cb, &sss_id, true);
+	nodeChainIter(ntree, output_node, ntree_tag_bsdf_cb, tags, true);
 }
 
 /* This one needs to work on a local tree. */
@@ -727,8 +712,12 @@ void ntreeGPUMaterialNodes(bNodeTree *localtree, GPUMaterial *mat, bool *has_sur
 	 */
 	ntree_shader_relink_displacement(localtree, output);
 
-	ntree_shader_tag_ssr_node(localtree, output);
-	ntree_shader_tag_sss_node(localtree, output);
+	/* TODO(fclem): consider moving this to the gpu shader tree evaluation. */
+	nTreeTags tags = {
+		.ssr_id = 1.0,
+		.sss_id = 1.0
+	};
+	ntree_shader_tag_nodes(localtree, output, &tags);
 
 	exec = ntreeShaderBeginExecTree(localtree);
 	ntreeExecGPUNodes(exec, mat, 1);



More information about the Bf-blender-cvs mailing list