From 29b9187b327ce09362c3ad369ba24058a76cae45 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Mon, 25 Apr 2022 01:21:21 +0200 Subject: VSE: Update first thumbnail when moving handle When handles are moved, job is created only for strips that need to update first thumbnail. ref T91618 --- .../editors/space_sequencer/sequencer_thumbnails.c | 65 ++++++++-------------- source/blender/sequencer/SEQ_render.h | 14 ++++- source/blender/sequencer/intern/render.c | 41 +++++++++++--- 3 files changed, 68 insertions(+), 52 deletions(-) diff --git a/source/blender/editors/space_sequencer/sequencer_thumbnails.c b/source/blender/editors/space_sequencer/sequencer_thumbnails.c index f5c5c7af4b6..43c5e004040 100644 --- a/source/blender/editors/space_sequencer/sequencer_thumbnails.c +++ b/source/blender/editors/space_sequencer/sequencer_thumbnails.c @@ -86,6 +86,11 @@ static bool check_seq_need_thumbnails(Sequence *seq, rctf *view_area) return false; } + /* Handle is moved, but not for this strip. */ + if ((G.moving & G_TRANSFORM_SEQ) != 0 && (seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == 0) { + return false; + } + return true; } @@ -123,26 +128,13 @@ static void seq_get_thumb_image_dimensions(Sequence *seq, } } -static float seq_thumbnail_get_start_frame(Sequence *seq, float frame_step, rctf *view_area) -{ - if (seq->start > view_area->xmin && seq->start < view_area->xmax) { - return seq->start; - } - - /* Drawing and caching both check to see if strip is in view area or not before calling this - * function so assuming strip/part of strip in view. */ - - int no_invisible_thumbs = (view_area->xmin - seq->start) / frame_step; - return ((no_invisible_thumbs - 1) * frame_step) + seq->start; -} - static void thumbnail_start_job(void *data, short *stop, short *UNUSED(do_update), float *UNUSED(progress)) { ThumbnailDrawJob *tj = data; - float start_frame, frame_step; + float frame_step; GHashIterator gh_iter; @@ -155,9 +147,8 @@ static void thumbnail_start_job(void *data, if (check_seq_need_thumbnails(seq_orig, tj->view_area)) { seq_get_thumb_image_dimensions( val->seq_dupli, tj->pixelx, tj->pixely, &frame_step, tj->thumb_height, NULL, NULL); - start_frame = seq_thumbnail_get_start_frame(seq_orig, frame_step, tj->view_area); SEQ_render_thumbnails( - &tj->context, val->seq_dupli, seq_orig, start_frame, frame_step, tj->view_area, stop); + &tj->context, val->seq_dupli, seq_orig, frame_step, tj->view_area, stop); SEQ_relations_sequence_free_anim(val->seq_dupli); } BLI_ghashIterator_step(&gh_iter); @@ -172,7 +163,6 @@ static void thumbnail_start_job(void *data, if (check_seq_need_thumbnails(seq_orig, tj->view_area)) { seq_get_thumb_image_dimensions( val->seq_dupli, tj->pixelx, tj->pixely, &frame_step, tj->thumb_height, NULL, NULL); - start_frame = seq_thumbnail_get_start_frame(seq_orig, frame_step, tj->view_area); SEQ_render_thumbnails_base_set(&tj->context, val->seq_dupli, seq_orig, tj->view_area, stop); SEQ_relations_sequence_free_anim(val->seq_dupli); } @@ -458,40 +448,31 @@ void draw_seq_strip_thumbnail(View2D *v2d, upper_thumb_bound = seq->enddisp; } - float thumb_x_start = seq_thumbnail_get_start_frame(seq, thumb_width, &v2d->cur); + float timeline_frame = SEQ_render_thumbnail_first_frame_get(seq, thumb_width, &v2d->cur); float thumb_x_end; - while (thumb_x_start + thumb_width < v2d->cur.xmin) { - thumb_x_start += thumb_width; - } - - /* Ignore thumbs to the left of strip. */ - while (thumb_x_start + thumb_width < seq->startdisp) { - thumb_x_start += thumb_width; - } - GSet *last_displayed_thumbnails = last_displayed_thumbnails_list_ensure(C, seq); /* Cleanup thumbnail list outside of rendered range, which is cleaned up one by one to prevent * flickering after zooming. */ if (!sequencer_thumbnail_v2d_is_navigating(C)) { - last_displayed_thumbnails_list_cleanup(last_displayed_thumbnails, -FLT_MAX, thumb_x_start); + last_displayed_thumbnails_list_cleanup(last_displayed_thumbnails, -FLT_MAX, timeline_frame); } /* Start drawing. */ - while (thumb_x_start < upper_thumb_bound) { - thumb_x_end = thumb_x_start + thumb_width; + while (timeline_frame < upper_thumb_bound) { + thumb_x_end = timeline_frame + thumb_width; clipped = false; /* Checks to make sure that thumbs are loaded only when in view and within the confines of the * strip. Some may not be required but better to have conditions for safety as x1 here is * point to start caching from and not drawing. */ - if (thumb_x_start > v2d->cur.xmax) { + if (timeline_frame > v2d->cur.xmax) { break; } /* Set the clipping bound to show the left handle moving over thumbs and not shift thumbs. */ - if (IN_RANGE_INCL(seq->startdisp, thumb_x_start, thumb_x_end)) { - cut_off = seq->startdisp - thumb_x_start; + if (IN_RANGE_INCL(seq->startdisp, timeline_frame, thumb_x_end)) { + cut_off = seq->startdisp - timeline_frame; clipped = true; } @@ -499,7 +480,7 @@ void draw_seq_strip_thumbnail(View2D *v2d, if (thumb_x_end > (upper_thumb_bound)) { thumb_x_end = upper_thumb_bound; clipped = true; - if (thumb_x_end - thumb_x_start < 1) { + if (thumb_x_end - timeline_frame < 1) { break; } } @@ -508,14 +489,12 @@ void draw_seq_strip_thumbnail(View2D *v2d, float zoom_y = thumb_height / image_height; float cropx_min = (cut_off / pixelx) / (zoom_y / pixely); - float cropx_max = ((thumb_x_end - thumb_x_start) / pixelx) / (zoom_y / pixely); - if (cropx_max == (thumb_x_end - thumb_x_start)) { + float cropx_max = ((thumb_x_end - timeline_frame) / pixelx) / (zoom_y / pixely); + if (cropx_max == (thumb_x_end - timeline_frame)) { cropx_max = cropx_max + 1; } BLI_rcti_init(&crop, (int)(cropx_min), (int)cropx_max, 0, (int)(image_height)-1); - int timeline_frame = round_fl_to_int(thumb_x_start); - /* Get the image. */ ImBuf *ibuf = SEQ_get_thumbnail(&context, seq, timeline_frame, &crop, clipped); @@ -529,7 +508,7 @@ void draw_seq_strip_thumbnail(View2D *v2d, else if (!sequencer_thumbnail_v2d_is_navigating(C)) { /* Clear images in frame range occupied by new thumbnail. */ last_displayed_thumbnails_list_cleanup( - last_displayed_thumbnails, thumb_x_start, thumb_x_end); + last_displayed_thumbnails, timeline_frame, thumb_x_end); /* Insert new thumbnail frame to list. */ BLI_gset_add(last_displayed_thumbnails, POINTER_FROM_INT(timeline_frame)); } @@ -558,10 +537,10 @@ void draw_seq_strip_thumbnail(View2D *v2d, ED_draw_imbuf_ctx_clipping(C, ibuf, - thumb_x_start + cut_off, + timeline_frame + cut_off, y1, true, - thumb_x_start + cut_off, + timeline_frame + cut_off, y1, thumb_x_end, thumb_y_end, @@ -570,7 +549,7 @@ void draw_seq_strip_thumbnail(View2D *v2d, IMB_freeImBuf(ibuf); GPU_blend(GPU_BLEND_NONE); cut_off = 0; - thumb_x_start += thumb_width; + timeline_frame = SEQ_render_thumbnail_next_frame_get(seq, timeline_frame, thumb_width); } - last_displayed_thumbnails_list_cleanup(last_displayed_thumbnails, thumb_x_start, FLT_MAX); + last_displayed_thumbnails_list_cleanup(last_displayed_thumbnails, timeline_frame, FLT_MAX); } diff --git a/source/blender/sequencer/SEQ_render.h b/source/blender/sequencer/SEQ_render.h index bfe10d3eae9..a74eba5fc6f 100644 --- a/source/blender/sequencer/SEQ_render.h +++ b/source/blender/sequencer/SEQ_render.h @@ -17,6 +17,7 @@ struct ListBase; struct Main; struct Scene; struct Sequence; +struct rctf; typedef enum eSeqTaskId { SEQ_TASK_MAIN_RENDER, @@ -64,7 +65,6 @@ struct ImBuf *SEQ_render_give_ibuf_direct(const SeqRenderData *context, void SEQ_render_thumbnails(const struct SeqRenderData *context, struct Sequence *seq, struct Sequence *seq_orig, - float start_frame, float frame_step, rctf *view_area, const short *stop); @@ -76,6 +76,18 @@ struct ImBuf *SEQ_get_thumbnail(const struct SeqRenderData *context, float timeline_frame, rcti *crop, bool clipped); +/** + * Get frame for first thumbnail. + */ +float SEQ_render_thumbnail_first_frame_get(struct Sequence *seq, + float frame_step, + struct rctf *view_area); +/** + * Get frame for first thumbnail. + */ +float SEQ_render_thumbnail_next_frame_get(struct Sequence *seq, + float last_frame, + float frame_step); /** * Get frame step for equally spaced thumbnails. These thumbnails should always be present in * memory, so they can be used when zooming. diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c index 18b0794dc72..8d8a13be09e 100644 --- a/source/blender/sequencer/intern/render.c +++ b/source/blender/sequencer/intern/render.c @@ -1992,6 +1992,32 @@ ImBuf *SEQ_render_give_ibuf_direct(const SeqRenderData *context, return ibuf; } +float SEQ_render_thumbnail_first_frame_get(Sequence *seq, float frame_step, rctf *view_area) +{ + int first_drawable_frame = max_iii(seq->startdisp, seq->start, view_area->xmin); + + /* First frame should correspond to handle position. */ + if (first_drawable_frame == seq->startdisp) { + return seq->startdisp; + } + + float aligned_frame_offset = (int)((first_drawable_frame - seq->start) / frame_step) * + frame_step; + return seq->start + aligned_frame_offset; +} + +float SEQ_render_thumbnail_next_frame_get(Sequence *seq, float last_frame, float frame_step) +{ + float next_frame = last_frame + frame_step; + + /* If handle position was displayed, align next frame with `seq->start`. */ + if (last_frame == seq->startdisp) { + next_frame = seq->start + ((int)((last_frame - seq->start) / frame_step) + 1) * frame_step; + } + + return next_frame; +} + /* Gets the direct image from source and scales to thumbnail size. */ static ImBuf *seq_get_uncached_thumbnail(const SeqRenderData *context, SeqRenderState *state, @@ -2053,7 +2079,6 @@ ImBuf *SEQ_get_thumbnail( void SEQ_render_thumbnails(const SeqRenderData *context, Sequence *seq, Sequence *seq_orig, - float start_frame, float frame_step, rctf *view_area, const short *stop) @@ -2063,24 +2088,24 @@ void SEQ_render_thumbnails(const SeqRenderData *context, /* Adding the hold offset value (seq->anim_startofs) to the start frame. Position of image not * affected, but frame loaded affected. */ - start_frame = start_frame - frame_step; float upper_thumb_bound = (seq->endstill) ? (seq->start + seq->len) : seq->enddisp; upper_thumb_bound = (upper_thumb_bound > view_area->xmax) ? view_area->xmax + frame_step : upper_thumb_bound; - while ((start_frame < upper_thumb_bound) & !*stop) { + float timeline_frame = SEQ_render_thumbnail_first_frame_get(seq, frame_step, view_area); + while ((timeline_frame < upper_thumb_bound) & !*stop) { ImBuf *ibuf = seq_cache_get( - context, seq_orig, round_fl_to_int(start_frame), SEQ_CACHE_STORE_THUMBNAIL); + context, seq_orig, round_fl_to_int(timeline_frame), SEQ_CACHE_STORE_THUMBNAIL); if (ibuf) { IMB_freeImBuf(ibuf); - start_frame += frame_step; + timeline_frame = SEQ_render_thumbnail_next_frame_get(seq, timeline_frame, frame_step); continue; } - ibuf = seq_get_uncached_thumbnail(context, &state, seq, round_fl_to_int(start_frame)); + ibuf = seq_get_uncached_thumbnail(context, &state, seq, round_fl_to_int(timeline_frame)); if (ibuf) { - seq_cache_thumbnail_put(context, seq_orig, round_fl_to_int(start_frame), ibuf, view_area); + seq_cache_thumbnail_put(context, seq_orig, round_fl_to_int(timeline_frame), ibuf, view_area); IMB_freeImBuf(ibuf); seq_orig->flag &= ~SEQ_FLAG_SKIP_THUMBNAILS; } @@ -2090,7 +2115,7 @@ void SEQ_render_thumbnails(const SeqRenderData *context, return; } - start_frame += frame_step; + timeline_frame = SEQ_render_thumbnail_next_frame_get(seq, timeline_frame, frame_step); } } -- cgit v1.2.3