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:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2019-02-18 15:23:49 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2019-02-18 18:52:01 +0300
commit0e3a2acbfa6998b3a1ec967f3c25f7e12e0cf8fb (patch)
treedde289c6fbe219951ae5618866b33dfcfa3325e4
parent286c34b4abb0436fb370c8d49fd73738dabc0fcf (diff)
Fix T57457: animated image sequences not working in Eevee.
The dependency graph now handles updating image users to point to the current frame, and tags images to be refreshed on the GPU. The image editor user is still updated outside of the dependency graph. We still do not support multiple image users using a different current frame in the same image, same as 2.7. This may require adding a GPU image texture cache to keep memory usage under control. Things like rendering an animation while the viewport stays fixed at the current frame works though.
-rw-r--r--source/blender/blenkernel/BKE_image.h7
-rw-r--r--source/blender/blenkernel/intern/image.c73
-rw-r--r--source/blender/blenkernel/intern/object_update.c8
-rw-r--r--source/blender/blenkernel/intern/scene.c2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc19
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h1
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc15
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h1
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_operation.cc2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_operation.h3
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_utils.c6
-rw-r--r--source/blender/draw/engines/workbench/workbench_forward.c2
-rw-r--r--source/blender/draw/engines/workbench/workbench_materials.c2
-rw-r--r--source/blender/draw/intern/draw_manager_data.c3
-rw-r--r--source/blender/draw/modes/object_mode.c2
-rw-r--r--source/blender/draw/modes/paint_texture_mode.c4
-rw-r--r--source/blender/editors/space_image/image_buttons.c6
-rw-r--r--source/blender/editors/space_image/space_image.c2
-rw-r--r--source/blender/gpu/GPU_texture.h2
-rw-r--r--source/blender/gpu/intern/gpu_draw.c34
-rw-r--r--source/blender/makesrna/intern/rna_image.c20
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.c8
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];