diff options
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; |