Depsgraph: Fix missing material update when changing links in node tree

This commit is contained in:
Sergey Sharybin 2017-07-21 14:20:30 +02:00
parent 4e28d88ece
commit 9edb7e49d7
4 changed files with 42 additions and 2 deletions

View File

@ -157,6 +157,11 @@ enum {
/* Update copy on write component without flushing down the road. */
DEG_TAG_COPY_ON_WRITE = (1 << 8),
/* Tag shading components for update.
* Only parameters of material changed).
*/
DEG_TAG_SHADING_UPDATE = (1 << 9),
};
void DEG_id_tag_update(struct ID *id, int flag);
void DEG_id_tag_update_ex(struct Main *bmain,

View File

@ -234,6 +234,21 @@ void id_tag_update_particle(Depsgraph *graph, IDDepsNode *id_node, int tag)
particle_comp->tag_update(graph);
}
void id_tag_update_shading(Depsgraph *graph, IDDepsNode *id_node, int tag)
{
ComponentDepsNode *shading_comp =
id_node->find_component(DEG_NODE_TYPE_SHADING);
if (shading_comp == NULL) {
#ifdef STRICT_COMPONENT_TAGGING
DEG_ERROR_PRINTF("ERROR: Unable to find shading component for %s\n",
id_node->id_orig->name);
BLI_assert(!"This is not supposed to happen!");
#endif
return;
}
shading_comp->tag_update(graph);
}
#ifdef WITH_COPY_ON_WRITE
/* Tag corresponding to DEG_TAG_COPY_ON_WRITE. */
void id_tag_update_copy_on_write(Depsgraph *graph, IDDepsNode *id_node)
@ -272,6 +287,9 @@ void deg_graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id, int flag)
if (flag & PSYS_RECALC) {
id_tag_update_particle(graph, id_node, flag);
}
if (flag & DEG_TAG_SHADING_UPDATE) {
id_tag_update_shading(graph, id_node, flag);
}
#ifdef WITH_COPY_ON_WRITE
if (flag & DEG_TAG_COPY_ON_WRITE) {
id_tag_update_copy_on_write(graph, id_node);

View File

@ -298,6 +298,13 @@ static void material_changed(Main *bmain, Material *ma)
/* icons */
BKE_icon_changed(BKE_icon_id_ensure(&ma->id));
/* glsl */
if (ma->id.tag & LIB_TAG_ID_RECALC) {
if (!BLI_listbase_is_empty(&ma->gpumaterial)) {
GPU_material_free(&ma->gpumaterial);
}
}
/* find node materials using this */
for (parent = bmain->mat.first; parent; parent = parent->id.next) {
if (parent->use_nodes && parent->nodetree && nodes_use_material(parent->nodetree, ma)) {
@ -474,6 +481,16 @@ static void world_changed(Main *UNUSED(bmain), World *wo)
/* XXX temporary flag waiting for depsgraph proper tagging */
wo->update_flag = 1;
/* glsl */
if (wo->id.tag & LIB_TAG_ID_RECALC) {
if (!BLI_listbase_is_empty(&defmaterial.gpumaterial)) {
GPU_material_free(&defmaterial.gpumaterial);
}
if (!BLI_listbase_is_empty(&wo->gpumaterial)) {
GPU_material_free(&wo->gpumaterial);
}
}
}
static void image_changed(Main *bmain, Image *ima)

View File

@ -2284,11 +2284,11 @@ static void rna_NodeSocket_value_update(Main *bmain, Scene *scene, PointerRNA *p
FOREACH_NODETREE(bmain, tntree, id) {
switch (GS(id->name)) {
case ID_WO:
DEG_id_tag_update_ex(bmain, id, 0);
DEG_id_tag_update_ex(bmain, id, DEG_TAG_SHADING_UPDATE);
WM_main_add_notifier(NC_MATERIAL | ND_SHADING, NULL);
break;
case ID_MA:
DEG_id_tag_update_ex(bmain, id, 0);
DEG_id_tag_update_ex(bmain, id, DEG_TAG_SHADING_UPDATE);
WM_main_add_notifier(NC_MATERIAL | ND_SHADING, id);
break;
}