Fix T93092: incomplete animation rendering of multi-layer exr composition

This was broken by rB0c3b215e7d5456878b155d13440864f49ad1f230.
The caching of loaded exr files needed some special treatment.

Differential Revision: https://developer.blender.org/D13313
This commit is contained in:
Jacques Lucke 2021-11-23 09:43:00 +01:00
parent 84be741329
commit b02ac2d8be
Notes: blender-bot 2023-02-13 17:07:21 +01:00
Referenced by issue #93310, Compositor: Crash due to broken image paths
Referenced by issue #93092, Incomplete Animation Rendering of MultiLayer EXR composition
1 changed files with 40 additions and 11 deletions

View File

@ -4214,13 +4214,16 @@ static int image_num_files(Image *ima)
return BLI_listbase_count(&ima->views);
}
static ImBuf *load_sequence_single(Image *ima, ImageUser *iuser, int frame, const int view_id)
static ImBuf *load_sequence_single(
Image *ima, ImageUser *iuser, int frame, const int view_id, bool *r_cache_ibuf)
{
struct ImBuf *ibuf;
char name[FILE_MAX];
int flag;
ImageUser iuser_t = {0};
*r_cache_ibuf = true;
ima->lastframe = frame;
if (iuser) {
@ -4260,6 +4263,9 @@ static ImBuf *load_sequence_single(Image *ima, ImageUser *iuser, int frame, cons
ima->type = IMA_TYPE_MULTILAYER;
IMB_freeImBuf(ibuf);
ibuf = NULL;
/* NULL ibuf in the cache means the image failed to load. However for multilayer we load
* pixels into RenderResult instead and intentionally leave ibuf NULL. */
*r_cache_ibuf = false;
}
}
else {
@ -4280,17 +4286,21 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int entry,
const int totfiles = image_num_files(ima);
if (!is_multiview) {
ibuf = load_sequence_single(ima, iuser, frame, 0);
image_assign_ibuf(ima, ibuf, 0, entry);
bool put_in_cache;
ibuf = load_sequence_single(ima, iuser, frame, 0, &put_in_cache);
if (put_in_cache) {
image_assign_ibuf(ima, ibuf, 0, entry);
}
}
else {
const int totviews = BLI_listbase_count(&ima->views);
struct ImBuf **ibuf_arr;
ibuf_arr = MEM_mallocN(sizeof(ImBuf *) * totviews, "Image Views Imbufs");
bool *cache_ibuf_arr = MEM_mallocN(sizeof(bool) * totviews, "Image View Put In Cache");
for (int i = 0; i < totfiles; i++) {
ibuf_arr[i] = load_sequence_single(ima, iuser, frame, i);
ibuf_arr[i] = load_sequence_single(ima, iuser, frame, i, cache_ibuf_arr + i);
}
if (BKE_image_is_stereo(ima) && ima->views_format == R_IMF_VIEWS_STEREO_3D) {
@ -4301,7 +4311,9 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int entry,
ibuf = ibuf_arr[(iuser ? iuser->multi_index : 0)];
for (int i = 0; i < totviews; i++) {
image_assign_ibuf(ima, ibuf_arr[i], i, entry);
if (cache_ibuf_arr[i]) {
image_assign_ibuf(ima, ibuf_arr[i], i, entry);
}
}
/* "remove" the others (decrease their refcount) */
@ -4313,6 +4325,7 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int entry,
/* cleanup */
MEM_freeN(ibuf_arr);
MEM_freeN(cache_ibuf_arr);
}
return ibuf;
@ -4474,13 +4487,19 @@ static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame)
return ibuf;
}
static ImBuf *load_image_single(
Image *ima, ImageUser *iuser, int cfra, const int view_id, const bool has_packed)
static ImBuf *load_image_single(Image *ima,
ImageUser *iuser,
int cfra,
const int view_id,
const bool has_packed,
bool *r_cache_ibuf)
{
char filepath[FILE_MAX];
struct ImBuf *ibuf = NULL;
int flag;
*r_cache_ibuf = true;
/* is there a PackedFile with this image ? */
if (has_packed) {
ImagePackedFile *imapf;
@ -4531,6 +4550,9 @@ static ImBuf *load_image_single(
ima->type = IMA_TYPE_MULTILAYER;
IMB_freeImBuf(ibuf);
ibuf = NULL;
/* NULL ibuf in the cache means the image failed to load. However for multilayer we load
* pixels into RenderResult instead and intentionally leave ibuf NULL. */
*r_cache_ibuf = false;
}
}
else
@ -4575,8 +4597,11 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
}
if (!is_multiview) {
ibuf = load_image_single(ima, iuser, cfra, 0, has_packed);
image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
bool put_in_cache;
ibuf = load_image_single(ima, iuser, cfra, 0, has_packed, &put_in_cache);
if (put_in_cache) {
image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
}
}
else {
struct ImBuf **ibuf_arr;
@ -4584,9 +4609,10 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
BLI_assert(totviews > 0);
ibuf_arr = MEM_callocN(sizeof(ImBuf *) * totviews, "Image Views Imbufs");
bool *cache_ibuf_arr = MEM_mallocN(sizeof(bool) * totviews, "Image Views Put In Cache");
for (int i = 0; i < totfiles; i++) {
ibuf_arr[i] = load_image_single(ima, iuser, cfra, i, has_packed);
ibuf_arr[i] = load_image_single(ima, iuser, cfra, i, has_packed, cache_ibuf_arr + i);
}
/* multi-views/multi-layers OpenEXR files directly populate ima, and return NULL ibuf... */
@ -4600,7 +4626,9 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
ibuf = ibuf_arr[i];
for (i = 0; i < totviews; i++) {
image_assign_ibuf(ima, ibuf_arr[i], i, 0);
if (cache_ibuf_arr[i]) {
image_assign_ibuf(ima, ibuf_arr[i], i, 0);
}
}
/* "remove" the others (decrease their refcount) */
@ -4612,6 +4640,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
/* cleanup */
MEM_freeN(ibuf_arr);
MEM_freeN(cache_ibuf_arr);
}
return ibuf;