Fix sequencer multi-view context check

Own regression caused by [0] made to ensure the string was initialized,
without accounting for it being static & reused between calls.

Replace static variables with a struct that's passed to the function,
this explicitly shares state between calls as this static variable use
depended on BKE_scene_multiview_view_prefix_get always clearing prefix
variables with a zero view_id so future calls would also be cleared.

While this non-obvious behavior could be documented,
use more straightforward logic.

[0]: bdad2c0595
This commit is contained in:
Campbell Barton
2023-05-30 09:46:06 +10:00
parent 67d0ba4f80
commit 0a125fccf4

View File

@@ -314,35 +314,51 @@ static void seq_proxy_build_frame(const SeqRenderData *context,
}
/**
* Returns whether the file this context would read from even exist,
* if not, don't create the context
* Cache the result of #BKE_scene_multiview_view_prefix_get.
*/
static bool seq_proxy_multiview_context_invalid(Sequence *seq, Scene *scene, const int view_id)
typedef struct MultiViewPrefixVars {
char prefix[FILE_MAX];
const char *ext;
} MultiViewPrefixVars;
/**
* Returns whether the file this context would read from even exist,
* if not, don't create the context.
*
* \param prefix_vars: Stores prefix variables for reuse,
* these variables are for internal use, the caller must not depend on them.
*
* \note This function must first a `view_id` of zero, to initialize `prefix_vars`
* for use with other views.
*/
static bool seq_proxy_multiview_context_invalid(Sequence *seq,
Scene *scene,
const int view_id,
MultiViewPrefixVars *prefix_vars)
{
if ((scene->r.scemode & R_MULTIVIEW) == 0) {
return false;
}
if ((seq->type == SEQ_TYPE_IMAGE) && (seq->views_format == R_IMF_VIEWS_INDIVIDUAL)) {
static char prefix[FILE_MAX];
static const char *ext = NULL;
char str[FILE_MAX];
if (view_id == 0) {
/* Clear on first use. */
prefix_vars->prefix[0] = '\0';
prefix_vars->ext = NULL;
char path[FILE_MAX];
BLI_path_join(path, sizeof(path), seq->strip->dirpath, seq->strip->stripdata->filename);
BLI_path_abs(path, BKE_main_blendfile_path_from_global());
BKE_scene_multiview_view_prefix_get(scene, path, prefix, &ext);
}
else {
prefix[0] = '\0';
BKE_scene_multiview_view_prefix_get(scene, path, prefix_vars->prefix, &prefix_vars->ext);
}
if (prefix[0] == '\0') {
if (prefix_vars->prefix[0] == '\0') {
return view_id != 0;
}
seq_multiview_name(scene, view_id, prefix, ext, str, FILE_MAX);
seq_multiview_name(scene, view_id, prefix_vars->prefix, prefix_vars->ext, str, FILE_MAX);
if (BLI_access(str, R_OK) == 0) {
return false;
@@ -425,8 +441,9 @@ bool SEQ_proxy_rebuild_context(Main *bmain,
num_files = seq_proxy_context_count(seq, scene);
MultiViewPrefixVars prefix_vars; /* Initialized by #seq_proxy_multiview_context_invalid. */
for (i = 0; i < num_files; i++) {
if (seq_proxy_multiview_context_invalid(seq, scene, i)) {
if (seq_proxy_multiview_context_invalid(seq, scene, i, &prefix_vars)) {
continue;
}