diff options
23 files changed, 169 insertions, 61 deletions
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index ed8dab7aa0d..a6a709c204b 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -207,10 +207,13 @@ void BKE_image_verify_viewer_views(const struct RenderData *rd, struct Image *im /* called on frame change or before render */ void BKE_image_user_frame_calc(struct ImageUser *iuser, int cfra); -void BKE_image_user_check_frame_calc(struct ImageUser *iuser, int cfra); int BKE_image_user_frame_get(const struct ImageUser *iuser, int cfra, bool *r_is_in_range); void BKE_image_user_file_path(struct ImageUser *iuser, struct Image *ima, char *path); -void BKE_image_update_frame(const struct Main *bmain, int cfra); +void BKE_image_editors_update_frame(const struct Main *bmain, int cfra); + +/* dependency graph update for image user users */ +bool BKE_image_user_id_has_animation(struct ID *id); +void BKE_image_user_id_eval_animation(struct Depsgraph *depsgrah, struct ID *id); /* sets index offset for multilayer files */ struct RenderPass *BKE_image_multilayer_index(struct RenderResult *rr, struct ImageUser *iuser); diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 948d22f5146..072aaaf2310 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -88,6 +88,9 @@ #include "BLI_sys_types.h" // for intptr_t support +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + /* for image user iteration */ #include "DNA_node_types.h" #include "DNA_space_types.h" @@ -4418,26 +4421,72 @@ void BKE_image_user_frame_calc(ImageUser *iuser, int cfra) } } -void BKE_image_user_check_frame_calc(ImageUser *iuser, int cfra) +/* goes over all ImageUsers, and sets frame numbers if auto-refresh is set */ +static void image_editors_update_frame(struct Image *UNUSED(ima), struct ImageUser *iuser, void *customdata) { - if ((iuser->flag & IMA_ANIM_ALWAYS) || (iuser->flag & IMA_NEED_FRAME_RECALC)) { - BKE_image_user_frame_calc(iuser, cfra); + int cfra = *(int *)customdata; + if ((iuser->flag & IMA_ANIM_ALWAYS) || + (iuser->flag & IMA_NEED_FRAME_RECALC)) + { + BKE_image_user_frame_calc(iuser, cfra); iuser->flag &= ~IMA_NEED_FRAME_RECALC; } } -/* goes over all ImageUsers, and sets frame numbers if auto-refresh is set */ -static void image_update_frame(struct Image *UNUSED(ima), struct ImageUser *iuser, void *customdata) +void BKE_image_editors_update_frame(const Main *bmain, int cfra) { - int cfra = *(int *)customdata; + /* This only updates images used by the user interface. For others the + * dependency graph will call BKE_image_user_id_eval_animation. */ + wmWindowManager *wm = bmain->wm.first; + BKE_image_walk_id_all_users(&wm->id, &cfra, image_editors_update_frame); +} + +static void image_user_id_has_animation(struct Image *ima, struct ImageUser *UNUSED(iuser), void *customdata) +{ + if (ima && BKE_image_is_animated(ima)) { + *(bool *)customdata = true; + } +} + +bool BKE_image_user_id_has_animation(ID *id) +{ + bool has_animation = false; + BKE_image_walk_id_all_users(id, &has_animation, image_user_id_has_animation); + return has_animation; +} + +static void image_user_id_eval_animation(struct Image *ima, struct ImageUser *iuser, void *customdata) +{ + if (ima && BKE_image_is_animated(ima)) { + Depsgraph *depsgraph = (Depsgraph *)customdata; + + if ((iuser->flag & IMA_ANIM_ALWAYS) || + (iuser->flag & IMA_NEED_FRAME_RECALC) || + (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER)) + { + int framenr = iuser->framenr; + float cfra = DEG_get_ctime(depsgraph); + + BKE_image_user_frame_calc(iuser, cfra); + iuser->flag &= ~IMA_NEED_FRAME_RECALC; - BKE_image_user_check_frame_calc(iuser, cfra); + if (iuser->framenr != framenr) { + /* Note: a single texture and refresh doesn't really work when + * multiple image users may use different frames, this is to + * be improved with perhaps a GPU texture cache. */ + ima->gpuflag |= IMA_GPU_REFRESH; + } + } + } } -void BKE_image_update_frame(const Main *bmain, int cfra) +void BKE_image_user_id_eval_animation(Depsgraph *depsgraph, ID *id) { - BKE_image_walk_all_users(bmain, &cfra, image_update_frame); + /* This is called from the dependency graph to update the image + * users in datablocks. It computes the current frame number + * and tags the image to be refreshed. */ + BKE_image_walk_id_all_users(id, depsgraph, image_user_id_eval_animation); } void BKE_image_user_file_path(ImageUser *iuser, Image *ima, char *filepath) @@ -4605,11 +4654,7 @@ bool BKE_image_has_packedfile(Image *ima) return (BLI_listbase_is_empty(&ima->packedfiles) == false); } -/** - * Checks the image buffer changes (not keyframed values) - * - * to see if we need to call #BKE_image_user_check_frame_calc - */ +/* Checks the image buffer changes with time (not keyframed values). */ bool BKE_image_is_animated(Image *image) { return ELEM(image->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE); diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index b82ff00c656..9ab25f01f7b 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -152,8 +152,6 @@ void BKE_object_handle_data_update( Scene *scene, Object *ob) { - float ctime = BKE_scene_frame_get(scene); - DEG_debug_print_eval(depsgraph, __func__, ob->id.name, ob); /* includes all keys and modifiers */ @@ -209,12 +207,6 @@ void BKE_object_handle_data_update( case OB_LATTICE: BKE_lattice_modifiers_calc(depsgraph, scene, ob); break; - - case OB_EMPTY: - if (ob->empty_drawtype == OB_EMPTY_IMAGE && ob->data) - if (BKE_image_is_animated(ob->data)) - BKE_image_user_check_frame_calc(ob->iuser, (int)ctime); - break; } /* particles */ diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 9f665fee8b6..b055c3695bc 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1524,7 +1524,7 @@ void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph, /* Update animated image textures for particles, modifiers, gpu, etc, * call this at the start so modifiers with textures don't lag 1 frame. */ - BKE_image_update_frame(bmain, scene->r.cfra); + BKE_image_editors_update_frame(bmain, scene->r.cfra); BKE_sound_set_cfra(scene->r.cfra); DEG_graph_relations_update(depsgraph, bmain, scene, view_layer); /* Update animated cache files for modifiers. diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 524462793fc..59c024e8a3e 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -73,6 +73,7 @@ extern "C" { #include "BKE_gpencil.h" #include "BKE_gpencil_modifier.h" #include "BKE_idcode.h" +#include "BKE_image.h" #include "BKE_key.h" #include "BKE_lattice.h" #include "BKE_mask.h" @@ -825,11 +826,13 @@ void DepsgraphNodeBuilder::build_object_pointcache(Object *object) } /** - * Build graph nodes for AnimData block + * Build graph nodes for AnimData block and any animated images used. * \param id: ID-Block which hosts the AnimData */ void DepsgraphNodeBuilder::build_animdata(ID *id) { + build_animation_images(id); + AnimData *adt = BKE_animdata_from_id(id); if (adt == NULL) { return; @@ -886,6 +889,20 @@ void DepsgraphNodeBuilder::build_animdata_nlastrip_targets(ListBase *strips) } } +/** + * Build graph nodes to update the current frame in image users. + */ +void DepsgraphNodeBuilder::build_animation_images(ID *id) +{ + if (BKE_image_user_id_has_animation(id)) { + ID *id_cow = get_cow_id(id); + add_operation_node(id, + NodeType::ANIMATION, + OperationCode::IMAGE_ANIMATION, + function_bind(BKE_image_user_id_eval_animation, _1, id_cow)); + } +} + void DepsgraphNodeBuilder::build_action(bAction *action) { if (built_map_.checkIsBuiltAndTag(action)) { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 3b55131d7e2..ce3c6995fe7 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -187,6 +187,7 @@ struct DepsgraphNodeBuilder { void build_particle_settings(ParticleSettings *part); void build_animdata(ID *id); void build_animdata_nlastrip_targets(ListBase *strips); + void build_animation_images(ID *id); void build_action(bAction *action); void build_driver(ID *id, FCurve *fcurve, int driver_index); void build_driver_variables(ID *id, FCurve *fcurve); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 2b77f8c2587..e3b2614ca05 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -72,6 +72,7 @@ extern "C" { #include "BKE_effect.h" #include "BKE_collision.h" #include "BKE_fcurve.h" +#include "BKE_image.h" #include "BKE_key.h" #include "BKE_material.h" #include "BKE_mball.h" @@ -1199,6 +1200,8 @@ void DepsgraphRelationBuilder::build_constraints(ID *id, void DepsgraphRelationBuilder::build_animdata(ID *id) { + /* Images. */ + build_animation_images(id); /* Animation curves and NLA. */ build_animdata_curves(id); /* Drivers. */ @@ -1391,6 +1394,18 @@ void DepsgraphRelationBuilder::build_animdata_drivers(ID *id) } } +void DepsgraphRelationBuilder::build_animation_images(ID *id) +{ + /* TODO: can we check for existance of node for performance? */ + if (BKE_image_user_id_has_animation(id)) { + OperationKey image_animation_key(id, + NodeType::ANIMATION, + OperationCode::IMAGE_ANIMATION); + TimeSourceKey time_src_key; + add_relation(time_src_key, image_animation_key, "TimeSrc -> Image Animation"); + } +} + void DepsgraphRelationBuilder::build_action(bAction *action) { if (built_map_.checkIsBuiltAndTag(action)) { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 7170eb29f0b..b8dee11bebd 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -238,6 +238,7 @@ struct DepsgraphRelationBuilder OperationNode *operation_from, ListBase *strips); void build_animdata_drivers(ID *id); + void build_animation_images(ID *id); void build_action(bAction *action); void build_driver(ID *id, FCurve *fcurve); void build_driver_data(ID *id, FCurve *fcurve); diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc index a407a3ed99e..0d3ec70d22c 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.cc +++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc @@ -119,6 +119,8 @@ const char *operationCodeAsString(OperationCode opcode) case OperationCode::MOVIECLIP_EVAL: return "MOVIECLIP_EVAL"; case OperationCode::MOVIECLIP_SELECT_UPDATE: return "MOVIECLIP_SELECT_UPDATE"; + /* Image. */ + case OperationCode::IMAGE_ANIMATION: return "IMAGE_ANIMATION"; /* Synchronization. */ case OperationCode::SYNCHRONIZE_TO_ORIGINAL: return "SYNCHRONIZE_TO_ORIGINAL"; diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.h b/source/blender/depsgraph/intern/node/deg_node_operation.h index 909f535a789..da823595705 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.h +++ b/source/blender/depsgraph/intern/node/deg_node_operation.h @@ -173,6 +173,9 @@ enum class OperationCode { MOVIECLIP_EVAL, MOVIECLIP_SELECT_UPDATE, + /* Images. -------------------------------------------------------------- */ + IMAGE_ANIMATION, + /* Synchronization clips. ----------------------------------------------- */ SYNCHRONIZE_TO_ORIGINAL, diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c index 6d5b870d2e0..795bc6b436f 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c @@ -319,7 +319,7 @@ static DRWShadingGroup *DRW_gpencil_shgroup_fill_create( BKE_image_release_ibuf(image, ibuf, NULL); } else { - GPUTexture *texture = GPU_texture_from_blender(gp_style->ima, &iuser, GL_TEXTURE_2D, true, 0.0); + GPUTexture *texture = GPU_texture_from_blender(gp_style->ima, &iuser, GL_TEXTURE_2D, true); DRW_shgroup_uniform_texture(grp, "myTexture", texture); stl->shgroups[id].texture_clamp = gp_style->flag & GP_STYLE_COLOR_TEX_CLAMP ? 1 : 0; @@ -432,7 +432,7 @@ DRWShadingGroup *DRW_gpencil_shgroup_stroke_create( BKE_image_release_ibuf(image, ibuf, NULL); } else { - GPUTexture *texture = GPU_texture_from_blender(gp_style->sima, &iuser, GL_TEXTURE_2D, true, 0.0f); + GPUTexture *texture = GPU_texture_from_blender(gp_style->sima, &iuser, GL_TEXTURE_2D, true); DRW_shgroup_uniform_texture(grp, "myTexture", texture); BKE_image_release_ibuf(image, ibuf, NULL); @@ -525,7 +525,7 @@ static DRWShadingGroup *DRW_gpencil_shgroup_point_create( BKE_image_release_ibuf(image, ibuf, NULL); } else { - GPUTexture *texture = GPU_texture_from_blender(gp_style->sima, &iuser, GL_TEXTURE_2D, true, 0.0f); + GPUTexture *texture = GPU_texture_from_blender(gp_style->sima, &iuser, GL_TEXTURE_2D, true); DRW_shgroup_uniform_texture(grp, "myTexture", texture); BKE_image_release_ibuf(image, ibuf, NULL); diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index cd6990f2e33..ef9e1682a8b 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -189,7 +189,7 @@ WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data( if (workbench_material_determine_color_type(wpd, material->ima, ob) == V3D_SHADING_TEXTURE_COLOR) { material->shgrp_object_outline = DRW_shgroup_create( e_data.object_outline_texture_sh, psl->object_outline_pass); - GPUTexture *tex = GPU_texture_from_blender(material->ima, NULL, GL_TEXTURE_2D, false, 0.0f); + GPUTexture *tex = GPU_texture_from_blender(material->ima, NULL, GL_TEXTURE_2D, false); DRW_shgroup_uniform_texture(material->shgrp_object_outline, "image", tex); } else { diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c index 10104358bdf..3f0f119a106 100644 --- a/source/blender/draw/engines/workbench/workbench_materials.c +++ b/source/blender/draw/engines/workbench/workbench_materials.c @@ -247,7 +247,7 @@ void workbench_material_shgroup_uniform( ImBuf *ibuf = BKE_image_acquire_ibuf(material->ima, NULL, NULL); const bool do_color_correction = (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0); BKE_image_release_ibuf(material->ima, ibuf, NULL); - GPUTexture *tex = GPU_texture_from_blender(material->ima, NULL, GL_TEXTURE_2D, false, 0.0f); + GPUTexture *tex = GPU_texture_from_blender(material->ima, NULL, GL_TEXTURE_2D, false); DRW_shgroup_uniform_texture(grp, "image", tex); DRW_shgroup_uniform_bool_copy(grp, "imageSrgb", do_color_correction); DRW_shgroup_uniform_bool_copy(grp, "imageNearest", (interp == SHD_INTERP_CLOSEST)); diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index 54456d43ef7..ca0bfba4da1 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -848,8 +848,7 @@ static DRWShadingGroup *drw_shgroup_material_inputs(DRWShadingGroup *grp, struct GPUTexture *tex = NULL; if (input->ima) { - double time = 0.0; /* TODO make time variable */ - tex = GPU_texture_from_blender(input->ima, input->iuser, GL_TEXTURE_2D, input->image_isdata, time); + tex = GPU_texture_from_blender(input->ima, input->iuser, GL_TEXTURE_2D, input->image_isdata); } else { /* Color Ramps */ diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 86ab27fe6a1..ac863395ab5 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -924,7 +924,7 @@ static void DRW_shgroup_empty_image( GPUTexture *tex = NULL; if (ob->data != NULL) { - tex = GPU_texture_from_blender(ob->data, ob->iuser, GL_TEXTURE_2D, false, 0.0f); + tex = GPU_texture_from_blender(ob->data, ob->iuser, GL_TEXTURE_2D, false); if (tex) { size[0] = GPU_texture_width(tex); size[1] = GPU_texture_height(tex); diff --git a/source/blender/draw/modes/paint_texture_mode.c b/source/blender/draw/modes/paint_texture_mode.c index 8289a8bc06f..45ba03b8e36 100644 --- a/source/blender/draw/modes/paint_texture_mode.c +++ b/source/blender/draw/modes/paint_texture_mode.c @@ -193,7 +193,7 @@ static void PAINT_TEXTURE_cache_init(void *vedata) Image *ima = (ma && ma->texpaintslot) ? ma->texpaintslot[ma->paint_active_slot].ima : NULL; int interp = (ma && ma->texpaintslot) ? ma->texpaintslot[ma->paint_active_slot].interp : 0; GPUTexture *tex = ima ? - GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D, false, 0.0f) : NULL; + GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D, false) : NULL; if (tex) { DRWShadingGroup *grp = DRW_shgroup_create(e_data.image_sh, psl->image_faces); @@ -211,7 +211,7 @@ static void PAINT_TEXTURE_cache_init(void *vedata) else { Image *ima = imapaint->canvas; GPUTexture *tex = ima ? - GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D, false, 0.0f) : NULL; + GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D, false) : NULL; if (tex) { DRWShadingGroup *grp = DRW_shgroup_create(e_data.image_sh, psl->image_faces); diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index f2185c2a3d2..b77c08736dc 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -857,7 +857,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char ima = imaptr.data; iuser = userptr->data; - BKE_image_user_check_frame_calc(iuser, (int)scene->r.cfra); + BKE_image_user_frame_calc(iuser, (int)scene->r.cfra); cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb"); cb->ptr = *ptr; @@ -1242,6 +1242,7 @@ void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser void uiTemplateImageInfo(uiLayout *layout, bContext *C, Image *ima, ImageUser *iuser) { + Scene *scene = CTX_data_scene(C); ImBuf *ibuf; char str[MAX_IMAGE_INFO_LEN]; void *lock; @@ -1251,7 +1252,8 @@ void uiTemplateImageInfo(uiLayout *layout, bContext *C, Image *ima, ImageUser *i ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock); - image_info(CTX_data_scene(C), iuser, ima, ibuf, str, MAX_IMAGE_INFO_LEN); + BKE_image_user_frame_calc(iuser, (int)scene->r.cfra); + image_info(scene, iuser, ima, ibuf, str, MAX_IMAGE_INFO_LEN); BKE_image_release_ibuf(ima, ibuf, lock); uiItemL(layout, str, ICON_NONE); } diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 0cac6360205..9171b923bad 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -335,7 +335,7 @@ static void image_refresh(const bContext *C, ScrArea *sa) ima = ED_space_image(sima); - BKE_image_user_check_frame_calc(&sima->iuser, scene->r.cfra); + BKE_image_user_frame_calc(&sima->iuser, scene->r.cfra); /* check if we have to set the image from the editmesh */ if (ima && (ima->source == IMA_SRC_VIEWER && sima->mode == SI_MODE_MASK)) { diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index 8efd721b800..5732bad81a9 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -174,7 +174,7 @@ GPUTexture *GPU_texture_create_buffer( GPUTexture *GPU_texture_from_bindcode(int textarget, int bindcode); GPUTexture *GPU_texture_from_blender( - struct Image *ima, struct ImageUser *iuser, int textarget, bool is_data, double time); + struct Image *ima, struct ImageUser *iuser, int textarget, bool is_data); GPUTexture *GPU_texture_from_preview(struct PreviewImage *prv, int mipmap); void GPU_texture_add_mipmap(GPUTexture *tex, eGPUDataFormat gpu_data_format, int miplvl, const void *pixels); diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index a3a220ad530..f6654ecfd0b 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -75,6 +75,8 @@ # include "smoke_API.h" #endif +static void gpu_free_image_immediate(Image *ima); + //* Checking powers of two for images since OpenGL ES requires it */ #ifdef WITH_DDS static bool is_power_of_2_resolution(int w, int h) @@ -262,13 +264,18 @@ GPUTexture *GPU_texture_from_blender( Image *ima, ImageUser *iuser, int textarget, - bool is_data, - double UNUSED(time)) + bool is_data) { if (ima == NULL) { return NULL; } + /* currently, gpu refresh tagging is used by ima sequences */ + if (ima->gpuflag & IMA_GPU_REFRESH) { + gpu_free_image_immediate(ima); + ima->gpuflag &= ~IMA_GPU_REFRESH; + } + /* Test if we already have a texture. */ GPUTexture **tex = gpu_get_image_gputexture(ima, textarget); if (*tex) { @@ -283,12 +290,6 @@ GPUTexture *GPU_texture_from_blender( return *tex; } - /* currently, tpage refresh is used by ima sequences */ - if (ima->gpuflag & IMA_GPU_REFRESH) { - GPU_free_image(ima); - ima->gpuflag &= ~IMA_GPU_REFRESH; - } - /* check if we have a valid image buffer */ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL); if (ibuf == NULL) { @@ -1128,13 +1129,8 @@ void GPU_free_unused_buffers(Main *bmain) BLI_thread_unlock(LOCK_OPENGL); } -void GPU_free_image(Image *ima) +static void gpu_free_image_immediate(Image *ima) { - if (!BLI_thread_is_main()) { - gpu_queue_image_for_free(ima); - return; - } - for (int i = 0; i < TEXTARGET_COUNT; i++) { /* free glsl image binding */ if (ima->gputexture[i]) { @@ -1146,6 +1142,16 @@ void GPU_free_image(Image *ima) ima->gpuflag &= ~(IMA_GPU_MIPMAP_COMPLETE | IMA_GPU_IS_DATA); } +void GPU_free_image(Image *ima) +{ + if (!BLI_thread_is_main()) { + gpu_queue_image_for_free(ima); + return; + } + + gpu_free_image_immediate(ima); +} + void GPU_free_images(Main *bmain) { if (bmain) { diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index ce92ddefc8f..84001926839 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -21,6 +21,7 @@ #include <stdlib.h> #include "DNA_image_types.h" +#include "DNA_node_types.h" #include "DNA_scene_types.h" #include "BLI_utildefines.h" @@ -66,6 +67,8 @@ static const EnumPropertyItem image_source_items[] = { #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" +#include "ED_node.h" + static bool rna_Image_is_stereo_3d_get(PointerRNA *ptr) { return BKE_image_is_stereo((Image *)ptr->data); @@ -136,16 +139,23 @@ static void rna_Image_views_format_update(Main *bmain, Scene *scene, PointerRNA BKE_image_release_ibuf(ima, ibuf, lock); } -static void rna_ImageUser_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr) +static void rna_ImageUser_update(Main *bmain, Scene *scene, PointerRNA *ptr) { ImageUser *iuser = ptr->data; + ID *id = ptr->id.data; BKE_image_user_frame_calc(iuser, scene->r.cfra); - if (ptr->id.data) { - /* Update material or texture for render preview. */ - DEG_id_tag_update(ptr->id.data, 0); - DEG_id_tag_update(ptr->id.data, ID_RECALC_EDITORS); + if (id) { + if (GS(id->name) == ID_NT) { + /* Special update for nodetrees to find parent datablock. */ + ED_node_tag_update_nodetree(bmain, (bNodeTree *)id, NULL); + } + else { + /* Update material or texture for render preview. */ + DEG_id_tag_update(id, 0); + DEG_id_tag_update(id, ID_RECALC_EDITORS); + } } } diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c index 5b5f6d0d7db..3f6c1b92d8b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c @@ -48,8 +48,14 @@ static void node_shader_init_tex_environment(bNodeTree *UNUSED(ntree), bNode *no static int node_shader_gpu_tex_environment(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { Image *ima = (Image *)node->id; - ImageUser *iuser = NULL; NodeTexEnvironment *tex = node->storage; + + /* We get the image user from the original node, since GPU image keeps + * a pointer to it and the dependency refreshes the original. */ + bNode *node_original = node->original ? node->original : node; + NodeTexImage *tex_original = node_original->storage; + ImageUser *iuser = &tex_original->iuser; + int isdata = tex->color_space == SHD_COLORSPACE_NONE; GPUNodeLink *outalpha; diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c index 7b15555630e..ba5d34a445f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c @@ -67,8 +67,14 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat }; Image *ima = (Image *)node->id; - ImageUser *iuser = NULL; NodeTexImage *tex = node->storage; + + /* We get the image user from the original node, since GPU image keeps + * a pointer to it and the dependency refreshes the original. */ + bNode *node_original = node->original ? node->original : node; + NodeTexImage *tex_original = node_original->storage; + ImageUser *iuser = &tex_original->iuser; + const char *gpu_node_name = (tex->projection == SHD_PROJ_BOX) ? names_box[tex->interpolation] : names[tex->interpolation]; |