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:
Diffstat (limited to 'source/blender/sequencer/intern/render.c')
-rw-r--r--source/blender/sequencer/intern/render.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c
index 12d97d7e3e3..2246336369b 100644
--- a/source/blender/sequencer/intern/render.c
+++ b/source/blender/sequencer/intern/render.c
@@ -466,6 +466,45 @@ static void sequencer_thumbnail_transform(ImBuf *in, ImBuf *out)
IMB_transform(in, out, transform_matrix, &source_crop, IMB_FILTER_NEAREST);
}
+/* Check whether transform introduces transparent ares in the result (happens when the transformed
+ * image does not fully cover the render frame).
+ *
+ * The check is done by checking whether all corners of viewport fit inside of the transformed
+ * image. If they do not the image will have transparent areas. */
+static bool seq_image_transform_transparency_gained(const SeqRenderData *context, Sequence *seq)
+{
+ Scene *scene = context->scene;
+ const int x = context->rectx;
+ const int y = context->recty;
+
+ float seq_image_quad[4][2];
+ SEQ_image_transform_final_quad_get(scene, seq, seq_image_quad);
+ for (int i = 0; i < 4; i++) {
+ add_v2_v2(seq_image_quad[i], (float[]){x / 2, y / 2});
+ }
+
+ return !isect_point_quad_v2((float[]){x, y},
+ seq_image_quad[0],
+ seq_image_quad[1],
+ seq_image_quad[2],
+ seq_image_quad[3]) ||
+ !isect_point_quad_v2((float[]){0, y},
+ seq_image_quad[0],
+ seq_image_quad[1],
+ seq_image_quad[2],
+ seq_image_quad[3]) ||
+ !isect_point_quad_v2((float[]){x, 0},
+ seq_image_quad[0],
+ seq_image_quad[1],
+ seq_image_quad[2],
+ seq_image_quad[3]) ||
+ !isect_point_quad_v2((float[]){0, 0},
+ seq_image_quad[0],
+ seq_image_quad[1],
+ seq_image_quad[2],
+ seq_image_quad[3]);
+}
+
static void sequencer_preprocess_transform_crop(
ImBuf *in, ImBuf *out, const SeqRenderData *context, Sequence *seq, const bool is_proxy_image)
{
@@ -490,6 +529,13 @@ static void sequencer_preprocess_transform_crop(
const eIMBInterpolationFilterMode filter = context->for_render ? IMB_FILTER_BILINEAR :
IMB_FILTER_NEAREST;
IMB_transform(in, out, transform_matrix, &source_crop, filter);
+
+ if (!seq_image_transform_transparency_gained(context, seq)) {
+ out->planes = in->planes;
+ }
+ else {
+ out->planes = R_IMF_PLANES_RGBA;
+ }
}
static void multibuf(ImBuf *ibuf, const float fmul)
@@ -525,6 +571,10 @@ static void multibuf(ImBuf *ibuf, const float fmul)
rt_float += 4;
}
}
+
+ if (ELEM(ibuf->planes, R_IMF_PLANES_BW, R_IMF_PLANES_RGB) && fmul < 1.0f) {
+ ibuf->planes = R_IMF_PLANES_RGBA;
+ }
}
static ImBuf *input_preprocess(const SeqRenderData *context,
@@ -1804,6 +1854,20 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
early_out = seq_get_early_out_for_blend_mode(seq);
+ /* Early out for alpha over. It requires image to be rendered, so it can't use
+ * `seq_get_early_out_for_blend_mode`. */
+ if (out == NULL && seq->blend_mode == SEQ_TYPE_ALPHAOVER && seq->blend_opacity == 100.0f) {
+ ImBuf *test = seq_render_strip(context, state, seq, timeline_frame);
+ if (ELEM(test->planes, R_IMF_PLANES_BW, R_IMF_PLANES_RGB)) {
+ early_out = EARLY_USE_INPUT_2;
+ }
+ else {
+ early_out = EARLY_DO_EFFECT;
+ }
+ /* Free the image. It is stored in cache, so this doesn't affect performance. */
+ IMB_freeImBuf(test);
+ }
+
switch (early_out) {
case EARLY_NO_INPUT:
case EARLY_USE_INPUT_2:
@@ -1828,6 +1892,7 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
}
break;
}
+
if (out) {
break;
}