Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2021-12-31 16:23:14 +0300
committerJacques Lucke <jacques@blender.org>2021-12-31 16:24:11 +0300
commitd09b1d2759861aa012ab2e7e4ce2ffa2b56bd9d3 (patch)
tree7cdbb28a6ba1ae13ff61acaaf3473544932827d3 /source/blender
parent56344fb30fe41bb18a2fce246a30a9e14a8d4e25 (diff)
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.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/intern/image.c20
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc9
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc5
3 files changed, 32 insertions, 2 deletions
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;