[Bf-blender-cvs] [d09b1d27598] master: Fix T94464: video texture is not refreshing

Jacques Lucke noreply at git.blender.org
Fri Dec 31 14:25:35 CET 2021


Commit: d09b1d2759861aa012ab2e7e4ce2ffa2b56bd9d3
Author: Jacques Lucke
Date:   Fri Dec 31 14:23:14 2021 +0100
Branches: master
https://developer.blender.org/rBd09b1d2759861aa012ab2e7e4ce2ffa2b56bd9d3

Fix T94464: video texture is not refreshing

In the past that worked because the `GPUMaterial` referenced the
`ImageUser` from the image node. However, that design was incompatible
with the recent node tree update refactor (rB7e712b2d6a0d257d272e).
Also, in general it is a bad idea to have references between data that is
owned by two different data blocks.

This incompatibility was resolved by copying the image user from the node
to the `GPUMaterial` (rB28df0107d4a8). Unfortunately, eevee depended
on this reference, because the image user on the node was update when the
frame changed. Because the image user was copied, the image user in the
`GPUMaterial` did not receive the frame update anymore.

This frame update is added back by this commit. The main change is that
the image user iterator now also iterates over image users in `GPUMaterial`s
on material and world data blocks. An issue is that these materials don't
exist on the original data blocks and that caused the check in
`build_animation_images` in the depsgraph to give the wrong answer.
Therefore the check is extended.

Right now the check is not optimal, because it results in more depsgraph
nodes than are necessary. This can be improved when it becomes cheaper
to check if a node tree contains any references to a video texture.
The node tree update refactor mentioned before makes it much easier
to construct this kind of run-time data from the bottom up, instead of
scanning the entire node tree recursively every time some information
is needed.

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

M	source/blender/blenkernel/intern/image.c
M	source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
M	source/blender/depsgraph/intern/builder/deg_builder_relations.cc

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

diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index edd5073da79..3fec5db422d 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -98,6 +98,7 @@
 
 #include "SEQ_utils.h" /* SEQ_get_topmost_sequence() */
 
+#include "GPU_material.h"
 #include "GPU_texture.h"
 
 #include "BLI_sys_types.h" /* for intptr_t support */
@@ -3364,6 +3365,23 @@ static void image_walk_ntree_all_users(
   }
 }
 
+static void image_walk_gpu_materials(
+    ID *id,
+    ListBase *gpu_materials,
+    void *customdata,
+    void callback(Image *ima, ID *iuser_id, ImageUser *iuser, void *customdata))
+{
+  LISTBASE_FOREACH (LinkData *, link, gpu_materials) {
+    GPUMaterial *gpu_material = (GPUMaterial *)link->data;
+    ListBase textures = GPU_material_textures(gpu_material);
+    LISTBASE_FOREACH (GPUMaterialTexture *, gpu_material_texture, &textures) {
+      if (gpu_material_texture->iuser_available) {
+        callback(gpu_material_texture->ima, id, &gpu_material_texture->iuser, customdata);
+      }
+    }
+  }
+}
+
 static void image_walk_id_all_users(
     ID *id,
     bool skip_nested_nodes,
@@ -3383,6 +3401,7 @@ static void image_walk_id_all_users(
       if (ma->nodetree && ma->use_nodes && !skip_nested_nodes) {
         image_walk_ntree_all_users(ma->nodetree, &ma->id, customdata, callback);
       }
+      image_walk_gpu_materials(id, &ma->gpumaterial, customdata, callback);
       break;
     }
     case ID_LA: {
@@ -3397,6 +3416,7 @@ static void image_walk_id_all_users(
       if (world->nodetree && world->use_nodes && !skip_nested_nodes) {
         image_walk_ntree_all_users(world->nodetree, &world->id, customdata, callback);
       }
+      image_walk_gpu_materials(id, &world->gpumaterial, customdata, callback);
       break;
     }
     case ID_TE: {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 16eacc735d4..f8562e16746 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -1121,7 +1121,14 @@ void DepsgraphNodeBuilder::build_animdata_nlastrip_targets(ListBase *strips)
 
 void DepsgraphNodeBuilder::build_animation_images(ID *id)
 {
-  if (BKE_image_user_id_has_animation(id)) {
+  /* GPU materials might use an animated image. However, these materials have no been built yet. We
+   * could scan the entire node tree recursively to check if any texture node has a video. That is
+   * quite expensive. For now just always add this operation node, because it is very fast. */
+  /* TODO: Add a more precise check when it is cheaper to iterate over all image nodes in a node
+   * tree. */
+  const bool can_have_gpu_material = ELEM(GS(id->name), ID_MA, ID_WO);
+
+  if (BKE_image_user_id_has_animation(id) || can_have_gpu_material) {
     ID *id_cow = get_cow_id(id);
     add_operation_node(
         id,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 09263718677..558ea3dd6e0 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -1466,8 +1466,11 @@ void DepsgraphRelationBuilder::build_animdata_drivers(ID *id)
 
 void DepsgraphRelationBuilder::build_animation_images(ID *id)
 {
+  /* See #DepsgraphNodeBuilder::build_animation_images. */
+  const bool can_have_gpu_material = ELEM(GS(id->name), ID_MA, ID_WO);
+
   /* TODO: can we check for existence of node for performance? */
-  if (BKE_image_user_id_has_animation(id)) {
+  if (BKE_image_user_id_has_animation(id) || can_have_gpu_material) {
     OperationKey image_animation_key(
         id, NodeType::IMAGE_ANIMATION, OperationCode::IMAGE_ANIMATION);
     TimeSourceKey time_src_key;



More information about the Bf-blender-cvs mailing list