diff --git a/source/blender/sequencer/SEQ_modifier.hh b/source/blender/sequencer/SEQ_modifier.hh index ab98a35f766..df04dd9ce0c 100644 --- a/source/blender/sequencer/SEQ_modifier.hh +++ b/source/blender/sequencer/SEQ_modifier.hh @@ -20,6 +20,7 @@ struct StripModifierData; namespace blender::seq { +struct SeqRenderState; struct StripScreenQuad; struct RenderData; @@ -79,6 +80,7 @@ void modifier_free(StripModifierData *smd); void modifier_unique_name(Strip *strip, StripModifierData *smd); StripModifierData *modifier_find_by_name(Strip *strip, const char *name); void modifier_apply_stack(const RenderData *context, + SeqRenderState *state, const Strip *strip, ImBuf *ibuf, int timeline_frame); diff --git a/source/blender/sequencer/intern/modifiers/modifier.cc b/source/blender/sequencer/intern/modifiers/modifier.cc index 96c161c5b94..70993e96035 100644 --- a/source/blender/sequencer/intern/modifiers/modifier.cc +++ b/source/blender/sequencer/intern/modifiers/modifier.cc @@ -326,6 +326,7 @@ void apply_and_advance_mask(float4 /*input*/, float4 & /*result*/, const void *& * \a timeline_frame is offset by \a fra_offset only in case we are using a real mask. */ static ImBuf *modifier_render_mask_input(const RenderData *context, + SeqRenderState *state, int mask_input_type, Strip *mask_strip, Mask *mask_id, @@ -336,8 +337,7 @@ static ImBuf *modifier_render_mask_input(const RenderData *context, if (mask_input_type == STRIP_MASK_INPUT_STRIP) { if (mask_strip) { - SeqRenderState state; - mask_input = seq_render_strip(context, &state, mask_strip, timeline_frame); + mask_input = seq_render_strip(context, state, mask_strip, timeline_frame); } } else if (mask_input_type == STRIP_MASK_INPUT_ID) { @@ -353,11 +353,17 @@ static ImBuf *modifier_render_mask_input(const RenderData *context, static ImBuf *modifier_mask_get(StripModifierData *smd, const RenderData *context, + SeqRenderState *state, int timeline_frame, int fra_offset) { - return modifier_render_mask_input( - context, smd->mask_input_type, smd->mask_strip, smd->mask_id, timeline_frame, fra_offset); + return modifier_render_mask_input(context, + state, + smd->mask_input_type, + smd->mask_strip, + smd->mask_id, + timeline_frame, + fra_offset); } /* -------------------------------------------------------------------- */ @@ -497,6 +503,7 @@ static bool skip_modifier(Scene *scene, const StripModifierData *smd, int timeli } void modifier_apply_stack(const RenderData *context, + SeqRenderState *state, const Strip *strip, ImBuf *ibuf, int timeline_frame) @@ -529,7 +536,7 @@ void modifier_apply_stack(const RenderData *context, frame_offset = smd->mask_id ? ((Mask *)smd->mask_id)->sfra : 0; } - ImBuf *mask = modifier_mask_get(smd, context, timeline_frame, frame_offset); + ImBuf *mask = modifier_mask_get(smd, context, state, timeline_frame, frame_offset); smti->apply(context, quad, smd, ibuf, mask); if (mask) { IMB_freeImBuf(mask); diff --git a/source/blender/sequencer/intern/render.cc b/source/blender/sequencer/intern/render.cc index 5b494a642f3..bd389ad9281 100644 --- a/source/blender/sequencer/intern/render.cc +++ b/source/blender/sequencer/intern/render.cc @@ -621,6 +621,7 @@ static void multiply_ibuf(ImBuf *ibuf, const float fmul, const bool multiply_alp } static ImBuf *input_preprocess(const RenderData *context, + SeqRenderState *state, Strip *strip, float timeline_frame, ImBuf *ibuf, @@ -691,13 +692,14 @@ static ImBuf *input_preprocess(const RenderData *context, } if (strip->modifiers.first) { - modifier_apply_stack(context, strip, preprocessed_ibuf, timeline_frame); + modifier_apply_stack(context, state, strip, preprocessed_ibuf, timeline_frame); } return preprocessed_ibuf; } static ImBuf *seq_render_preprocess_ibuf(const RenderData *context, + SeqRenderState *state, Strip *strip, ImBuf *ibuf, float timeline_frame, @@ -722,7 +724,7 @@ static ImBuf *seq_render_preprocess_ibuf(const RenderData *context, } if (use_preprocess) { - ibuf = input_preprocess(context, strip, timeline_frame, ibuf, is_proxy_image); + ibuf = input_preprocess(context, state, strip, timeline_frame, ibuf, is_proxy_image); } return ibuf; @@ -933,6 +935,7 @@ static ImBuf *create_missing_media_image(const RenderData *context, int width, i } static ImBuf *seq_render_image_strip(const RenderData *context, + SeqRenderState *state, Strip *strip, int timeline_frame, bool *r_is_proxy_image) @@ -985,7 +988,7 @@ static ImBuf *seq_render_image_strip(const RenderData *context, if (view_id != context->view_id) { ibufs_arr[view_id] = seq_render_preprocess_ibuf( - &localcontext, strip, ibufs_arr[view_id], timeline_frame, true, false); + &localcontext, state, strip, ibufs_arr[view_id], timeline_frame, true, false); } } @@ -1105,6 +1108,7 @@ static ImBuf *seq_render_movie_strip_view(const RenderData *context, } static ImBuf *seq_render_movie_strip(const RenderData *context, + SeqRenderState *state, Strip *strip, float timeline_frame, bool *r_is_proxy_image) @@ -1150,7 +1154,7 @@ static ImBuf *seq_render_movie_strip(const RenderData *context, if (view_id != context->view_id && ibuf_arr[view_id]) { ibuf_arr[view_id] = seq_render_preprocess_ibuf( - &localcontext, strip, ibuf_arr[view_id], timeline_frame, true, false); + &localcontext, state, strip, ibuf_arr[view_id], timeline_frame, true, false); } } @@ -1693,10 +1697,10 @@ static ImBuf *do_render_strip_uncached(const RenderData *context, ibuf = seq_render_effect_strip_impl(context, state, strip, timeline_frame); } else if (strip->type == STRIP_TYPE_IMAGE) { - ibuf = seq_render_image_strip(context, strip, timeline_frame, r_is_proxy_image); + ibuf = seq_render_image_strip(context, state, strip, timeline_frame, r_is_proxy_image); } else if (strip->type == STRIP_TYPE_MOVIE) { - ibuf = seq_render_movie_strip(context, strip, timeline_frame, r_is_proxy_image); + ibuf = seq_render_movie_strip(context, state, strip, timeline_frame, r_is_proxy_image); } else if (strip->type == STRIP_TYPE_MOVIECLIP) { ibuf = seq_render_movieclip_strip( @@ -1750,7 +1754,7 @@ ImBuf *seq_render_strip(const RenderData *context, if (ibuf) { use_preprocess = seq_input_have_to_preprocess(context, strip, timeline_frame); ibuf = seq_render_preprocess_ibuf( - context, strip, ibuf, timeline_frame, use_preprocess, is_proxy_image); + context, state, strip, ibuf, timeline_frame, use_preprocess, is_proxy_image); intra_frame_cache_put_preprocessed(context->scene, strip, ibuf); } diff --git a/tests/files/sequence_editing/effects/recursive_mask_crash_146943.blend b/tests/files/sequence_editing/effects/recursive_mask_crash_146943.blend new file mode 100644 index 00000000000..b79c65b7d47 --- /dev/null +++ b/tests/files/sequence_editing/effects/recursive_mask_crash_146943.blend @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82282256f8051ceb1dea4a3244705d698e880d6a3fd89c93e93123590e54b090 +size 75980 diff --git a/tests/files/sequence_editing/effects/reference/recursive_mask_crash_146943.png b/tests/files/sequence_editing/effects/reference/recursive_mask_crash_146943.png new file mode 100644 index 00000000000..208532a1a5c --- /dev/null +++ b/tests/files/sequence_editing/effects/reference/recursive_mask_crash_146943.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a8575461ef5880eec3b52544c72f11b58b3462b1db029537fffd1db6ba26378 +size 1799